diff --git a/.gitignore b/.gitignore index 6df2d7096383..b559f5331c95 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.settings/ /.idea /*.iml +/deploy diff --git a/bootstrap/build.xml b/bootstrap/build.xml index 7f8e332a1f68..b303cc4d2be4 100644 --- a/bootstrap/build.xml +++ b/bootstrap/build.xml @@ -1,50 +1,50 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bootstrap/findbugs-exclude.xml b/bootstrap/findbugs-exclude.xml index a4b4e8251d57..0193409a64e7 100644 --- a/bootstrap/findbugs-exclude.xml +++ b/bootstrap/findbugs-exclude.xml @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/ProductInfo.java b/bootstrap/src/main/java/com/navercorp/pinpoint/ProductInfo.java index 050f93a5fa3e..61f4fcd7aa49 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/ProductInfo.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/ProductInfo.java @@ -1,9 +1,9 @@ -package com.nhn.pinpoint; - -/** - * @author emeroad - */ -public final class ProductInfo { - public static final String NAME = "pinpoint"; - public static final String CAMEL_NAME = "Pinpoint"; -} +package com.nhn.pinpoint; + +/** + * @author emeroad + */ +public final class ProductInfo { + public static final String NAME = "pinpoint"; + public static final String CAMEL_NAME = "Pinpoint"; +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/Agent.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/Agent.java index b0a323bd3566..49f4800b7d2a 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/Agent.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/Agent.java @@ -1,23 +1,22 @@ -package com.nhn.pinpoint.bootstrap; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.TraceContext; - -/** - * @author emeroad - */ -public interface Agent { - // TODO 필요없을것 같음 started를 start로 바꿔도 될 듯... - void start(); - - void started(); - - void stop(); - - void addConnector(String protocol, int port); - - TraceContext getTraceContext(); - - ProfilerConfig getProfilerConfig(); - -} +package com.nhn.pinpoint.bootstrap; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.context.TraceContext; + +/** + * @author emeroad + * @author hyungil.jeong + */ +public interface Agent { + + void start(); + + void stop(); + + void addConnector(String protocol, int port); + + TraceContext getTraceContext(); + + ProfilerConfig getProfilerConfig(); + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentClassLoader.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentClassLoader.java index e0c426b4dfc7..a439b74f0c0e 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentClassLoader.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentClassLoader.java @@ -1,101 +1,101 @@ -package com.nhn.pinpoint.bootstrap; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; - -import java.lang.instrument.Instrumentation; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.concurrent.Callable; - -/** - * @author emeroad - */ -public class AgentClassLoader { - - private URLClassLoader classLoader; - - private String bootClass; - - private Agent agentBootStrap; - private ContextClassLoaderExecuteTemplate executeTemplate; - - public AgentClassLoader(URL[] urls) { - if (urls == null) { - throw new NullPointerException("urls"); - } - - ClassLoader bootStrapClassLoader = AgentClassLoader.class.getClassLoader(); - this.classLoader = new PinpointURLClassLoader(urls, bootStrapClassLoader); - - this.executeTemplate = new ContextClassLoaderExecuteTemplate(classLoader); - } - - public void setBootClass(String bootClass) { - this.bootClass = bootClass; - } - - public void boot(final String agentArgs, final Instrumentation instrumentation, final ProfilerConfig profilerConfig) { - - final Class bootStrapClazz = getBootStrapClass(); - - agentBootStrap = (Agent) executeTemplate.execute(new Callable() { - @Override - public Object call() throws Exception { - try { - Constructor constructor = bootStrapClazz.getConstructor(String.class, Instrumentation.class, ProfilerConfig.class); - return constructor.newInstance(agentArgs, instrumentation, profilerConfig); - } catch (InstantiationException e) { - throw new BootStrapException("boot create fail. Caused:" + e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new BootStrapException("boot method invoke fail. Caused:" + e.getMessage(), e); - } - } - }); - } - - - private Class getBootStrapClass() { - try { - return this.classLoader.loadClass(bootClass); - } catch (ClassNotFoundException e) { - throw new BootStrapException("boot class not found. Caused:" + e.getMessage(), e); - } - } - - @Deprecated - public Object initializeLoggerBinder() { - if (agentBootStrap != null) { - return reflectionInvoke(this.agentBootStrap, "initializeLogger", null, null); - } - return null; - } - - private Object reflectionInvoke(Object target, String method, Class[] type, final Object[] args) { - final Method findMethod = findMethod(target.getClass(), method, type); - return executeTemplate.execute(new Callable() { - @Override - public Object call() { - try { - return findMethod.invoke(agentBootStrap, args); - } catch (InvocationTargetException e) { - throw new BootStrapException(findMethod.getName() + "() fail. Caused:" + e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new BootStrapException("boot method invoke fail. Caused:" + e.getMessage(), e); - } - } - }); - - } - - private Method findMethod(Class clazz, String method, Class[] type) { - try { - return clazz.getDeclaredMethod(method, type); - } catch (NoSuchMethodException e) { - throw new BootStrapException("(" + method + ") boot method not found. Caused:" + e.getMessage(), e); - } - } - -} +package com.nhn.pinpoint.bootstrap; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; + +import java.lang.instrument.Instrumentation; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.concurrent.Callable; + +/** + * @author emeroad + */ +public class AgentClassLoader { + + private URLClassLoader classLoader; + + private String bootClass; + + private Agent agentBootStrap; + private ContextClassLoaderExecuteTemplate executeTemplate; + + public AgentClassLoader(URL[] urls) { + if (urls == null) { + throw new NullPointerException("urls"); + } + + ClassLoader bootStrapClassLoader = AgentClassLoader.class.getClassLoader(); + this.classLoader = new PinpointURLClassLoader(urls, bootStrapClassLoader); + + this.executeTemplate = new ContextClassLoaderExecuteTemplate(classLoader); + } + + public void setBootClass(String bootClass) { + this.bootClass = bootClass; + } + + public void boot(final String agentArgs, final Instrumentation instrumentation, final ProfilerConfig profilerConfig) { + + final Class bootStrapClazz = getBootStrapClass(); + + agentBootStrap = (Agent) executeTemplate.execute(new Callable() { + @Override + public Object call() throws Exception { + try { + Constructor constructor = bootStrapClazz.getConstructor(String.class, Instrumentation.class, ProfilerConfig.class); + return constructor.newInstance(agentArgs, instrumentation, profilerConfig); + } catch (InstantiationException e) { + throw new BootStrapException("boot create fail. Caused:" + e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new BootStrapException("boot method invoke fail. Caused:" + e.getMessage(), e); + } + } + }); + } + + + private Class getBootStrapClass() { + try { + return this.classLoader.loadClass(bootClass); + } catch (ClassNotFoundException e) { + throw new BootStrapException("boot class not found. Caused:" + e.getMessage(), e); + } + } + + @Deprecated + public Object initializeLoggerBinder() { + if (agentBootStrap != null) { + return reflectionInvoke(this.agentBootStrap, "initializeLogger", null, null); + } + return null; + } + + private Object reflectionInvoke(Object target, String method, Class[] type, final Object[] args) { + final Method findMethod = findMethod(target.getClass(), method, type); + return executeTemplate.execute(new Callable() { + @Override + public Object call() { + try { + return findMethod.invoke(agentBootStrap, args); + } catch (InvocationTargetException e) { + throw new BootStrapException(findMethod.getName() + "() fail. Caused:" + e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new BootStrapException("boot method invoke fail. Caused:" + e.getMessage(), e); + } + } + }); + + } + + private Method findMethod(Class clazz, String method, Class[] type) { + try { + return clazz.getDeclaredMethod(method, type); + } catch (NoSuchMethodException e) { + throw new BootStrapException("(" + method + ") boot method not found. Caused:" + e.getMessage(), e); + } + } + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/BootStrapException.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/BootStrapException.java index 83e07546d527..999589d9880e 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/BootStrapException.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/BootStrapException.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.bootstrap; - -import com.nhn.pinpoint.exception.PinpointException; - -/** - * @author emeroad - */ -public class BootStrapException extends PinpointException { - - public BootStrapException(String message, Throwable cause) { - super(message, cause); - } - - public BootStrapException(String message) { - super(message); - } -} +package com.nhn.pinpoint.bootstrap; + +import com.nhn.pinpoint.exception.PinpointException; + +/** + * @author emeroad + */ +public class BootStrapException extends PinpointException { + + public BootStrapException(String message, Throwable cause) { + super(message, cause); + } + + public BootStrapException(String message) { + super(message); + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ClassPathResolver.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ClassPathResolver.java index 0b5754055cdb..05fff4c93981 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ClassPathResolver.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ClassPathResolver.java @@ -1,195 +1,195 @@ -package com.nhn.pinpoint.bootstrap; - - -import java.io.File; -import java.io.FileFilter; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author emeroad - */ -public class ClassPathResolver { - - private final Logger logger = Logger.getLogger(this.getClass().getName()); - - private static final Pattern DEFAULT_AGENT_PATTERN = Pattern.compile("pinpoint-bootstrap(-[0-9]+\\.[0-9]+\\.[0-9]+(\\-SNAPSHOT)?)?\\.jar"); - - private String classPath; - - private String agentJarName; - private String agentJarFullPath; - private String agentDirPath; - private Pattern agentPattern; - private List fileExtensionList; - - public ClassPathResolver() { - this(getClassPathFromSystemProperty()); - } - - - public ClassPathResolver(String classPath) { - this.classPath = classPath; - this.agentPattern = DEFAULT_AGENT_PATTERN; - this.fileExtensionList = getDefaultFileExtensionList(); - } - - public List getDefaultFileExtensionList() { - List extensionList = new ArrayList(); - extensionList.add("jar"); - extensionList.add("xml"); - extensionList.add("properties"); - return extensionList; - } - - public ClassPathResolver(String classPath, String agentPattern) { - this.classPath = classPath; - this.agentPattern = Pattern.compile(agentPattern); - } - - public void setClassPath(String classPath) { - this.classPath = classPath; - } - - public void setClassPathFromSystemProperty() { - this.classPath = getClassPathFromSystemProperty(); - } - - public static String getClassPathFromSystemProperty() { - return System.getProperty("java.class.path"); - } - - public boolean findAgentJar() { - Matcher matcher = agentPattern.matcher(classPath); - if (!matcher.find()) { - return false; - } - this.agentJarName = parseAgentJar(matcher); - this.agentJarFullPath = parseAgentJarPath(classPath, agentJarName); - if (agentJarFullPath == null) { - return false; - } - this.agentDirPath = parseAgentDirPath(agentJarFullPath); - return true; - } - - - private String parseAgentJar(Matcher matcher) { - int start = matcher.start(); - int end = matcher.end(); - return this.classPath.substring(start, end); - } - - - public String getAgentJarName() { - return this.agentJarName; - } - - - private String parseAgentJarPath(String classPath, String agentJar) { - String[] classPathList = classPath.split(File.pathSeparator); - for (String findPath : classPathList) { - boolean find = findPath.contains(agentJar); - if (find) { - return findPath; - } - } - return null; - } - - public String getAgentJarFullPath() { - return agentJarFullPath; - } - - public String getAgentLibPath() { - return this.agentDirPath + File.separator + "lib"; - } - - public String getAgentLogFilePath() { - return this.agentDirPath + File.separator + "log"; - } - - public List resolveLib() { - String agentLibPath = getAgentLibPath(); - File libDir = new File(agentLibPath); - if (!libDir.exists()) { - logger.warning(agentLibPath + " not found"); - return Collections.emptyList(); - } - if (!libDir.isDirectory()) { - logger.warning(agentLibPath + " not Directory"); - return Collections.emptyList(); - } - final List jarURLList = new ArrayList(); - - final File[] findJarList = findjar(libDir); - if (findJarList != null) { - for (File file : findJarList) { - URL url = toURI(file); - if (url != null) { - jarURLList.add(url); - } - } - } - - // agentDir 패스도 넣어야 xml을 찾을 때 해당 패스에서 찾음. - URL agentDirUri = toURI(new File(agentLibPath)); - if (agentDirUri != null) { - jarURLList.add(agentDirUri); - } - - return jarURLList; - } - - private URL toURI(File file) { - URI uri = file.toURI(); - try { - return uri.toURL(); - } catch (MalformedURLException e) { - logger.log(Level.WARNING, file.getName() + ".toURL() fail. Caused:" + e.getMessage(), e); - return null; - } - } - - private File[] findjar(File libDir) { - return libDir.listFiles(new FileFilter() { - @Override - public boolean accept(File pathname) { - String path = pathname.getName(); - for (String extension : fileExtensionList) { - if (path.lastIndexOf("." + extension) != -1) { - return true; - } - } - return false; - } - }); - } - - public String parseAgentDirPath(String agentJarFullPath) { - int index1 = agentJarFullPath.lastIndexOf("/"); - int index2 = agentJarFullPath.lastIndexOf("\\"); - int max = Math.max(index1, index2); - if (max == -1) { - return null; - } - return agentJarFullPath.substring(0, max); - } - - public String getAgentDirPath() { - return agentDirPath; - } - - public String getAgentConfigPath() { - return agentDirPath + File.separator + "pinpoint.config"; - } - -} +package com.nhn.pinpoint.bootstrap; + + +import java.io.File; +import java.io.FileFilter; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author emeroad + */ +public class ClassPathResolver { + + private final Logger logger = Logger.getLogger(this.getClass().getName()); + + private static final Pattern DEFAULT_AGENT_PATTERN = Pattern.compile("pinpoint-bootstrap(-[0-9]+\\.[0-9]+\\.[0-9]+(\\-SNAPSHOT)?)?\\.jar"); + + private String classPath; + + private String agentJarName; + private String agentJarFullPath; + private String agentDirPath; + private Pattern agentPattern; + private List fileExtensionList; + + public ClassPathResolver() { + this(getClassPathFromSystemProperty()); + } + + + public ClassPathResolver(String classPath) { + this.classPath = classPath; + this.agentPattern = DEFAULT_AGENT_PATTERN; + this.fileExtensionList = getDefaultFileExtensionList(); + } + + public List getDefaultFileExtensionList() { + List extensionList = new ArrayList(); + extensionList.add("jar"); + extensionList.add("xml"); + extensionList.add("properties"); + return extensionList; + } + + public ClassPathResolver(String classPath, String agentPattern) { + this.classPath = classPath; + this.agentPattern = Pattern.compile(agentPattern); + } + + public void setClassPath(String classPath) { + this.classPath = classPath; + } + + public void setClassPathFromSystemProperty() { + this.classPath = getClassPathFromSystemProperty(); + } + + public static String getClassPathFromSystemProperty() { + return System.getProperty("java.class.path"); + } + + public boolean findAgentJar() { + Matcher matcher = agentPattern.matcher(classPath); + if (!matcher.find()) { + return false; + } + this.agentJarName = parseAgentJar(matcher); + this.agentJarFullPath = parseAgentJarPath(classPath, agentJarName); + if (agentJarFullPath == null) { + return false; + } + this.agentDirPath = parseAgentDirPath(agentJarFullPath); + return true; + } + + + private String parseAgentJar(Matcher matcher) { + int start = matcher.start(); + int end = matcher.end(); + return this.classPath.substring(start, end); + } + + + public String getAgentJarName() { + return this.agentJarName; + } + + + private String parseAgentJarPath(String classPath, String agentJar) { + String[] classPathList = classPath.split(File.pathSeparator); + for (String findPath : classPathList) { + boolean find = findPath.contains(agentJar); + if (find) { + return findPath; + } + } + return null; + } + + public String getAgentJarFullPath() { + return agentJarFullPath; + } + + public String getAgentLibPath() { + return this.agentDirPath + File.separator + "lib"; + } + + public String getAgentLogFilePath() { + return this.agentDirPath + File.separator + "log"; + } + + public List resolveLib() { + String agentLibPath = getAgentLibPath(); + File libDir = new File(agentLibPath); + if (!libDir.exists()) { + logger.warning(agentLibPath + " not found"); + return Collections.emptyList(); + } + if (!libDir.isDirectory()) { + logger.warning(agentLibPath + " not Directory"); + return Collections.emptyList(); + } + final List jarURLList = new ArrayList(); + + final File[] findJarList = findjar(libDir); + if (findJarList != null) { + for (File file : findJarList) { + URL url = toURI(file); + if (url != null) { + jarURLList.add(url); + } + } + } + + // agentDir 패스도 넣어야 xml을 찾을 때 해당 패스에서 찾음. + URL agentDirUri = toURI(new File(agentLibPath)); + if (agentDirUri != null) { + jarURLList.add(agentDirUri); + } + + return jarURLList; + } + + private URL toURI(File file) { + URI uri = file.toURI(); + try { + return uri.toURL(); + } catch (MalformedURLException e) { + logger.log(Level.WARNING, file.getName() + ".toURL() fail. Caused:" + e.getMessage(), e); + return null; + } + } + + private File[] findjar(File libDir) { + return libDir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + String path = pathname.getName(); + for (String extension : fileExtensionList) { + if (path.lastIndexOf("." + extension) != -1) { + return true; + } + } + return false; + } + }); + } + + public String parseAgentDirPath(String agentJarFullPath) { + int index1 = agentJarFullPath.lastIndexOf("/"); + int index2 = agentJarFullPath.lastIndexOf("\\"); + int max = Math.max(index1, index2); + if (max == -1) { + return null; + } + return agentJarFullPath.substring(0, max); + } + + public String getAgentDirPath() { + return agentDirPath; + } + + public String getAgentConfigPath() { + return agentDirPath + File.separator + "pinpoint.config"; + } + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ContextClassLoaderExecuteTemplate.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ContextClassLoaderExecuteTemplate.java index fb199bf88a11..9414d82552c3 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ContextClassLoaderExecuteTemplate.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ContextClassLoaderExecuteTemplate.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.bootstrap; - -import java.util.concurrent.Callable; - -/** - * contextClassLoader에 별도의 classLoader를 세팅하고 실행하는 template - * @author emeroad - */ -public class ContextClassLoaderExecuteTemplate { - private final ClassLoader classLoader; - - public ContextClassLoaderExecuteTemplate(ClassLoader classLoader) { - if (classLoader == null) { - throw new NullPointerException("classLoader must not be null"); - } - this.classLoader = classLoader; - } - - public V execute(Callable callable) throws BootStrapException { - try { - final Thread currentThread = Thread.currentThread(); - final ClassLoader before = currentThread.getContextClassLoader(); - currentThread.setContextClassLoader(ContextClassLoaderExecuteTemplate.this.classLoader); - try { - return callable.call(); - } finally { - // null일 경우도 다시 원복하는게 맞음. - // getContextClassLoader 호출시 에러가 발생하였을 경우 여기서 호출당하지 않으므로 이부분에서 원복하는게 맞음. - currentThread.setContextClassLoader(before); - } - } catch (BootStrapException ex){ - throw ex; - } catch (Exception ex) { - throw new BootStrapException("execute fail. Caused:" + ex.getMessage(), ex); - } - } -} +package com.nhn.pinpoint.bootstrap; + +import java.util.concurrent.Callable; + +/** + * contextClassLoader에 별도의 classLoader를 세팅하고 실행하는 template + * @author emeroad + */ +public class ContextClassLoaderExecuteTemplate { + private final ClassLoader classLoader; + + public ContextClassLoaderExecuteTemplate(ClassLoader classLoader) { + if (classLoader == null) { + throw new NullPointerException("classLoader must not be null"); + } + this.classLoader = classLoader; + } + + public V execute(Callable callable) throws BootStrapException { + try { + final Thread currentThread = Thread.currentThread(); + final ClassLoader before = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(ContextClassLoaderExecuteTemplate.this.classLoader); + try { + return callable.call(); + } finally { + // null일 경우도 다시 원복하는게 맞음. + // getContextClassLoader 호출시 에러가 발생하였을 경우 여기서 호출당하지 않으므로 이부분에서 원복하는게 맞음. + currentThread.setContextClassLoader(before); + } + } catch (BootStrapException ex){ + throw ex; + } catch (Exception ex) { + throw new BootStrapException("execute fail. Caused:" + ex.getMessage(), ex); + } + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrap.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrap.java index acc87ed70bf7..f7a51c45c71e 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrap.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrap.java @@ -1,196 +1,196 @@ -package com.nhn.pinpoint.bootstrap; - -import com.nhn.pinpoint.ProductInfo; -import com.nhn.pinpoint.common.PinpointConstants; -import com.nhn.pinpoint.common.util.TransactionIdUtils; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; - -import java.io.UnsupportedEncodingException; -import java.lang.instrument.Instrumentation; -import java.net.URL; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; - -/** - * @author emeroad - * @author netspider - */ -public class PinpointBootStrap { - - private static final Logger logger = Logger.getLogger(PinpointBootStrap.class.getName()); - - private static final int LIMIT_LENGTH = 24; - private static final String DELIMITER = TransactionIdUtils.TRANSACTION_ID_DELIMITER; - - public static final String BOOT_CLASS = "com.nhn.pinpoint.profiler.DefaultAgent"; - - public static final String BOOT_STRAP_LOAD_STATE = "com.nhn.pinpoint.bootstrap.load.state"; - public static final String BOOT_STRAP_LOAD_STATE_LOADING = "LOADING"; - public static final String BOOT_STRAP_LOAD_STATE_COMPLETE = "COMPLETE"; - public static final String BOOT_STRAP_LOAD_STATE_ERROR = "ERROR"; - - private static final Pattern validIdPattern = Pattern.compile("[^a-zA-Z0-9._(\\-)]"); - - public static void premain(String agentArgs, Instrumentation instrumentation) { - if (agentArgs != null) { - logger.info(ProductInfo.CAMEL_NAME + " agentArgs:" + agentArgs); - } - final boolean duplicated = checkDuplicateLoadState(); - if (duplicated) { - // 중복 케이스는 내가 처리하면 안됨. 아래와 같은 코드는 없어야 한다. - //loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); - return; - } - - ClassPathResolver classPathResolver = new ClassPathResolver(); - boolean agentJarNotFound = classPathResolver.findAgentJar(); - if (!agentJarNotFound) { - // TODO 이거 변경해야 함. - logger.severe("pinpoint-bootstrap-x.x.x.jar not found."); - loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); - return; - } - - if (!isValidId("pinpoint.agentId", PinpointConstants.AGENT_NAME_MAX_LEN)) { - loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); - return; - } - if (!isValidId("pinpoint.applicationName", PinpointConstants.APPLICATION_NAME_MAX_LEN)) { - loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); - return; - } - - String configPath = getConfigPath(classPathResolver); - if (configPath == null ) { - loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); - // 설정파일을 못찾으므로 종료. - return; - } - // 로그가 저장될 위치를 시스템 properties로 저장한다. - saveLogFilePath(classPathResolver); - - try { - // 설정파일 로드 이게 bootstrap에 있어야 되나는게 맞나? - ProfilerConfig profilerConfig = new ProfilerConfig(); - profilerConfig.readConfigFile(configPath); - - // 이게 로드할 lib List임. - List libUrlList = resolveLib(classPathResolver); - AgentClassLoader agentClassLoader = new AgentClassLoader(libUrlList.toArray(new URL[libUrlList.size()])); - agentClassLoader.setBootClass(BOOT_CLASS); - logger.info("pinpoint agent start."); - agentClassLoader.boot(agentArgs, instrumentation, profilerConfig); - logger.info("pinpoint agent start success."); - loadStateChange(BOOT_STRAP_LOAD_STATE_COMPLETE); - } catch (Exception e) { - logger.log(Level.SEVERE, ProductInfo.CAMEL_NAME + " start fail. Caused:" + e.getMessage(), e); - // 위에서 리턴하는거에서 세는게 이 - loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); - } - - } - - private static void loadStateChange(String loadState) { - System.setProperty(BOOT_STRAP_LOAD_STATE, loadState); - } - - private static boolean checkDuplicateLoadState() { - final String exist = System.getProperty(BOOT_STRAP_LOAD_STATE); - if (exist == null) { - loadStateChange(BOOT_STRAP_LOAD_STATE_LOADING); - } else { - if (logger.isLoggable(Level.SEVERE)) { - logger.severe("pinpoint-bootstrap already started. skip agent loading. loadState:" + exist); - } - return true; - } - return false; - } - - private static boolean isValidId(String propertyName, int maxSize) { - logger.info("check -D" + propertyName); - String value = System.getProperty(propertyName); - if (value != null) { - // 문자열 앞뒤에 공백은 허용되지 않음. - value = value.trim(); - - if (validIdPattern.matcher(value).find()) { - logger.severe("invalid Id. " + propertyName + " can only contain alphanumeric, dot, dash and underscore. value:" + value); - return false; - } - - final byte[] bytes; - try { - bytes = toBytes(value); - } catch (UnsupportedEncodingException e) { - logger.severe("toBytes() fail. propertyName:" + propertyName + " propertyValue:" + value); - return false; - } - if (bytes.length == 0) { - logger.severe("invalid " + propertyName + ". agentId is empty. length:" + bytes.length + " value:" + value); - return false; - } - if (bytes.length > maxSize) { - logger.severe("invalid " + propertyName + ". too large bytes. length:" + bytes.length + " value:" + value); - return false; - } - logger.info("check success. -D" + propertyName + ":" + value + " length:" + bytes.length); - return true; - } else { - logger.severe("-D" + propertyName + " is null."); - return false; - } - } - - private static byte[] toBytes(String property) throws UnsupportedEncodingException { - return property.getBytes("UTF-8"); - } - - private static void saveLogFilePath(ClassPathResolver classPathResolver) { - String agentLogFilePath = classPathResolver.getAgentLogFilePath(); - logger.info("logPath:" + agentLogFilePath); - - System.setProperty(ProductInfo.NAME + ".log", agentLogFilePath); - } - - private static String getConfigPath(ClassPathResolver classPathResolver) { - final String configName = ProductInfo.NAME + ".config"; - String pinpointConfigFormSystemProperty = System.getProperty(configName); - if (pinpointConfigFormSystemProperty != null) { - logger.info(configName + " systemProperty found. " + pinpointConfigFormSystemProperty); - return pinpointConfigFormSystemProperty; - } - - String classPathAgentConfigPath = classPathResolver.getAgentConfigPath(); - if (classPathAgentConfigPath != null) { - logger.info("classpath " + configName + " found. " + classPathAgentConfigPath); - return classPathAgentConfigPath; - } - - logger.severe(configName + " file not found."); - return null; - } - - - private static List resolveLib(ClassPathResolver classPathResolver) { - // 절대경로만 처리되지 않나함. 상대 경로(./../agentlib/lib등)일 경우의 처리가 있어야 될것 같음. - String agentJarFullPath = classPathResolver.getAgentJarFullPath(); - String agentLibPath = classPathResolver.getAgentLibPath(); - List urlList = classPathResolver.resolveLib(); - String agentConfigPath = classPathResolver.getAgentConfigPath(); - - if (logger.isLoggable(Level.INFO)) { - logger.info("agentJarPath:" + agentJarFullPath); - logger.info("agentLibPath:" + agentLibPath); - logger.info("agent lib list:" + urlList); - logger.info("agent config:" + agentConfigPath); - } - - return urlList; - } - - - -} +package com.nhn.pinpoint.bootstrap; + +import com.nhn.pinpoint.ProductInfo; +import com.nhn.pinpoint.common.PinpointConstants; +import com.nhn.pinpoint.common.util.TransactionIdUtils; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; + +import java.io.UnsupportedEncodingException; +import java.lang.instrument.Instrumentation; +import java.net.URL; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * @author emeroad + * @author netspider + */ +public class PinpointBootStrap { + + private static final Logger logger = Logger.getLogger(PinpointBootStrap.class.getName()); + + private static final int LIMIT_LENGTH = 24; + private static final String DELIMITER = TransactionIdUtils.TRANSACTION_ID_DELIMITER; + + public static final String BOOT_CLASS = "com.nhn.pinpoint.profiler.DefaultAgent"; + + public static final String BOOT_STRAP_LOAD_STATE = "com.nhn.pinpoint.bootstrap.load.state"; + public static final String BOOT_STRAP_LOAD_STATE_LOADING = "LOADING"; + public static final String BOOT_STRAP_LOAD_STATE_COMPLETE = "COMPLETE"; + public static final String BOOT_STRAP_LOAD_STATE_ERROR = "ERROR"; + + private static final Pattern validIdPattern = Pattern.compile("[^a-zA-Z0-9._(\\-)]"); + + public static void premain(String agentArgs, Instrumentation instrumentation) { + if (agentArgs != null) { + logger.info(ProductInfo.CAMEL_NAME + " agentArgs:" + agentArgs); + } + final boolean duplicated = checkDuplicateLoadState(); + if (duplicated) { + // 중복 케이스는 내가 처리하면 안됨. 아래와 같은 코드는 없어야 한다. + //loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); + return; + } + + ClassPathResolver classPathResolver = new ClassPathResolver(); + boolean agentJarNotFound = classPathResolver.findAgentJar(); + if (!agentJarNotFound) { + // TODO 이거 변경해야 함. + logger.severe("pinpoint-bootstrap-x.x.x.jar not found."); + loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); + return; + } + + if (!isValidId("pinpoint.agentId", PinpointConstants.AGENT_NAME_MAX_LEN)) { + loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); + return; + } + if (!isValidId("pinpoint.applicationName", PinpointConstants.APPLICATION_NAME_MAX_LEN)) { + loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); + return; + } + + String configPath = getConfigPath(classPathResolver); + if (configPath == null ) { + loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); + // 설정파일을 못찾으므로 종료. + return; + } + // 로그가 저장될 위치를 시스템 properties로 저장한다. + saveLogFilePath(classPathResolver); + + try { + // 설정파일 로드 이게 bootstrap에 있어야 되나는게 맞나? + ProfilerConfig profilerConfig = new ProfilerConfig(); + profilerConfig.readConfigFile(configPath); + + // 이게 로드할 lib List임. + List libUrlList = resolveLib(classPathResolver); + AgentClassLoader agentClassLoader = new AgentClassLoader(libUrlList.toArray(new URL[libUrlList.size()])); + agentClassLoader.setBootClass(BOOT_CLASS); + logger.info("pinpoint agent start."); + agentClassLoader.boot(agentArgs, instrumentation, profilerConfig); + logger.info("pinpoint agent start success."); + loadStateChange(BOOT_STRAP_LOAD_STATE_COMPLETE); + } catch (Exception e) { + logger.log(Level.SEVERE, ProductInfo.CAMEL_NAME + " start fail. Caused:" + e.getMessage(), e); + // 위에서 리턴하는거에서 세는게 이 + loadStateChange(BOOT_STRAP_LOAD_STATE_ERROR); + } + + } + + private static void loadStateChange(String loadState) { + System.setProperty(BOOT_STRAP_LOAD_STATE, loadState); + } + + private static boolean checkDuplicateLoadState() { + final String exist = System.getProperty(BOOT_STRAP_LOAD_STATE); + if (exist == null) { + loadStateChange(BOOT_STRAP_LOAD_STATE_LOADING); + } else { + if (logger.isLoggable(Level.SEVERE)) { + logger.severe("pinpoint-bootstrap already started. skip agent loading. loadState:" + exist); + } + return true; + } + return false; + } + + private static boolean isValidId(String propertyName, int maxSize) { + logger.info("check -D" + propertyName); + String value = System.getProperty(propertyName); + if (value != null) { + // 문자열 앞뒤에 공백은 허용되지 않음. + value = value.trim(); + + if (validIdPattern.matcher(value).find()) { + logger.severe("invalid Id. " + propertyName + " can only contain alphanumeric, dot, dash and underscore. value:" + value); + return false; + } + + final byte[] bytes; + try { + bytes = toBytes(value); + } catch (UnsupportedEncodingException e) { + logger.severe("toBytes() fail. propertyName:" + propertyName + " propertyValue:" + value); + return false; + } + if (bytes.length == 0) { + logger.severe("invalid " + propertyName + ". agentId is empty. length:" + bytes.length + " value:" + value); + return false; + } + if (bytes.length > maxSize) { + logger.severe("invalid " + propertyName + ". too large bytes. length:" + bytes.length + " value:" + value); + return false; + } + logger.info("check success. -D" + propertyName + ":" + value + " length:" + bytes.length); + return true; + } else { + logger.severe("-D" + propertyName + " is null."); + return false; + } + } + + private static byte[] toBytes(String property) throws UnsupportedEncodingException { + return property.getBytes("UTF-8"); + } + + private static void saveLogFilePath(ClassPathResolver classPathResolver) { + String agentLogFilePath = classPathResolver.getAgentLogFilePath(); + logger.info("logPath:" + agentLogFilePath); + + System.setProperty(ProductInfo.NAME + ".log", agentLogFilePath); + } + + private static String getConfigPath(ClassPathResolver classPathResolver) { + final String configName = ProductInfo.NAME + ".config"; + String pinpointConfigFormSystemProperty = System.getProperty(configName); + if (pinpointConfigFormSystemProperty != null) { + logger.info(configName + " systemProperty found. " + pinpointConfigFormSystemProperty); + return pinpointConfigFormSystemProperty; + } + + String classPathAgentConfigPath = classPathResolver.getAgentConfigPath(); + if (classPathAgentConfigPath != null) { + logger.info("classpath " + configName + " found. " + classPathAgentConfigPath); + return classPathAgentConfigPath; + } + + logger.severe(configName + " file not found."); + return null; + } + + + private static List resolveLib(ClassPathResolver classPathResolver) { + // 절대경로만 처리되지 않나함. 상대 경로(./../agentlib/lib등)일 경우의 처리가 있어야 될것 같음. + String agentJarFullPath = classPathResolver.getAgentJarFullPath(); + String agentLibPath = classPathResolver.getAgentLibPath(); + List urlList = classPathResolver.resolveLib(); + String agentConfigPath = classPathResolver.getAgentConfigPath(); + + if (logger.isLoggable(Level.INFO)) { + logger.info("agentJarPath:" + agentJarFullPath); + logger.info("agentLibPath:" + agentLibPath); + logger.info("agent lib list:" + urlList); + logger.info("agent config:" + agentConfigPath); + } + + return urlList; + } + + + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoader.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoader.java index 5119fd6f6c02..4ad4f4d833d7 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoader.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoader.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.bootstrap; - -import java.net.URL; -import java.net.URLClassLoader; - -/** - * profiler lib 디렉토리의 jar의 경우 delegation하지 않고 자기 자신에게 로드하도록 함. - * standalone java 일 경우 dead lock문제가 발생할수 있어, 자기자신이 load할 class일 경우 parent로 넘기지 않음. - * @author emeroad - */ -public class PinpointURLClassLoader extends URLClassLoader { - - - private final ClassLoader parent; - - private final ProfilerLibClass profilerLibClass = new ProfilerLibClass(); - - public PinpointURLClassLoader(URL[] urls, ClassLoader parent) { - super(urls, parent); - if (parent == null) { - throw new NullPointerException("parent must not be null"); - } - // parent가 null인 케이스는 지원하지 않는다. - this.parent = parent; - } - - - @Override - protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - // First, check if the class has already been loaded - Class clazz = findLoadedClass(name); - if (clazz == null) { - if (onLoadClass(name)) { - // 나한테 있어야 하는 class의 경우 그냥 로드. - clazz = findClass(name); - } else { - try { - // 부모를 찾고. - clazz = parent.loadClass(name); - } catch (ClassNotFoundException e) { - // class를 못찾음. - } - if (clazz == null) { - // 없으면 나한테 로드 시도. - clazz = findClass(name); - } - } - } - if (resolve) { - resolveClass(clazz); - } - return clazz; - } - - // for test - boolean onLoadClass(String name) { - return profilerLibClass.onLoadClass(name); - } - -} +package com.nhn.pinpoint.bootstrap; + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * profiler lib 디렉토리의 jar의 경우 delegation하지 않고 자기 자신에게 로드하도록 함. + * standalone java 일 경우 dead lock문제가 발생할수 있어, 자기자신이 load할 class일 경우 parent로 넘기지 않음. + * @author emeroad + */ +public class PinpointURLClassLoader extends URLClassLoader { + + + private final ClassLoader parent; + + private final ProfilerLibClass profilerLibClass = new ProfilerLibClass(); + + public PinpointURLClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); + if (parent == null) { + throw new NullPointerException("parent must not be null"); + } + // parent가 null인 케이스는 지원하지 않는다. + this.parent = parent; + } + + + @Override + protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + // First, check if the class has already been loaded + Class clazz = findLoadedClass(name); + if (clazz == null) { + if (onLoadClass(name)) { + // 나한테 있어야 하는 class의 경우 그냥 로드. + clazz = findClass(name); + } else { + try { + // 부모를 찾고. + clazz = parent.loadClass(name); + } catch (ClassNotFoundException e) { + // class를 못찾음. + } + if (clazz == null) { + // 없으면 나한테 로드 시도. + clazz = findClass(name); + } + } + } + if (resolve) { + resolveClass(clazz); + } + return clazz; + } + + // for test + boolean onLoadClass(String name) { + return profilerLibClass.onLoadClass(name); + } + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ProfilerLibClass.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ProfilerLibClass.java index 3d0760a24487..bc120cad4369 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ProfilerLibClass.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/ProfilerLibClass.java @@ -1,31 +1,31 @@ -package com.nhn.pinpoint.bootstrap; - -/** - * @author emeroad - */ -public class ProfilerLibClass { - - private static final String[] PINPOINT_PROFILER_CLASS = new String[] { - "com.nhn.pinpoint.profiler", - "com.nhn.pinpoint.thrift", - "com.nhn.pinpoint.rpc", - "javassist", - "org.slf4j", - "org.apache.thrift", - "org.jboss.netty", - "com.google.common", - "org.apache.commons.lang", - "org.apache.log4j", - "com.codahale.metrics" - }; - - public boolean onLoadClass(String clazzName) { - final int length = PINPOINT_PROFILER_CLASS.length; - for (int i = 0; i < length; i++) { - if (clazzName.startsWith(PINPOINT_PROFILER_CLASS[i])) { - return true; - } - } - return false; - } -} +package com.nhn.pinpoint.bootstrap; + +/** + * @author emeroad + */ +public class ProfilerLibClass { + + private static final String[] PINPOINT_PROFILER_CLASS = new String[] { + "com.nhn.pinpoint.profiler", + "com.nhn.pinpoint.thrift", + "com.nhn.pinpoint.rpc", + "javassist", + "org.slf4j", + "org.apache.thrift", + "org.jboss.netty", + "com.google.common", + "org.apache.commons.lang", + "org.apache.log4j", + "com.codahale.metrics" + }; + + public boolean onLoadClass(String clazzName) { + final int length = PINPOINT_PROFILER_CLASS.length; + for (int i = 0; i < length; i++) { + if (clazzName.startsWith(PINPOINT_PROFILER_CLASS[i])) { + return true; + } + } + return false; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/DumpType.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/DumpType.java index ebb87b0d52f7..e98f890bd7c4 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/DumpType.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/DumpType.java @@ -1,20 +1,20 @@ -package com.nhn.pinpoint.bootstrap.config; - -/** - * @author emeroad - */ -public enum DumpType { -// NONE(-1), 의 경우 이미 더 앞단에서 할지 말지를 결정하므로 중복설정이라 주석처리함. - ALWAYS(0), EXCEPTION(1); - - private int code; - private DumpType(int code) { - this.code = code; - } - - public int getCode() { - return code; - } - - -} +package com.nhn.pinpoint.bootstrap.config; + +/** + * @author emeroad + */ +public enum DumpType { +// NONE(-1), 의 경우 이미 더 앞단에서 할지 말지를 결정하므로 중복설정이라 주석처리함. + ALWAYS(0), EXCEPTION(1); + + private int code; + private DumpType(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java index 7056c516c820..21b15161a2cf 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java @@ -44,7 +44,10 @@ public class ProfilerConfig { private boolean jdbcProfileMySqlCommit = false; private boolean jdbcProfileMySqlRollback = false; - private boolean jdbcProfileMsSql = true; + private boolean jdbcProfileJtds = true; + private boolean jdbcProfileJtdsSetAutoCommit = false; + private boolean jdbcProfileJtdsCommit = false; + private boolean jdbcProfileJtdsRollback = false; private boolean jdbcProfileOracle = true; private boolean jdbcProfileOracleSetAutoCommit = false; @@ -68,9 +71,6 @@ public class ProfilerConfig { private boolean mybatis = true; - private boolean redis = true; - private boolean nBaseArc = true; - /** * apache http client */ @@ -253,10 +253,22 @@ public boolean isJdbcProfileMySqlRollback() { } // mysql end----------------------------------------------------- - public boolean isJdbcProfileMsSql() { - return jdbcProfileMsSql; + public boolean isJdbcProfileJtds() { + return jdbcProfileJtds; } + public boolean isJdbcProfileJtdsSetAutoCommit() { + return jdbcProfileJtdsSetAutoCommit; + } + + public boolean isJdbcProfileJtdsCommit() { + return jdbcProfileJtdsCommit; + } + + public boolean isJdbcProfileJtdsRollback() { + return jdbcProfileJtdsRollback; + } + // oracle start ----------------------------------------------------- public boolean isJdbcProfileOracle() { return jdbcProfileOracle; @@ -306,7 +318,7 @@ public boolean isIoBufferingEnable() { return ioBufferingEnable; } - public int getIoBufferingBufferBufferSize() { + public int getIoBufferingBufferSize() { return ioBufferingBufferSize; } @@ -449,15 +461,7 @@ public boolean isMyBatisEnabled() { return mybatis; } - public boolean isRedisEnabled() { - return redis; - } - - public boolean isNBaseArcEnabled() { - return nBaseArc; - } - - /** + /** * TODO remove this. 테스트 장비에서 call stack view가 잘 보이는지 테스트 하려고 추가함. * * @param className @@ -517,7 +521,10 @@ private void readPropertyValues(Properties prop) { this.jdbcProfileMySqlRollback = readBoolean(prop, "profiler.jdbc.mysql.rollback", false); - this.jdbcProfileMsSql = readBoolean(prop, "profiler.jdbc.mssql", true); + this.jdbcProfileJtds = readBoolean(prop, "profiler.jdbc.jtds", true); + this.jdbcProfileJtdsSetAutoCommit = readBoolean(prop, "profiler.jdbc.jtds.setautocommit", false); + this.jdbcProfileJtdsCommit = readBoolean(prop, "profiler.jdbc.jtds.commit", false); + this.jdbcProfileJtdsRollback = readBoolean(prop, "profiler.jdbc.jtds.rollback", false); this.jdbcProfileOracle = readBoolean(prop, "profiler.jdbc.oracle", true); @@ -576,11 +583,6 @@ private void readPropertyValues(Properties prop) { this.ningAsyncHttpClientProfileParamDumpSize = readInt(prop, "profiler.ning.asynchttpclient.param.dumpsize", 1024); this.ningAsyncHttpClientProfileParamSamplingRate = readInt(prop, "profiler.asynchttpclient.param.sampling.rate", 1); - // redis & nBase-ARC - this.redis = readBoolean(prop, "profiler.redis", true); - this.nBaseArc = readBoolean(prop, "profiler.nBaseArc", true); - - // // FIXME 임시용, line game netty configuration // @@ -708,83 +710,85 @@ private boolean readBoolean(Properties prop, String propertyName, boolean defaul } + + @Override public String toString() { - final StringBuilder sb = new StringBuilder(512); - sb.append("ProfilerConfig{"); + final StringBuilder sb = new StringBuilder("ProfilerConfig{"); sb.append("profileEnable=").append(profileEnable); - sb.append("\n collectorServerIp='").append(collectorServerIp).append('\''); - sb.append("\n collectorUdpSpanServerPort=").append(collectorUdpSpanServerPort); - sb.append("\n collectorUdpServerPort=").append(collectorUdpServerPort); - sb.append("\n collectorTcpServerPort=").append(collectorTcpServerPort); - sb.append("\n spanDataSenderWriteQueueSize=").append(spanDataSenderWriteQueueSize); - sb.append("\n spanDataSenderSocketSendBufferSize=").append(spanDataSenderSocketSendBufferSize); - sb.append("\n spanDataSenderSocketTimeout=").append(spanDataSenderSocketTimeout); - sb.append("\n statDataSenderWriteQueueSize=").append(statDataSenderWriteQueueSize); - sb.append("\n statDataSenderSocketSendBufferSize=").append(statDataSenderSocketSendBufferSize); - sb.append("\n statDataSenderSocketTimeout=").append(statDataSenderSocketTimeout); - sb.append("\n tcpCommandAcceptEnable=").append(tcpDataSenderCommandAcceptEnable); - sb.append("\n jdbcSqlCacheSize=").append(jdbcSqlCacheSize); - sb.append("\n jdbcProfile=").append(jdbcProfile); - sb.append("\n jdbcProfileMySql=").append(jdbcProfileMySql); - sb.append("\n jdbcProfileMySqlSetAutoCommit=").append(jdbcProfileMySqlSetAutoCommit); - sb.append("\n jdbcProfileMySqlCommit=").append(jdbcProfileMySqlCommit); - sb.append("\n jdbcProfileMySqlRollback=").append(jdbcProfileMySqlRollback); - sb.append("\n jdbcProfileMsSql=").append(jdbcProfileMsSql); - sb.append("\n jdbcProfileOracle=").append(jdbcProfileOracle); - sb.append("\n jdbcProfileOracleSetAutoCommit=").append(jdbcProfileOracleSetAutoCommit); - sb.append("\n jdbcProfileOracleCommit=").append(jdbcProfileOracleCommit); - sb.append("\n jdbcProfileOracleRollback=").append(jdbcProfileOracleRollback); - sb.append("\n jdbcProfileCubrid=").append(jdbcProfileCubrid); - sb.append("\n jdbcProfileCubridSetAutoCommit=").append(jdbcProfileCubridSetAutoCommit); - sb.append("\n jdbcProfileCubridCommit=").append(jdbcProfileCubridCommit); - sb.append("\n jdbcProfileCubridRollback=").append(jdbcProfileCubridRollback); - sb.append("\n jdbcProfileDbcp=").append(jdbcProfileDbcp); - sb.append("\n jdbcProfileDbcpConnectionClose=").append(jdbcProfileDbcpConnectionClose); - sb.append("\n arucs=").append(arucs); - sb.append("\n arucsKeyTrace=").append(arucsKeyTrace); - sb.append("\n memcached=").append(memcached); - sb.append("\n memcachedKeyTrace=").append(memcachedKeyTrace); - sb.append("\n redis=").append(redis); - sb.append("\n nBaseArc=").append(nBaseArc); - sb.append("\n ibatis=").append(ibatis); - sb.append("\n mybatis=").append(mybatis); - sb.append("\n apacheHttpClient4Profile=").append(apacheHttpClient4Profile); - sb.append("\n apacheHttpClient4ProfileCookie=").append(apacheHttpClient4ProfileCookie); - sb.append("\n apacheHttpClient4ProfileCookieDumpType=").append(apacheHttpClient4ProfileCookieDumpType); - sb.append("\n apacheHttpClient4ProfileCookieSamplingRate=").append(apacheHttpClient4ProfileCookieSamplingRate); - sb.append("\n apacheHttpClient4ProfileEntity=").append(apacheHttpClient4ProfileEntity); - sb.append("\n apacheHttpClient4ProfileEntityDumpType=").append(apacheHttpClient4ProfileEntityDumpType); - sb.append("\n apacheHttpClient4ProfileEntitySamplingRate=").append(apacheHttpClient4ProfileEntitySamplingRate); - sb.append("\n apacheNIOHttpClient4Profile=").append(apacheNIOHttpClient4Profile); - sb.append("\n ningAsyncHttpClientProfile=").append(ningAsyncHttpClientProfile); - sb.append("\n ningAsyncHttpClientProfileCookie=").append(ningAsyncHttpClientProfileCookie); - sb.append("\n ningAsyncHttpClientProfileCookieDumpType=").append(ningAsyncHttpClientProfileCookieDumpType); - sb.append("\n ningAsyncHttpClientProfileCookieDumpSize=").append(ningAsyncHttpClientProfileCookieDumpSize); - sb.append("\n ningAsyncHttpClientProfileCookieSamplingRate=").append(ningAsyncHttpClientProfileCookieSamplingRate); - sb.append("\n ningAsyncHttpClientProfileEntity=").append(ningAsyncHttpClientProfileEntity); - sb.append("\n ningAsyncHttpClientProfileEntityDumpType=").append(ningAsyncHttpClientProfileEntityDumpType); - sb.append("\n ningAsyncHttpClientProfileEntityDumpSize=").append(ningAsyncHttpClientProfileEntityDumpSize); - sb.append("\n ningAsyncHttpClientProfileEntitySamplingRate=").append(ningAsyncHttpClientProfileEntitySamplingRate); - sb.append("\n ningAsyncHttpClientProfileParam=").append(ningAsyncHttpClientProfileParam); - sb.append("\n ningAsyncHttpClientProfileParamDumpType=").append(ningAsyncHttpClientProfileParamDumpType); - sb.append("\n ningAsyncHttpClientProfileParamDumpSize=").append(ningAsyncHttpClientProfileParamDumpSize); - sb.append("\n ningAsyncHttpClientProfileParamSamplingRate=").append(ningAsyncHttpClientProfileParamSamplingRate); - sb.append("\n lineGameNettyParamDumpSize=").append(lineGameNettyParamDumpSize); - sb.append("\n lineGameNettyEntityDumpSize=").append(lineGameNettyEntityDumpSize); - sb.append("\n samplingEnable=").append(samplingEnable); - sb.append("\n samplingRate=").append(samplingRate); - sb.append("\n ioBufferingEnable=").append(ioBufferingEnable); - sb.append("\n ioBufferingBufferSize=").append(ioBufferingBufferSize); - sb.append("\n profileJvmCollectInterval=").append(profileJvmCollectInterval); - sb.append("\n profileInclude=").append(profileInclude); - sb.append("\n profileIncludeSub=").append(profileIncludeSub); - sb.append("\n heartbeatInterval=").append(heartbeatInterval); - sb.append("\n applicationServerType=").append(applicationServerType); + sb.append(", collectorServerIp='").append(collectorServerIp).append('\''); + sb.append(", collectorUdpSpanServerPort=").append(collectorUdpSpanServerPort); + sb.append(", collectorUdpServerPort=").append(collectorUdpServerPort); + sb.append(", collectorTcpServerPort=").append(collectorTcpServerPort); + sb.append(", spanDataSenderWriteQueueSize=").append(spanDataSenderWriteQueueSize); + sb.append(", spanDataSenderSocketSendBufferSize=").append(spanDataSenderSocketSendBufferSize); + sb.append(", spanDataSenderSocketTimeout=").append(spanDataSenderSocketTimeout); + sb.append(", statDataSenderWriteQueueSize=").append(statDataSenderWriteQueueSize); + sb.append(", statDataSenderSocketSendBufferSize=").append(statDataSenderSocketSendBufferSize); + sb.append(", statDataSenderSocketTimeout=").append(statDataSenderSocketTimeout); + sb.append(", tcpDataSenderCommandAcceptEnable=").append(tcpDataSenderCommandAcceptEnable); + sb.append(", jdbcSqlCacheSize=").append(jdbcSqlCacheSize); + sb.append(", jdbcMaxSqlBindValueSize=").append(jdbcMaxSqlBindValueSize); + sb.append(", jdbcProfile=").append(jdbcProfile); + sb.append(", jdbcProfileMySql=").append(jdbcProfileMySql); + sb.append(", jdbcProfileMySqlSetAutoCommit=").append(jdbcProfileMySqlSetAutoCommit); + sb.append(", jdbcProfileMySqlCommit=").append(jdbcProfileMySqlCommit); + sb.append(", jdbcProfileMySqlRollback=").append(jdbcProfileMySqlRollback); + sb.append(", jdbcProfileJtds=").append(jdbcProfileJtds); + sb.append(", jdbcProfileJtdsSetAutoCommit=").append(jdbcProfileJtdsSetAutoCommit); + sb.append(", jdbcProfileJtdsCommit=").append(jdbcProfileJtdsCommit); + sb.append(", jdbcProfileJtdsRollback=").append(jdbcProfileJtdsRollback); + sb.append(", jdbcProfileOracle=").append(jdbcProfileOracle); + sb.append(", jdbcProfileOracleSetAutoCommit=").append(jdbcProfileOracleSetAutoCommit); + sb.append(", jdbcProfileOracleCommit=").append(jdbcProfileOracleCommit); + sb.append(", jdbcProfileOracleRollback=").append(jdbcProfileOracleRollback); + sb.append(", jdbcProfileCubrid=").append(jdbcProfileCubrid); + sb.append(", jdbcProfileCubridSetAutoCommit=").append(jdbcProfileCubridSetAutoCommit); + sb.append(", jdbcProfileCubridCommit=").append(jdbcProfileCubridCommit); + sb.append(", jdbcProfileCubridRollback=").append(jdbcProfileCubridRollback); + sb.append(", jdbcProfileDbcp=").append(jdbcProfileDbcp); + sb.append(", jdbcProfileDbcpConnectionClose=").append(jdbcProfileDbcpConnectionClose); + sb.append(", arucs=").append(arucs); + sb.append(", arucsKeyTrace=").append(arucsKeyTrace); + sb.append(", memcached=").append(memcached); + sb.append(", memcachedKeyTrace=").append(memcachedKeyTrace); + sb.append(", ibatis=").append(ibatis); + sb.append(", mybatis=").append(mybatis); + sb.append(", apacheHttpClient4Profile=").append(apacheHttpClient4Profile); + sb.append(", apacheHttpClient4ProfileCookie=").append(apacheHttpClient4ProfileCookie); + sb.append(", apacheHttpClient4ProfileCookieDumpType=").append(apacheHttpClient4ProfileCookieDumpType); + sb.append(", apacheHttpClient4ProfileCookieSamplingRate=").append(apacheHttpClient4ProfileCookieSamplingRate); + sb.append(", apacheHttpClient4ProfileEntity=").append(apacheHttpClient4ProfileEntity); + sb.append(", apacheHttpClient4ProfileEntityDumpType=").append(apacheHttpClient4ProfileEntityDumpType); + sb.append(", apacheHttpClient4ProfileEntitySamplingRate=").append(apacheHttpClient4ProfileEntitySamplingRate); + sb.append(", apacheNIOHttpClient4Profile=").append(apacheNIOHttpClient4Profile); + sb.append(", ningAsyncHttpClientProfile=").append(ningAsyncHttpClientProfile); + sb.append(", ningAsyncHttpClientProfileCookie=").append(ningAsyncHttpClientProfileCookie); + sb.append(", ningAsyncHttpClientProfileCookieDumpType=").append(ningAsyncHttpClientProfileCookieDumpType); + sb.append(", ningAsyncHttpClientProfileCookieDumpSize=").append(ningAsyncHttpClientProfileCookieDumpSize); + sb.append(", ningAsyncHttpClientProfileCookieSamplingRate=").append(ningAsyncHttpClientProfileCookieSamplingRate); + sb.append(", ningAsyncHttpClientProfileEntity=").append(ningAsyncHttpClientProfileEntity); + sb.append(", ningAsyncHttpClientProfileEntityDumpType=").append(ningAsyncHttpClientProfileEntityDumpType); + sb.append(", ningAsyncHttpClientProfileEntityDumpSize=").append(ningAsyncHttpClientProfileEntityDumpSize); + sb.append(", ningAsyncHttpClientProfileEntitySamplingRate=").append(ningAsyncHttpClientProfileEntitySamplingRate); + sb.append(", ningAsyncHttpClientProfileParam=").append(ningAsyncHttpClientProfileParam); + sb.append(", ningAsyncHttpClientProfileParamDumpType=").append(ningAsyncHttpClientProfileParamDumpType); + sb.append(", ningAsyncHttpClientProfileParamDumpSize=").append(ningAsyncHttpClientProfileParamDumpSize); + sb.append(", ningAsyncHttpClientProfileParamSamplingRate=").append(ningAsyncHttpClientProfileParamSamplingRate); + sb.append(", lineGameNettyParamDumpSize=").append(lineGameNettyParamDumpSize); + sb.append(", lineGameNettyEntityDumpSize=").append(lineGameNettyEntityDumpSize); + sb.append(", samplingEnable=").append(samplingEnable); + sb.append(", samplingRate=").append(samplingRate); + sb.append(", ioBufferingEnable=").append(ioBufferingEnable); + sb.append(", ioBufferingBufferSize=").append(ioBufferingBufferSize); + sb.append(", profileJvmCollectInterval=").append(profileJvmCollectInterval); + sb.append(", profileInclude=").append(profileInclude); + sb.append(", profileIncludeSub=").append(profileIncludeSub); + sb.append(", DEFAULT_HEART_BEAT_INTERVAL=").append(DEFAULT_HEART_BEAT_INTERVAL); + sb.append(", heartbeatInterval=").append(heartbeatInterval); + sb.append(", applicationServerType=").append(applicationServerType); sb.append('}'); return sb.toString(); } - - } diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/AsyncTrace.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/AsyncTrace.java index 38b82b4bd8cb..47ef24b218b3 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/AsyncTrace.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/AsyncTrace.java @@ -1,58 +1,58 @@ -package com.nhn.pinpoint.bootstrap.context; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; - -import java.util.TimerTask; - -/** - * @author emeroad - */ -public interface AsyncTrace { - public static final int STATE_INIT = 0; - public static final int STATE_FIRE = 1; - public static final int STATE_TIMEOUT = 2; - - int getState(); - boolean fire(); - - void setTimeoutTask(TimerTask timeoutTask); - - void setAsyncId(int asyncId); - - int getAsyncId(); - - Object getAttachObject(); - - void setAttachObject(Object attachObject); - - void traceBlockBegin(); - - void markBeforeTime(); - - long getBeforeTime(); - - void traceBlockEnd(); - - void markAfterTime(); - - void recordApi(MethodDescriptor methodDescriptor); - - void recordException(Object result); - - void recordAttribute(AnnotationKey key, String value); - - void recordAttribute(AnnotationKey key, int value); - - void recordAttribute(AnnotationKey key, Object value); - - void recordServiceType(ServiceType serviceType); - - void recordRpcName(String rpcName); - - void recordDestinationId(String destinationId); - - // TODO: final String... endPoint로 받으면 합치는데 비용이 들어가 그냥 한번에 받는게 나을것 같음. - void recordEndPoint(String endPoint); -} +package com.nhn.pinpoint.bootstrap.context; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; + +import java.util.TimerTask; + +/** + * @author emeroad + */ +public interface AsyncTrace { + public static final int STATE_INIT = 0; + public static final int STATE_FIRE = 1; + public static final int STATE_TIMEOUT = 2; + + int getState(); + boolean fire(); + + void setTimeoutTask(TimerTask timeoutTask); + + void setAsyncId(int asyncId); + + int getAsyncId(); + + Object getAttachObject(); + + void setAttachObject(Object attachObject); + + void traceBlockBegin(); + + void markBeforeTime(); + + long getBeforeTime(); + + void traceBlockEnd(); + + void markAfterTime(); + + void recordApi(MethodDescriptor methodDescriptor); + + void recordException(Object result); + + void recordAttribute(AnnotationKey key, String value); + + void recordAttribute(AnnotationKey key, int value); + + void recordAttribute(AnnotationKey key, Object value); + + void recordServiceType(ServiceType serviceType); + + void recordRpcName(String rpcName); + + void recordDestinationId(String destinationId); + + // TODO: final String... endPoint로 받으면 합치는데 비용이 들어가 그냥 한번에 받는게 나을것 같음. + void recordEndPoint(String endPoint); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java index b7fbbfd3908f..f5b6438817e0 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.bootstrap.context; - -import com.nhn.pinpoint.common.ServiceType; - -import java.util.List; - -/** - * @author emeroad - */ -public interface DatabaseInfo { - List getHost(); - - String getMultipleHost(); - - String getDatabaseId(); - - String getRealUrl(); - - String getUrl(); - - ServiceType getType(); - - ServiceType getExecuteQueryType(); -} +package com.nhn.pinpoint.bootstrap.context; + +import com.nhn.pinpoint.common.ServiceType; + +import java.util.List; + +/** + * @author emeroad + */ +public interface DatabaseInfo { + List getHost(); + + String getMultipleHost(); + + String getDatabaseId(); + + String getRealUrl(); + + String getUrl(); + + ServiceType getType(); + + ServiceType getExecuteQueryType(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Metric.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Metric.java index b84402a0a300..234208ec267a 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Metric.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Metric.java @@ -1,7 +1,7 @@ -package com.nhn.pinpoint.bootstrap.context; - -/** - * @author emeroad - */ -public interface Metric { -} +package com.nhn.pinpoint.bootstrap.context; + +/** + * @author emeroad + */ +public interface Metric { +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/ReadableStorage.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/ReadableStorage.java deleted file mode 100644 index b7126a384b3c..000000000000 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/ReadableStorage.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.nhn.pinpoint.bootstrap.context; - -import java.util.List; - -import com.nhn.pinpoint.common.bo.SpanEventBo; - -/** - * @author Hyun Jeong - */ -public interface ReadableStorage { - public List getSpanEventList(); -} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/RecordableTrace.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/RecordableTrace.java index f5c17771715a..5d8207e03ef3 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/RecordableTrace.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/RecordableTrace.java @@ -1,75 +1,75 @@ -package com.nhn.pinpoint.bootstrap.context; - -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.util.ParsingResult; - -/** - * @author emeroad - */ -public interface RecordableTrace { - - void markBeforeTime(); - - long getBeforeTime(); - - void markAfterTime(); - - long getAfterTime(); - - TraceId getTraceId(); - - boolean canSampled(); - - boolean isRoot(); - - - void recordException(Throwable throwable); - - void recordApi(MethodDescriptor methodDescriptor); - - void recordApi(MethodDescriptor methodDescriptor, Object[] args); - - void recordApi(MethodDescriptor methodDescriptor, Object args, int index); - - void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end); - - void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index); - - ParsingResult recordSqlInfo(String sql); - - void recordSqlParsingResult(ParsingResult parsingResult); - - void recordSqlParsingResult(ParsingResult parsingResult, String bindValue); - - void recordAttribute(AnnotationKey key, String value); - - void recordAttribute(AnnotationKey key, int value); - - void recordAttribute(AnnotationKey key, Object value); - - void recordServiceType(ServiceType serviceType); - - void recordRpcName(String rpc); - - void recordDestinationId(String destinationId); - - void recordEndPoint(String endPoint); - - void recordRemoteAddress(String remoteAddress); - - void recordNextSpanId(long spanId); - - void recordParentApplication(String parentApplicationName, short parentApplicationType); - - /** - * WAS_A -> WAS_B 호출 관계일 때 WAS_B에서 WAS_A가 보내준 호출 정보를 통해 자기 자신의 정보를 추출하여 저장 - * 이 데이터는 서버맵에서 WAS끼리 호출관계를 알아낼 떄 필요하다. - * - * @param host host 값은 WAS를 호출한 URL상의 host를 가져와야 한다. - */ - void recordAcceptorHost(String host); - - int getStackFrameId(); -} +package com.nhn.pinpoint.bootstrap.context; + +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.util.ParsingResult; + +/** + * @author emeroad + */ +public interface RecordableTrace { + + void markBeforeTime(); + + long getBeforeTime(); + + void markAfterTime(); + + long getAfterTime(); + + TraceId getTraceId(); + + boolean canSampled(); + + boolean isRoot(); + + + void recordException(Throwable throwable); + + void recordApi(MethodDescriptor methodDescriptor); + + void recordApi(MethodDescriptor methodDescriptor, Object[] args); + + void recordApi(MethodDescriptor methodDescriptor, Object args, int index); + + void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end); + + void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index); + + ParsingResult recordSqlInfo(String sql); + + void recordSqlParsingResult(ParsingResult parsingResult); + + void recordSqlParsingResult(ParsingResult parsingResult, String bindValue); + + void recordAttribute(AnnotationKey key, String value); + + void recordAttribute(AnnotationKey key, int value); + + void recordAttribute(AnnotationKey key, Object value); + + void recordServiceType(ServiceType serviceType); + + void recordRpcName(String rpc); + + void recordDestinationId(String destinationId); + + void recordEndPoint(String endPoint); + + void recordRemoteAddress(String remoteAddress); + + void recordNextSpanId(long spanId); + + void recordParentApplication(String parentApplicationName, short parentApplicationType); + + /** + * WAS_A -> WAS_B 호출 관계일 때 WAS_B에서 WAS_A가 보내준 호출 정보를 통해 자기 자신의 정보를 추출하여 저장 + * 이 데이터는 서버맵에서 WAS끼리 호출관계를 알아낼 떄 필요하다. + * + * @param host host 값은 WAS를 호출한 URL상의 host를 가져와야 한다. + */ + void recordAcceptorHost(String host); + + int getStackFrameId(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/StackOperation.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/StackOperation.java index aec2aa3f4ddc..18357aa92934 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/StackOperation.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/StackOperation.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.bootstrap.context; - -/** - * @author emeroad - */ -public interface StackOperation { - - public static final int DEFAULT_STACKID = -1; - public static final int ROOT_STACKID = 0; - - void traceBlockBegin(); - - void traceBlockBegin(int stackId); - - // traceRootBlockBegin을 명시적으로 빼내야 되듯함. - - void traceRootBlockEnd(); - - void traceBlockEnd(); - - void traceBlockEnd(int stackId); -} +package com.nhn.pinpoint.bootstrap.context; + +/** + * @author emeroad + */ +public interface StackOperation { + + public static final int DEFAULT_STACKID = -1; + public static final int ROOT_STACKID = 0; + + void traceBlockBegin(); + + void traceBlockBegin(int stackId); + + // traceRootBlockBegin을 명시적으로 빼내야 되듯함. + + void traceRootBlockEnd(); + + void traceBlockEnd(); + + void traceBlockEnd(int stackId); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Trace.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Trace.java index cab67ab9c09c..e0818f22b989 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Trace.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/Trace.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.bootstrap.context; - -/** - * @author emeroad - */ -public interface Trace extends RecordableTrace, StackOperation { - - - - - - -} +package com.nhn.pinpoint.bootstrap.context; + +/** + * @author emeroad + */ +public interface Trace extends RecordableTrace, StackOperation { + + + + + + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java index 29cbe846bfc7..d1195b154360 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java @@ -1,64 +1,64 @@ -package com.nhn.pinpoint.bootstrap.context; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.util.ParsingResult; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; - -/** - * @author emeroad - */ -public interface TraceContext { - - Trace currentTraceObject(); - - /** - * sampling rate를 추가적으로 확인해야 되는 trace를 리턴한다. - * @return - */ - Trace currentRawTraceObject(); - - Trace continueTraceObject(TraceId traceID); - - Trace newTraceObject(); - - void detachTraceObject(); - -// ActiveThreadCounter getActiveThreadCounter(); - - String getAgentId(); - - String getApplicationName(); - - long getAgentStartTime(); - - short getServerTypeCode(); - - String getServerType(); - - int cacheApi(MethodDescriptor methodDescriptor); - - int cacheString(String value); - - ParsingResult parseSql(String sql); - - DatabaseInfo parseJdbcUrl(String sql); - - DatabaseInfo createDatabaseInfo(ServiceType type, ServiceType executeQueryType, String url, int port, String databaseId); - - TraceId createTraceId(String transactionId, long parentSpanID, long spanID, short flags); - - Trace disableSampling(); - - ProfilerConfig getProfilerConfig(); - - Metric getRpcMetric(ServiceType serviceType); - - void recordContextMetricIsError(); - - void recordContextMetric(int elapsedTime); - - void recordAcceptResponseTime(String parentApplicationName, short parentApplicationType, int elapsedTime); - - void recordUserAcceptResponseTime(int elapsedTime); -} +package com.nhn.pinpoint.bootstrap.context; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.util.ParsingResult; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; + +/** + * @author emeroad + */ +public interface TraceContext { + + Trace currentTraceObject(); + + /** + * sampling rate를 추가적으로 확인해야 되는 trace를 리턴한다. + * @return + */ + Trace currentRawTraceObject(); + + Trace continueTraceObject(TraceId traceID); + + Trace newTraceObject(); + + void detachTraceObject(); + +// ActiveThreadCounter getActiveThreadCounter(); + + String getAgentId(); + + String getApplicationName(); + + long getAgentStartTime(); + + short getServerTypeCode(); + + String getServerType(); + + int cacheApi(MethodDescriptor methodDescriptor); + + int cacheString(String value); + + ParsingResult parseSql(String sql); + + DatabaseInfo parseJdbcUrl(String sql); + + DatabaseInfo createDatabaseInfo(ServiceType type, ServiceType executeQueryType, String url, int port, String databaseId); + + TraceId createTraceId(String transactionId, long parentSpanID, long spanID, short flags); + + Trace disableSampling(); + + ProfilerConfig getProfilerConfig(); + + Metric getRpcMetric(ServiceType serviceType); + + void recordContextMetricIsError(); + + void recordContextMetric(int elapsedTime); + + void recordAcceptResponseTime(String parentApplicationName, short parentApplicationType, int elapsedTime); + + void recordUserAcceptResponseTime(int elapsedTime); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceId.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceId.java index a4c5c16a7144..023660710517 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceId.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceId.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.bootstrap.context; - -/** - * @author emeroad - */ -public interface TraceId { - - TraceId getNextTraceId(); - - long getSpanId(); - - String getTransactionId(); - - String getAgentId(); - - long getAgentStartTime(); - - long getTransactionSequence(); - - long getParentSpanId(); - - short getFlags(); - - boolean isRoot(); -} +package com.nhn.pinpoint.bootstrap.context; + +/** + * @author emeroad + */ +public interface TraceId { + + TraceId getNextTraceId(); + + long getSpanId(); + + String getTransactionId(); + + String getAgentId(); + + long getAgentStartTime(); + + long getTransactionSequence(); + + long getParentSpanId(); + + short getFlags(); + + boolean isRoot(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ByteCodeMethodDescriptorSupport.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ByteCodeMethodDescriptorSupport.java index 056f670cd360..fcc9431aecdc 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ByteCodeMethodDescriptorSupport.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ByteCodeMethodDescriptorSupport.java @@ -1,9 +1,9 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * precompile level의 methodDescriptor를 setting 받을수 있게 한다. - * @author emeroad - */ -public interface ByteCodeMethodDescriptorSupport { - void setMethodDescriptor(MethodDescriptor descriptor); -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * precompile level의 methodDescriptor를 setting 받을수 있게 한다. + * @author emeroad + */ +public interface ByteCodeMethodDescriptorSupport { + void setMethodDescriptor(MethodDescriptor descriptor); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/EmptyParameterExtractor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/EmptyParameterExtractor.java index ce1b01365361..73f724b7eb6b 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/EmptyParameterExtractor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/EmptyParameterExtractor.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * @author emeroad - */ -public class EmptyParameterExtractor implements ParameterExtractor { - - public static final ParameterExtractor INSTANCE = new EmptyParameterExtractor(); - - private EmptyParameterExtractor() { - } - - @Override - public int getIndex() { - return NOT_FOUND; - } - - @Override - public Object extractObject(Object[] parameterList) { - return NULL; - } -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * @author emeroad + */ +public class EmptyParameterExtractor implements ParameterExtractor { + + public static final ParameterExtractor INSTANCE = new EmptyParameterExtractor(); + + private EmptyParameterExtractor() { + } + + @Override + public int getIndex() { + return NOT_FOUND; + } + + @Override + public Object extractObject(Object[] parameterList) { + return NULL; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/Interceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/Interceptor.java index a3a4b4fb41ed..0952aa719585 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/Interceptor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/Interceptor.java @@ -1,7 +1,7 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * @author emeroad - */ -public interface Interceptor { -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * @author emeroad + */ +public interface Interceptor { +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java index 71ea7e06b738..d141c8075f02 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java @@ -37,10 +37,9 @@ public int addInterceptor0(StaticAroundInterceptor interceptor) { if (interceptor == null) { return -1; } - int newId = nextId(); - - if (newId > max) { - throw new IndexOutOfBoundsException("size=" + index.length + ", id=" + id); + final int newId = nextId(); + if (newId >= max) { + throw new IndexOutOfBoundsException("size=" + index.length + " id=" + id); } this.index[newId] = interceptor; @@ -49,18 +48,16 @@ public int addInterceptor0(StaticAroundInterceptor interceptor) { } private int nextId() { - int number = id.getAndIncrement(); - - return number; + return id.getAndIncrement(); } int addSimpleInterceptor0(SimpleAroundInterceptor interceptor) { if (interceptor == null) { return -1; } - int newId = nextId(); + final int newId = nextId(); if (newId >= max) { - throw new IndexOutOfBoundsException("size=" + index.length + ", id=" + id); + throw new IndexOutOfBoundsException("size=" + index.length + " id=" + id); } this.simpleIndex[newId] = interceptor; diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/LoggingInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/LoggingInterceptor.java index cc4b98d44471..2a801a2340ab 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/LoggingInterceptor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/LoggingInterceptor.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.bootstrap.util.StringUtils; - -import java.util.Arrays; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author emeroad - */ -public class LoggingInterceptor implements StaticAroundInterceptor, SimpleAroundInterceptor { - - private final Logger logger; - - public LoggingInterceptor(String loggerName) { - this.logger = Logger.getLogger(loggerName); - } - - @Override - public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { - if (logger.isLoggable(Level.FINE)) { - logger.fine("before " + StringUtils.toString(target) + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); - } - } - - @Override - public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - if (logger.isLoggable(Level.FINE)) { - logger.fine("after " + StringUtils.toString(target) + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args) + " result:" + result + " Throwable:" + throwable); - } - } - - @Override - public void before(Object target, Object[] args) { - if (logger.isLoggable(Level.FINE)) { - logger.fine("before " + StringUtils.toString(target) + " args:" + Arrays.toString(args) ); - } - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (logger.isLoggable(Level.FINE)) { - logger.fine("after " + StringUtils.toString(target) + " args:" + Arrays.toString(args) + " result:" + result + " Throwable:" + throwable); - } - } - -} +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.bootstrap.util.StringUtils; + +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author emeroad + */ +public class LoggingInterceptor implements StaticAroundInterceptor, SimpleAroundInterceptor { + + private final Logger logger; + + public LoggingInterceptor(String loggerName) { + this.logger = Logger.getLogger(loggerName); + } + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("before " + StringUtils.toString(target) + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); + } + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("after " + StringUtils.toString(target) + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args) + " result:" + result + " Throwable:" + throwable); + } + } + + @Override + public void before(Object target, Object[] args) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("before " + StringUtils.toString(target) + " args:" + Arrays.toString(args) ); + } + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("after " + StringUtils.toString(target) + " args:" + Arrays.toString(args) + " result:" + result + " Throwable:" + throwable); + } + } + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/MethodDescriptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/MethodDescriptor.java index a58c8d95fa77..f4221be2ee2b 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/MethodDescriptor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/MethodDescriptor.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * @author emeroad - */ -public interface MethodDescriptor { - String getMethodName(); - - String getClassName(); - - String[] getParameterTypes(); - - String[] getParameterVariableName(); - - String getParameterDescriptor(); - - int getLineNumber(); - - String getFullName(); - - void setApiId(int apiId); - - int getApiId(); - - String getApiDescriptor(); -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * @author emeroad + */ +public interface MethodDescriptor { + String getMethodName(); + + String getClassName(); + + String[] getParameterTypes(); + + String[] getParameterVariableName(); + + String getParameterDescriptor(); + + int getLineNumber(); + + String getFullName(); + + void setApiId(int apiId); + + int getApiId(); + + String getApiDescriptor(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractor.java index fc53066017be..51cc9f31896d 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractor.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * 객체 생성을 줄이기 위해서 객체를 리턴하지 않고 c 스타일 api로 디자인함. - * @author emeroad - */ -public interface ParameterExtractor { - public static final Object NULL = new Object(); - - public static final int NOT_FOUND = -1; - - int getIndex(); - - Object extractObject(Object[] parameterList); -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * 객체 생성을 줄이기 위해서 객체를 리턴하지 않고 c 스타일 api로 디자인함. + * @author emeroad + */ +public interface ParameterExtractor { + public static final Object NULL = new Object(); + + public static final int NOT_FOUND = -1; + + int getIndex(); + + Object extractObject(Object[] parameterList); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractorSupport.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractorSupport.java index b003880932ff..7c8a7b9f3181 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractorSupport.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ParameterExtractorSupport.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * @author emeroad - */ -public interface ParameterExtractorSupport { - void setParameterExtractor(ParameterExtractor parameterExtractor); -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * @author emeroad + */ +public interface ParameterExtractorSupport { + void setParameterExtractor(ParameterExtractor parameterExtractor); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ServiceTypeSupport.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ServiceTypeSupport.java index a1fe2059a150..5619a5990b6d 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ServiceTypeSupport.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/ServiceTypeSupport.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.common.ServiceType; - -/** - * @author emeroad - */ -public interface ServiceTypeSupport { - - void setServiceType(ServiceType serviceType); - -} +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.common.ServiceType; + +/** + * @author emeroad + */ +public interface ServiceTypeSupport { + + void setServiceType(ServiceType serviceType); + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAroundInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAroundInterceptor.java index 9225f33e6ec2..d05d43497816 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAroundInterceptor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAroundInterceptor.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * @author emeroad - */ -public interface SimpleAroundInterceptor extends Interceptor { - - void before(Object target, Object[] args); - - void after(Object target, Object[] args, Object result, Throwable throwable); -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * @author emeroad + */ +public interface SimpleAroundInterceptor extends Interceptor { + + void before(Object target, Object[] args); + + void after(Object target, Object[] args, Object result, Throwable throwable); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanEventSimpleAroundInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanEventSimpleAroundInterceptor.java index 357d8bed956f..4d7e8cd71c81 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanEventSimpleAroundInterceptor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanEventSimpleAroundInterceptor.java @@ -1,111 +1,111 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -/** - * @author emeroad - */ -public abstract class SpanEventSimpleAroundInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { - protected final PLogger logger; - protected final boolean isDebug; - - private MethodDescriptor descriptor; - - private TraceContext traceContext; - - protected SpanEventSimpleAroundInterceptor(Class childClazz) { - this.logger = PLoggerFactory.getLogger(childClazz); - this.isDebug = logger.isDebugEnabled(); - } - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logBeforeInterceptor(target, args); - } - - prepareBeforeTrace(target, args); - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - try { - // blockBegin 인터페이스 분리가 필요함. - trace.traceBlockBegin(); - doInBeforeTrace(trace, target, args); - } catch (Throwable th) { - if (logger.isWarnEnabled()) { - logger.warn("before. Caused:{}", th.getMessage(), th); - } - } - } - - protected void logBeforeInterceptor(Object target, Object[] args) { - logger.beforeInterceptor(target, args); - } - - protected void prepareBeforeTrace(Object target, Object[] args) { - - } - - protected abstract void doInBeforeTrace(final RecordableTrace trace, final Object target, final Object[] args); - - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logAfterInterceptor(target, args, result, throwable); - } - - prepareAfterTrace(target, args, result, throwable); - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - try { - doInAfterTrace(trace, target, args, result, throwable); - } catch (Throwable th) { - if (logger.isWarnEnabled()) { - logger.warn("after error. Caused:{}", th.getMessage(), th); - } - } finally { - trace.traceBlockEnd(); - } - } - - protected void logAfterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { - logger.afterInterceptor(target, args, result, throwable); - } - - protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { - - } - - protected abstract void doInAfterTrace(final RecordableTrace trace, final Object target, final Object[] args, final Object result, Throwable throwable); - - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.descriptor = descriptor; - this.traceContext.cacheApi(descriptor); - } - - public MethodDescriptor getMethodDescriptor() { - return descriptor; - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - public TraceContext getTraceContext() { - return traceContext; - } -} +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; + +/** + * @author emeroad + */ +public abstract class SpanEventSimpleAroundInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { + protected final PLogger logger; + protected final boolean isDebug; + + private MethodDescriptor descriptor; + + private TraceContext traceContext; + + protected SpanEventSimpleAroundInterceptor(Class childClazz) { + this.logger = PLoggerFactory.getLogger(childClazz); + this.isDebug = logger.isDebugEnabled(); + } + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logBeforeInterceptor(target, args); + } + + prepareBeforeTrace(target, args); + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + try { + // blockBegin 인터페이스 분리가 필요함. + trace.traceBlockBegin(); + doInBeforeTrace(trace, target, args); + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("before. Caused:{}", th.getMessage(), th); + } + } + } + + protected void logBeforeInterceptor(Object target, Object[] args) { + logger.beforeInterceptor(target, args); + } + + protected void prepareBeforeTrace(Object target, Object[] args) { + + } + + protected abstract void doInBeforeTrace(final RecordableTrace trace, final Object target, final Object[] args); + + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logAfterInterceptor(target, args, result, throwable); + } + + prepareAfterTrace(target, args, result, throwable); + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + try { + doInAfterTrace(trace, target, args, result, throwable); + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("after error. Caused:{}", th.getMessage(), th); + } + } finally { + trace.traceBlockEnd(); + } + } + + protected void logAfterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { + logger.afterInterceptor(target, args, result, throwable); + } + + protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { + + } + + protected abstract void doInAfterTrace(final RecordableTrace trace, final Object target, final Object[] args, final Object result, Throwable throwable); + + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + this.traceContext.cacheApi(descriptor); + } + + public MethodDescriptor getMethodDescriptor() { + return descriptor; + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + public TraceContext getTraceContext() { + return traceContext; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptor.java index be53ef275515..4cf1a8cc8836 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptor.java @@ -1,101 +1,101 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -/** - * @author emeroad - */ -public abstract class SpanSimpleAroundInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { - protected final PLogger logger; - protected final boolean isDebug; - - private MethodDescriptor methodDescriptor; - - private TraceContext traceContext; - - protected SpanSimpleAroundInterceptor(Class childClazz) { - this.logger = PLoggerFactory.getLogger(childClazz); - this.isDebug = logger.isDebugEnabled(); - } - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - try { - final Trace trace = createTrace(target, args); - if (trace == null) { - return; - } - // TODO STATDISABLE 일단 통계 저장기능을 disable하기 위해 아래 로직을 추가함. - if (!trace.canSampled()) { - return; - } - //------------------------------------------------------ - doInBeforeTrace(trace, target, args); - } catch (Throwable th) { - if (logger.isWarnEnabled()) { - logger.warn("before. Caused:{}", th.getMessage(), th); - } - } - } - - protected abstract void doInBeforeTrace(final RecordableTrace trace, Object target, final Object[] args); - - protected abstract Trace createTrace(final Object target, final Object[] args); - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - final Trace trace = traceContext.currentRawTraceObject(); - if (trace == null) { - return; - } - traceContext.detachTraceObject(); - // TODO STATDISABLE 일단 통계 저장기능을 disable하기 위해 아래 로직을 추가함. - if (!trace.canSampled()) { - return; - } - //------------------------------------------------------ - try { - doInAfterTrace(trace, target, args, result, throwable); - } catch (Throwable th) { - if (logger.isWarnEnabled()) { - logger.warn("after. Caused:{}", th.getMessage(), th); - } - } finally { - trace.traceRootBlockEnd(); - } - } - - protected abstract void doInAfterTrace(final RecordableTrace trace, final Object target, final Object[] args, final Object result, Throwable throwable); - - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.methodDescriptor = descriptor; - this.traceContext.cacheApi(descriptor); - } - - public MethodDescriptor getMethodDescriptor() { - return methodDescriptor; - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - public TraceContext getTraceContext() { - return traceContext; - } -} +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; + +/** + * @author emeroad + */ +public abstract class SpanSimpleAroundInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { + protected final PLogger logger; + protected final boolean isDebug; + + private MethodDescriptor methodDescriptor; + + private TraceContext traceContext; + + protected SpanSimpleAroundInterceptor(Class childClazz) { + this.logger = PLoggerFactory.getLogger(childClazz); + this.isDebug = logger.isDebugEnabled(); + } + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + try { + final Trace trace = createTrace(target, args); + if (trace == null) { + return; + } + // TODO STATDISABLE 일단 통계 저장기능을 disable하기 위해 아래 로직을 추가함. + if (!trace.canSampled()) { + return; + } + //------------------------------------------------------ + doInBeforeTrace(trace, target, args); + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("before. Caused:{}", th.getMessage(), th); + } + } + } + + protected abstract void doInBeforeTrace(final RecordableTrace trace, Object target, final Object[] args); + + protected abstract Trace createTrace(final Object target, final Object[] args); + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + final Trace trace = traceContext.currentRawTraceObject(); + if (trace == null) { + return; + } + traceContext.detachTraceObject(); + // TODO STATDISABLE 일단 통계 저장기능을 disable하기 위해 아래 로직을 추가함. + if (!trace.canSampled()) { + return; + } + //------------------------------------------------------ + try { + doInAfterTrace(trace, target, args, result, throwable); + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("after. Caused:{}", th.getMessage(), th); + } + } finally { + trace.traceRootBlockEnd(); + } + } + + protected abstract void doInAfterTrace(final RecordableTrace trace, final Object target, final Object[] args, final Object result, Throwable throwable); + + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.methodDescriptor = descriptor; + this.traceContext.cacheApi(descriptor); + } + + public MethodDescriptor getMethodDescriptor() { + return methodDescriptor; + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + public TraceContext getTraceContext() { + return traceContext; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/StaticAroundInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/StaticAroundInterceptor.java index 58a4c2d34cc6..adce072ac17b 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/StaticAroundInterceptor.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/StaticAroundInterceptor.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * @author emeroad - */ -public interface StaticAroundInterceptor extends Interceptor { - - void before(Object target, String className, String methodName, String parameterDescription, Object[] args); - - void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable); - -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * @author emeroad + */ +public interface StaticAroundInterceptor extends Interceptor { + + void before(Object target, String className, String methodName, String parameterDescription, Object[] args); + + void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable); + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TargetClassLoader.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TargetClassLoader.java index a92f60a329be..3def6fe97fc8 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TargetClassLoader.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TargetClassLoader.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * 마커 newInterceptor를 통해 new할 경우 마크로 붙여야 한다. new Interceptor()를 하지 않아도 되는 곳에 강제 로딩을 하였을 경우 에러를 발생시키기 위해서 만듬. - * @author emeroad - */ -public interface TargetClassLoader { -} +package com.nhn.pinpoint.bootstrap.interceptor; + +/** + * 마커 newInterceptor를 통해 new할 경우 마크로 붙여야 한다. new Interceptor()를 하지 않아도 되는 곳에 강제 로딩을 하였을 경우 에러를 발생시키기 위해서 만듬. + * @author emeroad + */ +public interface TargetClassLoader { +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TraceContextSupport.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TraceContextSupport.java index 28b027388266..9b63208ddd8c 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TraceContextSupport.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/TraceContextSupport.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.bootstrap.context.TraceContext; - -/** - * @author emeroad - */ -public interface TraceContextSupport { - void setTraceContext(TraceContext traceContext); -} +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.bootstrap.context.TraceContext; + +/** + * @author emeroad + */ +public interface TraceContextSupport { + void setTraceContext(TraceContext traceContext); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/BindValueTraceValue.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/BindValueTraceValue.java index 0c5408d1dbce..c19c20ccee3b 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/BindValueTraceValue.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/BindValueTraceValue.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; - - -import java.util.Map; - -/** - * @author emeroad - */ -public interface BindValueTraceValue extends TraceValue { - void __setTraceBindValue(Map value); - - Map __getTraceBindValue(); -} +package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; + + +import java.util.Map; + +/** + * @author emeroad + */ +public interface BindValueTraceValue extends TraceValue { + void __setTraceBindValue(Map value); + + Map __getTraceBindValue(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValue.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValue.java index 00cf5e91ed4f..8850e4a10574 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValue.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValue.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; - -/** - * @author emeroad - */ -public interface DatabaseInfoTraceValue extends TraceValue { - void __setTraceDatabaseInfo(DatabaseInfo value); - - DatabaseInfo __getTraceDatabaseInfo(); - -} +package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; + +/** + * @author emeroad + */ +public interface DatabaseInfoTraceValue extends TraceValue { + void __setTraceDatabaseInfo(DatabaseInfo value); + + DatabaseInfo __getTraceDatabaseInfo(); + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValueUtils.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValueUtils.java index 481f01275867..b4429a2a5c08 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValueUtils.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/DatabaseInfoTraceValueUtils.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; - -/** - * @author emeroad - */ -public class DatabaseInfoTraceValueUtils { - - public static DatabaseInfo __getTraceDatabaseInfo(Object target, DatabaseInfo defaultValue) { - if (target == null) { - return defaultValue; - } - if (target instanceof DatabaseInfoTraceValue) { - final DatabaseInfo databaseInfo = ((DatabaseInfoTraceValue) target).__getTraceDatabaseInfo(); - if (databaseInfo == null) { - return defaultValue; - } - return databaseInfo; - } - return defaultValue; - } - - public static void __setTraceDatabaseInfo(Object target, DatabaseInfo databaseInfo) { - if (target == null) { - return; - } - if (target instanceof DatabaseInfoTraceValue) { - ((DatabaseInfoTraceValue) target).__setTraceDatabaseInfo(databaseInfo); - } - } -} +package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; + +/** + * @author emeroad + */ +public class DatabaseInfoTraceValueUtils { + + public static DatabaseInfo __getTraceDatabaseInfo(Object target, DatabaseInfo defaultValue) { + if (target == null) { + return defaultValue; + } + if (target instanceof DatabaseInfoTraceValue) { + final DatabaseInfo databaseInfo = ((DatabaseInfoTraceValue) target).__getTraceDatabaseInfo(); + if (databaseInfo == null) { + return defaultValue; + } + return databaseInfo; + } + return defaultValue; + } + + public static void __setTraceDatabaseInfo(Object target, DatabaseInfo databaseInfo) { + if (target == null) { + return; + } + if (target instanceof DatabaseInfoTraceValue) { + ((DatabaseInfoTraceValue) target).__setTraceDatabaseInfo(databaseInfo); + } + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/IntTraceValue.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/IntTraceValue.java index c5b5c19b9ab8..8d6cc10116d4 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/IntTraceValue.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/IntTraceValue.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; - -/** - * @author emeroad - */ -public interface IntTraceValue extends TraceValue { - void __setTraceInt(int value); - - int __getTraceInt(); -} +package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; + +/** + * @author emeroad + */ +public interface IntTraceValue extends TraceValue { + void __setTraceInt(int value); + + int __getTraceInt(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ObjectTraceValue.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ObjectTraceValue.java index 49bee6ab3be3..e37679039645 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ObjectTraceValue.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ObjectTraceValue.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; - -/** - * @author emeroad - */ -public interface ObjectTraceValue extends TraceValue { - - void __setTraceObject(Object value); - - Object __getTraceObject(); -} +package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; + +/** + * @author emeroad + */ +public interface ObjectTraceValue extends TraceValue { + + void __setTraceObject(Object value); + + Object __getTraceObject(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ParsingResultTraceValue.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ParsingResultTraceValue.java index ecd6cd5e58d0..bded984d388c 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ParsingResultTraceValue.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/ParsingResultTraceValue.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; - -import com.nhn.pinpoint.common.util.ParsingResult; - -/** - * @author emeroad - */ -public interface ParsingResultTraceValue extends TraceValue { - void __setTraceParsingResult(ParsingResult parsingResult); - - ParsingResult __getTraceParsingResult(); -} +package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; + +import com.nhn.pinpoint.common.util.ParsingResult; + +/** + * @author emeroad + */ +public interface ParsingResultTraceValue extends TraceValue { + void __setTraceParsingResult(ParsingResult parsingResult); + + ParsingResult __getTraceParsingResult(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/TraceValue.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/TraceValue.java index 189ca3e9429a..63bdc7c2cd29 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/TraceValue.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/tracevalue/TraceValue.java @@ -1,9 +1,9 @@ -package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; - -/** - * marker Interface - * @author emeroad - */ -public interface TraceValue { - -} +package com.nhn.pinpoint.bootstrap.interceptor.tracevalue; + +/** + * marker Interface + * @author emeroad + */ +public interface TraceValue { + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/DummyPLogger.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/DummyPLogger.java index eee94ce36af0..1138a96a547b 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/DummyPLogger.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/DummyPLogger.java @@ -1,186 +1,186 @@ -package com.nhn.pinpoint.bootstrap.logging; - -/** - * @author emeroad - */ -public class DummyPLogger implements PLogger { - - public static final PLogger INSTANCE = new DummyPLogger(); - - @Override - public void beforeInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { - } - - @Override - public void beforeInterceptor(Object target, Object[] args) { - } - - - @Override - public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - - } - - @Override - public void afterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { - } - - - @Override - public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { - } - - @Override - public void afterInterceptor(Object target, Object[] args) { - } - - @Override - public boolean isTraceEnabled() { - return false; - } - - @Override - public void trace(String msg) { - - } - - @Override - public void trace(String format, Object arg) { - - } - - @Override - public void trace(String format, Object arg1, Object arg2) { - - } - - @Override - public void trace(String format, Object[] argArray) { - - } - - @Override - public void trace(String msg, Throwable t) { - - } - - @Override - public boolean isDebugEnabled() { - return false; - } - - @Override - public void debug(String msg) { - - } - - @Override - public void debug(String format, Object arg) { - - } - - @Override - public void debug(String format, Object arg1, Object arg2) { - - } - - @Override - public void debug(String format, Object[] argArray) { - - } - - @Override - public void debug(String msg, Throwable t) { - - } - - @Override - public boolean isInfoEnabled() { - return false; - } - - @Override - public void info(String msg) { - - } - - @Override - public void info(String format, Object arg) { - - } - - @Override - public void info(String format, Object arg1, Object arg2) { - - } - - @Override - public void info(String format, Object[] argArray) { - - } - - @Override - public void info(String msg, Throwable t) { - - } - - @Override - public boolean isWarnEnabled() { - return false; - } - - @Override - public void warn(String msg) { - - } - - @Override - public void warn(String format, Object arg) { - - } - - @Override - public void warn(String format, Object[] argArray) { - - } - - @Override - public void warn(String format, Object arg1, Object arg2) { - - } - - @Override - public void warn(String msg, Throwable t) { - - } - - @Override - public boolean isErrorEnabled() { - return false; - } - - @Override - public void error(String msg) { - - } - - @Override - public void error(String format, Object arg) { - - } - - @Override - public void error(String format, Object arg1, Object arg2) { - - } - - @Override - public void error(String format, Object[] argArray) { - - } - - @Override - public void error(String msg, Throwable t) { - - } -} +package com.nhn.pinpoint.bootstrap.logging; + +/** + * @author emeroad + */ +public class DummyPLogger implements PLogger { + + public static final PLogger INSTANCE = new DummyPLogger(); + + @Override + public void beforeInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { + } + + @Override + public void beforeInterceptor(Object target, Object[] args) { + } + + + @Override + public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + + } + + @Override + public void afterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { + } + + + @Override + public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { + } + + @Override + public void afterInterceptor(Object target, Object[] args) { + } + + @Override + public boolean isTraceEnabled() { + return false; + } + + @Override + public void trace(String msg) { + + } + + @Override + public void trace(String format, Object arg) { + + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + + } + + @Override + public void trace(String format, Object[] argArray) { + + } + + @Override + public void trace(String msg, Throwable t) { + + } + + @Override + public boolean isDebugEnabled() { + return false; + } + + @Override + public void debug(String msg) { + + } + + @Override + public void debug(String format, Object arg) { + + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + + } + + @Override + public void debug(String format, Object[] argArray) { + + } + + @Override + public void debug(String msg, Throwable t) { + + } + + @Override + public boolean isInfoEnabled() { + return false; + } + + @Override + public void info(String msg) { + + } + + @Override + public void info(String format, Object arg) { + + } + + @Override + public void info(String format, Object arg1, Object arg2) { + + } + + @Override + public void info(String format, Object[] argArray) { + + } + + @Override + public void info(String msg, Throwable t) { + + } + + @Override + public boolean isWarnEnabled() { + return false; + } + + @Override + public void warn(String msg) { + + } + + @Override + public void warn(String format, Object arg) { + + } + + @Override + public void warn(String format, Object[] argArray) { + + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + + } + + @Override + public void warn(String msg, Throwable t) { + + } + + @Override + public boolean isErrorEnabled() { + return false; + } + + @Override + public void error(String msg) { + + } + + @Override + public void error(String format, Object arg) { + + } + + @Override + public void error(String format, Object arg1, Object arg2) { + + } + + @Override + public void error(String format, Object[] argArray) { + + } + + @Override + public void error(String msg, Throwable t) { + + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/LoggingUtils.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/LoggingUtils.java index b8dd092b27df..b70f8d15c35e 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/LoggingUtils.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/LoggingUtils.java @@ -1,53 +1,53 @@ -package com.nhn.pinpoint.bootstrap.logging; - -import java.util.Arrays; - -/** - * @author emeroad - */ -public class LoggingUtils { - - - public static void logBefore(PLogger logger, Object target, String className, String methodName, String parameterDescription, Object[] args) { - StringBuilder sb = new StringBuilder(512); - sb.append("before "); - logMethod(sb, getTarget(target), className, methodName, parameterDescription, args); - logger.debug(sb.toString()); - } - - public static void logAfter(PLogger logger, Object target, String className, String methodName, String parameterDescription, Object[] args, Object result) { - StringBuilder sb = new StringBuilder(512); - sb.append("after "); - logMethod(sb, getTarget(target), className, methodName, parameterDescription, args); - sb.append(" result:"); - sb.append(getTarget(result)); - logger.debug(sb.toString()); - } - - public static void logAfter(PLogger logger, Object target, String className, String methodName, String parameterDescription, Object[] args) { - StringBuilder sb = new StringBuilder(512); - sb.append("after "); - logMethod(sb, getTarget(target), className, methodName, parameterDescription, args); - logger.debug(sb.toString()); - } - - private static void logMethod(StringBuilder sb, Object target, String className, String methodName, String parameterDescription, Object[] args) { - sb.append(getTarget(target)); - sb.append(' '); - sb.append(className); - sb.append(' '); - sb.append(methodName); - sb.append(parameterDescription); - sb.append(" args:"); - sb.append(Arrays.toString(args)); - } - - private static Object getTarget(Object target) { - if (target == null) { - return "target=null"; - } - return target.getClass().getName(); - } - - -} +package com.nhn.pinpoint.bootstrap.logging; + +import java.util.Arrays; + +/** + * @author emeroad + */ +public class LoggingUtils { + + + public static void logBefore(PLogger logger, Object target, String className, String methodName, String parameterDescription, Object[] args) { + StringBuilder sb = new StringBuilder(512); + sb.append("before "); + logMethod(sb, getTarget(target), className, methodName, parameterDescription, args); + logger.debug(sb.toString()); + } + + public static void logAfter(PLogger logger, Object target, String className, String methodName, String parameterDescription, Object[] args, Object result) { + StringBuilder sb = new StringBuilder(512); + sb.append("after "); + logMethod(sb, getTarget(target), className, methodName, parameterDescription, args); + sb.append(" result:"); + sb.append(getTarget(result)); + logger.debug(sb.toString()); + } + + public static void logAfter(PLogger logger, Object target, String className, String methodName, String parameterDescription, Object[] args) { + StringBuilder sb = new StringBuilder(512); + sb.append("after "); + logMethod(sb, getTarget(target), className, methodName, parameterDescription, args); + logger.debug(sb.toString()); + } + + private static void logMethod(StringBuilder sb, Object target, String className, String methodName, String parameterDescription, Object[] args) { + sb.append(getTarget(target)); + sb.append(' '); + sb.append(className); + sb.append(' '); + sb.append(methodName); + sb.append(parameterDescription); + sb.append(" args:"); + sb.append(Arrays.toString(args)); + } + + private static Object getTarget(Object target) { + if (target == null) { + return "target=null"; + } + return target.getClass().getName(); + } + + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLogger.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLogger.java index 6c5b2eb60146..f9300cd1e419 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLogger.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLogger.java @@ -1,124 +1,124 @@ -package com.nhn.pinpoint.bootstrap.logging; - -/** - * @author emeroad - */ -public interface PLogger { - - - void beforeInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args); - - void beforeInterceptor(Object target, Object[] args); - - void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable); - - void afterInterceptor(Object target, Object[] args, Object result, Throwable throwable); - - void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args); - - void afterInterceptor(Object target, Object[] args); - - boolean isTraceEnabled(); - - - void trace(String msg); - - - void trace(String format, Object arg); - - - - void trace(String format, Object arg1, Object arg2); - - void trace(String format, Object[] argArray); - - void trace(String msg, Throwable t); - - - - public boolean isDebugEnabled(); - - - - public void debug(String msg); - - - - public void debug(String format, Object arg); - - - - - public void debug(String format, Object arg1, Object arg2); - - - public void debug(String format, Object[] argArray); - - - public void debug(String msg, Throwable t); - - - - - - public boolean isInfoEnabled(); - - - public void info(String msg); - - - - public void info(String format, Object arg); - - - - public void info(String format, Object arg1, Object arg2); - - - public void info(String format, Object[] argArray); - - - public void info(String msg, Throwable t); - - - - public boolean isWarnEnabled(); - - - public void warn(String msg); - - - public void warn(String format, Object arg); - - - public void warn(String format, Object[] argArray); - - - public void warn(String format, Object arg1, Object arg2); - - - public void warn(String msg, Throwable t); - - - - public boolean isErrorEnabled(); - - - public void error(String msg); - - - public void error(String format, Object arg); - - - public void error(String format, Object arg1, Object arg2); - - - public void error(String format, Object[] argArray); - - - public void error(String msg, Throwable t); - - - - -} +package com.nhn.pinpoint.bootstrap.logging; + +/** + * @author emeroad + */ +public interface PLogger { + + + void beforeInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args); + + void beforeInterceptor(Object target, Object[] args); + + void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable); + + void afterInterceptor(Object target, Object[] args, Object result, Throwable throwable); + + void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args); + + void afterInterceptor(Object target, Object[] args); + + boolean isTraceEnabled(); + + + void trace(String msg); + + + void trace(String format, Object arg); + + + + void trace(String format, Object arg1, Object arg2); + + void trace(String format, Object[] argArray); + + void trace(String msg, Throwable t); + + + + public boolean isDebugEnabled(); + + + + public void debug(String msg); + + + + public void debug(String format, Object arg); + + + + + public void debug(String format, Object arg1, Object arg2); + + + public void debug(String format, Object[] argArray); + + + public void debug(String msg, Throwable t); + + + + + + public boolean isInfoEnabled(); + + + public void info(String msg); + + + + public void info(String format, Object arg); + + + + public void info(String format, Object arg1, Object arg2); + + + public void info(String format, Object[] argArray); + + + public void info(String msg, Throwable t); + + + + public boolean isWarnEnabled(); + + + public void warn(String msg); + + + public void warn(String format, Object arg); + + + public void warn(String format, Object[] argArray); + + + public void warn(String format, Object arg1, Object arg2); + + + public void warn(String msg, Throwable t); + + + + public boolean isErrorEnabled(); + + + public void error(String msg); + + + public void error(String format, Object arg); + + + public void error(String format, Object arg1, Object arg2); + + + public void error(String format, Object[] argArray); + + + public void error(String msg, Throwable t); + + + + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerBinder.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerBinder.java index 2e1f851cd3db..650f2c4f3a68 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerBinder.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerBinder.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.bootstrap.logging; - -/** - * @author emeroad - */ -public interface PLoggerBinder { - PLogger getLogger(String name); - - void shutdown(); -} +package com.nhn.pinpoint.bootstrap.logging; + +/** + * @author emeroad + */ +public interface PLoggerBinder { + PLogger getLogger(String name); + + void shutdown(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerFactory.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerFactory.java index 268caebcca81..4b687b72b90c 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerFactory.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/logging/PLoggerFactory.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.bootstrap.logging; - -import java.util.logging.Logger; - -/** - * @author emeroad - */ -public final class PLoggerFactory { - - private static PLoggerBinder loggerBinder; - - public static void initialize(PLoggerBinder loggerBinder) { - if (PLoggerFactory.loggerBinder == null) { - PLoggerFactory.loggerBinder = loggerBinder; - } else { - final Logger logger = Logger.getLogger(PLoggerFactory.class.getName()); - logger.warning("loggerBinder is not null"); - } - } - - public static void unregister(PLoggerBinder loggerBinder) { - // 등록한 놈만 제거 가능하도록 제한 - // testcase 작성시 가능한 logger를 등록했다가 삭제하는 로직은 beforeClass, afterClass에 넣어야 한다. - if (loggerBinder == PLoggerFactory.loggerBinder) { - PLoggerFactory.loggerBinder = null; - } - } - - public static PLogger getLogger(String name) { - if (loggerBinder == null) { - // 바인딩 되지 않은 상태에서 getLogger를 호출시 null ex가 발생하므로 dummy logger를 리턴하도록 함. - return DummyPLogger.INSTANCE; - } - return loggerBinder.getLogger(name); - } - - public static PLogger getLogger(Class clazz) { - if (clazz == null) { - throw new NullPointerException("class must not be null"); - } - return getLogger(clazz.getName()); - } -} +package com.nhn.pinpoint.bootstrap.logging; + +import java.util.logging.Logger; + +/** + * @author emeroad + */ +public final class PLoggerFactory { + + private static PLoggerBinder loggerBinder; + + public static void initialize(PLoggerBinder loggerBinder) { + if (PLoggerFactory.loggerBinder == null) { + PLoggerFactory.loggerBinder = loggerBinder; + } else { + final Logger logger = Logger.getLogger(PLoggerFactory.class.getName()); + logger.warning("loggerBinder is not null"); + } + } + + public static void unregister(PLoggerBinder loggerBinder) { + // 등록한 놈만 제거 가능하도록 제한 + // testcase 작성시 가능한 logger를 등록했다가 삭제하는 로직은 beforeClass, afterClass에 넣어야 한다. + if (loggerBinder == PLoggerFactory.loggerBinder) { + PLoggerFactory.loggerBinder = null; + } + } + + public static PLogger getLogger(String name) { + if (loggerBinder == null) { + // 바인딩 되지 않은 상태에서 getLogger를 호출시 null ex가 발생하므로 dummy logger를 리턴하도록 함. + return DummyPLogger.INSTANCE; + } + return loggerBinder.getLogger(name); + } + + public static PLogger getLogger(Class clazz) { + if (clazz == null) { + throw new NullPointerException("class must not be null"); + } + return getLogger(clazz.getName()); + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameIntValuePair.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameIntValuePair.java index 26536a03e307..21adc1ed8c15 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameIntValuePair.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameIntValuePair.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.bootstrap.pair; - -/** - * classLoading구조에서 interceptor가 parent에 위치하면서 멀티 value access 데이터 전달이 필요할 경우의 공통 자료구조로 사용한다. - * value가 int type일때 사용 - * @author emeroad - */ -public class NameIntValuePair { - private T name; - private int value; - - public NameIntValuePair(T name, int value) { - this.name = name; - this.value = value; - } - - public T getName() { - return name; - } - - public void setName(T name) { - this.name = name; - } - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } -} +package com.nhn.pinpoint.bootstrap.pair; + +/** + * classLoading구조에서 interceptor가 parent에 위치하면서 멀티 value access 데이터 전달이 필요할 경우의 공통 자료구조로 사용한다. + * value가 int type일때 사용 + * @author emeroad + */ +public class NameIntValuePair { + private T name; + private int value; + + public NameIntValuePair(T name, int value) { + this.name = name; + this.value = value; + } + + public T getName() { + return name; + } + + public void setName(T name) { + this.name = name; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameValuePair.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameValuePair.java index f59a744fce80..0dde24e2628a 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameValuePair.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/pair/NameValuePair.java @@ -1,31 +1,31 @@ -package com.nhn.pinpoint.bootstrap.pair; - -/** - * classLoading구조에서 interceptor가 parent에 위치하면서 멀티 value access 데이터 전달이 필요할 경우의 공통 자료구조로 사용한다. - * @author emeroad - */ -public class NameValuePair { - private T name; - private V value; - - public NameValuePair(T name, V value) { - this.name = name; - this.value = value; - } - - public T getName() { - return name; - } - - public void setName(T name) { - this.name = name; - } - - public V getValue() { - return value; - } - - public void setValue(V value) { - this.value = value; - } -} +package com.nhn.pinpoint.bootstrap.pair; + +/** + * classLoading구조에서 interceptor가 parent에 위치하면서 멀티 value access 데이터 전달이 필요할 경우의 공통 자료구조로 사용한다. + * @author emeroad + */ +public class NameValuePair { + private T name; + private V value; + + public NameValuePair(T name, V value) { + this.name = name; + this.value = value; + } + + public T getName() { + return name; + } + + public void setName(T name) { + this.name = name; + } + + public V getValue() { + return value; + } + + public void setValue(V value) { + this.value = value; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/Sampler.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/Sampler.java index d347ff2e2b8f..805a1abbe5b9 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/Sampler.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/Sampler.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.bootstrap.sampler; - -/** - * @author emeroad - */ -public interface Sampler { - boolean isSampling(); -} +package com.nhn.pinpoint.bootstrap.sampler; + +/** + * @author emeroad + */ +public interface Sampler { + boolean isSampling(); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/SamplingFlagUtils.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/SamplingFlagUtils.java index 1c296790472e..2c332b533dd6 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/SamplingFlagUtils.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/sampler/SamplingFlagUtils.java @@ -1,31 +1,31 @@ -package com.nhn.pinpoint.bootstrap.sampler; - -/** - * @author emeroad - */ -public final class SamplingFlagUtils { - - // 향후 다른 샘플링 스펙이 추가될수 있으므로 - // 일부러 1개 byte를 소비하여 sampling마크 한다. - public static final String SAMPLING_RATE_PREFIX = "s"; - - - public static final String SAMPLING_RATE_FALSE = SAMPLING_RATE_PREFIX + "0"; - public static final String SAMPLING_RATE_TRUE = SAMPLING_RATE_PREFIX + "1"; - - private SamplingFlagUtils() { - } - - public static boolean isSamplingFlag(String samplingFlag) { - if (samplingFlag == null) { - return true; - } - // 정확하게 하지 말란 flag가 세팅되었을 경우만 샘플링을 하지 않는다. - // prefix를 보고 뭔가 더 정확하게 동작되어야 필요성이 있음. - if (samplingFlag.startsWith(SAMPLING_RATE_PREFIX)) { - return !SAMPLING_RATE_FALSE.equals(samplingFlag); - } - return true; - } -} - +package com.nhn.pinpoint.bootstrap.sampler; + +/** + * @author emeroad + */ +public final class SamplingFlagUtils { + + // 향후 다른 샘플링 스펙이 추가될수 있으므로 + // 일부러 1개 byte를 소비하여 sampling마크 한다. + public static final String SAMPLING_RATE_PREFIX = "s"; + + + public static final String SAMPLING_RATE_FALSE = SAMPLING_RATE_PREFIX + "0"; + public static final String SAMPLING_RATE_TRUE = SAMPLING_RATE_PREFIX + "1"; + + private SamplingFlagUtils() { + } + + public static boolean isSamplingFlag(String samplingFlag) { + if (samplingFlag == null) { + return true; + } + // 정확하게 하지 말란 flag가 세팅되었을 경우만 샘플링을 하지 않는다. + // prefix를 보고 뭔가 더 정확하게 동작되어야 필요성이 있음. + if (samplingFlag.startsWith(SAMPLING_RATE_PREFIX)) { + return !SAMPLING_RATE_FALSE.equals(samplingFlag); + } + return true; + } +} + diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/InterceptorUtils.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/InterceptorUtils.java index 806369d34465..57c5bee31ba4 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/InterceptorUtils.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/InterceptorUtils.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.bootstrap.util; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; - -public final class InterceptorUtils { - private InterceptorUtils() { - } - - public static boolean isThrowable(Object result) { - return result instanceof Throwable; - } - - public static boolean isSuccess(Throwable throwable) { - return throwable == null; - } - - - public static String exceptionToString(Throwable ex) { - if (ex != null) { - StringBuilder sb = new StringBuilder(128); - sb.append(ex.toString()).append("\n"); - - Writer writer = new StringWriter(); - PrintWriter printWriter = new PrintWriter(writer); - ex.printStackTrace(printWriter); - sb.append(writer.toString()); - - return sb.toString(); - } - return null; - } -} +package com.nhn.pinpoint.bootstrap.util; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; + +public final class InterceptorUtils { + private InterceptorUtils() { + } + + public static boolean isThrowable(Object result) { + return result instanceof Throwable; + } + + public static boolean isSuccess(Throwable throwable) { + return throwable == null; + } + + + public static String exceptionToString(Throwable ex) { + if (ex != null) { + StringBuilder sb = new StringBuilder(128); + sb.append(ex.toString()).append("\n"); + + Writer writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + sb.append(writer.toString()); + + return sb.toString(); + } + return null; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/MetaObject.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/MetaObject.java index e71c170ae961..fd13e927b591 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/MetaObject.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/MetaObject.java @@ -1,82 +1,82 @@ -package com.nhn.pinpoint.bootstrap.util; - -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * TraceValue interface를 구현하여 사용하라 - */ -@Deprecated -public final class MetaObject { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - - private final String methodName; - private final Class[] args; - private final R defaultReturnValue; - - // 이것을 class loading시 정적 타임에서 생성해 둘수 없는가? - private Method methodRef; - - - - public MetaObject(String methodName, Class... args) { - this.methodName = methodName; - this.args = args; - this.defaultReturnValue = null; - } - - public MetaObject(R defaultReturnValue, String methodName, Class... args) { - this.methodName = methodName; - this.args = args; - this.defaultReturnValue = defaultReturnValue; - } - - public R invoke(Object target, Object... args) { - if (target == null) { - return defaultReturnValue; - } - - Method method = this.methodRef; - if (method == null) { - // 멀티쓰레드에서 중복 엑세스해도 별 문제 없을것임. - final Class aClass = target.getClass(); - method = findMethod(aClass); - this.methodRef = method; - } - return invoke(method, target, args); - } - - private R invoke(Method method, Object target, Object[] args) { - if (method == null) { - return defaultReturnValue; - } - try { - return (R) method.invoke(target, args); - } catch (IllegalAccessException e) { - logger.warn("{} invoke fail", this.methodName, e); - return defaultReturnValue; - } catch (InvocationTargetException e) { - logger.warn("{} invoke fail", this.methodName, e); - return defaultReturnValue; - } - } - - private Method findMethod(Class aClass) { - try { - final Method method = aClass.getMethod(this.methodName, this.args); - if (!method.isAccessible()) { - // package등과 같이 access 제한이 걸려 있을 경우 강 푼다. - method.setAccessible(true); - } - return method; - } catch (NoSuchMethodException e) { - logger.warn("{} not found class:{} Caused:{}", new Object[] { this.methodName, aClass, e.getMessage(), e }); - return null; - } - } - -} +package com.nhn.pinpoint.bootstrap.util; + +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * TraceValue interface를 구현하여 사용하라 + */ +@Deprecated +public final class MetaObject { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + + private final String methodName; + private final Class[] args; + private final R defaultReturnValue; + + // 이것을 class loading시 정적 타임에서 생성해 둘수 없는가? + private Method methodRef; + + + + public MetaObject(String methodName, Class... args) { + this.methodName = methodName; + this.args = args; + this.defaultReturnValue = null; + } + + public MetaObject(R defaultReturnValue, String methodName, Class... args) { + this.methodName = methodName; + this.args = args; + this.defaultReturnValue = defaultReturnValue; + } + + public R invoke(Object target, Object... args) { + if (target == null) { + return defaultReturnValue; + } + + Method method = this.methodRef; + if (method == null) { + // 멀티쓰레드에서 중복 엑세스해도 별 문제 없을것임. + final Class aClass = target.getClass(); + method = findMethod(aClass); + this.methodRef = method; + } + return invoke(method, target, args); + } + + private R invoke(Method method, Object target, Object[] args) { + if (method == null) { + return defaultReturnValue; + } + try { + return (R) method.invoke(target, args); + } catch (IllegalAccessException e) { + logger.warn("{} invoke fail", this.methodName, e); + return defaultReturnValue; + } catch (InvocationTargetException e) { + logger.warn("{} invoke fail", this.methodName, e); + return defaultReturnValue; + } + } + + private Method findMethod(Class aClass) { + try { + final Method method = aClass.getMethod(this.methodName, this.args); + if (!method.isAccessible()) { + // package등과 같이 access 제한이 걸려 있을 경우 강 푼다. + method.setAccessible(true); + } + return method; + } catch (NoSuchMethodException e) { + logger.warn("{} not found class:{} Caused:{}", new Object[] { this.methodName, aClass, e.getMessage(), e }); + return null; + } + } + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NetworkUtils.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NetworkUtils.java index 5e8fd3c7a60d..dac4dbb09ed5 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NetworkUtils.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NetworkUtils.java @@ -1,78 +1,78 @@ -package com.nhn.pinpoint.bootstrap.util; - -import java.net.*; -import java.util.Enumeration; -import java.util.logging.Logger; - -/** - * @author emeroad - */ -public final class NetworkUtils { - - public static final String ERROR_HOST_NAME = "UNKNOWN-HOST"; - - private NetworkUtils() { - } - - public static String getHostName() { - try { - final InetAddress localHost = InetAddress.getLocalHost(); - return localHost.getHostName(); - } catch (UnknownHostException e) { - // Try to get machine name from network interface. - return getMachineName(); - } - } - - @Deprecated - public static String getMachineName() { - try { - String name = null; - Enumeration enet = NetworkInterface.getNetworkInterfaces(); - - while (enet.hasMoreElements() && (name == null)) { - NetworkInterface net = enet.nextElement(); - - if (net.isLoopback()) - continue; - - Enumeration eaddr = net.getInetAddresses(); - - while (eaddr.hasMoreElements()) { - InetAddress inet = eaddr.nextElement(); - - final String canonicalHostName = inet.getCanonicalHostName(); - if (!canonicalHostName.equalsIgnoreCase(inet.getHostAddress())) { - name = canonicalHostName; - break; - } - } - } - return name; - } catch (SocketException e) { - Logger.getLogger(NetworkUtils.class.getClass().getName()).warning(e.getMessage()); - return "UNKNOWN-HOST"; - } - } - - public static String getHostFromURL(final String urlSpec) { - if (urlSpec == null) { - return null; - } - try { - final URL url = new URL(urlSpec); - - final String host = url.getHost(); - final int port = url.getPort(); - - if (port == -1) { - return host; - } else { - // TODO defualt port일 경우 아래와 같이 url을 만들어야 하는지 애매함. - return host + ":" + port; - } - } catch (MalformedURLException e) { - return null; - } - } -} +package com.nhn.pinpoint.bootstrap.util; + +import java.net.*; +import java.util.Enumeration; +import java.util.logging.Logger; + +/** + * @author emeroad + */ +public final class NetworkUtils { + + public static final String ERROR_HOST_NAME = "UNKNOWN-HOST"; + + private NetworkUtils() { + } + + public static String getHostName() { + try { + final InetAddress localHost = InetAddress.getLocalHost(); + return localHost.getHostName(); + } catch (UnknownHostException e) { + // Try to get machine name from network interface. + return getMachineName(); + } + } + + @Deprecated + public static String getMachineName() { + try { + String name = null; + Enumeration enet = NetworkInterface.getNetworkInterfaces(); + + while (enet.hasMoreElements() && (name == null)) { + NetworkInterface net = enet.nextElement(); + + if (net.isLoopback()) + continue; + + Enumeration eaddr = net.getInetAddresses(); + + while (eaddr.hasMoreElements()) { + InetAddress inet = eaddr.nextElement(); + + final String canonicalHostName = inet.getCanonicalHostName(); + if (!canonicalHostName.equalsIgnoreCase(inet.getHostAddress())) { + name = canonicalHostName; + break; + } + } + } + return name; + } catch (SocketException e) { + Logger.getLogger(NetworkUtils.class.getClass().getName()).warning(e.getMessage()); + return "UNKNOWN-HOST"; + } + } + + public static String getHostFromURL(final String urlSpec) { + if (urlSpec == null) { + return null; + } + try { + final URL url = new URL(urlSpec); + + final String host = url.getHost(); + final int port = url.getPort(); + + if (port == -1) { + return host; + } else { + // TODO defualt port일 경우 아래와 같이 url을 만들어야 하는지 애매함. + return host + ":" + port; + } + } catch (MalformedURLException e) { + return null; + } + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NumberUtils.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NumberUtils.java index 8b01a1cea3bf..547d45942848 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NumberUtils.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/NumberUtils.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.bootstrap.util; - -public final class NumberUtils { - private NumberUtils() { - } - - public static long parseLong(String str, long defaultLong) { - if (str == null) { - return defaultLong; - } - try { - return Long.parseLong(str); - } catch (NumberFormatException e) { - return defaultLong; - } - } - - public static int parseInteger(String str, int defaultInt) { - if (str == null) { - return defaultInt; - } - try { - return Integer.parseInt(str); - } catch (NumberFormatException e) { - return defaultInt; - } - } - - public static short parseShort(String str, short defaultInt) { - if (str == null) { - return defaultInt; - } - try { - return Short.parseShort(str); - } catch (NumberFormatException e) { - return defaultInt; - } - } - - public static Integer toInteger(Object integer) { - if (integer == null) { - return null; - } - if (integer instanceof Integer) { - return (Integer) integer; - } else { - return null; - } - } - -} +package com.nhn.pinpoint.bootstrap.util; + +public final class NumberUtils { + private NumberUtils() { + } + + public static long parseLong(String str, long defaultLong) { + if (str == null) { + return defaultLong; + } + try { + return Long.parseLong(str); + } catch (NumberFormatException e) { + return defaultLong; + } + } + + public static int parseInteger(String str, int defaultInt) { + if (str == null) { + return defaultInt; + } + try { + return Integer.parseInt(str); + } catch (NumberFormatException e) { + return defaultInt; + } + } + + public static short parseShort(String str, short defaultInt) { + if (str == null) { + return defaultInt; + } + try { + return Short.parseShort(str); + } catch (NumberFormatException e) { + return defaultInt; + } + } + + public static Integer toInteger(Object integer) { + if (integer == null) { + return null; + } + if (integer instanceof Integer) { + return (Integer) integer; + } else { + return null; + } + } + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSampler.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSampler.java index 0501e1108c6d..c504cf55c372 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSampler.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSampler.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.bootstrap.util; - -/** - * @author emeroad - */ -public interface SimpleSampler { - - boolean isSampling(); - -} +package com.nhn.pinpoint.bootstrap.util; + +/** + * @author emeroad + */ +public interface SimpleSampler { + + boolean isSampling(); + +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSamplerFactory.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSamplerFactory.java index 626728bc16d2..50f532a279cd 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSamplerFactory.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/SimpleSamplerFactory.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.bootstrap.util; - -import com.nhn.pinpoint.common.util.MathUtils; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class SimpleSamplerFactory { -// profiler에 있는 Sampler와 기능이 동일하지만. profiler에 있는 sampler의 경우 좀더 파생 모델이 나와야 되므로 별도로 분리한다. - public static final SimpleSampler FALSE_SAMPLER = new SimpleFalseSampler(); - public static final SimpleSampler TRUE_SAMPLER = new SimpleTrueSampler(); - - public static SimpleSampler createSampler(boolean sampling, int samplingRate) { - if (!sampling || samplingRate <= 0) { - return FALSE_SAMPLER; - } - if (samplingRate == 1) { - return TRUE_SAMPLER; - } - return new SamplingRateSampler(samplingRate); - } - - public static class SimpleTrueSampler implements SimpleSampler { - @Override - public boolean isSampling() { - return true; - } - } - - public static class SimpleFalseSampler implements SimpleSampler { - @Override - public boolean isSampling() { - return false; - } - } - - public static class SamplingRateSampler implements SimpleSampler { - private final AtomicInteger counter = new AtomicInteger(0); - private final int samplingRate; - - public SamplingRateSampler(int samplingRate) { - if (samplingRate <= 0) { - throw new IllegalArgumentException("Invalid samplingRate " + samplingRate); - } - this.samplingRate = samplingRate; - } - - @Override - public boolean isSampling() { - int samplingCount = MathUtils.fastAbs(counter.getAndIncrement()); - int isSampling = samplingCount % samplingRate; - return isSampling == 0; - } - } -} +package com.nhn.pinpoint.bootstrap.util; + +import com.nhn.pinpoint.common.util.MathUtils; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class SimpleSamplerFactory { +// profiler에 있는 Sampler와 기능이 동일하지만. profiler에 있는 sampler의 경우 좀더 파생 모델이 나와야 되므로 별도로 분리한다. + public static final SimpleSampler FALSE_SAMPLER = new SimpleFalseSampler(); + public static final SimpleSampler TRUE_SAMPLER = new SimpleTrueSampler(); + + public static SimpleSampler createSampler(boolean sampling, int samplingRate) { + if (!sampling || samplingRate <= 0) { + return FALSE_SAMPLER; + } + if (samplingRate == 1) { + return TRUE_SAMPLER; + } + return new SamplingRateSampler(samplingRate); + } + + public static class SimpleTrueSampler implements SimpleSampler { + @Override + public boolean isSampling() { + return true; + } + } + + public static class SimpleFalseSampler implements SimpleSampler { + @Override + public boolean isSampling() { + return false; + } + } + + public static class SamplingRateSampler implements SimpleSampler { + private final AtomicInteger counter = new AtomicInteger(0); + private final int samplingRate; + + public SamplingRateSampler(int samplingRate) { + if (samplingRate <= 0) { + throw new IllegalArgumentException("Invalid samplingRate " + samplingRate); + } + this.samplingRate = samplingRate; + } + + @Override + public boolean isSampling() { + int samplingCount = MathUtils.fastAbs(counter.getAndIncrement()); + int isSampling = samplingCount % samplingRate; + return isSampling == 0; + } + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/StringUtils.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/StringUtils.java index 9d7c2c9a763e..3f7e29bc5f79 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/StringUtils.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/StringUtils.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.bootstrap.util; - -public final class StringUtils { - - private StringUtils() { - } - - public static String defaultString(final String str, final String defaultStr) { - return str == null ? defaultStr : str; - } - - public static String toString(final Object object) { - if (object == null) { - return "null"; - } - return object.toString(); - } - - public static String drop(final String str) { - return drop(str, 64); - } - - public static String drop(final String str, final int length) { - if (str == null) { - return "null"; - } - if (length < 0) { - throw new IllegalArgumentException("negative length:" + length); - } - if (str.length() > length) { - StringBuilder buffer = new StringBuilder(length + 10); - buffer.append(str.substring(0, length)); - appendDropMessage(buffer, str.length()); - return buffer.toString(); - } else { - return str; - } - } - - public static void appendDrop(StringBuilder builder, final String str, final int length) { - if (str == null) { - return; - } - if (length < 0) { - return; - } - if (str.length() > length) { - builder.append(str.substring(0, length)); - appendDropMessage(builder, str.length()); - } else { - builder.append(str); - } - } - - private static void appendDropMessage(StringBuilder buffer, int length) { - buffer.append("...("); - buffer.append(length); - buffer.append(')'); - } -} +package com.nhn.pinpoint.bootstrap.util; + +public final class StringUtils { + + private StringUtils() { + } + + public static String defaultString(final String str, final String defaultStr) { + return str == null ? defaultStr : str; + } + + public static String toString(final Object object) { + if (object == null) { + return "null"; + } + return object.toString(); + } + + public static String drop(final String str) { + return drop(str, 64); + } + + public static String drop(final String str, final int length) { + if (str == null) { + return "null"; + } + if (length < 0) { + throw new IllegalArgumentException("negative length:" + length); + } + if (str.length() > length) { + StringBuilder buffer = new StringBuilder(length + 10); + buffer.append(str.substring(0, length)); + appendDropMessage(buffer, str.length()); + return buffer.toString(); + } else { + return str; + } + } + + public static void appendDrop(StringBuilder builder, final String str, final int length) { + if (str == null) { + return; + } + if (length < 0) { + return; + } + if (str.length() > length) { + builder.append(str.substring(0, length)); + appendDropMessage(builder, str.length()); + } else { + builder.append(str); + } + } + + private static void appendDropMessage(StringBuilder buffer, int length) { + buffer.append("...("); + buffer.append(length); + buffer.append(')'); + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/ThreadLocalMetadata.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/ThreadLocalMetadata.java index a53ed8164d34..fa1b4d498f24 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/ThreadLocalMetadata.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/ThreadLocalMetadata.java @@ -1,40 +1,40 @@ -package com.nhn.pinpoint.bootstrap.util; - -/** - * WARN - * 주의 ------------------
- * 이 data 전달자는 threadlocal로 전달하기 때문에. proxy클래스로 감쌋을 경우도 경계를 넘어 갈수 있으나.
- * 상태를 가질수 없음. static method나 parameter의 인자로 들어오는 값을 잠시 저장하여 다른 곳으로 넘기는 경우만 사용해야 함.
- * 절대 object의 상태를 가지고 있는데 사용할수 없음.
- * 주의 ------------------ - * @author emeroad - */ -@Deprecated -public class ThreadLocalMetadata { - private final String name; - private final ThreadLocal threadLocal; - - public ThreadLocalMetadata(String metadataName) { - this.name = metadataName; - this.threadLocal = new ThreadLocal(); - } - - public void set(T object) { - threadLocal.set(object); - } - - public T get() { - return threadLocal.get(); - } - - public void remove() { - threadLocal.remove(); - } - - public T getAndRemove() { - final ThreadLocal threadLocal = this.threadLocal; - final T t = threadLocal.get(); - threadLocal.remove(); - return t; - } -} +package com.nhn.pinpoint.bootstrap.util; + +/** + * WARN + * 주의 ------------------
+ * 이 data 전달자는 threadlocal로 전달하기 때문에. proxy클래스로 감쌋을 경우도 경계를 넘어 갈수 있으나.
+ * 상태를 가질수 없음. static method나 parameter의 인자로 들어오는 값을 잠시 저장하여 다른 곳으로 넘기는 경우만 사용해야 함.
+ * 절대 object의 상태를 가지고 있는데 사용할수 없음.
+ * 주의 ------------------ + * @author emeroad + */ +@Deprecated +public class ThreadLocalMetadata { + private final String name; + private final ThreadLocal threadLocal; + + public ThreadLocalMetadata(String metadataName) { + this.name = metadataName; + this.threadLocal = new ThreadLocal(); + } + + public void set(T object) { + threadLocal.set(object); + } + + public T get() { + return threadLocal.get(); + } + + public void remove() { + threadLocal.remove(); + } + + public T getAndRemove() { + final ThreadLocal threadLocal = this.threadLocal; + final T t = threadLocal.get(); + threadLocal.remove(); + return t; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/TimeObject.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/TimeObject.java index 83c6e5688cc7..2e5d7433952a 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/TimeObject.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/util/TimeObject.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.bootstrap.util; - -/** - * @author emeroad - */ -public class TimeObject { - private long cancelTime; - private long sendTime; - - public void markCancelTime() { - cancelTime = System.currentTimeMillis(); - } - - public long getCancelTime() { - return cancelTime; - } - - public void markSendTime() { - this.sendTime = System.currentTimeMillis(); - } - - public long getSendTime() { - return System.currentTimeMillis() - this.sendTime; - } -} +package com.nhn.pinpoint.bootstrap.util; + +/** + * @author emeroad + */ +public class TimeObject { + private long cancelTime; + private long sendTime; + + public void markCancelTime() { + cancelTime = System.currentTimeMillis(); + } + + public long getCancelTime() { + return cancelTime; + } + + public void markSendTime() { + this.sendTime = System.currentTimeMillis(); + } + + public long getSendTime() { + return System.currentTimeMillis() - this.sendTime; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/exception/PinpointException.java b/bootstrap/src/main/java/com/navercorp/pinpoint/exception/PinpointException.java index 4c6cb42c9aef..bfa1d7d7ff20 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/exception/PinpointException.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/exception/PinpointException.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.exception; - -/** - * @author emeroad - */ -public class PinpointException extends RuntimeException { - public PinpointException() { - } - - public PinpointException(String message) { - super(message); - } - - public PinpointException(String message, Throwable cause) { - super(message, cause); - } - - public PinpointException(Throwable cause) { - super(cause); - } -} +package com.nhn.pinpoint.exception; + +/** + * @author emeroad + */ +public class PinpointException extends RuntimeException { + public PinpointException() { + } + + public PinpointException(String message) { + super(message); + } + + public PinpointException(String message, Throwable cause) { + super(message, cause); + } + + public PinpointException(Throwable cause) { + super(cause); + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentClassLoaderTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentClassLoaderTest.java index ee6329cb8878..599e440f422f 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentClassLoaderTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentClassLoaderTest.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.bootstrap; - - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URL; -import java.security.CodeSource; -import java.security.ProtectionDomain; - -/** - * @author emeroad - */ -public class AgentClassLoaderTest { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void boot() throws IOException, ClassNotFoundException { - AgentClassLoader agentClassLoader = new AgentClassLoader(new URL[0]); - agentClassLoader.setBootClass("com.nhn.pinpoint.bootstrap.DummyAgent"); - agentClassLoader.boot("test", new DummyInstrumentation(), new ProfilerConfig()); - // TODO logger가져오는 기능이 달라져서 확인이 필요함. -// PLoggerBinder loggerBinder = (PLoggerBinder) agentClassLoader.initializeLoggerBinder(); -// PLogger test = loggerBinder.getLogger("test"); -// test.info("slf4j logger test"); - - } - - private String getProjectLibDir() { - // 필요는 없으나 protectionDomain을 테스트하기 좋아 내비둠. - ProtectionDomain protectionDomain = AgentClassLoader.class.getProtectionDomain(); - CodeSource codeSource = protectionDomain.getCodeSource(); - URL location = codeSource.getLocation(); - - logger.info("lib location:" + location); - String path = location.getPath(); - // file:/D:/nhn_source/pinpoint_project/pinpoint-tomcat-profiler/target/classes/ - int dirPath = path.lastIndexOf("target/classes/"); - if (dirPath == -1) { - throw new RuntimeException("target/classes/ not found"); - } - String projectDir = path.substring(1, dirPath); - return projectDir + "src/test/lib"; - } -} +package com.nhn.pinpoint.bootstrap; + + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URL; +import java.security.CodeSource; +import java.security.ProtectionDomain; + +/** + * @author emeroad + */ +public class AgentClassLoaderTest { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void boot() throws IOException, ClassNotFoundException { + AgentClassLoader agentClassLoader = new AgentClassLoader(new URL[0]); + agentClassLoader.setBootClass("com.nhn.pinpoint.bootstrap.DummyAgent"); + agentClassLoader.boot("test", new DummyInstrumentation(), new ProfilerConfig()); + // TODO logger가져오는 기능이 달라져서 확인이 필요함. +// PLoggerBinder loggerBinder = (PLoggerBinder) agentClassLoader.initializeLoggerBinder(); +// PLogger test = loggerBinder.getLogger("test"); +// test.info("slf4j logger test"); + + } + + private String getProjectLibDir() { + // 필요는 없으나 protectionDomain을 테스트하기 좋아 내비둠. + ProtectionDomain protectionDomain = AgentClassLoader.class.getProtectionDomain(); + CodeSource codeSource = protectionDomain.getCodeSource(); + URL location = codeSource.getLocation(); + + logger.info("lib location:" + location); + String path = location.getPath(); + // file:/D:/nhn_source/pinpoint_project/pinpoint-tomcat-profiler/target/classes/ + int dirPath = path.lastIndexOf("target/classes/"); + if (dirPath == -1) { + throw new RuntimeException("target/classes/ not found"); + } + String projectDir = path.substring(1, dirPath); + return projectDir + "src/test/lib"; + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/ClassPathResolverTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/ClassPathResolverTest.java index a73229474a52..bbdf69e3c74d 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/ClassPathResolverTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/ClassPathResolverTest.java @@ -1,103 +1,103 @@ -package com.nhn.pinpoint.bootstrap; - -import com.nhn.pinpoint.bootstrap.ClassPathResolver; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; - -/** - * @author emeroad - */ -@Ignore -public class ClassPathResolverTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - - @Test - public void testFindAgentJar() throws Exception { - String path = "D:\\nhn_source\\pinpoint_project\\deploy\\apache-tomcat-6.0.35\\bin\\bootstrap.jar;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/javassist-3.16.1.GA.jar;" + - "D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/pinpoint-commons-0.0.2.jar;;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/pinpoint-bootstrap-0.0.2.jar"; - // D:\nhn_source\pinpoint_project\deploy\agent\agentlib/pinpoint-tomcat-profiler-0.0.2.jar - ClassPathResolver classPathResolver = new ClassPathResolver(path); - boolean findAgentJar = classPathResolver.findAgentJar(); - Assert.assertTrue(findAgentJar); - - String agentJar = classPathResolver.getAgentJarName(); - Assert.assertEquals("pinpoint-bootstrap-0.0.2.jar", agentJar); - - String agentPath = classPathResolver.getAgentJarFullPath(); - Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/pinpoint-bootstrap-0.0.2.jar", agentPath); - - String agentDirPath = classPathResolver.getAgentDirPath(); - Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib", agentDirPath ); - - String agentLibPath = classPathResolver.getAgentLibPath(); - Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib"+File.separator+ "lib", agentLibPath); - } - - @Test - public void testFindAgentSnapshotJar() throws Exception { - String path = "D:\\nhn_source\\pinpoint_project\\deploy\\apache-tomcat-6.0.35\\bin\\bootstrap.jar;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/javassist-3.16.1.GA.jar;" + - "D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/pinpoint-commons-0.0.2.jar;;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib" + - "/pinpoint-bootstrap-0.0.2-SNAPSHOT.jar"; - // D:\nhn_source\pinpoint_project\deploy\agent\agentlib/pinpoint-tomcat-profiler-0.0.2.jar - ClassPathResolver classPathResolver = new ClassPathResolver(path); - boolean findAgentJar = classPathResolver.findAgentJar(); - Assert.assertTrue(findAgentJar); - - String agentJar = classPathResolver.getAgentJarName(); - Assert.assertEquals("pinpoint-bootstrap-0.0.2-SNAPSHOT.jar", agentJar); - - String agentPath = classPathResolver.getAgentJarFullPath(); - Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/pinpoint-bootstrap-0.0.2-SNAPSHOT.jar", agentPath); - - String agentDirPath = classPathResolver.getAgentDirPath(); - Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib", agentDirPath ); - - String agentLibPath = classPathResolver.getAgentLibPath(); - Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib"+File.separator+ "lib", agentLibPath); - } - - @Test - public void findAgentJar() { - findAgentJar("pinpoint-bootstrap-0.0.2.jar"); - findAgentJar("pinpoint-bootstrap-1.0.0.jar"); - findAgentJar("pinpoint-bootstrap-1.10.20.jar"); - findAgentJar("pinpoint-bootstrap.jar"); - - - findAgentJarAssertFail("pinpoint-bootstrap-1.a.test.jar"); - findAgentJarAssertFail("pinpointbootstrap-1.a.test.jar"); - findAgentJarAssertFail("pinpointbootstrap.jar"); - } - - private void findAgentJar(String path) { - ClassPathResolver classPathResolver = new ClassPathResolver(path); - boolean agentJar = classPathResolver.findAgentJar(); - Assert.assertTrue(agentJar); - } - - private void findAgentJarAssertFail(String path) { - ClassPathResolver classPathResolver = new ClassPathResolver(path); - boolean agentJar = classPathResolver.findAgentJar(); - Assert.assertFalse(agentJar); - } - - @Test - public void nullArray() { - String[] nullArray = null; - try { - for (String str : nullArray) { - logger.warn("null"); - } - Assert.fail(); - } catch (Exception e) { - } - } -} - +package com.nhn.pinpoint.bootstrap; + +import com.nhn.pinpoint.bootstrap.ClassPathResolver; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * @author emeroad + */ +@Ignore +public class ClassPathResolverTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void testFindAgentJar() throws Exception { + String path = "D:\\nhn_source\\pinpoint_project\\deploy\\apache-tomcat-6.0.35\\bin\\bootstrap.jar;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/javassist-3.16.1.GA.jar;" + + "D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/pinpoint-commons-0.0.2.jar;;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/pinpoint-bootstrap-0.0.2.jar"; + // D:\nhn_source\pinpoint_project\deploy\agent\agentlib/pinpoint-tomcat-profiler-0.0.2.jar + ClassPathResolver classPathResolver = new ClassPathResolver(path); + boolean findAgentJar = classPathResolver.findAgentJar(); + Assert.assertTrue(findAgentJar); + + String agentJar = classPathResolver.getAgentJarName(); + Assert.assertEquals("pinpoint-bootstrap-0.0.2.jar", agentJar); + + String agentPath = classPathResolver.getAgentJarFullPath(); + Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/pinpoint-bootstrap-0.0.2.jar", agentPath); + + String agentDirPath = classPathResolver.getAgentDirPath(); + Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib", agentDirPath ); + + String agentLibPath = classPathResolver.getAgentLibPath(); + Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib"+File.separator+ "lib", agentLibPath); + } + + @Test + public void testFindAgentSnapshotJar() throws Exception { + String path = "D:\\nhn_source\\pinpoint_project\\deploy\\apache-tomcat-6.0.35\\bin\\bootstrap.jar;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/javassist-3.16.1.GA.jar;" + + "D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/lib/pinpoint-commons-0.0.2.jar;;D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib" + + "/pinpoint-bootstrap-0.0.2-SNAPSHOT.jar"; + // D:\nhn_source\pinpoint_project\deploy\agent\agentlib/pinpoint-tomcat-profiler-0.0.2.jar + ClassPathResolver classPathResolver = new ClassPathResolver(path); + boolean findAgentJar = classPathResolver.findAgentJar(); + Assert.assertTrue(findAgentJar); + + String agentJar = classPathResolver.getAgentJarName(); + Assert.assertEquals("pinpoint-bootstrap-0.0.2-SNAPSHOT.jar", agentJar); + + String agentPath = classPathResolver.getAgentJarFullPath(); + Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib/pinpoint-bootstrap-0.0.2-SNAPSHOT.jar", agentPath); + + String agentDirPath = classPathResolver.getAgentDirPath(); + Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib", agentDirPath ); + + String agentLibPath = classPathResolver.getAgentLibPath(); + Assert.assertEquals("D:\\nhn_source\\pinpoint_project\\deploy\\agent\\agentlib"+File.separator+ "lib", agentLibPath); + } + + @Test + public void findAgentJar() { + findAgentJar("pinpoint-bootstrap-0.0.2.jar"); + findAgentJar("pinpoint-bootstrap-1.0.0.jar"); + findAgentJar("pinpoint-bootstrap-1.10.20.jar"); + findAgentJar("pinpoint-bootstrap.jar"); + + + findAgentJarAssertFail("pinpoint-bootstrap-1.a.test.jar"); + findAgentJarAssertFail("pinpointbootstrap-1.a.test.jar"); + findAgentJarAssertFail("pinpointbootstrap.jar"); + } + + private void findAgentJar(String path) { + ClassPathResolver classPathResolver = new ClassPathResolver(path); + boolean agentJar = classPathResolver.findAgentJar(); + Assert.assertTrue(agentJar); + } + + private void findAgentJarAssertFail(String path) { + ClassPathResolver classPathResolver = new ClassPathResolver(path); + boolean agentJar = classPathResolver.findAgentJar(); + Assert.assertFalse(agentJar); + } + + @Test + public void nullArray() { + String[] nullArray = null; + try { + for (String str : nullArray) { + logger.warn("null"); + } + Assert.fail(); + } catch (Exception e) { + } + } +} + diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyAgent.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyAgent.java index 534c34700056..83cd8204cd1d 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyAgent.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyAgent.java @@ -1,57 +1,54 @@ -package com.nhn.pinpoint.bootstrap; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.TraceContext; - -import java.lang.instrument.Instrumentation; - -/** - * @author emeroad - */ -public class DummyAgent implements Agent { - - public DummyAgent(String agentArgs, Instrumentation instrumentation, ProfilerConfig profilerConfig) { - - } - - @Override - public void start() { - } - - @Override - public void started() { - } - - @Override - public void stop() { - } - - @Override - public void addConnector(String protocol, int port) { - } - - @Override - public TraceContext getTraceContext() { - return null; - } - - @Override - public ProfilerConfig getProfilerConfig() { - return null; - } - -// @Override -// public PLoggerBinder initializeLogger() { -// return new PLoggerBinder() { -// @Override -// public PLogger getLogger(String name) { -// return new DummyPLogger(); -// } -// -// @Override -// public void shutdown() { -// -// } -// }; -// } -} +package com.nhn.pinpoint.bootstrap; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.context.TraceContext; + +import java.lang.instrument.Instrumentation; + +/** + * @author emeroad + * @author hyungil.jeong + */ +public class DummyAgent implements Agent { + + public DummyAgent(String agentArgs, Instrumentation instrumentation, ProfilerConfig profilerConfig) { + + } + + @Override + public void start() { + } + + @Override + public void stop() { + } + + @Override + public void addConnector(String protocol, int port) { + } + + @Override + public TraceContext getTraceContext() { + return null; + } + + @Override + public ProfilerConfig getProfilerConfig() { + return null; + } + + // @Override + // public PLoggerBinder initializeLogger() { + // return new PLoggerBinder() { + // @Override + // public PLogger getLogger(String name) { + // return new DummyPLogger(); + // } + // + // @Override + // public void shutdown() { + // + // } + // }; + // } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyInstrumentation.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyInstrumentation.java index 70230f9ad864..c347d9693653 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyInstrumentation.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/DummyInstrumentation.java @@ -1,87 +1,87 @@ -package com.nhn.pinpoint.bootstrap; - -import java.lang.instrument.ClassDefinition; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; -import java.util.jar.JarFile; - -/** - * @author emeroad - */ -public class DummyInstrumentation implements Instrumentation { - @Override - public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { - - } - - @Override - public void addTransformer(ClassFileTransformer transformer) { - - } - - @Override - public boolean removeTransformer(ClassFileTransformer transformer) { - return false; - } - - @Override - public boolean isRetransformClassesSupported() { - return false; - } - - @Override - public void retransformClasses(Class... classes) throws UnmodifiableClassException { - - } - - @Override - public boolean isRedefineClassesSupported() { - return false; - } - - @Override - public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException { - - } - - @Override - public boolean isModifiableClass(Class theClass) { - return false; - } - - @Override - public Class[] getAllLoadedClasses() { - return new Class[0]; - } - - @Override - public Class[] getInitiatedClasses(ClassLoader loader) { - return new Class[0]; - } - - @Override - public long getObjectSize(Object objectToSize) { - return 0; - } - - @Override - public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public void appendToSystemClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public boolean isNativeMethodPrefixSupported() { - return false; - } - - @Override - public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { - - } -} +package com.nhn.pinpoint.bootstrap; + +import java.lang.instrument.ClassDefinition; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; +import java.util.jar.JarFile; + +/** + * @author emeroad + */ +public class DummyInstrumentation implements Instrumentation { + @Override + public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { + + } + + @Override + public void addTransformer(ClassFileTransformer transformer) { + + } + + @Override + public boolean removeTransformer(ClassFileTransformer transformer) { + return false; + } + + @Override + public boolean isRetransformClassesSupported() { + return false; + } + + @Override + public void retransformClasses(Class... classes) throws UnmodifiableClassException { + + } + + @Override + public boolean isRedefineClassesSupported() { + return false; + } + + @Override + public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException { + + } + + @Override + public boolean isModifiableClass(Class theClass) { + return false; + } + + @Override + public Class[] getAllLoadedClasses() { + return new Class[0]; + } + + @Override + public Class[] getInitiatedClasses(ClassLoader loader) { + return new Class[0]; + } + + @Override + public long getObjectSize(Object objectToSize) { + return 0; + } + + @Override + public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { + + } + + @Override + public void appendToSystemClassLoaderSearch(JarFile jarfile) { + + } + + @Override + public boolean isNativeMethodPrefixSupported() { + return false; + } + + @Override + public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { + + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrapTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrapTest.java index 854a3569e769..cb47b228024f 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrapTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointBootStrapTest.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.bootstrap; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class PinpointBootStrapTest { - @Test - public void testDuplicatedLoadCheck() throws Exception { - PinpointBootStrap.premain("test", new DummyInstrumentation()); - String exist = System.getProperty(PinpointBootStrap.BOOT_STRAP_LOAD_STATE); - Assert.assertTrue(exist != null); - - PinpointBootStrap.premain("test", new DummyInstrumentation()); - // 중복 된경우를 체크 할수 있는 방법이 로그 확인 뿐이 없나?? - - String recheck = System.getProperty(PinpointBootStrap.BOOT_STRAP_LOAD_STATE); - Assert.assertEquals(exist, recheck); - } -} +package com.nhn.pinpoint.bootstrap; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class PinpointBootStrapTest { + @Test + public void testDuplicatedLoadCheck() throws Exception { + PinpointBootStrap.premain("test", new DummyInstrumentation()); + String exist = System.getProperty(PinpointBootStrap.BOOT_STRAP_LOAD_STATE); + Assert.assertTrue(exist != null); + + PinpointBootStrap.premain("test", new DummyInstrumentation()); + // 중복 된경우를 체크 할수 있는 방법이 로그 확인 뿐이 없나?? + + String recheck = System.getProperty(PinpointBootStrap.BOOT_STRAP_LOAD_STATE); + Assert.assertEquals(exist, recheck); + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoaderTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoaderTest.java index 32b0bfb142c9..88c8d0edee64 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoaderTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/PinpointURLClassLoaderTest.java @@ -1,33 +1,33 @@ -package com.nhn.pinpoint.bootstrap; - -import junit.framework.Assert; -import org.junit.Test; - -import java.net.URL; - -/** - * @author emeroad - */ -public class PinpointURLClassLoaderTest { - - @Test - public void testOnLoadClass() throws Exception { - - PinpointURLClassLoader cl = new PinpointURLClassLoader(new URL[]{}, Thread.currentThread().getContextClassLoader()); - try { - cl.loadClass("test"); - Assert.fail(); - } catch (ClassNotFoundException e) { - } - -// try { -// cl.loadClass("com.nhn.pinpoint.profiler.DefaultAgent"); -// } catch (ClassNotFoundException e) { -// -// } -// 사실 위에 코드로 정상 테스트가 가능해야 겠지만 bootstrap testcase에서는 jar라서 찾을수 없음 -// 아래 코드로 로드 하는 클래스인지 체크 정도만 하자. -// URL에 다가 pinpoint.jar를 걸면 되긴하겠지만. 관리가 힘들듯함. - Assert.assertTrue(cl.onLoadClass("com.nhn.pinpoint.profiler.DefaultAgent")); - } -} +package com.nhn.pinpoint.bootstrap; + +import junit.framework.Assert; +import org.junit.Test; + +import java.net.URL; + +/** + * @author emeroad + */ +public class PinpointURLClassLoaderTest { + + @Test + public void testOnLoadClass() throws Exception { + + PinpointURLClassLoader cl = new PinpointURLClassLoader(new URL[]{}, Thread.currentThread().getContextClassLoader()); + try { + cl.loadClass("test"); + Assert.fail(); + } catch (ClassNotFoundException e) { + } + +// try { +// cl.loadClass("com.nhn.pinpoint.profiler.DefaultAgent"); +// } catch (ClassNotFoundException e) { +// +// } +// 사실 위에 코드로 정상 테스트가 가능해야 겠지만 bootstrap testcase에서는 jar라서 찾을수 없음 +// 아래 코드로 로드 하는 클래스인지 체크 정도만 하자. +// URL에 다가 pinpoint.jar를 걸면 되긴하겠지만. 관리가 힘들듯함. + Assert.assertTrue(cl.onLoadClass("com.nhn.pinpoint.profiler.DefaultAgent")); + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/DumpTypeTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/DumpTypeTest.java index 324b4a6b1b40..14b35a499018 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/DumpTypeTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/DumpTypeTest.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.bootstrap.config; - -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class DumpTypeTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void find() { - DumpType none = DumpType.valueOf("ALWAYS"); - logger.debug("type:{}", none); - - try { - DumpType.valueOf("error"); - Assert.fail("not found"); - } catch (IllegalArgumentException e) { - - } - } -} +package com.nhn.pinpoint.bootstrap.config; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class DumpTypeTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void find() { + DumpType none = DumpType.valueOf("ALWAYS"); + logger.debug("type:{}", none); + + try { + DumpType.valueOf("error"); + Assert.fail("not found"); + } catch (IllegalArgumentException e) { + + } + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfigTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfigTest.java index 02519606808b..cfadad7ec005 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfigTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfigTest.java @@ -67,7 +67,7 @@ public void ioBuffering_test() throws IOException { profilerConfig.readConfigFile(path); Assert.assertEquals(profilerConfig.isIoBufferingEnable(), false); - Assert.assertEquals(profilerConfig.getIoBufferingBufferBufferSize(), 30); + Assert.assertEquals(profilerConfig.getIoBufferingBufferSize(), 30); } @Test @@ -79,7 +79,7 @@ public void ioBuffering_default() throws IOException { profilerConfig.readConfigFile(path); Assert.assertEquals(profilerConfig.isIoBufferingEnable(), true); - Assert.assertEquals(profilerConfig.getIoBufferingBufferBufferSize(), 10); + Assert.assertEquals(profilerConfig.getIoBufferingBufferSize(), 10); } @Test diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/default.property b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/default.property index 8cd6854cf069..0e9699e7f8ff 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/default.property +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/default.property @@ -1,5 +1,5 @@ -profiler.apache.httpclient4.cookie.dumptype=EXCEPTION - - -profiler.io.buffering.enable=true +profiler.apache.httpclient4.cookie.dumptype=EXCEPTION + + +profiler.io.buffering.enable=true profiler.io.buffering.buffersize=10 \ No newline at end of file diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test.property b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test.property index 50b6d868695d..613201a32e38 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test.property +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test.property @@ -1,5 +1,5 @@ -profiler.apache.httpclient4.cookie.dumptype=EXCEPTION - - -profiler.io.buffering.enable=false +profiler.apache.httpclient4.cookie.dumptype=EXCEPTION + + +profiler.io.buffering.enable=false profiler.io.buffering.buffersize=30 \ No newline at end of file diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test2.property b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test2.property index 0d574fc73030..0b30d639d80d 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test2.property +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/config/test2.property @@ -1,7 +1,7 @@ -profiler.apache.httpclient4.cookie.dumptype=EXCEPTION - - -profiler.io.buffering.enable=false -profiler.io.buffering.buffersize=30 - +profiler.apache.httpclient4.cookie.dumptype=EXCEPTION + + +profiler.io.buffering.enable=false +profiler.io.buffering.buffersize=30 + profiler.tcpdatasender.command.accept.enable=true \ No newline at end of file diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTrace.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTrace.java index c5d87afa9fd3..8cdf7ede06f7 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTrace.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTrace.java @@ -1,187 +1,187 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.util.ParsingResult; - -/** - * @author emeroad - */ -public class MockTrace implements Trace { - - private long beforeTime; - private long afterTime; - - private boolean sampled = true; - - @Override - public void markBeforeTime() { - beforeTime = System.currentTimeMillis(); - } - - @Override - public long getBeforeTime() { - return beforeTime; - } - - @Override - public void markAfterTime() { - afterTime = System.currentTimeMillis(); - } - - @Override - public long getAfterTime() { - return afterTime; - } - - @Override - public TraceId getTraceId() { - return null; - } - - public void setSampled(boolean sampled) { - this.sampled = sampled; - } - - @Override - public boolean canSampled() { - return sampled; - } - - @Override - public boolean isRoot() { - return false; - } - - @Override - public void recordException(Throwable throwable) { - - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor) { - - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { - - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) { - - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) { - - } - - @Override - public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) { - - } - - @Override - public ParsingResult recordSqlInfo(String sql) { - return null; - } - - @Override - public void recordSqlParsingResult(ParsingResult parsingResult) { - - } - - @Override - public void recordSqlParsingResult(ParsingResult parsingResult, String bindValue) { - - } - - @Override - public void recordAttribute(AnnotationKey key, String value) { - - } - - @Override - public void recordAttribute(AnnotationKey key, int value) { - - } - - @Override - public void recordAttribute(AnnotationKey key, Object value) { - - } - - @Override - public void recordServiceType(ServiceType serviceType) { - - } - - @Override - public void recordRpcName(String rpc) { - - } - - @Override - public void recordDestinationId(String destinationId) { - - } - - @Override - public void recordEndPoint(String endPoint) { - - } - - @Override - public void recordRemoteAddress(String remoteAddress) { - - } - - @Override - public void recordNextSpanId(long spanId) { - - } - - @Override - public void recordParentApplication(String parentApplicationName, short parentApplicationType) { - - } - - @Override - public void recordAcceptorHost(String host) { - - } - - @Override - public int getStackFrameId() { - return 0; - } - - @Override - public void traceBlockBegin() { - - } - - @Override - public void traceBlockBegin(int stackId) { - - } - - @Override - public void traceRootBlockEnd() { - - } - - @Override - public void traceBlockEnd() { - - } - - @Override - public void traceBlockEnd(int stackId) { - - } -} +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.util.ParsingResult; + +/** + * @author emeroad + */ +public class MockTrace implements Trace { + + private long beforeTime; + private long afterTime; + + private boolean sampled = true; + + @Override + public void markBeforeTime() { + beforeTime = System.currentTimeMillis(); + } + + @Override + public long getBeforeTime() { + return beforeTime; + } + + @Override + public void markAfterTime() { + afterTime = System.currentTimeMillis(); + } + + @Override + public long getAfterTime() { + return afterTime; + } + + @Override + public TraceId getTraceId() { + return null; + } + + public void setSampled(boolean sampled) { + this.sampled = sampled; + } + + @Override + public boolean canSampled() { + return sampled; + } + + @Override + public boolean isRoot() { + return false; + } + + @Override + public void recordException(Throwable throwable) { + + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor) { + + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { + + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) { + + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) { + + } + + @Override + public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) { + + } + + @Override + public ParsingResult recordSqlInfo(String sql) { + return null; + } + + @Override + public void recordSqlParsingResult(ParsingResult parsingResult) { + + } + + @Override + public void recordSqlParsingResult(ParsingResult parsingResult, String bindValue) { + + } + + @Override + public void recordAttribute(AnnotationKey key, String value) { + + } + + @Override + public void recordAttribute(AnnotationKey key, int value) { + + } + + @Override + public void recordAttribute(AnnotationKey key, Object value) { + + } + + @Override + public void recordServiceType(ServiceType serviceType) { + + } + + @Override + public void recordRpcName(String rpc) { + + } + + @Override + public void recordDestinationId(String destinationId) { + + } + + @Override + public void recordEndPoint(String endPoint) { + + } + + @Override + public void recordRemoteAddress(String remoteAddress) { + + } + + @Override + public void recordNextSpanId(long spanId) { + + } + + @Override + public void recordParentApplication(String parentApplicationName, short parentApplicationType) { + + } + + @Override + public void recordAcceptorHost(String host) { + + } + + @Override + public int getStackFrameId() { + return 0; + } + + @Override + public void traceBlockBegin() { + + } + + @Override + public void traceBlockBegin(int stackId) { + + } + + @Override + public void traceRootBlockEnd() { + + } + + @Override + public void traceBlockEnd() { + + } + + @Override + public void traceBlockEnd(int stackId) { + + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java index ddfcaa90f77f..de5c7a77c387 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java @@ -1,139 +1,139 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.*; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.util.ParsingResult; - -/** - * @author emeroad - */ -public class MockTraceContext implements TraceContext { - - private Trace trace; - - public void setTrace(Trace trace) { - this.trace = trace; - } - - @Override - public Trace currentTraceObject() { - if (trace == null) { - return null; - } - if (trace.canSampled()) { - return null; - } - return trace; - } - - @Override - public Trace currentRawTraceObject() { - return trace; - } - - @Override - public Trace continueTraceObject(TraceId traceID) { - return trace; - } - - @Override - public Trace newTraceObject() { - return trace; - } - - @Override - public void detachTraceObject() { - trace = null; - } - - @Override - public String getAgentId() { - return null; - } - - @Override - public String getApplicationName() { - return null; - } - - @Override - public long getAgentStartTime() { - return 0; - } - - @Override - public short getServerTypeCode() { - return 0; - } - - @Override - public String getServerType() { - return null; - } - - @Override - public int cacheApi(MethodDescriptor methodDescriptor) { - return 0; - } - - @Override - public int cacheString(String value) { - return 0; - } - - @Override - public ParsingResult parseSql(String sql) { - return null; - } - - @Override - public DatabaseInfo parseJdbcUrl(String sql) { - return null; - } - - @Override - public DatabaseInfo createDatabaseInfo(ServiceType type, ServiceType executeQueryType, String url, int port, String databaseId) { - return null; - } - - @Override - public TraceId createTraceId(String transactionId, long parentSpanID, long spanID, short flags) { - return null; - } - - @Override - public Trace disableSampling() { - return null; - } - - @Override - public ProfilerConfig getProfilerConfig() { - return null; - } - - @Override - public Metric getRpcMetric(ServiceType serviceType) { - return null; - } - - @Override - public void recordContextMetricIsError() { - - } - - @Override - public void recordContextMetric(int elapsedTime) { - - } - - @Override - public void recordAcceptResponseTime(String parentApplicationName, short parentApplicationType, int elapsedTime) { - - } - - @Override - public void recordUserAcceptResponseTime(int elapsedTime) { - - } -} +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.context.*; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.util.ParsingResult; + +/** + * @author emeroad + */ +public class MockTraceContext implements TraceContext { + + private Trace trace; + + public void setTrace(Trace trace) { + this.trace = trace; + } + + @Override + public Trace currentTraceObject() { + if (trace == null) { + return null; + } + if (trace.canSampled()) { + return null; + } + return trace; + } + + @Override + public Trace currentRawTraceObject() { + return trace; + } + + @Override + public Trace continueTraceObject(TraceId traceID) { + return trace; + } + + @Override + public Trace newTraceObject() { + return trace; + } + + @Override + public void detachTraceObject() { + trace = null; + } + + @Override + public String getAgentId() { + return null; + } + + @Override + public String getApplicationName() { + return null; + } + + @Override + public long getAgentStartTime() { + return 0; + } + + @Override + public short getServerTypeCode() { + return 0; + } + + @Override + public String getServerType() { + return null; + } + + @Override + public int cacheApi(MethodDescriptor methodDescriptor) { + return 0; + } + + @Override + public int cacheString(String value) { + return 0; + } + + @Override + public ParsingResult parseSql(String sql) { + return null; + } + + @Override + public DatabaseInfo parseJdbcUrl(String sql) { + return null; + } + + @Override + public DatabaseInfo createDatabaseInfo(ServiceType type, ServiceType executeQueryType, String url, int port, String databaseId) { + return null; + } + + @Override + public TraceId createTraceId(String transactionId, long parentSpanID, long spanID, short flags) { + return null; + } + + @Override + public Trace disableSampling() { + return null; + } + + @Override + public ProfilerConfig getProfilerConfig() { + return null; + } + + @Override + public Metric getRpcMetric(ServiceType serviceType) { + return null; + } + + @Override + public void recordContextMetricIsError() { + + } + + @Override + public void recordContextMetric(int elapsedTime) { + + } + + @Override + public void recordAcceptResponseTime(String parentApplicationName, short parentApplicationType, int elapsedTime) { + + } + + @Override + public void recordUserAcceptResponseTime(int elapsedTime) { + + } +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java index 60496c711022..00f074d2fd26 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java @@ -1,184 +1,184 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.context.Trace; -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static org.mockito.Mockito.*; - - -public class SpanSimpleAroundInterceptorTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - - @Test - public void lifeCycle() throws Exception { - MockTraceContext context = new MockTraceContext(); - MockTrace mockTrace = new MockTrace(); - context.setTrace(mockTrace); - - TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(); - interceptor.setTraceContext(context); - - checkSpanInterceptor(context, interceptor); - } - - @Test - public void beforeExceptionLifeCycle() throws Exception { - - MockTraceContext context = new MockTraceContext(); - MockTrace mockTrace = new MockTrace(); - context.setTrace(mockTrace); - - TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor() { - @Override - protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - touchBefore(); - throw new RuntimeException(); - } - }; - interceptor.setTraceContext(context); - - checkSpanInterceptor(context, interceptor); - } - - @Test - public void afterExceptionLifeCycle() throws Exception { - - MockTraceContext context = new MockTraceContext(); - MockTrace mockTrace = new MockTrace(); - context.setTrace(mockTrace); - - TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor() { - @Override - protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - touchAfter(); - throw new RuntimeException(); - } - }; - interceptor.setTraceContext(context); - - checkSpanInterceptor(context, interceptor); - } - - @Test - public void beforeAfterExceptionLifeCycle() throws Exception { - - MockTraceContext context = new MockTraceContext(); - MockTrace mockTrace = new MockTrace(); - context.setTrace(mockTrace); - - TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor() { - @Override - protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - touchBefore(); - throw new RuntimeException(); - } - - @Override - protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - touchAfter(); - throw new RuntimeException(); - } - }; - interceptor.setTraceContext(context); - - checkSpanInterceptor(context, interceptor); - } - - @Test - public void traceCreateFail() { - MockTraceContext context = mock(MockTraceContext.class); - when(context.newTraceObject()).thenReturn(null); - - MockTrace mockTrace = new MockTrace(); - context.setTrace(mockTrace); - - TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(); - interceptor.setTraceContext(context); - - checkTraceCreateFailInterceptor(context, interceptor); - } - - private void checkSpanInterceptor(MockTraceContext context, TestSpanSimpleAroundInterceptor interceptor) { - Trace createTrace = interceptor.createTrace(null, null); - interceptor.before(new Object(), null); - Assert.assertEquals(interceptor.getBeforeTouchCount(), 1); - Trace before = context.currentRawTraceObject(); - Assert.assertEquals(createTrace, before); - - interceptor.after(new Object(), null, null, null); - Assert.assertEquals(interceptor.getAfterTouchCount(), 1); - Trace after = context.currentRawTraceObject(); - Assert.assertNull(after); - } - - private void checkTraceCreateFailInterceptor(MockTraceContext context, TestSpanSimpleAroundInterceptor interceptor) { - Trace createTrace = interceptor.createTrace(null, null); - Assert.assertNull(createTrace); - interceptor.before(new Object(), null); - - Assert.assertEquals(interceptor.getBeforeTouchCount(), 0); - Assert.assertNull(context.currentRawTraceObject()); - - interceptor.after(new Object(), null, null, null); - Assert.assertEquals(interceptor.getAfterTouchCount(), 0); - Assert.assertNull(context.currentRawTraceObject()); - } - - - - @Test - public void testCreateTrace() throws Exception { - - } - - @Test - public void testDoInAfterTrace() throws Exception { - - } - - public static class TestSpanSimpleAroundInterceptor extends SpanSimpleAroundInterceptor { - private int beforeTouchCount; - private int afterTouchCount; - - public TestSpanSimpleAroundInterceptor() { - super(TestSpanSimpleAroundInterceptor.class); - } - - @Override - protected Trace createTrace(Object target, Object[] args) { - return getTraceContext().newTraceObject(); - } - - @Override - protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - touchBefore(); - } - - protected void touchBefore() { - beforeTouchCount++; - } - - public int getAfterTouchCount() { - return afterTouchCount; - } - - @Override - protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - touchAfter(); - } - - protected void touchAfter() { - afterTouchCount++; - } - - public int getBeforeTouchCount() { - return beforeTouchCount; - } - } +package com.nhn.pinpoint.bootstrap.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.context.Trace; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.mockito.Mockito.*; + + +public class SpanSimpleAroundInterceptorTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void lifeCycle() throws Exception { + MockTraceContext context = new MockTraceContext(); + MockTrace mockTrace = new MockTrace(); + context.setTrace(mockTrace); + + TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(); + interceptor.setTraceContext(context); + + checkSpanInterceptor(context, interceptor); + } + + @Test + public void beforeExceptionLifeCycle() throws Exception { + + MockTraceContext context = new MockTraceContext(); + MockTrace mockTrace = new MockTrace(); + context.setTrace(mockTrace); + + TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor() { + @Override + protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + touchBefore(); + throw new RuntimeException(); + } + }; + interceptor.setTraceContext(context); + + checkSpanInterceptor(context, interceptor); + } + + @Test + public void afterExceptionLifeCycle() throws Exception { + + MockTraceContext context = new MockTraceContext(); + MockTrace mockTrace = new MockTrace(); + context.setTrace(mockTrace); + + TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor() { + @Override + protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + touchAfter(); + throw new RuntimeException(); + } + }; + interceptor.setTraceContext(context); + + checkSpanInterceptor(context, interceptor); + } + + @Test + public void beforeAfterExceptionLifeCycle() throws Exception { + + MockTraceContext context = new MockTraceContext(); + MockTrace mockTrace = new MockTrace(); + context.setTrace(mockTrace); + + TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor() { + @Override + protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + touchBefore(); + throw new RuntimeException(); + } + + @Override + protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + touchAfter(); + throw new RuntimeException(); + } + }; + interceptor.setTraceContext(context); + + checkSpanInterceptor(context, interceptor); + } + + @Test + public void traceCreateFail() { + MockTraceContext context = mock(MockTraceContext.class); + when(context.newTraceObject()).thenReturn(null); + + MockTrace mockTrace = new MockTrace(); + context.setTrace(mockTrace); + + TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(); + interceptor.setTraceContext(context); + + checkTraceCreateFailInterceptor(context, interceptor); + } + + private void checkSpanInterceptor(MockTraceContext context, TestSpanSimpleAroundInterceptor interceptor) { + Trace createTrace = interceptor.createTrace(null, null); + interceptor.before(new Object(), null); + Assert.assertEquals(interceptor.getBeforeTouchCount(), 1); + Trace before = context.currentRawTraceObject(); + Assert.assertEquals(createTrace, before); + + interceptor.after(new Object(), null, null, null); + Assert.assertEquals(interceptor.getAfterTouchCount(), 1); + Trace after = context.currentRawTraceObject(); + Assert.assertNull(after); + } + + private void checkTraceCreateFailInterceptor(MockTraceContext context, TestSpanSimpleAroundInterceptor interceptor) { + Trace createTrace = interceptor.createTrace(null, null); + Assert.assertNull(createTrace); + interceptor.before(new Object(), null); + + Assert.assertEquals(interceptor.getBeforeTouchCount(), 0); + Assert.assertNull(context.currentRawTraceObject()); + + interceptor.after(new Object(), null, null, null); + Assert.assertEquals(interceptor.getAfterTouchCount(), 0); + Assert.assertNull(context.currentRawTraceObject()); + } + + + + @Test + public void testCreateTrace() throws Exception { + + } + + @Test + public void testDoInAfterTrace() throws Exception { + + } + + public static class TestSpanSimpleAroundInterceptor extends SpanSimpleAroundInterceptor { + private int beforeTouchCount; + private int afterTouchCount; + + public TestSpanSimpleAroundInterceptor() { + super(TestSpanSimpleAroundInterceptor.class); + } + + @Override + protected Trace createTrace(Object target, Object[] args) { + return getTraceContext().newTraceObject(); + } + + @Override + protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + touchBefore(); + } + + protected void touchBefore() { + beforeTouchCount++; + } + + public int getAfterTouchCount() { + return afterTouchCount; + } + + @Override + protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + touchAfter(); + } + + protected void touchAfter() { + afterTouchCount++; + } + + public int getBeforeTouchCount() { + return beforeTouchCount; + } + } } \ No newline at end of file diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/LocalHostTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/LocalHostTest.java index 023114d1f07e..9ca97c5a2600 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/LocalHostTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/LocalHostTest.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.bootstrap.util; - -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Enumeration; - -/** - * @author emeroad - */ -public class LocalHostTest { - - public static void main(String[] args) throws UnknownHostException, SocketException { - System.out.println("Canonical:" + InetAddress.getLocalHost().getCanonicalHostName()); - System.out.println("normal:" + InetAddress.getLocalHost().getHostName()); - - System.out.println("NetworkInterface"); - Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); - while (networkInterfaces.hasMoreElements()) { - NetworkInterface networkInterface = networkInterfaces.nextElement(); - System.out.println("Nic:" + networkInterface); - Enumeration inetAddresses = networkInterface.getInetAddresses(); - while (inetAddresses.hasMoreElements()) { - InetAddress inetAddress = inetAddresses.nextElement(); - System.out.println(inetAddress.getCanonicalHostName()); - System.out.println(inetAddress.getHostName()); - } - } - } - -} +package com.nhn.pinpoint.bootstrap.util; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Enumeration; + +/** + * @author emeroad + */ +public class LocalHostTest { + + public static void main(String[] args) throws UnknownHostException, SocketException { + System.out.println("Canonical:" + InetAddress.getLocalHost().getCanonicalHostName()); + System.out.println("normal:" + InetAddress.getLocalHost().getHostName()); + + System.out.println("NetworkInterface"); + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = networkInterfaces.nextElement(); + System.out.println("Nic:" + networkInterface); + Enumeration inetAddresses = networkInterface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = inetAddresses.nextElement(); + System.out.println(inetAddress.getCanonicalHostName()); + System.out.println(inetAddress.getHostName()); + } + } + } + +} diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/MetaObjectTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/MetaObjectTest.java index 8efe60484d8d..592c740a6e99 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/MetaObjectTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/util/MetaObjectTest.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.bootstrap.util; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class MetaObjectTest { - private String test; - - public String getTest() { - return test; - } - - public void setTest(String test) { - this.test = test; - } - - @Test - public void testSetInvoke() throws Exception { - MetaObjectTest test = new MetaObjectTest(); - - MetaObject metaObject = new MetaObject("setTest", String.class); - Object result = metaObject.invoke(test, "set"); - Assert.assertEquals(test.getTest(), "set"); - Assert.assertNull(result); - } - - @Test - public void testGetInvoke() throws Exception { - MetaObjectTest test = new MetaObjectTest(); - test.setTest("get"); - - MetaObject metaObject = new MetaObject("getTest"); - Object result = metaObject.invoke(test); - Assert.assertEquals(test.getTest(), result); - } -} +package com.nhn.pinpoint.bootstrap.util; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class MetaObjectTest { + private String test; + + public String getTest() { + return test; + } + + public void setTest(String test) { + this.test = test; + } + + @Test + public void testSetInvoke() throws Exception { + MetaObjectTest test = new MetaObjectTest(); + + MetaObject metaObject = new MetaObject("setTest", String.class); + Object result = metaObject.invoke(test, "set"); + Assert.assertEquals(test.getTest(), "set"); + Assert.assertNull(result); + } + + @Test + public void testGetInvoke() throws Exception { + MetaObjectTest test = new MetaObjectTest(); + test.setTest("get"); + + MetaObject metaObject = new MetaObject("getTest"); + Object result = metaObject.invoke(test); + Assert.assertEquals(test.getTest(), result); + } +} diff --git a/bootstrap/src/test/resources/log4j.xml b/bootstrap/src/test/resources/log4j.xml index b28d76cc0830..e3a26a0007c0 100644 --- a/bootstrap/src/test/resources/log4j.xml +++ b/bootstrap/src/test/resources/log4j.xml @@ -1,42 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/checkstyle-UTF8(ver0.6).xml b/checkstyle-UTF8(ver0.6).xml index dc952e1650f4..48c0f96a5657 100644 --- a/checkstyle-UTF8(ver0.6).xml +++ b/checkstyle-UTF8(ver0.6).xml @@ -1,87 +1,87 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml index 2f48e978ecfe..bc942cdda970 100644 --- a/checkstyle-suppressions.xml +++ b/checkstyle-suppressions.xml @@ -1,15 +1,15 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/collector/findbugs-exclude.xml b/collector/findbugs-exclude.xml index a4b4e8251d57..0193409a64e7 100644 --- a/collector/findbugs-exclude.xml +++ b/collector/findbugs-exclude.xml @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AbstractClusterService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AbstractClusterService.java new file mode 100644 index 000000000000..2ea65752a9e4 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AbstractClusterService.java @@ -0,0 +1,18 @@ +package com.nhn.pinpoint.collector.cluster; + +import com.nhn.pinpoint.collector.config.CollectorConfiguration; + +/** + * @author koo.taejin + */ +public abstract class AbstractClusterService implements ClusterService { + + protected final CollectorConfiguration config; + protected final ClusterPointRouter clusterPointRouter; + + public AbstractClusterService(CollectorConfiguration config, ClusterPointRouter clusterPointRouter) { + this.config = config; + this.clusterPointRouter = clusterPointRouter; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPoint.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPoint.java new file mode 100644 index 000000000000..93555d5326c4 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPoint.java @@ -0,0 +1,5 @@ +package com.nhn.pinpoint.collector.cluster; + +public interface ClusterPoint { + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouter.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouter.java new file mode 100644 index 000000000000..1dfb7b05ad2f --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouter.java @@ -0,0 +1,164 @@ +package com.nhn.pinpoint.collector.cluster; + +import java.util.Map; + +import javax.annotation.PreDestroy; + +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.jboss.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.nhn.pinpoint.collector.receiver.tcp.AgentPropertiesType; +import com.nhn.pinpoint.collector.util.CollectorUtils; +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.rpc.client.MessageListener; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.ResponsePacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.util.MapUtils; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.dto.command.TCommandTransfer; +import com.nhn.pinpoint.thrift.io.DeserializerFactory; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; +import com.nhn.pinpoint.thrift.io.SerializerFactory; +import com.nhn.pinpoint.thrift.io.TCommandTypeVersion; + +/** + * @author koo.taejin + */ +public class ClusterPointRouter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final String serverIdentifier = CollectorUtils.getServerIdentifier(); + + private final ProfilerClusterPoint profilerClusterPoint; + private final WebClusterPoint webClusterPoint; + + @Autowired + private SerializerFactory commandSerializerFactory; + + @Autowired + private DeserializerFactory commandDeserializerFactory; + + public ClusterPointRouter() { + this.profilerClusterPoint = new ProfilerClusterPoint(); + this.webClusterPoint = new WebClusterPoint(serverIdentifier, new WebPointMessageListener()); + } + + @PreDestroy + public void stop() { + if (webClusterPoint != null) { + webClusterPoint.close(); + } + } + + public ProfilerClusterPoint getProfilerClusterPoint() { + return profilerClusterPoint; + } + + public WebClusterPoint getWebClusterPoint() { + return webClusterPoint; + } + + private byte[] serialize(TBase result) { + if (result == null) { + logger.warn("tBase may not be null."); + return null; + } + + try { + HeaderTBaseSerializer serializer = commandSerializerFactory.createSerializer(); + byte[] payload = serializer.serialize(result); + return payload; + } catch (TException e) { + logger.warn(e.getMessage(), e); + } + + return null; + } + + private TBase deserialize(byte[] payload) { + if (payload == null) { + logger.warn("Payload may not be null."); + return null; + } + + try { + final HeaderTBaseDeserializer deserializer = commandDeserializerFactory.createDeserializer(); + TBase tBase = deserializer.deserialize(payload); + return tBase; + } catch (TException e) { + logger.warn(e.getMessage(), e); + } + + return null; + } + + class WebPointMessageListener implements MessageListener { + + @Override + public void handleSend(SendPacket sendPacket, Channel channel) { + logger.info("Received SendPacket {} {}.", sendPacket, channel); + } + + @Override + public void handleRequest(RequestPacket requestPacket, Channel channel) { + logger.info("Received RequestPacket {} {}.", requestPacket, channel); + + TBase request = deserialize(requestPacket.getPayload()); + + if (request == null) { + TResult tResult = new TResult(false); + tResult.setMessage("Unexpected decode result."); + + channel.write(new ResponsePacket(requestPacket.getRequestId(), serialize(tResult))); + } else if (request instanceof TCommandTransfer) { + + String applicationName = ((TCommandTransfer) request).getApplicationName(); + String agentId = ((TCommandTransfer) request).getAgentId(); + byte[] payload = ((TCommandTransfer) request).getPayload(); + + TBase command = deserialize(payload); + + ChannelContext channelContext = profilerClusterPoint.getChannelContext(applicationName, agentId, -1); + if (channelContext == null) { + TResult result = new TResult(false); + result.setMessage(applicationName + "/" + agentId + " can't find suitable ChannelContext."); + channel.write(new ResponsePacket(requestPacket.getRequestId(), serialize(result))); + return; + } + + Map proeprties = channelContext.getChannelProperties(); + String version = MapUtils.getString(proeprties, AgentPropertiesType.VERSION.getName()); + + TCommandTypeVersion commandVersion = TCommandTypeVersion.getVersion(version); + if (commandVersion.isSupportCommand(command)) { + Future future = channelContext.getSocketChannel().sendRequestMessage(payload); + future.await(); + ResponseMessage responseMessage = future.getResult(); + + channel.write(new ResponsePacket(requestPacket.getRequestId(), responseMessage.getMessage())); + } else { + TResult result = new TResult(false); + result.setMessage(applicationName + "/" + agentId + " unsupported command(" + command + ") type."); + + channel.write(new ResponsePacket(requestPacket.getRequestId(), serialize(result))); + } + } else { + TResult tResult = new TResult(false); + tResult.setMessage("Unsupported command(" + request + ") type."); + + channel.write(new ResponsePacket(requestPacket.getRequestId(), serialize(tResult))); + } + + } + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterService.java new file mode 100644 index 000000000000..e37e93ccbf4b --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterService.java @@ -0,0 +1,13 @@ +package com.nhn.pinpoint.collector.cluster; + + +/** + * @author koo.taejin + */ +public interface ClusterService { + + void setUp() throws Exception; + + void tearDown() throws Exception; + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/PinpointClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/PinpointClusterManager.java deleted file mode 100644 index 9003b279e1d6..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/PinpointClusterManager.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.nhn.pinpoint.collector.cluster; - -import com.nhn.pinpoint.rpc.server.ChannelContext; - -/** - * @author koo.taejin - */ -public interface PinpointClusterManager { - - void register(ChannelContext channelContext); - - void unregister(ChannelContext channelContext); - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ProfilerClusterPoint.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ProfilerClusterPoint.java new file mode 100644 index 000000000000..82921c075df1 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ProfilerClusterPoint.java @@ -0,0 +1,84 @@ +package com.nhn.pinpoint.collector.cluster; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.collector.receiver.tcp.AgentPropertiesType; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.util.MapUtils; + +/** + * @author koo.taejin + */ +public class ProfilerClusterPoint implements ClusterPoint { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final CopyOnWriteArrayList clusterRepository = new CopyOnWriteArrayList(); + + + public boolean registerChannelContext(ChannelContext channelContext) { + boolean isAdd = clusterRepository.addIfAbsent(channelContext); + + if (!isAdd) { + logger.warn("Already registered ChannelContext({}).", channelContext); + } + + return isAdd; + } + + public boolean unregisterChannelContext(ChannelContext channelContext) { + boolean isRemove = clusterRepository.remove(channelContext); + + if (!isRemove) { + logger.warn("Already unregistered or not registered ChannelContext({}).", channelContext); + } + + return isRemove; + } + + public List getChannelContext() { + return new ArrayList(clusterRepository); + } + + public ChannelContext getChannelContext(String applicationName, String agentId) { + return getChannelContext(applicationName, agentId, -1); + } + + public ChannelContext getChannelContext(String applicationName, String agentId, long startTimestamp) { + + for (ChannelContext channelContext : clusterRepository) { + if (checkSuitableChannelContext(channelContext, applicationName, agentId, startTimestamp)) { + return channelContext; + } + } + + return null; + } + + private boolean checkSuitableChannelContext(ChannelContext channelContext, String applicationName, String agentId, long startTimestamp) { + Map properties = channelContext.getChannelProperties(); + + if (!applicationName.equals(MapUtils.getString(properties, AgentPropertiesType.APPLICATION_NAME.getName()))) { + return false; + } + + if (!agentId.equals(MapUtils.getString(properties, AgentPropertiesType.AGENT_ID.getName()))) { + return false; + } + + if (startTimestamp <= 0) { + // Fix Me + // startTimestamp도 체크하게 변경해야함 + return true; + } + + return true; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WebClusterPoint.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WebClusterPoint.java new file mode 100644 index 000000000000..840b0ca7d2eb --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WebClusterPoint.java @@ -0,0 +1,106 @@ +package com.nhn.pinpoint.collector.cluster; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.client.MessageListener; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; + +/** + * @author koo.taejin + */ +public class WebClusterPoint implements ClusterPoint { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final PinpointSocketFactory factory; + + private final MessageListener messageListener; + // InetSocketAddress List로 전달 하는게 좋을거 같은데 이걸 Key로만들기가 쉽지 않네; + + private final Map clusterRepository = new HashMap(); + + public WebClusterPoint(String id, MessageListener messageListener) { + this.messageListener = messageListener; + + this.factory = new PinpointSocketFactory(); + this.factory.setTimeoutMillis(1000 * 5); + + Map properties = new HashMap(); + properties.put("id", id); + + factory.setProperties(properties); + } + + // Not safe for use by multiple threads. + public void connectPointIfAbsent(InetSocketAddress address) { + logger.info("localhost -> {} connect started.", address); + + if (clusterRepository.containsKey(address)) { + logger.info("localhost -> {} already connected.", address); + return; + } + + PinpointSocket socket = createPinpointSocket(address); + clusterRepository.put(address, socket); + + logger.info("localhost -> {} connect completed.", address); + } + + // Not safe for use by multiple threads. + public void disconnectPoint(InetSocketAddress address) { + logger.info("localhost -> {} disconnect started.", address); + + PinpointSocket socket = clusterRepository.remove(address); + if (socket != null) { + socket.close(); + logger.info("localhost -> {} disconnect completed.", address); + } else { + logger.info("localhost -> {} already disconnected.", address); + } + } + + private PinpointSocket createPinpointSocket(InetSocketAddress address) { + String host = address.getHostName(); + int port = address.getPort(); + + PinpointSocket socket = null; + for (int i = 0; i < 3; i++) { + try { + socket = factory.connect(host, port, messageListener); + logger.info("tcp connect success:{}/{}", host, port); + return socket; + } catch (PinpointSocketException e) { + logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); + } + } + logger.warn("change background tcp connect mode {}/{} ", host, port); + socket = factory.scheduledConnect(host, port, messageListener); + + return socket; + } + + public List getWebClusterList() { + return new ArrayList(clusterRepository.keySet()); + } + + public void close() { + for (PinpointSocket socket : clusterRepository.values()) { + if (socket != null) { + socket.close(); + } + } + + if (factory != null) { + factory.release(); + } + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WorkerState.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WorkerState.java new file mode 100644 index 000000000000..c26f2412ebcc --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WorkerState.java @@ -0,0 +1,13 @@ +package com.nhn.pinpoint.collector.cluster; + + +public enum WorkerState { + + NEW, + INITIALIZING, + STARTED, + DESTROYING, + STOPPED, + ILLEGAL_STATE + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WorkerStateContext.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WorkerStateContext.java new file mode 100644 index 000000000000..6371c7ecd189 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/WorkerStateContext.java @@ -0,0 +1,45 @@ +package com.nhn.pinpoint.collector.cluster; + +import java.util.concurrent.atomic.AtomicReference; + +public class WorkerStateContext { + + private final AtomicReference currentState = new AtomicReference(); + + public WorkerStateContext() { + currentState.set(WorkerState.NEW); + } + + public WorkerState getCurrentState() { + return currentState.get(); + } + + public boolean changeStateInitializing() { + return currentState.compareAndSet(WorkerState.NEW, WorkerState.INITIALIZING); + } + + public boolean changeStateStarted() { + return currentState.compareAndSet(WorkerState.INITIALIZING, WorkerState.STARTED); + } + + public boolean changeStateDestroying() { + return currentState.compareAndSet(WorkerState.STARTED, WorkerState.DESTROYING); + } + + public boolean changeStateStoped() { + return currentState.compareAndSet(WorkerState.DESTROYING, WorkerState.STOPPED); + } + + public boolean changeStateIllegal() { + currentState.set(WorkerState.ILLEGAL_STATE); + return true; + } + + public boolean isStarted() { + if (currentState.get() == WorkerState.STARTED) { + return true; + } else { + return false; + } + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClient.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClient.java index 30efcbe25083..eb881b1af98f 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClient.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClient.java @@ -1,214 +1,250 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper; - -import java.io.IOException; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.KeeperException; -import org.apache.zookeeper.KeeperException.Code; -import org.apache.zookeeper.ZooDefs.Ids; -import org.apache.zookeeper.ZooKeeper; -import org.apache.zookeeper.data.Stat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.collector.cluster.zookeeper.ZookeeperEventWatcher; -import com.nhn.pinpoint.collector.cluster.zookeeper.exception.AuthException; -import com.nhn.pinpoint.collector.cluster.zookeeper.exception.BadOperationException; -import com.nhn.pinpoint.collector.cluster.zookeeper.exception.ConnectionException; -import com.nhn.pinpoint.collector.cluster.zookeeper.exception.PinpointZookeeperException; -import com.nhn.pinpoint.collector.cluster.zookeeper.exception.TimeoutException; -import com.nhn.pinpoint.collector.cluster.zookeeper.exception.UnknownException; - -/** - * @author koo.taejin - */ -public class ZookeeperClient { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - // 쥬키퍼 클라이언트는 스레드 세이프함 - private final ZooKeeper zookeeper; - private final AtomicBoolean clientState = new AtomicBoolean(true); - - private final ZookeeperEventWatcher watcher; - - // 데이터를 이친구가 다가지고 있어야 할 거 같은데; - public ZookeeperClient(String hostPort, int sessionTimeout, ZookeeperEventWatcher watcher) throws KeeperException, IOException, InterruptedException { - this.watcher = watcher; - zookeeper = new ZooKeeper(hostPort, sessionTimeout, this.watcher); // server - } - - /** - * path의 가장마지막에 있는 node는 생성하지 않는다. - * - * @throws PinpointZookeeperException - * @throws InterruptedException - */ - public void createPath(String path) throws PinpointZookeeperException, InterruptedException { - checkState(); - - int pos = 1; - do { - pos = path.indexOf('/', pos + 1); - - if (pos == -1) { - pos = path.length(); - return; - } - - try { - String subPath = path.substring(0, pos); - if (zookeeper.exists(subPath, false) != null) { - continue; - } - - zookeeper.create(subPath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); - } catch (KeeperException exception) { - if (exception.code() != Code.NODEEXISTS) { - handleException(exception); - } - } - - } while (pos < path.length()); - } - -// 이미있는 노드가 괜찮은건지 검사 필요없을거 같긴한데, 혹시나 이건 일단 주석으로 -// Stat stat = zookeeper.exists(node, false); -// if (stat != null) { -// byte[] result = zookeeper.getData(node, false, stat); -// if (byte[] array같은지 검사) { -// return node; -// } -// } - - - // 데이터를 어떤식으로 넣지? - public String createNode(String znodePath, byte[] data) throws PinpointZookeeperException, InterruptedException { - checkState(); - - try { - if (zookeeper.exists(znodePath, false) != null) { - return znodePath; - } - - String pathName = zookeeper.create(znodePath, data, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); - return pathName; - } catch (KeeperException exception) { - if (exception.code() != Code.NODEEXISTS) { - handleException(exception); - } - } - return znodePath; - } - - public byte[] getData(String path) throws PinpointZookeeperException, InterruptedException { - checkState(); - - try { - return zookeeper.getData(path, false, null); - } catch (KeeperException exception) { - handleException(exception); - } - - throw new UnknownException("UnknownException."); - } - - public void setData(String path, byte[] data) throws PinpointZookeeperException, InterruptedException { - checkState(); - - try { - if (zookeeper.exists(path, false) == null) { - return; - } - - zookeeper.setData(path, data, -1); - } catch (KeeperException exception) { - handleException(exception); - } - } - - public void delete(String path) throws PinpointZookeeperException, InterruptedException { - checkState(); - - try { - zookeeper.delete(path, -1); - } catch (KeeperException exception) { - if (exception.code() != Code.NONODE) { - handleException(exception); - } - } - } - - public boolean exists(String path) throws PinpointZookeeperException, InterruptedException { - checkState(); - - try { - Stat stat = zookeeper.exists(path, false); - if (stat == null) { - return false; - } - } catch (KeeperException exception) { - if (exception.code() != Code.NODEEXISTS) { - handleException(exception); - } - } - return true; - } - - private void checkState() throws PinpointZookeeperException { - if (!watcher.isConnected() || !clientState.get()) { - throw new ConnectionException("instance must be connected."); - } - } - -// public byte[] getData(String path) throws KeeperException, InterruptedException { -// checkState(); -// -// return zookeeper.getData(path, false, null); -// } -// -// public List getChildrenNode(String path) throws KeeperException, InterruptedException { -// checkState(); -// -// List childNodeList = zookeeper.getChildren(path, false); -// logger.info("ChildNode List = {}", childNodeList); -// return childNodeList; -// } - - private void handleException(KeeperException keeperException) throws PinpointZookeeperException { - switch (keeperException.code()) { - case CONNECTIONLOSS: - case SESSIONEXPIRED: - throw new ConnectionException(keeperException.getMessage(), keeperException); - case AUTHFAILED: - case INVALIDACL: - case NOAUTH: - throw new AuthException(keeperException.getMessage(), keeperException); - case BADARGUMENTS: - case BADVERSION: - case NOCHILDRENFOREPHEMERALS: - case NOTEMPTY: - case NODEEXISTS: - case NONODE: - throw new BadOperationException(keeperException.getMessage(), keeperException); - case OPERATIONTIMEOUT: - throw new TimeoutException(keeperException.getMessage(), keeperException); - default: - throw new UnknownException(keeperException.getMessage(), keeperException); - } - } - - public void close() { - if (clientState.compareAndSet(true, false)) { - if (zookeeper != null) { - try { - zookeeper.close(); - } catch (InterruptedException ignore) { - logger.debug(ignore.getMessage(), ignore); - } - } - } - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.KeeperException.Code; +import org.apache.zookeeper.ZooDefs.Ids; +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.data.Stat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.AuthException; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.BadOperationException; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.ConnectionException; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.PinpointZookeeperException; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.TimeoutException; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.UnknownException; + +/** + * @author koo.taejin + */ +public class ZookeeperClient { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + // 쥬키퍼 클라이언트는 스레드 세이프함 + private final ZooKeeper zookeeper; + private final AtomicBoolean clientState = new AtomicBoolean(true); + + private final ZookeeperEventWatcher watcher; + + // 데이터를 이친구가 다가지고 있어야 할 거 같은데; + public ZookeeperClient(String hostPort, int sessionTimeout, ZookeeperEventWatcher watcher) throws KeeperException, IOException, InterruptedException { + this.watcher = watcher; + zookeeper = new ZooKeeper(hostPort, sessionTimeout, this.watcher); // server + } + + /** + * path의 가장마지막에 있는 node는 생성하지 않는다. + * + * @throws PinpointZookeeperException + * @throws InterruptedException + */ + public void createPath(String path) throws PinpointZookeeperException, InterruptedException { + createPath(path, false); + } + + public void createPath(String path, boolean createEndNode) throws PinpointZookeeperException, InterruptedException { + checkState(); + + int pos = 1; + do { + pos = path.indexOf('/', pos + 1); + + if (pos == -1) { + pos = path.length(); + } + + try { + if (pos == path.length()) { + if (!createEndNode) { + return; + } + } + + String subPath = path.substring(0, pos); + if (zookeeper.exists(subPath, false) != null) { + continue; + } + + zookeeper.create(subPath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); + } catch (KeeperException exception) { + if (exception.code() != Code.NODEEXISTS) { + handleException(exception); + } + } + + } while (pos < path.length()); + } + + +// 이미있는 노드가 괜찮은건지 검사 필요없을거 같긴한데, 혹시나 이건 일단 주석으로 +// Stat stat = zookeeper.exists(node, false); +// if (stat != null) { +// byte[] result = zookeeper.getData(node, false, stat); +// if (byte[] array같은지 검사) { +// return node; +// } +// } + + + // 데이터를 어떤식으로 넣지? + public String createNode(String znodePath, byte[] data) throws PinpointZookeeperException, InterruptedException { + checkState(); + + try { + if (zookeeper.exists(znodePath, false) != null) { + return znodePath; + } + + String pathName = zookeeper.create(znodePath, data, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); + return pathName; + } catch (KeeperException exception) { + if (exception.code() != Code.NODEEXISTS) { + handleException(exception); + } + } + return znodePath; + } + + public byte[] getData(String path) throws PinpointZookeeperException, InterruptedException { + checkState(); + + try { + return zookeeper.getData(path, false, null); + } catch (KeeperException exception) { + handleException(exception); + } + + throw new UnknownException("UnknownException."); + } + + public void setData(String path, byte[] data) throws PinpointZookeeperException, InterruptedException { + checkState(); + + try { + if (zookeeper.exists(path, false) == null) { + return; + } + + zookeeper.setData(path, data, -1); + } catch (KeeperException exception) { + handleException(exception); + } + } + + public void delete(String path) throws PinpointZookeeperException, InterruptedException { + checkState(); + + try { + zookeeper.delete(path, -1); + } catch (KeeperException exception) { + if (exception.code() != Code.NONODE) { + handleException(exception); + } + } + } + + public boolean exists(String path) throws PinpointZookeeperException, InterruptedException { + checkState(); + + try { + Stat stat = zookeeper.exists(path, false); + if (stat == null) { + return false; + } + } catch (KeeperException exception) { + if (exception.code() != Code.NODEEXISTS) { + handleException(exception); + } + } + return true; + } + + private void checkState() throws PinpointZookeeperException { + if (!isConnected()) { + throw new ConnectionException("instance must be connected."); + } + } + + public boolean isConnected() { + if (!watcher.isConnected() || !clientState.get()) { + return false; + } + + return true; + } + + public List getChildrenNode(String path, boolean watch) throws PinpointZookeeperException, InterruptedException { + checkState(); + + try { + List childNodeList = zookeeper.getChildren(path, watch, null); + + logger.info("ChildNode List = {}", childNodeList); + return childNodeList; + } catch (KeeperException exception) { + if (exception.code() != Code.NONODE) { + handleException(exception); + } + } + + return Collections.emptyList(); + } + +// public byte[] getData(String path) throws KeeperException, InterruptedException { +// checkState(); +// +// return zookeeper.getData(path, false, null); +// } +// +// public List getChildrenNode(String path) throws KeeperException, InterruptedException { +// checkState(); +// +// List childNodeList = zookeeper.getChildren(path, false); +// logger.info("ChildNode List = {}", childNodeList); +// return childNodeList; +// } + + private void handleException(KeeperException keeperException) throws PinpointZookeeperException { + switch (keeperException.code()) { + case CONNECTIONLOSS: + case SESSIONEXPIRED: + throw new ConnectionException(keeperException.getMessage(), keeperException); + case AUTHFAILED: + case INVALIDACL: + case NOAUTH: + throw new AuthException(keeperException.getMessage(), keeperException); + case BADARGUMENTS: + case BADVERSION: + case NOCHILDRENFOREPHEMERALS: + case NOTEMPTY: + case NODEEXISTS: + case NONODE: + throw new BadOperationException(keeperException.getMessage(), keeperException); + case OPERATIONTIMEOUT: + throw new TimeoutException(keeperException.getMessage(), keeperException); + default: + throw new UnknownException(keeperException.getMessage(), keeperException); + } + } + + public void close() { + if (clientState.compareAndSet(true, false)) { + if (zookeeper != null) { + try { + zookeeper.close(); + } catch (InterruptedException ignore) { + logger.debug(ignore.getMessage(), ignore); + } + } + } + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterManager.java deleted file mode 100644 index 879376870bf4..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterManager.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper; - -import java.io.IOException; -import java.net.InetAddress; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.commons.lang.StringUtils; -import org.apache.zookeeper.KeeperException; -import org.apache.zookeeper.WatchedEvent; -import org.apache.zookeeper.Watcher.Event.KeeperState; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.nhn.pinpoint.collector.cluster.zookeeper.job.DeleteJob; -import com.nhn.pinpoint.collector.cluster.zookeeper.job.UpdateJob; -import com.nhn.pinpoint.collector.receiver.tcp.AgentPropertiesType; -import com.nhn.pinpoint.rpc.server.ChannelContext; -import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; -import com.nhn.pinpoint.rpc.server.SocketChannelStateChangeEventListener; -import com.nhn.pinpoint.rpc.util.MapUtils; - -/** - * @author koo.taejin - */ -public class ZookeeperClusterManager implements SocketChannelStateChangeEventListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final InetAddress localHost; - - private final ZookeeperClient client; - private final ZookeeperLatestJobWorker worker; - - private final ObjectMapper objectmapper = new ObjectMapper(); - - - // 단순하게 하자 그냥 RUN이면 등록 FINISHED면 경우 삭제 그외 skip - // 만약 상태가 안맞으면(?) 보정 들어가야 하는데 leack detector 같은걸 worker내부에 둘 까도 고민중 - // - // RUN에서만 생성할수 있게 해야한다. - // 지금은 RUN_WITHOUT_REGISTER면 상대방의 상태를 알수 없는 상태이기 때문에 이상황에서 등록 - - public ZookeeperClusterManager(String hostPort, int sessionTimeout) throws KeeperException, IOException, InterruptedException { - // 디폴트값으로 사용할 ip같은거 지정해 주는게 좋을듯 - this.localHost = InetAddress.getLocalHost(); - - this.client = new ZookeeperClient(hostPort, sessionTimeout, new ClusterManagerWatcher()); - this.worker = new ZookeeperLatestJobWorker(client); - worker.start(); - } - - @Override - public void eventPerformed(ChannelContext channelContext, PinpointServerSocketStateCode stateCode) { - logger.info("eventPerformed ChannelContext={}, State={}", channelContext, stateCode); - - Map agentProperties = channelContext.getChannelProperties(); - - // 현재는 AgentProperties에 값을 모를 경우 skip - if (skipAgent(agentProperties)) { - return; - } - - if (PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION == stateCode) { - byte[] contents = serializeContents(agentProperties, stateCode); - if (contents == null) { - return; - } - - UpdateJob job = new UpdateJob(channelContext, contents); - worker.putJob(job); - } else if (PinpointServerSocketStateCode.isFinished(stateCode)) { - DeleteJob job = new DeleteJob(channelContext); - worker.putJob(job); - } - } - - public Map getData(ChannelContext channelContext) { - byte[] contents = worker.getData(channelContext); - - if (contents == null) { - return Collections.EMPTY_MAP; - } - - return deserializeContents(contents); - } - - private boolean skipAgent(Map agentProperties) { - String applicationName = MapUtils.getString(agentProperties, AgentPropertiesType.APPLICATION_NAME.getName()); - String agentId = MapUtils.getString(agentProperties, AgentPropertiesType.AGENT_ID.getName()); - - if (StringUtils.isEmpty(applicationName) || StringUtils.isEmpty(agentId)) { - return true; - } - - return false; - } - - private byte[] serializeContents(Map agentProperties, PinpointServerSocketStateCode state) { - Map contents = new HashMap(); - contents.put(localHost.getHostAddress(), agentProperties); - contents.put("state", state.name()); - - try { - return objectmapper.writeValueAsBytes(contents); - } catch (JsonProcessingException e) { - logger.warn(e.getMessage(), e); - } - - return null; - } - - private Map deserializeContents(byte[] contents) { - try { - return objectmapper.readValue(contents, Map.class); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - - return Collections.EMPTY_MAP; - } - - public void close() { - client.close(); - worker.stop(); - } - - // 쥬키퍼의 모든 노드를 EPHEMERAL 형태로 만들기 때문에 연결이 새로 연결되면 원래 가지고 있던 것들 재등록 함 - // 연결이 종료 될때는 별다른 액션을 취하지 않는다. - class ClusterManagerWatcher implements ZookeeperEventWatcher { - - private final AtomicBoolean connected = new AtomicBoolean(false); - - // 여기서 고민을 좀 해봐야 할듯 - // 이전에 있던 job을 다 지운다. 어떻게 지울까? - // 새로 생긴 job을 모두 새로 만든다 어떻게 만들지? 추가적으로 이걸 지워질수는 없나? - // 타이밍이 안좋아서 문제가 생길수 있나? - // - - @Override - public void process(WatchedEvent event) { - KeeperState state = event.getState(); - - // 상태가 되면 ephemeral 노드가 사라짐 - // 문서에 따라 자동으로 연결이 되고, 연결되는 이벤트는 process에서 감지가 됨 - if (state == KeeperState.Disconnected || state == KeeperState.Expired) { - connected.compareAndSet(true, false); - return; - } - - if (state == KeeperState.SyncConnected || state == KeeperState.NoSyncConnected) { - // 이전상태가 RUN일수 있기 때문에 유지해도 됨 - boolean changed = connected.compareAndSet(false, true); - if (changed) { - // 여기서 데이터가 있으면 다 넣어줘야함 - List currentChannelContextList = worker.getRegisteredChannelContextList(); - - for (ChannelContext channelContext : currentChannelContextList) { - eventPerformed(channelContext, channelContext.getCurrentStateCode()); - } - } - - return; - } - } - - @Override - public boolean isConnected() { - return connected.get(); - } - - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterService.java new file mode 100644 index 000000000000..b46098b9b968 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterService.java @@ -0,0 +1,207 @@ +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.WatchedEvent; +import org.apache.zookeeper.Watcher.Event.EventType; +import org.apache.zookeeper.Watcher.Event.KeeperState; +import org.apache.zookeeper.proto.WatcherEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.collector.cluster.AbstractClusterService; +import com.nhn.pinpoint.collector.cluster.ClusterPointRouter; +import com.nhn.pinpoint.collector.cluster.WorkerState; +import com.nhn.pinpoint.collector.cluster.WorkerStateContext; +import com.nhn.pinpoint.collector.config.CollectorConfiguration; +import com.nhn.pinpoint.collector.util.CollectorUtils; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.server.SocketChannelStateChangeEventListener; + +public class ZookeeperClusterService extends AbstractClusterService { + + private static final String PINPOINT_CLUSTER_PATH = "/pinpoint-cluster"; + private static final String PINPOINT_WEB_CLUSTER_PATH = PINPOINT_CLUSTER_PATH + "/web"; + private static final String PINPOINT_PROFILER_CLUSTER_PATH = PINPOINT_CLUSTER_PATH + "/profiler"; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + // 해당 값이 유일한 값이 아닌 경우 MAC주소나 IP주소 등으로 변경할 예정 + // 요렇게 하면 pid@hostname 으로 나옴 (localhost 요런놈은 겹칠 가능성이 존재함) + private final String serverIdentifier = CollectorUtils.getServerIdentifier(); + + private final WorkerStateContext serviceState; + + private ZookeeperClient client; + + + // ProfilerClusterManager는 프로파일러 -> 콜렉터 연결을 감지 및 관리하고, 쥬키퍼에 등록한다. + // private ZookeeperProfilerClusterManager profilerClusterManager; + // WebClusterManager는 웹 정보가 쥬키퍼에 등록되어 있는지 체크하고, 콜렉터 -> 웹 연결을 관리한다. + + private ZookeeperWebClusterManager webClusterManager; + private ZookeeperProfilerClusterManager profilerClusterManager; + + public ZookeeperClusterService(CollectorConfiguration config, ClusterPointRouter clusterPointRouter) { + super(config, clusterPointRouter); + this.serviceState = new WorkerStateContext(); + } + + @PostConstruct + @Override + public void setUp() throws KeeperException, IOException, InterruptedException { + if (!config.isClusterEnable()) { + logger.info("pinpoint-collector cluster disable."); + return; + } + + switch (this.serviceState.getCurrentState()) { + case NEW: + if (this.serviceState.changeStateInitializing()) { + logger.info("{} initialization started.", this.getClass().getSimpleName()); + + // 이 상태값은 반드시 필요한것들인데. + ClusterManagerWatcher watcher = new ClusterManagerWatcher(); + this.client = new ZookeeperClient(config.getClusterAddress(), config.getClusterSessionTimeout(), watcher); + + this.profilerClusterManager = new ZookeeperProfilerClusterManager(client, serverIdentifier, clusterPointRouter.getProfilerClusterPoint()); + this.profilerClusterManager.start(); + + this.webClusterManager = new ZookeeperWebClusterManager(client, PINPOINT_WEB_CLUSTER_PATH, serverIdentifier, clusterPointRouter.getWebClusterPoint()); + this.webClusterManager.start(); + + this.serviceState.changeStateStarted(); + logger.info("{} initialization completed.", this.getClass().getSimpleName()); + + if (client.isConnected()) { + WatcherEvent watcherEvent = new WatcherEvent(EventType.None.getIntValue(), KeeperState.SyncConnected.getIntValue(), ""); + WatchedEvent event = new WatchedEvent(watcherEvent); + + watcher.process(event); + } + } + break; + case INITIALIZING: + logger.info("{} already initializing.", this.getClass().getSimpleName()); + break; + case STARTED: + logger.info("{} already started.", this.getClass().getSimpleName()); + break; + case DESTROYING: + throw new IllegalStateException("Already destroying."); + case STOPPED: + throw new IllegalStateException("Already stopped."); + case ILLEGAL_STATE: + throw new IllegalStateException("Invalid State."); + } + } + + @PreDestroy + @Override + public void tearDown() { + if (!config.isClusterEnable()) { + logger.info("pinpoint-collector cluster disable."); + return; + } + + if (!(this.serviceState.changeStateDestroying())) { + WorkerState state = this.serviceState.getCurrentState(); + + logger.info("{} already {}.", this.getClass().getSimpleName(), state.toString()); + return; + } + + logger.info("{} destroying started.", this.getClass().getSimpleName()); + + if (this.profilerClusterManager != null) { + profilerClusterManager.stop(); + } + + if (this.webClusterManager != null) { + webClusterManager.stop(); + } + + if (client != null) { + client.close(); + } + + this.serviceState.changeStateStoped(); + logger.info("{} destroying completed.", this.getClass().getSimpleName()); + + return; + } + + public SocketChannelStateChangeEventListener getChannelStateChangeEventListener() { + return profilerClusterManager; + } + + public ZookeeperProfilerClusterManager getProfilerClusterManager() { + return profilerClusterManager; + } + + public ZookeeperWebClusterManager getWebClusterManager() { + return webClusterManager; + } + + class ClusterManagerWatcher implements ZookeeperEventWatcher { + + private final AtomicBoolean connected = new AtomicBoolean(false); + + @Override + public void process(WatchedEvent event) { + logger.debug("Process Zookeeper Event({})", event); + + KeeperState state = event.getState(); + EventType eventType = event.getType(); + + // 상태가 되면 ephemeral 노드가 사라짐 + // 문서에 따라 자동으로 연결이 되고, 연결되는 이벤트는 process에서 감지가 됨 + if (ZookeeperUtils.isDisconnectedEvent(state, eventType)) { + connected.compareAndSet(true, false); + return; + } + + if (ZookeeperUtils.isConnectedEvent(state, eventType)) { + // 이전상태가 RUN일수 있기 때문에 유지해도 됨 + boolean changed = connected.compareAndSet(false, true); + } + + if (serviceState.isStarted() && connected.get()) { + + // 중복 요청이 있을수 있음 일단은 중복 로직 감안함 + if (ZookeeperUtils.isConnectedEvent(state, eventType)) { + // 이전상태가 RUN일수 있기 때문에 유지해도 됨 + // 여기서 데이터가 있으면 다 넣어줘야함 + List currentChannelContextList = profilerClusterManager.getRegisteredChannelContextList(); + for (ChannelContext channelContext : currentChannelContextList) { + profilerClusterManager.eventPerformed(channelContext, channelContext.getCurrentStateCode()); + } + + webClusterManager.handleAndRegisterWatcher(PINPOINT_WEB_CLUSTER_PATH); + } else if (eventType == EventType.NodeChildrenChanged) { + String path = event.getPath(); + + if (PINPOINT_WEB_CLUSTER_PATH.equals(path)) { + webClusterManager.handleAndRegisterWatcher(path); + } else { + logger.warn("Unknown Path ChildrenChanged {}.", path); + } + + } + } + } + + @Override + public boolean isConnected() { + return connected.get(); + } + + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperEventWatcher.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperEventWatcher.java index 795f448ff695..a8496ec90ba9 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperEventWatcher.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperEventWatcher.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper; - -import org.apache.zookeeper.Watcher; - -/** - * @author koo.taejin - */ -public interface ZookeeperEventWatcher extends Watcher { - - boolean isConnected(); - -} +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import org.apache.zookeeper.Watcher; + +/** + * @author koo.taejin + */ +public interface ZookeeperEventWatcher extends Watcher { + + boolean isConnected(); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperLatestJobWorker.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperLatestJobWorker.java index ad4b02a3c8c2..57edf6a6dd31 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperLatestJobWorker.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperLatestJobWorker.java @@ -1,380 +1,401 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper; - -import java.lang.management.ManagementFactory; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.collector.cluster.zookeeper.exception.TimeoutException; -import com.nhn.pinpoint.collector.cluster.zookeeper.job.DeleteJob; -import com.nhn.pinpoint.collector.cluster.zookeeper.job.Job; -import com.nhn.pinpoint.collector.cluster.zookeeper.job.UpdateJob; -import com.nhn.pinpoint.common.util.PinpointThreadFactory; -import com.nhn.pinpoint.collector.receiver.tcp.AgentPropertiesType; -import com.nhn.pinpoint.rpc.server.ChannelContext; -import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; -import com.nhn.pinpoint.rpc.util.MapUtils; - -/** - * @author koo.taejin - */ -public class ZookeeperLatestJobWorker implements Runnable { - - private static final String PREFIX_ROOT_ZNODE = "/pinpoint-cluster"; - private static final String PATH_SEPRATOR = "/"; - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Object lock = new Object(); - - private final AtomicInteger workerState; - private final Thread workerThread; - - private final String identifier = ManagementFactory.getRuntimeMXBean().getName(); - private final AtomicInteger sequntialId = new AtomicInteger(0); - - private final ZookeeperClient zookeeperClient; - - // 메시지가 사라지면 ChannelContext 역시 사라짐 - private final Map latestJobRepository = new HashMap(); - - // 들어온 ChannelContext는 계속 유지됨 - private final Map znodeMappingRepository = new HashMap(); - - private final BlockingQueue leakJobQueue = new LinkedBlockingQueue(); - - // 등록순서 - // 순서대로 작업은 반드시 Worker에서만 돌아가기 때문에 동시성은 보장됨 - - public ZookeeperLatestJobWorker(ZookeeperClient zookeeperClient) { - // TODO Auto-generated constructor stub - this.zookeeperClient = zookeeperClient; - - this.workerState = new AtomicInteger(0); - - final ThreadFactory threadFactory = new PinpointThreadFactory(this.getClass().getSimpleName(), true); - this.workerThread = threadFactory.newThread(this); - } - - public void start() { - switch (this.workerState.get()) { - case 0: - if (this.workerState.compareAndSet(0, 1)) - logger.info("{} will be started", this.getClass().getSimpleName()); - this.workerThread.start(); - break; - case 1: - logger.info("{} already started.", this.getClass().getSimpleName()); - break; - case 2: - throw new IllegalStateException("Already stopped"); - default: - throw new Error("Invalid WorkerState"); - } - } - - public void stop() { - if (!(this.workerState.compareAndSet(1, 2))) { - logger.info("{} already stopped.", this.getClass().getSimpleName()); - this.workerState.set(2); - return; - } - - logger.info("{} will be stopped", this.getClass().getSimpleName()); - - boolean interrupted = false; - while (this.workerThread.isAlive()) { - this.workerThread.interrupt(); - try { - this.workerThread.join(100L); - } catch (InterruptedException e) { - interrupted = true; - } - } - - return; - } - - @Override - public void run() { - - // 고민할 것 - // 이벤트 삭제가 안될떄 spinlock 고민해야함 - // 이벤트 발생시 처리가 안될 경우 실제 등록이 안되어이는 ChannelContext가 남아있을 수 있음 이 경우 - // Manager에서 - // 종료가 될 경우 처리해주긴 하지만 LeakDetector같은게 있으면 더 좋을듯 안되면 (1분마다 확인등도 괜찮을듯) - while (workerState.get() == 1) { - boolean eventCreated = await(60000, 200); - if (workerState.get() != 1) { - break; - } - - // 이벤트 발생시 이벤트 처리 - // 이벤트 발생하지 않을 경우 leack ChannelContext 확인 및 처리 - if (eventCreated) { - // ConcurrentModificationException 발생 피하기 위해서 - Iterator keyIterator = getLatestJobRepositoryKeyIterator(); - - while (keyIterator.hasNext()) { - ChannelContext channelContext = keyIterator.next(); - Job job = getJob(channelContext); - - if (job == null) { - continue; - } - - if (job instanceof UpdateJob) { - handleUpdate((UpdateJob) job); - } else if (job instanceof DeleteJob) { - handleDelete((DeleteJob) job); - } - } - } else { - logger.debug("LeackDetector Start."); - - // while 걸자 - while (true) { - Job job = leakJobQueue.poll(); - if (job == null) { - break; - } - - if (job instanceof UpdateJob) { - putJob(new UpdateJob(job.getChannelContext(), 0, ((UpdateJob) job).getContents())); - } - } - - List currentChannelContextList = getRegisteredChannelContextList(); - for (ChannelContext channelContext : currentChannelContextList) { - if (PinpointServerSocketStateCode.isFinished(channelContext.getCurrentStateCode())) { - logger.info("LeackDetector Find Leak ChannelContext={}.", channelContext); - putJob(new DeleteJob(channelContext)); - } - } - - } - } - - logger.info("{} stopped", this.getClass().getSimpleName()); - } - - public boolean handleUpdate(UpdateJob job) { - ChannelContext channelContext = job.getChannelContext(); - - PinpointServerSocketStateCode code = channelContext.getCurrentStateCode(); - if (PinpointServerSocketStateCode.isFinished(code)) { - putJob(new DeleteJob(channelContext)); - return false; - } - - // 동시성에 문제 없게 하자 - String uniquePath = getUniquePath(channelContext, true); - - try { - if (zookeeperClient.exists(uniquePath)) { - zookeeperClient.setData(uniquePath, job.getContents()); - } else { - zookeeperClient.createPath(uniquePath); - zookeeperClient.createNode(uniquePath, job.getContents()); - logger.info("Registed Zookeeper UniqPath = {}", uniquePath); - } - return true; - } catch (Exception e) { - logger.warn(e.getMessage(), e); - if (e instanceof TimeoutException) { - job.incrementCurrentRetryCount(); - putJob(job); - } - } - - return false; - } - - public boolean handleDelete(Job job) { - ChannelContext channelContext = job.getChannelContext(); - - String uniquePath = getUniquePath(channelContext, false); - - if (uniquePath == null) { - logger.info("Already Delete Zookeeper UniqPath ChannelContext = {}.", channelContext); - return true; - } - - try { - if (zookeeperClient.exists(uniquePath)) { - zookeeperClient.delete(uniquePath); - logger.info("Unregisted Zookeeper UniqPath = {}", uniquePath); - } - removeUniquePath(channelContext); - return true; - } catch (Exception e) { - logger.warn(e.getMessage(), e); - if (e instanceof TimeoutException) { - job.incrementCurrentRetryCount(); - putJob(job); - } - } - - return false; - } - - public byte[] getData(ChannelContext channelContext) { - String uniquePath = getUniquePath(channelContext, false); - - if (uniquePath == null) { - logger.info("Can't find suitable UniqPath ChannelContext = {}.", channelContext); - return null; - } - - try { - return zookeeperClient.getData(uniquePath); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - - return null; - } - - public List getRegisteredChannelContextList() { - synchronized (znodeMappingRepository) { - return new ArrayList(znodeMappingRepository.keySet()); - } - } - - /** - * 파라미터의 대기시간동안 이벤트가 일어날 경우 true 일어나지 않을 경우 false - * - * @param waitTimeMillis - * @return - */ - private boolean await(long waitTimeMillis, long waitUnitTimeMillis) { - synchronized (lock) { - long waitTime = waitTimeMillis; - long waitUnitTime = waitUnitTimeMillis; - if (waitTimeMillis < 1000) { - waitTime = 1000; - } - if (waitUnitTimeMillis < 100) { - waitUnitTime = 100; - } - - long startTimeMillis = System.currentTimeMillis(); - - while (latestJobRepository.size() == 0 && !isOverWaitTime(waitTime, startTimeMillis) && workerState.get() == 1) { - try { - lock.wait(waitUnitTime); - } catch (InterruptedException e) { - - } - } - - if (isOverWaitTime(waitTime, startTimeMillis)) { - return false; - } - - return true; - } - } - - private boolean isOverWaitTime(long waitTimeMillis, long startTimeMillis) { - return waitTimeMillis < (System.currentTimeMillis() - startTimeMillis); - } - - private Iterator getLatestJobRepositoryKeyIterator() { - synchronized (lock) { - return latestJobRepository.keySet().iterator(); - } - } - - // 상당히 민감한 api임 Runnable에서만 사용해야함 - private Job getJob(ChannelContext channelContext) { - synchronized (lock) { - Job job = latestJobRepository.remove(channelContext); - return job; - } - - } - - public void putJob(Job job) { - if (job.getMaxRetryCount() < job.getCurrentRetryCount()) { - if (logger.isInfoEnabled()) { - logger.warn("Leack Job Queue Register Job={}.", job); - } - leakJobQueue.add(job); - return; - } - - synchronized (lock) { - ChannelContext channelContext = job.getChannelContext(); - - latestJobRepository.put(channelContext, job); - lock.notifyAll(); - } - } - - private String getUniquePath(ChannelContext channelContext, boolean create) { - synchronized (znodeMappingRepository) { - String zNodePath = znodeMappingRepository.get(channelContext); - - if (!create) { - return zNodePath; - } - - if (zNodePath == null) { - Map agentProperties = channelContext.getChannelProperties(); - final String applicationName = MapUtils.getString(agentProperties, AgentPropertiesType.APPLICATION_NAME.getName()); - final String agentId = MapUtils.getString(agentProperties, AgentPropertiesType.AGENT_ID.getName()); - - if (StringUtils.isEmpty(applicationName) || StringUtils.isEmpty(agentId)) { - return null; - } - - String path = PREFIX_ROOT_ZNODE + "/" + applicationName + "/" + agentId; - String zNodeName = createUniqueZnodeName(); - - zNodePath = bindingPathAndZnode(path, zNodeName); - znodeMappingRepository.put(channelContext, zNodePath); - - logger.info("Created Zookeeper UniqPath = {}", zNodePath); - } - - return zNodePath; - } - } - - private void removeUniquePath(ChannelContext channelContext) { - synchronized (znodeMappingRepository) { - String zNodePath = znodeMappingRepository.remove(channelContext); - if (zNodePath != null) { - logger.info("Deleted Zookeeper UniqPath = {}", zNodePath); - } - } - } - - private String createUniqueZnodeName() { - return identifier + "_" + sequntialId.getAndIncrement(); - } - - private String bindingPathAndZnode(String path, String znodeName) { - StringBuilder fullPath = new StringBuilder(); - - fullPath.append(path); - if (!path.endsWith(PATH_SEPRATOR)) { - fullPath.append(PATH_SEPRATOR); - } - fullPath.append(znodeName); - - return fullPath.toString(); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.collector.cluster.WorkerState; +import com.nhn.pinpoint.collector.cluster.WorkerStateContext; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.TimeoutException; +import com.nhn.pinpoint.collector.cluster.zookeeper.job.DeleteJob; +import com.nhn.pinpoint.collector.cluster.zookeeper.job.Job; +import com.nhn.pinpoint.collector.cluster.zookeeper.job.UpdateJob; +import com.nhn.pinpoint.collector.receiver.tcp.AgentPropertiesType; +import com.nhn.pinpoint.common.util.PinpointThreadFactory; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; +import com.nhn.pinpoint.rpc.util.MapUtils; + +/** + * @author koo.taejin + */ +public class ZookeeperLatestJobWorker implements Runnable { + + private static final String PINPOINT_CLUSTER_PATH = "/pinpoint-cluster"; + private static final String PINPOINT_PROFILER_CLUSTER_PATH = PINPOINT_CLUSTER_PATH + "/profiler"; + + private static final String PATH_SEPRATOR = "/"; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Object lock = new Object(); + + private final WorkerStateContext workerState; + private final Thread workerThread; + + private final String identifier; + private final AtomicInteger sequntialId = new AtomicInteger(0); + + private final ZookeeperClient zookeeperClient; + + // 메시지가 사라지면 ChannelContext 역시 사라짐 + private final Map latestJobRepository = new HashMap(); + + // 들어온 ChannelContext는 계속 유지됨 + private final Map znodeMappingRepository = new HashMap(); + + private final BlockingQueue leakJobQueue = new LinkedBlockingQueue(); + + // 등록순서 + // 순서대로 작업은 반드시 Worker에서만 돌아가기 때문에 동시성은 보장됨 + + public ZookeeperLatestJobWorker(ZookeeperClient zookeeperClient, String serverIdentifier) { + // TODO Auto-generated constructor stub + this.zookeeperClient = zookeeperClient; + + this.workerState = new WorkerStateContext(); + + this.identifier = serverIdentifier; + + final ThreadFactory threadFactory = new PinpointThreadFactory(this.getClass().getSimpleName(), true); + this.workerThread = threadFactory.newThread(this); + } + + public void start() { + switch (this.workerState.getCurrentState()) { + case NEW: + if (this.workerState.changeStateInitializing()) { + logger.info("{} initialization started.", this.getClass().getSimpleName()); + this.workerThread.start(); + + workerState.changeStateStarted(); + logger.info("{} initialization completed.", this.getClass().getSimpleName()); + + break; + } + case INITIALIZING: + logger.info("{} already initializing.", this.getClass().getSimpleName()); + break; + case STARTED: + logger.info("{} already started.", this.getClass().getSimpleName()); + break; + case DESTROYING: + throw new IllegalStateException("Already destroying."); + case STOPPED: + throw new IllegalStateException("Already stopped."); + case ILLEGAL_STATE: + throw new IllegalStateException("Invalid State."); + } + } + + public void stop() { + if (!(this.workerState.changeStateDestroying())) { + WorkerState state = this.workerState.getCurrentState(); + + logger.info("{} already {}.", this.getClass().getSimpleName(), state.toString()); + return; + } + + logger.info("{} destorying started.", this.getClass().getSimpleName()); + boolean interrupted = false; + while (this.workerThread.isAlive()) { + this.workerThread.interrupt(); + try { + this.workerThread.join(100L); + } catch (InterruptedException e) { + interrupted = true; + } + } + + this.workerState.changeStateStoped(); + logger.info("{} destorying completed.", this.getClass().getSimpleName()); + + return; + } + + @Override + public void run() { + + // 고민할 것 + // 이벤트 삭제가 안될떄 spinlock 고민해야함 + // 이벤트 발생시 처리가 안될 경우 실제 등록이 안되어이는 ChannelContext가 남아있을 수 있음 이 경우 + while (workerState.isStarted()) { + boolean eventCreated = await(60000, 200); + if (!workerState.isStarted()) { + break; + } + + // 이벤트 발생시 이벤트 처리 + // 이벤트 발생하지 않을 경우 leak ChannelContext 확인 및 처리 + if (eventCreated) { + // ConcurrentModificationException 발생 피하기 위해서 + Iterator keyIterator = getLatestJobRepositoryKeyIterator(); + + while (keyIterator.hasNext()) { + ChannelContext channelContext = keyIterator.next(); + Job job = getJob(channelContext); + + if (job == null) { + continue; + } + + if (job instanceof UpdateJob) { + handleUpdate((UpdateJob) job); + } else if (job instanceof DeleteJob) { + handleDelete((DeleteJob) job); + } + } + } else { + // 삭제 타이밍이 잘 안맞을 경우 메시지 유실이 발생할 가능성이 있어서 유실 Job 처리 + logger.debug("LeakDetector Start."); + + while (true) { + Job job = leakJobQueue.poll(); + if (job == null) { + break; + } + + if (job instanceof UpdateJob) { + putJob(new UpdateJob(job.getChannelContext(), 0, ((UpdateJob) job).getContents())); + } + } + + List currentChannelContextList = getRegisteredChannelContextList(); + for (ChannelContext channelContext : currentChannelContextList) { + if (PinpointServerSocketStateCode.isFinished(channelContext.getCurrentStateCode())) { + logger.info("LeakDetector Find Leak ChannelContext={}.", channelContext); + putJob(new DeleteJob(channelContext)); + } + } + + } + } + + logger.info("{} stopped", this.getClass().getSimpleName()); + } + + public boolean handleUpdate(UpdateJob job) { + ChannelContext channelContext = job.getChannelContext(); + + PinpointServerSocketStateCode code = channelContext.getCurrentStateCode(); + if (PinpointServerSocketStateCode.isFinished(code)) { + putJob(new DeleteJob(channelContext)); + return false; + } + + // 동시성에 문제 없게 하자 + String uniquePath = getUniquePath(channelContext, true); + if (uniquePath == null) { + logger.warn("Zookeeper UniqPath({}) may not be null.", uniquePath); + return false; + } + + try { + if (zookeeperClient.exists(uniquePath)) { + zookeeperClient.setData(uniquePath, job.getContents()); + } else { + zookeeperClient.createPath(uniquePath); + zookeeperClient.createNode(uniquePath, job.getContents()); + logger.info("Registed Zookeeper UniqPath = {}", uniquePath); + } + return true; + } catch (Exception e) { + logger.warn(e.getMessage(), e); + if (e instanceof TimeoutException) { + job.incrementCurrentRetryCount(); + putJob(job); + } + } + + return false; + } + + public boolean handleDelete(Job job) { + ChannelContext channelContext = job.getChannelContext(); + + String uniquePath = getUniquePath(channelContext, false); + + if (uniquePath == null) { + logger.info("Already Delete Zookeeper UniqPath ChannelContext = {}.", channelContext); + return true; + } + + try { + if (zookeeperClient.exists(uniquePath)) { + zookeeperClient.delete(uniquePath); + logger.info("Unregisted Zookeeper UniqPath = {}", uniquePath); + } + removeUniquePath(channelContext); + return true; + } catch (Exception e) { + logger.warn(e.getMessage(), e); + if (e instanceof TimeoutException) { + job.incrementCurrentRetryCount(); + putJob(job); + } + } + + return false; + } + + public byte[] getData(ChannelContext channelContext) { + String uniquePath = getUniquePath(channelContext, false); + + if (uniquePath == null) { + logger.info("Can't find suitable UniqPath ChannelContext = {}.", channelContext); + return null; + } + + try { + return zookeeperClient.getData(uniquePath); + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } + + return null; + } + + public List getRegisteredChannelContextList() { + synchronized (znodeMappingRepository) { + return new ArrayList(znodeMappingRepository.keySet()); + } + } + + /** + * 파라미터의 대기시간동안 이벤트가 일어날 경우 true 일어나지 않을 경우 false + * + * @param waitTimeMillis + * @return + */ + private boolean await(long waitTimeMillis, long waitUnitTimeMillis) { + synchronized (lock) { + long waitTime = waitTimeMillis; + long waitUnitTime = waitUnitTimeMillis; + if (waitTimeMillis < 1000) { + waitTime = 1000; + } + if (waitUnitTimeMillis < 100) { + waitUnitTime = 100; + } + + long startTimeMillis = System.currentTimeMillis(); + + while (latestJobRepository.size() == 0 && !isOverWaitTime(waitTime, startTimeMillis) && workerState.isStarted()) { + try { + lock.wait(waitUnitTime); + } catch (InterruptedException e) { + + } + } + + if (isOverWaitTime(waitTime, startTimeMillis)) { + return false; + } + + return true; + } + } + + private boolean isOverWaitTime(long waitTimeMillis, long startTimeMillis) { + return waitTimeMillis < (System.currentTimeMillis() - startTimeMillis); + } + + private Iterator getLatestJobRepositoryKeyIterator() { + synchronized (lock) { + return latestJobRepository.keySet().iterator(); + } + } + + // 상당히 민감한 api임 Runnable에서만 사용해야함 + private Job getJob(ChannelContext channelContext) { + synchronized (lock) { + Job job = latestJobRepository.remove(channelContext); + return job; + } + + } + + public void putJob(Job job) { + if (job.getMaxRetryCount() < job.getCurrentRetryCount()) { + if (logger.isInfoEnabled()) { + logger.warn("Leack Job Queue Register Job={}.", job); + } + leakJobQueue.add(job); + return; + } + + synchronized (lock) { + ChannelContext channelContext = job.getChannelContext(); + + latestJobRepository.put(channelContext, job); + lock.notifyAll(); + } + } + + private String getUniquePath(ChannelContext channelContext, boolean create) { + synchronized (znodeMappingRepository) { + String zNodePath = znodeMappingRepository.get(channelContext); + + if (!create) { + return zNodePath; + } + + if (zNodePath == null) { + Map agentProperties = channelContext.getChannelProperties(); + final String applicationName = MapUtils.getString(agentProperties, AgentPropertiesType.APPLICATION_NAME.getName()); + final String agentId = MapUtils.getString(agentProperties, AgentPropertiesType.AGENT_ID.getName()); + + if (StringUtils.isEmpty(applicationName) || StringUtils.isEmpty(agentId)) { + logger.warn("ApplicationName({}) and AgnetId({}) may not be null.", applicationName, agentId); + return null; + } + + String path = PINPOINT_PROFILER_CLUSTER_PATH + "/" + applicationName + "/" + agentId; + String zNodeName = createUniqueZnodeName(); + + zNodePath = bindingPathAndZnode(path, zNodeName); + znodeMappingRepository.put(channelContext, zNodePath); + + logger.info("Created Zookeeper UniqPath = {}", zNodePath); + } + + return zNodePath; + } + } + + private void removeUniquePath(ChannelContext channelContext) { + synchronized (znodeMappingRepository) { + String zNodePath = znodeMappingRepository.remove(channelContext); + if (zNodePath != null) { + logger.info("Deleted Zookeeper UniqPath = {}", zNodePath); + } + } + } + + private String createUniqueZnodeName() { + return identifier + "_" + sequntialId.getAndIncrement(); + } + + private String bindingPathAndZnode(String path, String znodeName) { + StringBuilder fullPath = new StringBuilder(); + + fullPath.append(path); + if (!path.endsWith(PATH_SEPRATOR)) { + fullPath.append(PATH_SEPRATOR); + } + fullPath.append(znodeName); + + return fullPath.toString(); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterManager.java new file mode 100644 index 000000000000..35b60d68443f --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterManager.java @@ -0,0 +1,200 @@ +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nhn.pinpoint.collector.cluster.ProfilerClusterPoint; +import com.nhn.pinpoint.collector.cluster.WorkerState; +import com.nhn.pinpoint.collector.cluster.WorkerStateContext; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.PinpointZookeeperException; +import com.nhn.pinpoint.collector.cluster.zookeeper.job.DeleteJob; +import com.nhn.pinpoint.collector.cluster.zookeeper.job.UpdateJob; +import com.nhn.pinpoint.collector.receiver.tcp.AgentPropertiesType; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; +import com.nhn.pinpoint.rpc.server.SocketChannelStateChangeEventListener; +import com.nhn.pinpoint.rpc.util.MapUtils; + +/** + * @author koo.taejin + */ +public class ZookeeperProfilerClusterManager implements SocketChannelStateChangeEventListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ZookeeperClient client; + private final ZookeeperLatestJobWorker worker; + + private final WorkerStateContext workerState; + + private final ProfilerClusterPoint clusterPoint; + + private final ObjectMapper objectmapper = new ObjectMapper(); + + // 단순하게 하자 그냥 RUN이면 등록 FINISHED면 경우 삭제 그외 skip + // 만약 상태가 안맞으면(?) 보정 들어가야 하는데 leak detector 같은걸 worker내부에 둘 까도 고민중 + // + // RUN_DUPLEX에서만 생성할수 있게 해야한다. + // 지금은 RUN 상대방의 상태를 알수 없는 상태이기 때문에 이상황에서 등록 + public ZookeeperProfilerClusterManager(ZookeeperClient client, String serverIdentifier, ProfilerClusterPoint clusterPoint) { + this.workerState = new WorkerStateContext(); + this.clusterPoint = clusterPoint; + + this.client = client; + this.worker = new ZookeeperLatestJobWorker(client, serverIdentifier); + } + + public void start() { + switch (this.workerState.getCurrentState()) { + case NEW: + if (this.workerState.changeStateInitializing()) { + logger.info("{} initialization started.", this.getClass().getSimpleName()); + + if (worker != null) { + worker.start(); + } + + workerState.changeStateStarted(); + logger.info("{} initialization completed.", this.getClass().getSimpleName()); + + break; + } + case INITIALIZING: + logger.info("{} already initializing.", this.getClass().getSimpleName()); + break; + case STARTED: + logger.info("{} already started.", this.getClass().getSimpleName()); + break; + case DESTROYING: + throw new IllegalStateException("Already destroying."); + case STOPPED: + throw new IllegalStateException("Already stopped."); + case ILLEGAL_STATE: + throw new IllegalStateException("Invalid State."); + } + } + + public void stop() { + if (!(this.workerState.changeStateDestroying())) { + WorkerState state = this.workerState.getCurrentState(); + + logger.info("{} already {}.", this.getClass().getSimpleName(), state.toString()); + return; + } + + logger.info("{} destorying started.", this.getClass().getSimpleName()); + + if (worker != null) { + worker.stop(); + } + + this.workerState.changeStateStoped(); + logger.info("{} destorying completed.", this.getClass().getSimpleName()); + + return; + + } + + @Override + public void eventPerformed(ChannelContext channelContext, PinpointServerSocketStateCode stateCode) { + if (workerState.isStarted()) { + logger.info("eventPerformed ChannelContext={}, State={}", channelContext, stateCode); + + Map agentProperties = channelContext.getChannelProperties(); + + // 현재는 AgentProperties에 값을 모를 경우 skip + if (skipAgent(agentProperties)) { + return; + } + + if (PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION == stateCode) { + byte[] contents = serializeContents(agentProperties, stateCode); + if (contents == null) { + return; + } + + UpdateJob job = new UpdateJob(channelContext, contents); + worker.putJob(job); + + clusterPoint.registerChannelContext(channelContext); + } else if (PinpointServerSocketStateCode.isFinished(stateCode)) { + DeleteJob job = new DeleteJob(channelContext); + worker.putJob(job); + + clusterPoint.unregisterChannelContext(channelContext); + } + } else { + WorkerState state = this.workerState.getCurrentState(); + logger.info("{} invalid state {}.", this.getClass().getSimpleName(), state.toString()); + return; + } + + } + + public Map getData(ChannelContext channelContext) { + byte[] contents = worker.getData(channelContext); + + if (contents == null) { + return Collections.emptyMap(); + } + + return deserializeContents(contents); + } + + public List getChildrenNode(String path, boolean watch) throws PinpointZookeeperException, InterruptedException { + if (client.exists(path)) { + return client.getChildrenNode(path, watch); + } else { + client.createPath(path); + return client.getChildrenNode(path, watch); + } + } + + public List getRegisteredChannelContextList() { + return worker.getRegisteredChannelContextList(); + } + + private boolean skipAgent(Map agentProperties) { + String applicationName = MapUtils.getString(agentProperties, AgentPropertiesType.APPLICATION_NAME.getName()); + String agentId = MapUtils.getString(agentProperties, AgentPropertiesType.AGENT_ID.getName()); + + if (StringUtils.isEmpty(applicationName) || StringUtils.isEmpty(agentId)) { + return true; + } + + return false; + } + + private byte[] serializeContents(Map agentProperties, PinpointServerSocketStateCode state) { + Map contents = new HashMap(); + contents.put("agent", agentProperties); + contents.put("state", state.name()); + + try { + return objectmapper.writeValueAsBytes(contents); + } catch (JsonProcessingException e) { + logger.warn(e.getMessage(), e); + } + + return null; + } + + private Map deserializeContents(byte[] contents) { + try { + return objectmapper.readValue(contents, Map.class); + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } + + return Collections.emptyMap(); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperUtils.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperUtils.java new file mode 100644 index 000000000000..e3dafaa411f6 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperUtils.java @@ -0,0 +1,47 @@ +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import org.apache.zookeeper.WatchedEvent; +import org.apache.zookeeper.Watcher.Event.EventType; +import org.apache.zookeeper.Watcher.Event.KeeperState; + +/** + * @author koo.taejin + */ +public final class ZookeeperUtils { + + // 나중에 commons-hbase 같은것이 생기면 그쪽에 포함하는 것도 방법일듯 + private ZookeeperUtils() { + } + + public static boolean isConnectedEvent(WatchedEvent event) { + KeeperState state = event.getState(); + EventType eventType = event.getType(); + + return isConnectedEvent(state, eventType); + } + + public static boolean isConnectedEvent(KeeperState state, EventType eventType) { + if ((state == KeeperState.SyncConnected || state == KeeperState.NoSyncConnected) && eventType == EventType.None) { + return true; + } else { + return false; + } + } + + + public static boolean isDisconnectedEvent(WatchedEvent event) { + KeeperState state = event.getState(); + EventType eventType = event.getType(); + + return isDisconnectedEvent(state, eventType); + } + + public static boolean isDisconnectedEvent(KeeperState state, EventType eventType) { + if ((state == KeeperState.Disconnected || state == KeeperState.Expired) && eventType == eventType.None) { + return true; + } else { + return false; + } + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperWebClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperWebClusterManager.java new file mode 100644 index 000000000000..927c669993fe --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperWebClusterManager.java @@ -0,0 +1,223 @@ +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.net.InetSocketAddress; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.collector.cluster.WebClusterPoint; +import com.nhn.pinpoint.collector.cluster.WorkerState; +import com.nhn.pinpoint.collector.cluster.WorkerStateContext; +import com.nhn.pinpoint.collector.cluster.zookeeper.exception.ConnectionException; +import com.nhn.pinpoint.common.util.NetUtils; +import com.nhn.pinpoint.common.util.PinpointThreadFactory; + +/** + * @author koo.taejin + */ +public class ZookeeperWebClusterManager implements Runnable { + + // 콜렉터 에서는 무한 retry를 해도됨 + // RETRY_INTERVAL을 받게만 하면 될듯 + private static final int DEFAULT_RETRY_INTERVAL = 10000; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final GetAndRegisterTask getAndRegisterTask = new GetAndRegisterTask(); + private final StopTask stopTask = new StopTask(); + + private final ZookeeperClient client; + private final WebClusterPoint webClusterPoint; + private final String zNodePath; + + private final AtomicBoolean retryMode = new AtomicBoolean(false); + + private final BlockingQueue queue = new LinkedBlockingQueue(1); + + private final WorkerStateContext workerState; + private final Thread workerThread; + + // private final Timer timer; + + // Worker + Job 등록 + // Job이 포함되면 실행. Job성공시 이후 Job 모두 삭제 + // 먼가 이상한 형태의 자료구조가 필요한거 같은데.... + + public ZookeeperWebClusterManager(ZookeeperClient client, String zookeeperClusterPath, String serverIdentifier, WebClusterPoint clusterPoint) { + this.client = client; + + this.webClusterPoint = clusterPoint; + this.zNodePath = zookeeperClusterPath; + + this.workerState = new WorkerStateContext(); + + final ThreadFactory threadFactory = new PinpointThreadFactory(this.getClass().getSimpleName(), true); + this.workerThread = threadFactory.newThread(this); + } + + public void start() { + switch (this.workerState.getCurrentState()) { + case NEW: + if (this.workerState.changeStateInitializing()) { + logger.info("{} initialization started.", this.getClass().getSimpleName()); + this.workerThread.start(); + + workerState.changeStateStarted(); + logger.info("{} initialization completed.", this.getClass().getSimpleName()); + break; + } + case INITIALIZING: + logger.info("{} already initializing.", this.getClass().getSimpleName()); + break; + case STARTED: + logger.info("{} already started.", this.getClass().getSimpleName()); + break; + case DESTROYING: + throw new IllegalStateException("Already destroying."); + case STOPPED: + throw new IllegalStateException("Already stopped."); + case ILLEGAL_STATE: + throw new IllegalStateException("Invalid State."); + } + } + + public void stop() { + if (!(this.workerState.changeStateDestroying())) { + WorkerState state = this.workerState.getCurrentState(); + + logger.info("{} already {}.", this.getClass().getSimpleName(), state.toString()); + return; + } + + logger.info("{} destorying started.", this.getClass().getSimpleName()); + + queue.offer(stopTask); + + boolean interrupted = false; + while (this.workerThread.isAlive()) { + this.workerThread.interrupt(); + try { + this.workerThread.join(100L); + } catch (InterruptedException e) { + interrupted = true; + } + } + + this.workerState.changeStateStoped(); + logger.info("{} destorying completed.", this.getClass().getSimpleName()); + + return; + } + + // NoNode인 경우 Node생성후 재 호출 + // Timeout인 경우 스케쥴 걸어서 재요청 + // 그외는 그대로 둠 + public void handleAndRegisterWatcher(String path) { + if (workerState.isStarted()) { + if (zNodePath.equals(path)) { + boolean offerSuccess = queue.offer(getAndRegisterTask); + + if (!offerSuccess) { + logger.info("Message Queue is Full."); + } + } else { + logger.info("Invald Path {}.", path); + } + } else { + WorkerState state = this.workerState.getCurrentState(); + logger.info("{} invalid state {}.", this.getClass().getSimpleName(), state.toString()); + return; + } + } + + @Override + public void run() { + while (workerState.isStarted()) { + Task task = null; + + try { + task = queue.poll(DEFAULT_RETRY_INTERVAL, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + logger.debug(e.getMessage(), e); + } + + if (!workerState.isStarted()) { + break; + } + + if (task == null) { + if (retryMode.get()) { + boolean success = getAndRegisterTask.handleAndRegisterWatcher0(); + if (success) { + retryMode.compareAndSet(true, false); + } + } + } else if (task instanceof GetAndRegisterTask) { + boolean success = ((GetAndRegisterTask) task).handleAndRegisterWatcher0(); + if (!success) { + retryMode.compareAndSet(false, true); + } + } else if (task instanceof StopTask) { + break; + } + } + + logger.info("{} stopped", this.getClass().getSimpleName()); + } + + interface Task { + + } + + class GetAndRegisterTask implements Task { + + private boolean handleAndRegisterWatcher0() { + boolean needNotRetry = false; + try { + + if (!client.exists(zNodePath)) { + client.createPath(zNodePath, true); + } + + List childNodeList = client.getChildrenNode(zNodePath, true); + List clusterAddressList = NetUtils.toInetSocketAddressLIst(childNodeList); + + List addressList = webClusterPoint.getWebClusterList(); + + logger.info("Handle register and remove Task. Current Address List = {}, Cluster Address List = {}", addressList, clusterAddressList); + + for (InetSocketAddress clusterAddress : clusterAddressList) { + if (!addressList.contains(clusterAddress)) { + webClusterPoint.connectPointIfAbsent(clusterAddress); + } + } + + for (InetSocketAddress address : addressList) { + if (!clusterAddressList.contains(address)) { + webClusterPoint.disconnectPoint(address); + } + } + + needNotRetry = true; + return needNotRetry; + } catch (Exception e) { + if (!(e instanceof ConnectionException)) { + needNotRetry = true; + } + } + + return needNotRetry; + } + } + + class StopTask implements Task { + + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/AuthException.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/AuthException.java index 7fcee00474da..9899f5b86b08 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/AuthException.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/AuthException.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.exception; - -/** - * @author koo.taejin - */ -public class AuthException extends PinpointZookeeperException { - - public AuthException() { - } - - public AuthException(String message) { - super(message); - } - - public AuthException(String message, Throwable cause) { - super(message, cause); - } - - public AuthException(Throwable cause) { - super(cause); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.exception; + +/** + * @author koo.taejin + */ +public class AuthException extends PinpointZookeeperException { + + public AuthException() { + } + + public AuthException(String message) { + super(message); + } + + public AuthException(String message, Throwable cause) { + super(message, cause); + } + + public AuthException(Throwable cause) { + super(cause); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/BadOperationException.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/BadOperationException.java index cfd48f804abc..5e0fdac15e23 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/BadOperationException.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/BadOperationException.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.exception; - -/** - * @author koo.taejin - */ -public class BadOperationException extends PinpointZookeeperException { - - public BadOperationException() { - } - - public BadOperationException(String message) { - super(message); - } - - public BadOperationException(String message, Throwable cause) { - super(message, cause); - } - - public BadOperationException(Throwable cause) { - super(cause); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.exception; + +/** + * @author koo.taejin + */ +public class BadOperationException extends PinpointZookeeperException { + + public BadOperationException() { + } + + public BadOperationException(String message) { + super(message); + } + + public BadOperationException(String message, Throwable cause) { + super(message, cause); + } + + public BadOperationException(Throwable cause) { + super(cause); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/ConnectionException.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/ConnectionException.java index 5e347edffc0a..cceaec2890d8 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/ConnectionException.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/ConnectionException.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.exception; - -/** - * @author koo.taejin - */ -public class ConnectionException extends PinpointZookeeperException { - - public ConnectionException() { - } - - public ConnectionException(String message) { - super(message); - } - - public ConnectionException(String message, Throwable cause) { - super(message, cause); - } - - public ConnectionException(Throwable cause) { - super(cause); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.exception; + +/** + * @author koo.taejin + */ +public class ConnectionException extends PinpointZookeeperException { + + public ConnectionException() { + } + + public ConnectionException(String message) { + super(message); + } + + public ConnectionException(String message, Throwable cause) { + super(message, cause); + } + + public ConnectionException(Throwable cause) { + super(cause); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/PinpointZookeeperException.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/PinpointZookeeperException.java index 12565bb48a8f..d5337a44e97b 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/PinpointZookeeperException.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/PinpointZookeeperException.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.exception; - -/** - * @author koo.taejin - */ -public class PinpointZookeeperException extends Exception { - - public PinpointZookeeperException() { - } - - public PinpointZookeeperException(String message) { - super(message); - } - - public PinpointZookeeperException(String message, Throwable cause) { - super(message, cause); - } - - public PinpointZookeeperException(Throwable cause) { - super(cause); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.exception; + +/** + * @author koo.taejin + */ +public class PinpointZookeeperException extends Exception { + + public PinpointZookeeperException() { + } + + public PinpointZookeeperException(String message) { + super(message); + } + + public PinpointZookeeperException(String message, Throwable cause) { + super(message, cause); + } + + public PinpointZookeeperException(Throwable cause) { + super(cause); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/TimeoutException.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/TimeoutException.java index 6caed139b464..d84771053d99 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/TimeoutException.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/TimeoutException.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.exception; - -/** - * @author koo.taejin - */ -public class TimeoutException extends PinpointZookeeperException { - - public TimeoutException() { - } - - public TimeoutException(String message) { - super(message); - } - - public TimeoutException(String message, Throwable cause) { - super(message, cause); - } - - public TimeoutException(Throwable cause) { - super(cause); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.exception; + +/** + * @author koo.taejin + */ +public class TimeoutException extends PinpointZookeeperException { + + public TimeoutException() { + } + + public TimeoutException(String message) { + super(message); + } + + public TimeoutException(String message, Throwable cause) { + super(message, cause); + } + + public TimeoutException(Throwable cause) { + super(cause); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/UnknownException.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/UnknownException.java index 5713ff16beb8..75bf1c9029c0 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/UnknownException.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/exception/UnknownException.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.exception; - -/** - * @author koo.taejin - */ -public class UnknownException extends PinpointZookeeperException { - - public UnknownException() { - } - - public UnknownException(String message) { - super(message); - } - - public UnknownException(String message, Throwable cause) { - super(message, cause); - } - - public UnknownException(Throwable cause) { - super(cause); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.exception; + +/** + * @author koo.taejin + */ +public class UnknownException extends PinpointZookeeperException { + + public UnknownException() { + } + + public UnknownException(String message) { + super(message); + } + + public UnknownException(String message, Throwable cause) { + super(message, cause); + } + + public UnknownException(Throwable cause) { + super(cause); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/AbstractJob.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/AbstractJob.java index 7f54775bcbab..2c87c8704c8b 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/AbstractJob.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/AbstractJob.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.job; - -import java.util.concurrent.atomic.AtomicInteger; - -import com.nhn.pinpoint.rpc.server.ChannelContext; - -public class AbstractJob implements Job { - - private final ChannelContext channelContext; - - private final int maxCount; - private final AtomicInteger currentCount; - - public AbstractJob(ChannelContext channelContext) { - this(channelContext, 3); - } - - public AbstractJob(ChannelContext channelContext, int maxCount) { - this.channelContext = channelContext; - - this.maxCount = maxCount; - this.currentCount = new AtomicInteger(0); - } - - @Override - public ChannelContext getChannelContext() { - return channelContext; - } - - @Override - public int getMaxRetryCount() { - return maxCount; - } - - @Override - public int getCurrentRetryCount() { - return currentCount.get(); - } - - @Override - public void incrementCurrentRetryCount() { - currentCount.incrementAndGet(); - } - - @Override - public String toString() { - StringBuilder toString = new StringBuilder(); - toString.append(this.getClass().getSimpleName()); - toString.append(", ChannelContext=" + channelContext); - toString.append(", Retry=" + currentCount.get() + "/" + maxCount); - - return toString.toString(); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.job; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.nhn.pinpoint.rpc.server.ChannelContext; + +public class AbstractJob implements Job { + + private final ChannelContext channelContext; + + private final int maxCount; + private final AtomicInteger currentCount; + + public AbstractJob(ChannelContext channelContext) { + this(channelContext, 3); + } + + public AbstractJob(ChannelContext channelContext, int maxCount) { + this.channelContext = channelContext; + + this.maxCount = maxCount; + this.currentCount = new AtomicInteger(0); + } + + @Override + public ChannelContext getChannelContext() { + return channelContext; + } + + @Override + public int getMaxRetryCount() { + return maxCount; + } + + @Override + public int getCurrentRetryCount() { + return currentCount.get(); + } + + @Override + public void incrementCurrentRetryCount() { + currentCount.incrementAndGet(); + } + + @Override + public String toString() { + StringBuilder toString = new StringBuilder(); + toString.append(this.getClass().getSimpleName()); + toString.append(", ChannelContext=" + channelContext); + toString.append(", Retry=" + currentCount.get() + "/" + maxCount); + + return toString.toString(); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/DeleteJob.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/DeleteJob.java index c82260466e6f..c5da3d836a39 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/DeleteJob.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/DeleteJob.java @@ -1,14 +1,14 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.job; - -import com.nhn.pinpoint.rpc.server.ChannelContext; - -/** - * @author koo.taejin - */ -public class DeleteJob extends AbstractJob { - - public DeleteJob(ChannelContext channelContext) { - super(channelContext); - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.job; + +import com.nhn.pinpoint.rpc.server.ChannelContext; + +/** + * @author koo.taejin + */ +public class DeleteJob extends AbstractJob { + + public DeleteJob(ChannelContext channelContext) { + super(channelContext); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/Job.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/Job.java index d3b9b1334052..d609f7048b87 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/Job.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/Job.java @@ -1,19 +1,19 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.job; - -import com.nhn.pinpoint.rpc.server.ChannelContext; - -/** - * @author koo.taejin - */ -public interface Job { - - - ChannelContext getChannelContext(); - - int getMaxRetryCount(); - - int getCurrentRetryCount(); - - void incrementCurrentRetryCount(); - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.job; + +import com.nhn.pinpoint.rpc.server.ChannelContext; + +/** + * @author koo.taejin + */ +public interface Job { + + + ChannelContext getChannelContext(); + + int getMaxRetryCount(); + + int getCurrentRetryCount(); + + void incrementCurrentRetryCount(); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/UpdateJob.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/UpdateJob.java index 6724862fd1d5..d69d052c9992 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/UpdateJob.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/UpdateJob.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.collector.cluster.zookeeper.job; - -import com.nhn.pinpoint.rpc.server.ChannelContext; - -/** - * @author koo.taejin - */ -public class UpdateJob extends AbstractJob { - - private final byte[] contents; - - public UpdateJob(ChannelContext channelContext, byte[] contents) { - super(channelContext); - this.contents = contents; - } - - public UpdateJob(ChannelContext channelContext, int maxRetryCount, byte[] contents) { - super(channelContext, maxRetryCount); - this.contents = contents; - } - - public byte[] getContents() { - return contents; - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper.job; + +import com.nhn.pinpoint.rpc.server.ChannelContext; + +/** + * @author koo.taejin + */ +public class UpdateJob extends AbstractJob { + + private final byte[] contents; + + public UpdateJob(ChannelContext channelContext, byte[] contents) { + super(channelContext); + this.contents = contents; + } + + public UpdateJob(ChannelContext channelContext, int maxRetryCount, byte[] contents) { + super(channelContext, maxRetryCount); + this.contents = contents; + } + + public byte[] getContents() { + return contents; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorBeanConfiguration.java b/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorBeanConfiguration.java new file mode 100644 index 000000000000..d2783e77d219 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorBeanConfiguration.java @@ -0,0 +1,52 @@ +package com.nhn.pinpoint.collector.config; + +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.protocol.TProtocolFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +import com.nhn.pinpoint.common.Version; +import com.nhn.pinpoint.thrift.io.DeserializerFactory; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; +import com.nhn.pinpoint.thrift.io.SerializerFactory; +import com.nhn.pinpoint.thrift.io.TBaseLocator; +import com.nhn.pinpoint.thrift.io.TCommandRegistry; +import com.nhn.pinpoint.thrift.io.TCommandTypeVersion; +import com.nhn.pinpoint.thrift.io.ThreadLocalHeaderTBaseDeserializerFactory; +import com.nhn.pinpoint.thrift.io.ThreadLocalHeaderTBaseSerializerFactory; + +/** + * @author koo.taejin + */ +@Configuration +public class CollectorBeanConfiguration { + + public static final int DEFAULT_SERIALIZER_MAX_SIZE = 1024 * 64; + + @Bean + @Scope(value = "singleton") + public SerializerFactory commandSerializerFactory() { + TBaseLocator commandTbaseLocator = new TCommandRegistry(TCommandTypeVersion.getVersion(Version.VERSION)); + + TProtocolFactory protocolFactory = new TCompactProtocol.Factory(); + HeaderTBaseSerializerFactory serializerFactory = new HeaderTBaseSerializerFactory(true, DEFAULT_SERIALIZER_MAX_SIZE, protocolFactory, commandTbaseLocator); + + ThreadLocalHeaderTBaseSerializerFactory threadLocalSerializerFactory = new ThreadLocalHeaderTBaseSerializerFactory(serializerFactory); + return threadLocalSerializerFactory; + } + + @Bean + @Scope(value = "singleton") + public DeserializerFactory commandDeserializerFactory() { + TBaseLocator commandTbaseLocator = new TCommandRegistry(TCommandTypeVersion.getVersion(Version.VERSION)); + + TProtocolFactory protocolFactory = new TCompactProtocol.Factory(); + HeaderTBaseDeserializerFactory deserializerFactory = new HeaderTBaseDeserializerFactory(protocolFactory, commandTbaseLocator); + + ThreadLocalHeaderTBaseDeserializerFactory threadLocalDeserializerFactory = new ThreadLocalHeaderTBaseDeserializerFactory(deserializerFactory); + return threadLocalDeserializerFactory; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorConfiguration.java b/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorConfiguration.java index 59ca5c0abb01..dc3299b1382e 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorConfiguration.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorConfiguration.java @@ -17,6 +17,9 @@ public class CollectorConfiguration implements InitializingBean { private final Logger logger = LoggerFactory.getLogger(this.getClass()); +// cluster.zookeeper.address=dev.zk.pinpoint.navercorp.com +// cluster.zookeeper.sessiontimeout=3000 + private static final String CONFIG_FILE_NAME = "pinpoint-collector.properties"; private static final String DEFAULT_LISTEN_IP = "0.0.0.0"; @@ -44,6 +47,9 @@ public void setProperties(Properties properties) { private int udpSpanWorkerQueueSize; private int udpSpanSocketReceiveBufferSize; + private boolean clusterEnable; + private String clusterAddress; + private int clusterSessionTimeout; public String getTcpListenIp() { return tcpListenIp; @@ -108,6 +114,29 @@ public void setUdpSpanSocketReceiveBufferSize(int udpSpanSocketReceiveBufferSize this.udpSpanSocketReceiveBufferSize = udpSpanSocketReceiveBufferSize; } + public boolean isClusterEnable() { + return clusterEnable; + } + + public void setClusterEnable(boolean clusterEnable) { + this.clusterEnable = clusterEnable; + } + + public String getClusterAddress() { + return clusterAddress; + } + + public void setClusterAddress(String clusterAddress) { + this.clusterAddress = clusterAddress; + } + + public int getClusterSessionTimeout() { + return clusterSessionTimeout; + } + + public void setClusterSessionTimeout(int clusterSessionTimeout) { + this.clusterSessionTimeout = clusterSessionTimeout; + } public void readConfigFile() { // testcase와 같이 단독으로 사용할 경우 해당 api를 사용하면 좋을듯. testcase에서 쓸려면 classpath를 읽도록 고쳐야 될거임. @@ -118,7 +147,7 @@ public void readConfigFile() { } try { - Properties prop = PropertyUtils.readProperties(configFileName); + Properties prop = PropertyUtils.loadProperty(configFileName); readPropertyValues(prop); } catch (FileNotFoundException fe) { logger.error("File '{}' is not exists. Please check configuration.", configFileName, fe); @@ -154,6 +183,10 @@ private void readPropertyValues(Properties properties) { this.udpSpanWorkerThread = readInt(properties, "collector.udpSpanWorkerThread", 256); this.udpSpanWorkerQueueSize = readInt(properties, "collector.udpSpanWorkerQueueSize", 1024 * 5); this.udpSpanSocketReceiveBufferSize = readInt(properties, "collector.udpSpanSocketReceiveBufferSize", 1024 * 4096); + + this.clusterEnable = readBoolen(properties, "cluster.enable"); + this.clusterAddress = readString(properties, "cluster.zookeeper.address", ""); + this.clusterSessionTimeout = readInt(properties, "cluster.zookeeper.sessiontimeout", -1); } private String readString(Properties properties, String propertyName, String defaultValue) { @@ -173,6 +206,18 @@ private int readInt(Properties properties, String propertyName, int defaultValue } return result; } + + private boolean readBoolen(Properties properties, String propertyName) { + final String value = properties.getProperty(propertyName); + + // true 문자열인 경우만 true 그외는 모두 false + // 이후 default value가 필요할 경우, Utils 대신 문자열 매칭으로 해야할듯 현재는 필요없기 떄문에 그냥 둠 + boolean result = Boolean.valueOf(value); + if (logger.isInfoEnabled()) { + logger.info("{}={}", propertyName, result); + } + return result; + } @Override public String toString() { @@ -189,7 +234,12 @@ public String toString() { sb.append(", udpSpanWorkerThread=").append(udpSpanWorkerThread); sb.append(", udpSpanWorkerQueueSize=").append(udpSpanWorkerQueueSize); sb.append(", udpSpanSocketReceiveBufferSize=").append(udpSpanSocketReceiveBufferSize); + sb.append(", clusterEnable=").append(clusterEnable); + sb.append(", clusterAddress=").append(clusterAddress); + sb.append(", clusterSessionTimeout=").append(clusterSessionTimeout); + sb.append('}'); return sb.toString(); } + } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentInfoDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentInfoDao.java index 2b1183765877..de1f06d44b6a 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentInfoDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentInfoDao.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.collector.dao; - -import com.nhn.pinpoint.thrift.dto.TAgentInfo; - -/** - * @author emeroad - */ -public interface AgentInfoDao { - void insert(TAgentInfo agentInfo); -} +package com.nhn.pinpoint.collector.dao; + +import com.nhn.pinpoint.thrift.dto.TAgentInfo; + +/** + * @author emeroad + */ +public interface AgentInfoDao { + void insert(TAgentInfo agentInfo); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/ApiMetaDataDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/ApiMetaDataDao.java index 26c7b2f6b64d..4876e412c199 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/ApiMetaDataDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/ApiMetaDataDao.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.collector.dao; - -import com.nhn.pinpoint.thrift.dto.TApiMetaData; - -/** - * @author emeroad - */ -public interface ApiMetaDataDao { - - void insert(TApiMetaData apiMetaData); -} +package com.nhn.pinpoint.collector.dao; + +import com.nhn.pinpoint.thrift.dto.TApiMetaData; + +/** + * @author emeroad + */ +public interface ApiMetaDataDao { + + void insert(TApiMetaData apiMetaData); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/HostApplicationMapDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/HostApplicationMapDao.java index 71e998ac65eb..d313b5592b07 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/HostApplicationMapDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/HostApplicationMapDao.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.collector.dao; - -/** - * - * @author netspider - * - */ -public interface HostApplicationMapDao { - void insert(String host, String bindApplicationName, short bindServiceType, String parentApplicationName, short parentServiceType); -} +package com.nhn.pinpoint.collector.dao; + +/** + * + * @author netspider + * + */ +public interface HostApplicationMapDao { + void insert(String host, String bindApplicationName, short bindServiceType, String parentApplicationName, short parentServiceType); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapResponseTimeDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapResponseTimeDao.java index f992bdb44ef7..53e77b103ac9 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapResponseTimeDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapResponseTimeDao.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.collector.dao; - -/** - * @author emeroad - */ -public interface MapResponseTimeDao extends CachedStatisticsDao { - void received(String applicationName, short serviceType, String agentId, int elapsed, boolean isError); -} +package com.nhn.pinpoint.collector.dao; + +/** + * @author emeroad + */ +public interface MapResponseTimeDao extends CachedStatisticsDao { + void received(String applicationName, short serviceType, String agentId, int elapsed, boolean isError); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCalleeDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCalleeDao.java index abe9a1f55739..5b41643c8a64 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCalleeDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCalleeDao.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.collector.dao; - -/** - * - * @author netspider - * @author emeroad - */ -public interface MapStatisticsCalleeDao extends CachedStatisticsDao { - void update(String calleeApplicationName, short calleeServiceType, String callerApplicationName, short callerServiceType, String callerHost, int elapsed, boolean isError); -} +package com.nhn.pinpoint.collector.dao; + +/** + * + * @author netspider + * @author emeroad + */ +public interface MapStatisticsCalleeDao extends CachedStatisticsDao { + void update(String calleeApplicationName, short calleeServiceType, String callerApplicationName, short callerServiceType, String callerHost, int elapsed, boolean isError); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCallerDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCallerDao.java index a70b303162c2..e1c7f0e74d0c 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCallerDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/MapStatisticsCallerDao.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.collector.dao; - -/** - * - * @author netspider - * @author emeroad - */ -public interface MapStatisticsCallerDao extends CachedStatisticsDao { - void update(String callerApplicationName, short callerServiceType, String callerAgentId, String calleeApplicationName, short calleeServiceType, String calleeHost, int elapsed, boolean isError); -} +package com.nhn.pinpoint.collector.dao; + +/** + * + * @author netspider + * @author emeroad + */ +public interface MapStatisticsCallerDao extends CachedStatisticsDao { + void update(String callerApplicationName, short callerServiceType, String callerAgentId, String calleeApplicationName, short calleeServiceType, String calleeHost, int elapsed, boolean isError); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/SqlMetaDataDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/SqlMetaDataDao.java index 1ed4c005f9ec..4c6649c510e2 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/SqlMetaDataDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/SqlMetaDataDao.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.collector.dao; - -import com.nhn.pinpoint.thrift.dto.TSqlMetaData; - -/** - * @author emeroad - */ -public interface SqlMetaDataDao { - void insert(TSqlMetaData sqlMetaData); -} +package com.nhn.pinpoint.collector.dao; + +import com.nhn.pinpoint.thrift.dto.TSqlMetaData; + +/** + * @author emeroad + */ +public interface SqlMetaDataDao { + void insert(TSqlMetaData sqlMetaData); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/StringMetaDataDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/StringMetaDataDao.java index a7aa4f1d3dd4..5f68b489ec4a 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/StringMetaDataDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/StringMetaDataDao.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.collector.dao; - -import com.nhn.pinpoint.thrift.dto.TStringMetaData; - -/** - * @author emeroad - */ -public interface StringMetaDataDao { - - void insert(TStringMetaData stringMetaData); -} +package com.nhn.pinpoint.collector.dao; + +import com.nhn.pinpoint.thrift.dto.TStringMetaData; + +/** + * @author emeroad + */ +public interface StringMetaDataDao { + + void insert(TStringMetaData stringMetaData); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TracesDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TracesDao.java index 3d293e56065f..1c3a1997d658 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TracesDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TracesDao.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.collector.dao; - -import com.nhn.pinpoint.thrift.dto.TSpan; -import com.nhn.pinpoint.thrift.dto.TSpanChunk; - -/** - * @author emeroad - */ -public interface TracesDao { - void insert(TSpan span); - - void insertSpanChunk(TSpanChunk spanChunk); -} +package com.nhn.pinpoint.collector.dao; + +import com.nhn.pinpoint.thrift.dto.TSpan; +import com.nhn.pinpoint.thrift.dto.TSpanChunk; + +/** + * @author emeroad + */ +public interface TracesDao { + void insert(TSpan span); + + void insertSpanChunk(TSpanChunk spanChunk); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentInfoDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentInfoDao.java index e3c781e5dc57..6881bb5ada8e 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentInfoDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentInfoDao.java @@ -1,52 +1,52 @@ -package com.nhn.pinpoint.collector.dao.hbase; - -import com.nhn.pinpoint.thrift.dto.TAgentInfo; -import org.apache.hadoop.hbase.client.Put; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.common.util.RowKeyUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.collector.dao.AgentInfoDao; -import org.springframework.stereotype.Repository; - -/** - * @author emeroad - */ -@Repository -public class HbaseAgentInfoDao implements AgentInfoDao { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private HbaseOperations2 hbaseTemplate; - - @Override - public void insert(TAgentInfo agentInfo) { - if (agentInfo == null) { - throw new NullPointerException("agentInfo must not be null"); - } - - if (logger.isDebugEnabled()) { - logger.debug("insert agent info. {}", agentInfo); - } - - byte[] agentId = Bytes.toBytes(agentInfo.getAgentId()); - long reverseKey = TimeUtils.reverseTimeMillis(agentInfo.getStartTimestamp()); - byte[] rowKey = RowKeyUtils.concatFixedByteAndLong(agentId, HBaseTables.AGENT_NAME_MAX_LEN, reverseKey); - Put put = new Put(rowKey); - - // 추가 agent 정보를 넣어야 됨. 일단 sqlMetaData에 필요한 starttime만 넣음. - AgentInfoBo agentInfoBo = new AgentInfoBo(agentInfo); - byte[] bytes = agentInfoBo.writeValue(); - - put.add(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER, bytes); - - hbaseTemplate.put(HBaseTables.AGENTINFO, put); - } -} +package com.nhn.pinpoint.collector.dao.hbase; + +import com.nhn.pinpoint.thrift.dto.TAgentInfo; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.common.util.RowKeyUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.collector.dao.AgentInfoDao; +import org.springframework.stereotype.Repository; + +/** + * @author emeroad + */ +@Repository +public class HbaseAgentInfoDao implements AgentInfoDao { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private HbaseOperations2 hbaseTemplate; + + @Override + public void insert(TAgentInfo agentInfo) { + if (agentInfo == null) { + throw new NullPointerException("agentInfo must not be null"); + } + + if (logger.isDebugEnabled()) { + logger.debug("insert agent info. {}", agentInfo); + } + + byte[] agentId = Bytes.toBytes(agentInfo.getAgentId()); + long reverseKey = TimeUtils.reverseTimeMillis(agentInfo.getStartTimestamp()); + byte[] rowKey = RowKeyUtils.concatFixedByteAndLong(agentId, HBaseTables.AGENT_NAME_MAX_LEN, reverseKey); + Put put = new Put(rowKey); + + // 추가 agent 정보를 넣어야 됨. 일단 sqlMetaData에 필요한 starttime만 넣음. + AgentInfoBo agentInfoBo = new AgentInfoBo(agentInfo); + byte[] bytes = agentInfoBo.writeValue(); + + put.add(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER, bytes); + + hbaseTemplate.put(HBaseTables.AGENTINFO, put); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApiMetaDataDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApiMetaDataDao.java index 98956d341598..72a78c8cfdcc 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApiMetaDataDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApiMetaDataDao.java @@ -1,63 +1,63 @@ -package com.nhn.pinpoint.collector.dao.hbase; - -import com.nhn.pinpoint.common.bo.ApiMetaDataBo; -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.thrift.dto.TApiMetaData; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.collector.dao.ApiMetaDataDao; -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.client.Put; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Repository; - -/** - * @author emeroad - */ -@Repository -public class HbaseApiMetaDataDao implements ApiMetaDataDao { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private HbaseOperations2 hbaseTemplate; - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public void insert(TApiMetaData apiMetaData) { - if (logger.isDebugEnabled()) { - logger.debug("insert:{}", apiMetaData); - } - - - ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo(apiMetaData.getAgentId(), apiMetaData.getAgentStartTime(), apiMetaData.getApiId()); - byte[] rowKey = getDistributedKey(apiMetaDataBo.toRowKey()); - - final Put put = new Put(rowKey); - - final Buffer buffer = new AutomaticBuffer(64); - String api = apiMetaData.getApiInfo(); - buffer.putPrefixedString(api); - if (apiMetaData.isSetLine()) { - buffer.put(apiMetaData.getLine()); - } else { - buffer.put(-1); - } - final byte[] apiMetaDataBytes = buffer.getBuffer(); - put.add(HBaseTables.API_METADATA_CF_API, apiMetaDataBytes, null); - - hbaseTemplate.put(HBaseTables.API_METADATA, put); - } - - private byte[] getDistributedKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); - } -} +package com.nhn.pinpoint.collector.dao.hbase; + +import com.nhn.pinpoint.common.bo.ApiMetaDataBo; +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.thrift.dto.TApiMetaData; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.collector.dao.ApiMetaDataDao; +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.client.Put; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Repository; + +/** + * @author emeroad + */ +@Repository +public class HbaseApiMetaDataDao implements ApiMetaDataDao { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private HbaseOperations2 hbaseTemplate; + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public void insert(TApiMetaData apiMetaData) { + if (logger.isDebugEnabled()) { + logger.debug("insert:{}", apiMetaData); + } + + + ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo(apiMetaData.getAgentId(), apiMetaData.getAgentStartTime(), apiMetaData.getApiId()); + byte[] rowKey = getDistributedKey(apiMetaDataBo.toRowKey()); + + final Put put = new Put(rowKey); + + final Buffer buffer = new AutomaticBuffer(64); + String api = apiMetaData.getApiInfo(); + buffer.putPrefixedString(api); + if (apiMetaData.isSetLine()) { + buffer.put(apiMetaData.getLine()); + } else { + buffer.put(-1); + } + final byte[] apiMetaDataBytes = buffer.getBuffer(); + put.add(HBaseTables.API_METADATA_CF_API, apiMetaDataBytes, null); + + hbaseTemplate.put(HBaseTables.API_METADATA, put); + } + + private byte[] getDistributedKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseSqlMetaDataDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseSqlMetaDataDao.java index 05ab5d8d8baa..55e7f8aa43ba 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseSqlMetaDataDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseSqlMetaDataDao.java @@ -1,58 +1,58 @@ -package com.nhn.pinpoint.collector.dao.hbase; - -import com.nhn.pinpoint.common.bo.SqlMetaDataBo; -import com.nhn.pinpoint.thrift.dto.TSqlMetaData; -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.client.Put; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.collector.dao.SqlMetaDataDao; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Repository; - -/** - * @author emeroad - */ -@Repository -public class HbaseSqlMetaDataDao implements SqlMetaDataDao { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private HbaseOperations2 hbaseTemplate; - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public void insert(TSqlMetaData sqlMetaData) { - if (sqlMetaData == null) { - throw new NullPointerException("sqlMetaData must not be null"); - } - if (logger.isDebugEnabled()) { - logger.debug("insert:{}", sqlMetaData); - } - - SqlMetaDataBo sqlMetaDataBo = new SqlMetaDataBo(sqlMetaData.getAgentId(), sqlMetaData.getAgentStartTime(), sqlMetaData.getSqlId()); - final byte[] rowKey = getDistributedKey(sqlMetaDataBo.toRowKey()); - - - Put put = new Put(rowKey); - String sql = sqlMetaData.getSql(); - byte[] sqlBytes = Bytes.toBytes(sql); - // hashCode가 충돌날수 있으므로 일부러 qualifier에 넣음. - put.add(HBaseTables.SQL_METADATA_CF_SQL, sqlBytes, null); - - hbaseTemplate.put(HBaseTables.SQL_METADATA, put); - } - - private byte[] getDistributedKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); - } -} +package com.nhn.pinpoint.collector.dao.hbase; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import com.nhn.pinpoint.thrift.dto.TSqlMetaData; +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.collector.dao.SqlMetaDataDao; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Repository; + +/** + * @author emeroad + */ +@Repository +public class HbaseSqlMetaDataDao implements SqlMetaDataDao { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private HbaseOperations2 hbaseTemplate; + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public void insert(TSqlMetaData sqlMetaData) { + if (sqlMetaData == null) { + throw new NullPointerException("sqlMetaData must not be null"); + } + if (logger.isDebugEnabled()) { + logger.debug("insert:{}", sqlMetaData); + } + + SqlMetaDataBo sqlMetaDataBo = new SqlMetaDataBo(sqlMetaData.getAgentId(), sqlMetaData.getAgentStartTime(), sqlMetaData.getSqlId()); + final byte[] rowKey = getDistributedKey(sqlMetaDataBo.toRowKey()); + + + Put put = new Put(rowKey); + String sql = sqlMetaData.getSql(); + byte[] sqlBytes = Bytes.toBytes(sql); + // hashCode가 충돌날수 있으므로 일부러 qualifier에 넣음. + put.add(HBaseTables.SQL_METADATA_CF_SQL, sqlBytes, null); + + hbaseTemplate.put(HBaseTables.SQL_METADATA, put); + } + + private byte[] getDistributedKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseStringMetaDataDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseStringMetaDataDao.java index 4c318bc655a0..a7671eccc8a2 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseStringMetaDataDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseStringMetaDataDao.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.collector.dao.hbase; - -import com.nhn.pinpoint.collector.dao.StringMetaDataDao; -import com.nhn.pinpoint.common.bo.StringMetaDataBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.thrift.dto.TStringMetaData; -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.client.Put; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Repository; - -/** - * @author emeroad - */ -@Repository -public class HbaseStringMetaDataDao implements StringMetaDataDao { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private HbaseOperations2 hbaseTemplate; - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public void insert(TStringMetaData stringMetaData) { - if (stringMetaData == null) { - throw new NullPointerException("stringMetaData must not be null"); - } - if (logger.isDebugEnabled()) { - logger.debug("insert:{}", stringMetaData); - } - - final StringMetaDataBo stringMetaDataBo = new StringMetaDataBo(stringMetaData.getAgentId(), stringMetaData.getAgentStartTime(), stringMetaData.getStringId()); - final byte[] rowKey = getDistributedKey(stringMetaDataBo.toRowKey()); - - - Put put = new Put(rowKey); - String stringValue = stringMetaData.getStringValue(); - byte[] sqlBytes = Bytes.toBytes(stringValue); - // hashCode가 충돌날수 있으므로 일부러 qualifier에 넣음. - put.add(HBaseTables.STRING_METADATA_CF_STR, sqlBytes, null); - - hbaseTemplate.put(HBaseTables.STRING_METADATA, put); - } - - private byte[] getDistributedKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); - } -} +package com.nhn.pinpoint.collector.dao.hbase; + +import com.nhn.pinpoint.collector.dao.StringMetaDataDao; +import com.nhn.pinpoint.common.bo.StringMetaDataBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.thrift.dto.TStringMetaData; +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Repository; + +/** + * @author emeroad + */ +@Repository +public class HbaseStringMetaDataDao implements StringMetaDataDao { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private HbaseOperations2 hbaseTemplate; + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public void insert(TStringMetaData stringMetaData) { + if (stringMetaData == null) { + throw new NullPointerException("stringMetaData must not be null"); + } + if (logger.isDebugEnabled()) { + logger.debug("insert:{}", stringMetaData); + } + + final StringMetaDataBo stringMetaDataBo = new StringMetaDataBo(stringMetaData.getAgentId(), stringMetaData.getAgentStartTime(), stringMetaData.getStringId()); + final byte[] rowKey = getDistributedKey(stringMetaDataBo.toRowKey()); + + + Put put = new Put(rowKey); + String stringValue = stringMetaData.getStringValue(); + byte[] sqlBytes = Bytes.toBytes(stringValue); + // hashCode가 충돌날수 있으므로 일부러 qualifier에 넣음. + put.add(HBaseTables.STRING_METADATA_CF_STR, sqlBytes, null); + + hbaseTemplate.put(HBaseTables.STRING_METADATA, put); + } + + private byte[] getDistributedKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallRowKey.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallRowKey.java index db49b78f161b..fb1eeb8c0f2d 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallRowKey.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallRowKey.java @@ -1,73 +1,73 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import org.apache.thrift.transport.TFileTransport; - -/** - * @author emeroad - */ -public class CallRowKey implements RowKey { - private final String callApplicationName; - private final short callServiceType; - private final long rowTimeSlot; - - // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. - private int hash; - - public CallRowKey(String callApplicationName, short callServiceType, long rowTimeSlot) { - if (callApplicationName == null) { - throw new NullPointerException("callApplicationName must not be null"); - } - this.callApplicationName = callApplicationName; - this.callServiceType = callServiceType; - this.rowTimeSlot = rowTimeSlot; - } - public byte[] getRowKey() { -// final Buffer buffer = new AutomaticBuffer(); -// buffer.putPrefixedString(callApplicationName); -// buffer.put(callServiceType); -// buffer.put(TimeUtils.reverseTimeMillis(rowTimeSlot)); -// 마지막에 buffer.getBuffer()를 호출하지 않음. 이미 데이터가 들어가 있는 상황이므로, 그냥 가고 추후 수정한다.. - return ApplicationMapStatisticsUtils.makeRowKey(callApplicationName, callServiceType, rowTimeSlot); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CallRowKey that = (CallRowKey) o; - - if (callServiceType != that.callServiceType) return false; - if (rowTimeSlot != that.rowTimeSlot) return false; - if (callApplicationName != null ? !callApplicationName.equals(that.callApplicationName) : that.callApplicationName != null) - return false; - - return true; - } - - @Override - public int hashCode() { - if (hash != 0) { - return hash; - } - int result = callApplicationName != null ? callApplicationName.hashCode() : 0; - result = 31 * result + (int) callServiceType; - result = 31 * result + (int) (rowTimeSlot ^ (rowTimeSlot >>> 32)); - hash = result; - return result; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CallRowKey{"); - sb.append("callApplicationName='").append(callApplicationName).append('\''); - sb.append(", callServiceType=").append(callServiceType); - sb.append(", rowTimeSlot=").append(rowTimeSlot); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import org.apache.thrift.transport.TFileTransport; + +/** + * @author emeroad + */ +public class CallRowKey implements RowKey { + private final String callApplicationName; + private final short callServiceType; + private final long rowTimeSlot; + + // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. + private int hash; + + public CallRowKey(String callApplicationName, short callServiceType, long rowTimeSlot) { + if (callApplicationName == null) { + throw new NullPointerException("callApplicationName must not be null"); + } + this.callApplicationName = callApplicationName; + this.callServiceType = callServiceType; + this.rowTimeSlot = rowTimeSlot; + } + public byte[] getRowKey() { +// final Buffer buffer = new AutomaticBuffer(); +// buffer.putPrefixedString(callApplicationName); +// buffer.put(callServiceType); +// buffer.put(TimeUtils.reverseTimeMillis(rowTimeSlot)); +// 마지막에 buffer.getBuffer()를 호출하지 않음. 이미 데이터가 들어가 있는 상황이므로, 그냥 가고 추후 수정한다.. + return ApplicationMapStatisticsUtils.makeRowKey(callApplicationName, callServiceType, rowTimeSlot); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CallRowKey that = (CallRowKey) o; + + if (callServiceType != that.callServiceType) return false; + if (rowTimeSlot != that.rowTimeSlot) return false; + if (callApplicationName != null ? !callApplicationName.equals(that.callApplicationName) : that.callApplicationName != null) + return false; + + return true; + } + + @Override + public int hashCode() { + if (hash != 0) { + return hash; + } + int result = callApplicationName != null ? callApplicationName.hashCode() : 0; + result = 31 * result + (int) callServiceType; + result = 31 * result + (int) (rowTimeSlot ^ (rowTimeSlot >>> 32)); + hash = result; + return result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("CallRowKey{"); + sb.append("callApplicationName='").append(callApplicationName).append('\''); + sb.append(", callServiceType=").append(callServiceType); + sb.append(", rowTimeSlot=").append(rowTimeSlot); + sb.append('}'); + return sb.toString(); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CalleeColumnName.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CalleeColumnName.java index 8746b43a3571..35657fc808ec 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CalleeColumnName.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CalleeColumnName.java @@ -1,109 +1,109 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; - -/** - * @author emeroad - */ -public class CalleeColumnName implements ColumnName { - private final String callerAgentId; - private final short calleeServiceType; - private final String calleeApplicationName; - // 호출당하거나, 호출한 host, - private final String callHost; - private final short columnSlotNumber; - - // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. - private int hash; - - private long callCount; - - public CalleeColumnName(String callerAgentId, short calleeServiceType, String calleeApplicationName, String callHost, short columnSlotNumber) { - if (callerAgentId == null) { - throw new NullPointerException("callerAgentId must not be null"); - } - if (calleeApplicationName == null) { - throw new NullPointerException("calleeApplicationName must not be null"); - } - if (callHost == null) { - throw new NullPointerException("callHost must not be null"); - } - this.callerAgentId = callerAgentId; - this.calleeServiceType = calleeServiceType; - this.calleeApplicationName = calleeApplicationName; - this.callHost = callHost; - this.columnSlotNumber = columnSlotNumber; - } - - public long getCallCount() { - return callCount; - } - - public void setCallCount(long callCount) { - this.callCount = callCount; - } - - public byte[] getColumnName() { - final Buffer buffer = new AutomaticBuffer(64); - buffer.put(calleeServiceType); - buffer.putPrefixedString(calleeApplicationName); - buffer.putPrefixedString(callHost); - buffer.put(columnSlotNumber); - buffer.putPrefixedString(callerAgentId); - return buffer.getBuffer(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CalleeColumnName that = (CalleeColumnName) o; - - if (callCount != that.callCount) return false; - if (calleeServiceType != that.calleeServiceType) return false; - if (columnSlotNumber != that.columnSlotNumber) return false; - if (!callHost.equals(that.callHost)) return false; - if (!calleeApplicationName.equals(that.calleeApplicationName)) return false; - if (!callerAgentId.equals(that.callerAgentId)) return false; - - return true; - } - - @Override - public int hashCode() { - if (hash != 0) { - return hash; - } - int result = callerAgentId.hashCode(); - result = 31 * result + (int) calleeServiceType; - result = 31 * result + calleeApplicationName.hashCode(); - result = 31 * result + callHost.hashCode(); - result = 31 * result + (int) columnSlotNumber; - result = 31 * result + hash; - result = 31 * result + (int) (callCount ^ (callCount >>> 32)); - this.hash = result; - return result; - } - - /** - * hashCode수정시 주의할겻 hbasekey 캐쉬값이 있음. - * @return - */ - - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CalleeColumnName{"); - sb.append("callerAgentId=").append(callerAgentId); - sb.append(", calleeServiceType=").append(calleeServiceType); - sb.append(", calleeApplicationName='").append(calleeApplicationName).append('\''); - sb.append(", callHost='").append(callHost).append('\''); - sb.append(", columnSlotNumber=").append(columnSlotNumber); - sb.append(", callCount=").append(callCount); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; + +/** + * @author emeroad + */ +public class CalleeColumnName implements ColumnName { + private final String callerAgentId; + private final short calleeServiceType; + private final String calleeApplicationName; + // 호출당하거나, 호출한 host, + private final String callHost; + private final short columnSlotNumber; + + // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. + private int hash; + + private long callCount; + + public CalleeColumnName(String callerAgentId, short calleeServiceType, String calleeApplicationName, String callHost, short columnSlotNumber) { + if (callerAgentId == null) { + throw new NullPointerException("callerAgentId must not be null"); + } + if (calleeApplicationName == null) { + throw new NullPointerException("calleeApplicationName must not be null"); + } + if (callHost == null) { + throw new NullPointerException("callHost must not be null"); + } + this.callerAgentId = callerAgentId; + this.calleeServiceType = calleeServiceType; + this.calleeApplicationName = calleeApplicationName; + this.callHost = callHost; + this.columnSlotNumber = columnSlotNumber; + } + + public long getCallCount() { + return callCount; + } + + public void setCallCount(long callCount) { + this.callCount = callCount; + } + + public byte[] getColumnName() { + final Buffer buffer = new AutomaticBuffer(64); + buffer.put(calleeServiceType); + buffer.putPrefixedString(calleeApplicationName); + buffer.putPrefixedString(callHost); + buffer.put(columnSlotNumber); + buffer.putPrefixedString(callerAgentId); + return buffer.getBuffer(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CalleeColumnName that = (CalleeColumnName) o; + + if (callCount != that.callCount) return false; + if (calleeServiceType != that.calleeServiceType) return false; + if (columnSlotNumber != that.columnSlotNumber) return false; + if (!callHost.equals(that.callHost)) return false; + if (!calleeApplicationName.equals(that.calleeApplicationName)) return false; + if (!callerAgentId.equals(that.callerAgentId)) return false; + + return true; + } + + @Override + public int hashCode() { + if (hash != 0) { + return hash; + } + int result = callerAgentId.hashCode(); + result = 31 * result + (int) calleeServiceType; + result = 31 * result + calleeApplicationName.hashCode(); + result = 31 * result + callHost.hashCode(); + result = 31 * result + (int) columnSlotNumber; + result = 31 * result + hash; + result = 31 * result + (int) (callCount ^ (callCount >>> 32)); + this.hash = result; + return result; + } + + /** + * hashCode수정시 주의할겻 hbasekey 캐쉬값이 있음. + * @return + */ + + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("CalleeColumnName{"); + sb.append("callerAgentId=").append(callerAgentId); + sb.append(", calleeServiceType=").append(calleeServiceType); + sb.append(", calleeApplicationName='").append(calleeApplicationName).append('\''); + sb.append(", callHost='").append(callHost).append('\''); + sb.append(", columnSlotNumber=").append(columnSlotNumber); + sb.append(", callCount=").append(callCount); + sb.append('}'); + return sb.toString(); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallerColumnName.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallerColumnName.java index f10c2c885333..2e476face2cf 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallerColumnName.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/CallerColumnName.java @@ -1,90 +1,90 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; - -/** - * @author emeroad - */ -public class CallerColumnName implements ColumnName { - private short callerServiceType; - private String callerApplicationName; - // 호출당하거나, 호출한 host, - private String callHost; - private short columnSlotNumber; - - // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. - private int hash; - - private long callCount; - - public CallerColumnName(short callerServiceType, String callerApplicationName, String callHost, short columnSlotNumber) { - if (callerApplicationName == null) { - throw new NullPointerException("callerApplicationName must not be null"); - } - if (callHost == null) { - throw new NullPointerException("callHost must not be null"); - } - this.callerServiceType = callerServiceType; - this.callerApplicationName = callerApplicationName; - this.callHost = callHost; - this.columnSlotNumber = columnSlotNumber; - } - - public long getCallCount() { - return callCount; - } - - public void setCallCount(long callCount) { - this.callCount = callCount; - } - - public byte[] getColumnName() { - return ApplicationMapStatisticsUtils.makeColumnName(callerServiceType, callerApplicationName, callHost, columnSlotNumber); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CallerColumnName that = (CallerColumnName) o; - - if (callerServiceType != that.callerServiceType) return false; - if (columnSlotNumber != that.columnSlotNumber) return false; - if (callerApplicationName != null ? !callerApplicationName.equals(that.callerApplicationName) : that.callerApplicationName != null) return false; - if (callHost != null ? !callHost.equals(that.callHost) : that.callHost != null) return false; - - return true; - } - - /** - * hashCode수정시 주의할겻 hbasekey 캐쉬값이 있음. - * @return - */ - @Override - public int hashCode() { - if (hash != 0) { - return hash; - } - int result = (int) callerServiceType; - result = 31 * result + (callerApplicationName != null ? callerApplicationName.hashCode() : 0); - result = 31 * result + (callHost != null ? callHost.hashCode() : 0); - result = 31 * result + (int) columnSlotNumber; - hash = result; - return result; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CallerColumnName{"); - sb.append("callerServiceType=").append(callerServiceType); - sb.append(", callerApplicationName='").append(callerApplicationName).append('\''); - sb.append(", callHost='").append(callHost).append('\''); - sb.append(", columnSlotNumber=").append(columnSlotNumber); - sb.append(", callCount=").append(callCount); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; + +/** + * @author emeroad + */ +public class CallerColumnName implements ColumnName { + private short callerServiceType; + private String callerApplicationName; + // 호출당하거나, 호출한 host, + private String callHost; + private short columnSlotNumber; + + // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. + private int hash; + + private long callCount; + + public CallerColumnName(short callerServiceType, String callerApplicationName, String callHost, short columnSlotNumber) { + if (callerApplicationName == null) { + throw new NullPointerException("callerApplicationName must not be null"); + } + if (callHost == null) { + throw new NullPointerException("callHost must not be null"); + } + this.callerServiceType = callerServiceType; + this.callerApplicationName = callerApplicationName; + this.callHost = callHost; + this.columnSlotNumber = columnSlotNumber; + } + + public long getCallCount() { + return callCount; + } + + public void setCallCount(long callCount) { + this.callCount = callCount; + } + + public byte[] getColumnName() { + return ApplicationMapStatisticsUtils.makeColumnName(callerServiceType, callerApplicationName, callHost, columnSlotNumber); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CallerColumnName that = (CallerColumnName) o; + + if (callerServiceType != that.callerServiceType) return false; + if (columnSlotNumber != that.columnSlotNumber) return false; + if (callerApplicationName != null ? !callerApplicationName.equals(that.callerApplicationName) : that.callerApplicationName != null) return false; + if (callHost != null ? !callHost.equals(that.callHost) : that.callHost != null) return false; + + return true; + } + + /** + * hashCode수정시 주의할겻 hbasekey 캐쉬값이 있음. + * @return + */ + @Override + public int hashCode() { + if (hash != 0) { + return hash; + } + int result = (int) callerServiceType; + result = 31 * result + (callerApplicationName != null ? callerApplicationName.hashCode() : 0); + result = 31 * result + (callHost != null ? callHost.hashCode() : 0); + result = 31 * result + (int) columnSlotNumber; + hash = result; + return result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("CallerColumnName{"); + sb.append("callerServiceType=").append(callerServiceType); + sb.append(", callerApplicationName='").append(callerApplicationName).append('\''); + sb.append(", callHost='").append(callHost).append('\''); + sb.append(", columnSlotNumber=").append(columnSlotNumber); + sb.append(", callCount=").append(callCount); + sb.append('}'); + return sb.toString(); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ColumnName.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ColumnName.java index 7339207e087b..15e6c79ba459 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ColumnName.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ColumnName.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -/** - * @author emeroad - */ -public interface ColumnName { - byte[] getColumnName(); - - long getCallCount(); - - void setCallCount(long callCount); -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +/** + * @author emeroad + */ +public interface ColumnName { + byte[] getColumnName(); + + long getCallCount(); + + void setCallCount(long callCount); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/DefaultRowInfo.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/DefaultRowInfo.java index e833335fd0ca..2c8c8e0bc659 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/DefaultRowInfo.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/DefaultRowInfo.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -/** - * @author emeroad - */ -public class DefaultRowInfo implements RowInfo { - - private RowKey rowKey; - private ColumnName columnName; - - public DefaultRowInfo(RowKey rowKey, ColumnName columnName) { - if (rowKey == null) { - throw new NullPointerException("rowKey must not be null"); - } - if (columnName == null) { - throw new NullPointerException("columnName must not be null"); - } - - this.rowKey = rowKey; - this.columnName = columnName; - } - - public RowKey getRowKey() { - return rowKey; - } - - public ColumnName getColumnName() { - return columnName; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - DefaultRowInfo that = (DefaultRowInfo) o; - - if (!columnName.equals(that.columnName)) return false; - if (!rowKey.equals(that.rowKey)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = rowKey.hashCode(); - result = 31 * result + columnName.hashCode(); - return result; - } -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +/** + * @author emeroad + */ +public class DefaultRowInfo implements RowInfo { + + private RowKey rowKey; + private ColumnName columnName; + + public DefaultRowInfo(RowKey rowKey, ColumnName columnName) { + if (rowKey == null) { + throw new NullPointerException("rowKey must not be null"); + } + if (columnName == null) { + throw new NullPointerException("columnName must not be null"); + } + + this.rowKey = rowKey; + this.columnName = columnName; + } + + public RowKey getRowKey() { + return rowKey; + } + + public ColumnName getColumnName() { + return columnName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DefaultRowInfo that = (DefaultRowInfo) o; + + if (!columnName.equals(that.columnName)) return false; + if (!rowKey.equals(that.rowKey)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = rowKey.hashCode(); + result = 31 * result + columnName.hashCode(); + return result; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ResponseColumnName.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ResponseColumnName.java index 5f08cb3ff56f..4e996f04075b 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ResponseColumnName.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/ResponseColumnName.java @@ -1,75 +1,75 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; - -/** - * @author emeroad - */ -public class ResponseColumnName implements ColumnName { - - private String agentId; - private short columnSlotNumber; - - // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. - private int hash; - - private long callCount; - - public ResponseColumnName(String agentId, short columnSlotNumber) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - this.agentId = agentId; - this.columnSlotNumber = columnSlotNumber; - } - - public long getCallCount() { - return callCount; - } - - public void setCallCount(long callCount) { - this.callCount = callCount; - } - - public byte[] getColumnName() { - return ApplicationMapStatisticsUtils.makeColumnName(agentId, columnSlotNumber); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ResponseColumnName that = (ResponseColumnName) o; - - if (columnSlotNumber != that.columnSlotNumber) return false; - if (!agentId.equals(that.agentId)) return false; - - return true; - } - - /** - * hashCode수정시 주의할겻 hbasekey 캐쉬값이 있음. - * @return - */ - @Override - public int hashCode() { - - if (hash != 0) { - return hash; - } - int result = agentId.hashCode(); - result = 31 * result + (int) columnSlotNumber; - hash = result; - return result; - } - - @Override - public String toString() { - return "ResponseColumnName{" + - "agentId='" + agentId + '\'' + - ", columnSlotNumber=" + columnSlotNumber + - ", callCount=" + callCount + - '}'; - } -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; + +/** + * @author emeroad + */ +public class ResponseColumnName implements ColumnName { + + private String agentId; + private short columnSlotNumber; + + // 주의 hash 값 캐시는 equals/hashCode 생성시 넣으면 안됨. + private int hash; + + private long callCount; + + public ResponseColumnName(String agentId, short columnSlotNumber) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + this.agentId = agentId; + this.columnSlotNumber = columnSlotNumber; + } + + public long getCallCount() { + return callCount; + } + + public void setCallCount(long callCount) { + this.callCount = callCount; + } + + public byte[] getColumnName() { + return ApplicationMapStatisticsUtils.makeColumnName(agentId, columnSlotNumber); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ResponseColumnName that = (ResponseColumnName) o; + + if (columnSlotNumber != that.columnSlotNumber) return false; + if (!agentId.equals(that.agentId)) return false; + + return true; + } + + /** + * hashCode수정시 주의할겻 hbasekey 캐쉬값이 있음. + * @return + */ + @Override + public int hashCode() { + + if (hash != 0) { + return hash; + } + int result = agentId.hashCode(); + result = 31 * result + (int) columnSlotNumber; + hash = result; + return result; + } + + @Override + public String toString() { + return "ResponseColumnName{" + + "agentId='" + agentId + '\'' + + ", columnSlotNumber=" + columnSlotNumber + + ", callCount=" + callCount + + '}'; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowInfo.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowInfo.java index b06ceaeea83a..65f3ab8cd776 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowInfo.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowInfo.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -/** - * @author emeroad - */ -public interface RowInfo { - - RowKey getRowKey(); - - ColumnName getColumnName(); - -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +/** + * @author emeroad + */ +public interface RowInfo { + + RowKey getRowKey(); + + ColumnName getColumnName(); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKey.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKey.java index ff18fb6d56d4..79bacc965595 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKey.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKey.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -/** - * @author emeroad - */ -public interface RowKey { - byte[] getRowKey(); -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +/** + * @author emeroad + */ +public interface RowKey { + byte[] getRowKey(); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKeyMerge.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKeyMerge.java index bf7f83b3ff22..29a419df3f63 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKeyMerge.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/statistics/RowKeyMerge.java @@ -1,73 +1,73 @@ -package com.nhn.pinpoint.collector.dao.hbase.statistics; - -import com.nhn.pinpoint.collector.util.ConcurrentCounterMap; -import org.apache.hadoop.hbase.client.Increment; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class RowKeyMerge { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final byte[] family; - - public RowKeyMerge(byte[] family) { - if (family == null) { - throw new NullPointerException("family must not be null"); - } - this.family = Arrays.copyOf(family, family.length); - } - - public List createBulkIncrement(Map data) { - if (data.isEmpty()) { - return Collections.emptyList(); - } - - final Map> rowkeyMerge = rowKeyBaseMerge(data); - - List incrementList = new ArrayList(); - //합쳐서 flush 뭔가 로직이 복잡함. - for (Map.Entry> rowKeyEntry : rowkeyMerge.entrySet()) { - Increment increment = createIncrement(rowKeyEntry); - incrementList.add(increment); - } - return incrementList; - } - - private Increment createIncrement(Map.Entry> rowKeyEntry) { - RowKey rowKey = rowKeyEntry.getKey(); - final Increment increment = new Increment(rowKey.getRowKey()); - for(ColumnName columnName : rowKeyEntry.getValue()) { - increment.addColumn(family, columnName.getColumnName(), columnName.getCallCount()); - } - logger.trace("create increment row:{}, column:{}", rowKey, rowKeyEntry.getValue()); - return increment; - } - - private Map> rowKeyBaseMerge(Map data) { - final Map> merge = new HashMap>(); - - for (Map.Entry entry : data.entrySet()) { - final RowInfo rowInfo = entry.getKey(); - // callcount는 columnName에 저장하고 버린다. - long callCount = entry.getValue().get(); - rowInfo.getColumnName().setCallCount(callCount); - - // 흠 괜히 복잡한게 class로 빼야 될듯. - RowKey rowKey = rowInfo.getRowKey(); - List oldList = merge.get(rowKey); - if (oldList == null) { - List newList = new ArrayList(); - newList.add(rowInfo.getColumnName()); - merge.put(rowKey, newList); - } else { - oldList.add(rowInfo.getColumnName()); - } - } - return merge; - } -} +package com.nhn.pinpoint.collector.dao.hbase.statistics; + +import com.nhn.pinpoint.collector.util.ConcurrentCounterMap; +import org.apache.hadoop.hbase.client.Increment; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class RowKeyMerge { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final byte[] family; + + public RowKeyMerge(byte[] family) { + if (family == null) { + throw new NullPointerException("family must not be null"); + } + this.family = Arrays.copyOf(family, family.length); + } + + public List createBulkIncrement(Map data) { + if (data.isEmpty()) { + return Collections.emptyList(); + } + + final Map> rowkeyMerge = rowKeyBaseMerge(data); + + List incrementList = new ArrayList(); + //합쳐서 flush 뭔가 로직이 복잡함. + for (Map.Entry> rowKeyEntry : rowkeyMerge.entrySet()) { + Increment increment = createIncrement(rowKeyEntry); + incrementList.add(increment); + } + return incrementList; + } + + private Increment createIncrement(Map.Entry> rowKeyEntry) { + RowKey rowKey = rowKeyEntry.getKey(); + final Increment increment = new Increment(rowKey.getRowKey()); + for(ColumnName columnName : rowKeyEntry.getValue()) { + increment.addColumn(family, columnName.getColumnName(), columnName.getCallCount()); + } + logger.trace("create increment row:{}, column:{}", rowKey, rowKeyEntry.getValue()); + return increment; + } + + private Map> rowKeyBaseMerge(Map data) { + final Map> merge = new HashMap>(); + + for (Map.Entry entry : data.entrySet()) { + final RowInfo rowInfo = entry.getKey(); + // callcount는 columnName에 저장하고 버린다. + long callCount = entry.getValue().get(); + rowInfo.getColumnName().setCallCount(callCount); + + // 흠 괜히 복잡한게 class로 빼야 될듯. + RowKey rowKey = rowInfo.getRowKey(); + List oldList = merge.get(rowKey); + if (oldList == null) { + List newList = new ArrayList(); + newList.add(rowInfo.getColumnName()); + merge.put(rowKey, newList); + } else { + oldList.add(rowInfo.getColumnName()); + } + } + return merge; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/ApiMetaDataHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/ApiMetaDataHandler.java index 647f130b5f95..7c758f898fc6 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/ApiMetaDataHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/ApiMetaDataHandler.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.collector.handler; - -import com.nhn.pinpoint.thrift.dto.TApiMetaData; -import com.nhn.pinpoint.collector.dao.ApiMetaDataDao; -import com.nhn.pinpoint.thrift.dto.TResult; -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * @author emeroad - */ -@Service -public class ApiMetaDataHandler implements RequestResponseHandler { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - @Autowired - private ApiMetaDataDao sqlMetaDataDao; - - @Override - public TBase handleRequest(TBase tbase) { - if (!(tbase instanceof TApiMetaData)) { - logger.error("invalid tbase:{}", tbase); - return null; - } - - TApiMetaData apiMetaData = (TApiMetaData) tbase; - // api 데이터는 중요한거니 그냥 info로 찍음. - if (logger.isInfoEnabled()) { - logger.info("Received ApiMetaData={}", apiMetaData); - } - - try { - sqlMetaDataDao.insert(apiMetaData); - } catch (Exception e) { - logger.warn("{} handler error. Caused:{}", this.getClass(), e.getMessage(), e); - TResult result = new TResult(false); - result.setMessage(e.getMessage()); - return result; - } - return new TResult(true); - } -} +package com.nhn.pinpoint.collector.handler; + +import com.nhn.pinpoint.thrift.dto.TApiMetaData; +import com.nhn.pinpoint.collector.dao.ApiMetaDataDao; +import com.nhn.pinpoint.thrift.dto.TResult; +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author emeroad + */ +@Service +public class ApiMetaDataHandler implements RequestResponseHandler { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApiMetaDataDao sqlMetaDataDao; + + @Override + public TBase handleRequest(TBase tbase) { + if (!(tbase instanceof TApiMetaData)) { + logger.error("invalid tbase:{}", tbase); + return null; + } + + TApiMetaData apiMetaData = (TApiMetaData) tbase; + // api 데이터는 중요한거니 그냥 info로 찍음. + if (logger.isInfoEnabled()) { + logger.info("Received ApiMetaData={}", apiMetaData); + } + + try { + sqlMetaDataDao.insert(apiMetaData); + } catch (Exception e) { + logger.warn("{} handler error. Caused:{}", this.getClass(), e.getMessage(), e); + TResult result = new TResult(false); + result.setMessage(e.getMessage()); + return result; + } + return new TResult(true); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/Handler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/Handler.java index 3f6253bc0a08..9de8bbf00206 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/Handler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/Handler.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.collector.handler; - -import org.apache.thrift.TBase; - -/** - * @author emeroad - * @author koo.taejin - */ -public interface Handler { - - void handle(TBase tbase, byte[] packet, int offset, int length); - -} +package com.nhn.pinpoint.collector.handler; + +import org.apache.thrift.TBase; + +/** + * @author emeroad + * @author koo.taejin + */ +public interface Handler { + + void handle(TBase tbase, byte[] packet, int offset, int length); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/RequestResponseHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/RequestResponseHandler.java index 02f06bd62cef..1c6e2d0359d3 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/RequestResponseHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/RequestResponseHandler.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.collector.handler; - -import org.apache.thrift.TBase; -import org.springframework.stereotype.Service; - -/** - * @author emeroad - * @author koo.taejin - */ -@Service -public interface RequestResponseHandler { - - TBase handleRequest(TBase tbase); - -} +package com.nhn.pinpoint.collector.handler; + +import org.apache.thrift.TBase; +import org.springframework.stereotype.Service; + +/** + * @author emeroad + * @author koo.taejin + */ +@Service +public interface RequestResponseHandler { + + TBase handleRequest(TBase tbase); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SimpleHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SimpleHandler.java index 1dd0fcc68545..579c858faedc 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SimpleHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SimpleHandler.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.collector.handler; - -import org.apache.thrift.TBase; - -/** - * @author emeroad - * @author koo.taejin - */ -public interface SimpleHandler { - - void handleSimple(TBase tbase); - -} +package com.nhn.pinpoint.collector.handler; + +import org.apache.thrift.TBase; + +/** + * @author emeroad + * @author koo.taejin + */ +public interface SimpleHandler { + + void handleSimple(TBase tbase); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java index 99d733be0a25..959020f71046 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java @@ -1,76 +1,76 @@ -package com.nhn.pinpoint.collector.handler; - -import java.util.List; - -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.nhn.pinpoint.collector.dao.TracesDao; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.thrift.dto.TSpanChunk; -import com.nhn.pinpoint.thrift.dto.TSpanEvent; -import com.nhn.pinpoint.common.util.SpanEventUtils; -import org.springframework.stereotype.Service; - -/** - * @author emeroad - */ -@Service -public class SpanChunkHandler implements SimpleHandler { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - @Autowired - private TracesDao traceDao; - - @Autowired - private StatisticsHandler statisticsHandler; - - @Override - public void handleSimple(TBase tbase) { - - if (!(tbase instanceof TSpanChunk)) { - throw new IllegalArgumentException("unexpected tbase:" + tbase + " expected:" + this.getClass().getName()); - } - - try { - TSpanChunk spanChunk = (TSpanChunk) tbase; - - if (logger.isDebugEnabled()) { - logger.debug("Received SpanChunk={}", spanChunk); - } - - traceDao.insertSpanChunk(spanChunk); - - List spanEventList = spanChunk.getSpanEventList(); - if (spanEventList != null) { - logger.debug("SpanChunk Size:{}", spanEventList.size()); - // TODO 껀바이 껀인데. 나중에 뭔가 한번에 업데이트 치는걸로 변경해야 될듯. - for (TSpanEvent spanEvent : spanEventList) { - final ServiceType serviceType = ServiceType.findServiceType(spanEvent.getServiceType()); - - if (!serviceType.isRecordStatistics()) { - continue; - } - - // if terminal update statistics - final int elapsed = spanEvent.getEndElapsed(); - final boolean hasException = SpanEventUtils.hasException(spanEvent); - - /** - * 통계정보에 기반한 서버맵을 그리기 위한 정보 저장. - */ - // 내가 호출한 정보 저장. (span이 호출한 spanevent) - statisticsHandler.updateCaller(spanChunk.getApplicationName(), spanChunk.getServiceType(), spanChunk.getAgentId(), spanEvent.getDestinationId(), serviceType.getCode(), spanEvent.getEndPoint(), elapsed, hasException); - - // 나를 호출한 정보 저장 (spanevent를 호출한 span) - statisticsHandler.updateCallee(spanEvent.getDestinationId(), spanEvent.getServiceType(), spanChunk.getApplicationName(), spanChunk.getServiceType(), spanChunk.getEndPoint(), elapsed, hasException); - } - } - } catch (Exception e) { - logger.warn("SpanChunk handle error Caused:{}", e.getMessage(), e); - } - } +package com.nhn.pinpoint.collector.handler; + +import java.util.List; + +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.nhn.pinpoint.collector.dao.TracesDao; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.thrift.dto.TSpanChunk; +import com.nhn.pinpoint.thrift.dto.TSpanEvent; +import com.nhn.pinpoint.common.util.SpanEventUtils; +import org.springframework.stereotype.Service; + +/** + * @author emeroad + */ +@Service +public class SpanChunkHandler implements SimpleHandler { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private TracesDao traceDao; + + @Autowired + private StatisticsHandler statisticsHandler; + + @Override + public void handleSimple(TBase tbase) { + + if (!(tbase instanceof TSpanChunk)) { + throw new IllegalArgumentException("unexpected tbase:" + tbase + " expected:" + this.getClass().getName()); + } + + try { + TSpanChunk spanChunk = (TSpanChunk) tbase; + + if (logger.isDebugEnabled()) { + logger.debug("Received SpanChunk={}", spanChunk); + } + + traceDao.insertSpanChunk(spanChunk); + + List spanEventList = spanChunk.getSpanEventList(); + if (spanEventList != null) { + logger.debug("SpanChunk Size:{}", spanEventList.size()); + // TODO 껀바이 껀인데. 나중에 뭔가 한번에 업데이트 치는걸로 변경해야 될듯. + for (TSpanEvent spanEvent : spanEventList) { + final ServiceType serviceType = ServiceType.findServiceType(spanEvent.getServiceType()); + + if (!serviceType.isRecordStatistics()) { + continue; + } + + // if terminal update statistics + final int elapsed = spanEvent.getEndElapsed(); + final boolean hasException = SpanEventUtils.hasException(spanEvent); + + /** + * 통계정보에 기반한 서버맵을 그리기 위한 정보 저장. + */ + // 내가 호출한 정보 저장. (span이 호출한 spanevent) + statisticsHandler.updateCaller(spanChunk.getApplicationName(), spanChunk.getServiceType(), spanChunk.getAgentId(), spanEvent.getDestinationId(), serviceType.getCode(), spanEvent.getEndPoint(), elapsed, hasException); + + // 나를 호출한 정보 저장 (spanevent를 호출한 span) + statisticsHandler.updateCallee(spanEvent.getDestinationId(), spanEvent.getServiceType(), spanChunk.getApplicationName(), spanChunk.getServiceType(), spanChunk.getEndPoint(), elapsed, hasException); + } + } + } catch (Exception e) { + logger.warn("SpanChunk handle error Caused:{}", e.getMessage(), e); + } + } } \ No newline at end of file diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SqlMetaDataHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SqlMetaDataHandler.java index 41c2de0638da..d02e99e1e8fd 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SqlMetaDataHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SqlMetaDataHandler.java @@ -1,47 +1,47 @@ -package com.nhn.pinpoint.collector.handler; - -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.dto.TSqlMetaData; -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.nhn.pinpoint.collector.dao.SqlMetaDataDao; -import org.springframework.stereotype.Service; - -/** - * @author emeroad - */ -@Service -public class SqlMetaDataHandler implements RequestResponseHandler { - private final Logger logger = LoggerFactory.getLogger(getClass()); - - @Autowired - private SqlMetaDataDao sqlMetaDataDao; - - @Override - public TBase handleRequest(TBase tbase) { - if (!(tbase instanceof TSqlMetaData)) { - logger.error("invalid tbase:{}", tbase); - return null; - } - - TSqlMetaData sqlMetaData = (TSqlMetaData) tbase; - - if (logger.isInfoEnabled()) { - logger.info("Received SqlMetaData:{}", sqlMetaData); - } - - - try { - sqlMetaDataDao.insert(sqlMetaData); - } catch (Exception e) { - logger.warn("{} handler error. Caused:{}", this.getClass(), e.getMessage(), e); - TResult result = new TResult(false); - result.setMessage(e.getMessage()); - return result; - } - return new TResult(true); - } -} +package com.nhn.pinpoint.collector.handler; + +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.dto.TSqlMetaData; +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.nhn.pinpoint.collector.dao.SqlMetaDataDao; +import org.springframework.stereotype.Service; + +/** + * @author emeroad + */ +@Service +public class SqlMetaDataHandler implements RequestResponseHandler { + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private SqlMetaDataDao sqlMetaDataDao; + + @Override + public TBase handleRequest(TBase tbase) { + if (!(tbase instanceof TSqlMetaData)) { + logger.error("invalid tbase:{}", tbase); + return null; + } + + TSqlMetaData sqlMetaData = (TSqlMetaData) tbase; + + if (logger.isInfoEnabled()) { + logger.info("Received SqlMetaData:{}", sqlMetaData); + } + + + try { + sqlMetaDataDao.insert(sqlMetaData); + } catch (Exception e) { + logger.warn("{} handler error. Caused:{}", this.getClass(), e.getMessage(), e); + TResult result = new TResult(false); + result.setMessage(e.getMessage()); + return result; + } + return new TResult(true); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/StringMetaDataHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/StringMetaDataHandler.java index 4a71a12456f0..2e2e7757046d 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/StringMetaDataHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/StringMetaDataHandler.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.collector.handler; - -import com.nhn.pinpoint.collector.dao.StringMetaDataDao; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.dto.TStringMetaData; -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * @author emeroad - */ -@Service -public class StringMetaDataHandler implements RequestResponseHandler { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - @Autowired - private StringMetaDataDao stringMetaDataDao; - - @Override - public TBase handleRequest(TBase tbase) { - if (!(tbase instanceof TStringMetaData)) { - logger.error("invalid tbase:{}", tbase); - return null; - } - - TStringMetaData stringMetaData = (TStringMetaData) tbase; - // api 데이터는 중요한거니 그냥 info로 찍음. - if (logger.isInfoEnabled()) { - logger.info("Received StringMetaData={}", stringMetaData); - } - - try { - stringMetaDataDao.insert(stringMetaData); - } catch (Exception e) { - logger.warn("{} handler error. Caused:{}", this.getClass(), e.getMessage(), e); - TResult result = new TResult(false); - result.setMessage(e.getMessage()); - return result; - } - return new TResult(true); - } -} +package com.nhn.pinpoint.collector.handler; + +import com.nhn.pinpoint.collector.dao.StringMetaDataDao; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.dto.TStringMetaData; +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author emeroad + */ +@Service +public class StringMetaDataHandler implements RequestResponseHandler { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private StringMetaDataDao stringMetaDataDao; + + @Override + public TBase handleRequest(TBase tbase) { + if (!(tbase instanceof TStringMetaData)) { + logger.error("invalid tbase:{}", tbase); + return null; + } + + TStringMetaData stringMetaData = (TStringMetaData) tbase; + // api 데이터는 중요한거니 그냥 info로 찍음. + if (logger.isInfoEnabled()) { + logger.info("Received StringMetaData={}", stringMetaData); + } + + try { + stringMetaDataDao.insert(stringMetaData); + } catch (Exception e) { + logger.warn("{} handler error. Caused:{}", this.getClass(), e.getMessage(), e); + TResult result = new TResult(false); + result.setMessage(e.getMessage()); + return result; + } + return new TResult(true); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapper.java b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapper.java index ee1a5be9d874..fa820748988a 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapper.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapper.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.collector.mapper.thrift; - -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; -import com.nhn.pinpoint.thrift.dto.TAgentStat; -import com.nhn.pinpoint.thrift.dto.TCpuLoad; - -/** - * @author hyungil.jeong - */ -@Component -public class AgentStatCpuLoadBoMapper implements ThriftBoMapper { - - @Override - public AgentStatCpuLoadBo map(TAgentStat thriftObject) { - final String agentId = thriftObject.getAgentId(); - final long startTimestamp = thriftObject.getStartTimestamp(); - final long timestamp = thriftObject.getTimestamp(); - final TCpuLoad cpuLoad = thriftObject.getCpuLoad(); - - final AgentStatCpuLoadBo.Builder builder = new AgentStatCpuLoadBo.Builder(agentId, startTimestamp, timestamp); - // cpuLoad is optional (for now, null check is enough for non-primitives) - if (cpuLoad != null) { - // jvmCpuLoad is optional - if (cpuLoad.isSetJvmCpuLoad()) { - builder.jvmCpuLoad(cpuLoad.getJvmCpuLoad()); - } - // systemCpuLoad is optional - if (cpuLoad.isSetSystemCpuLoad()) { - builder.systemCpuLoad(cpuLoad.getSystemCpuLoad()); - } - } - return builder.build(); - } - -} +package com.nhn.pinpoint.collector.mapper.thrift; + +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; +import com.nhn.pinpoint.thrift.dto.TAgentStat; +import com.nhn.pinpoint.thrift.dto.TCpuLoad; + +/** + * @author hyungil.jeong + */ +@Component +public class AgentStatCpuLoadBoMapper implements ThriftBoMapper { + + @Override + public AgentStatCpuLoadBo map(TAgentStat thriftObject) { + final String agentId = thriftObject.getAgentId(); + final long startTimestamp = thriftObject.getStartTimestamp(); + final long timestamp = thriftObject.getTimestamp(); + final TCpuLoad cpuLoad = thriftObject.getCpuLoad(); + + final AgentStatCpuLoadBo.Builder builder = new AgentStatCpuLoadBo.Builder(agentId, startTimestamp, timestamp); + // cpuLoad is optional (for now, null check is enough for non-primitives) + if (cpuLoad != null) { + // jvmCpuLoad is optional + if (cpuLoad.isSetJvmCpuLoad()) { + builder.jvmCpuLoad(cpuLoad.getJvmCpuLoad()); + } + // systemCpuLoad is optional + if (cpuLoad.isSetSystemCpuLoad()) { + builder.systemCpuLoad(cpuLoad.getSystemCpuLoad()); + } + } + return builder.build(); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapper.java b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapper.java index 0e12a175ab1a..ec1fe03f7900 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapper.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapper.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.collector.mapper.thrift; - -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; -import com.nhn.pinpoint.thrift.dto.TAgentStat; -import com.nhn.pinpoint.thrift.dto.TJvmGc; -import com.nhn.pinpoint.thrift.dto.TJvmGcType; - -/** - * @author hyungil.jeong - */ -@Component -public class AgentStatMemoryGcBoMapper implements ThriftBoMapper { - - @Override - public AgentStatMemoryGcBo map(TAgentStat thriftObject) { - final String agentId = thriftObject.getAgentId(); - final long startTimestamp = thriftObject.getStartTimestamp(); - final long timestamp = thriftObject.getTimestamp(); - final TJvmGc gc = thriftObject.getGc(); - - final AgentStatMemoryGcBo.Builder builder = new AgentStatMemoryGcBo.Builder(agentId, startTimestamp, timestamp); - // gc is optional (for now, null check is enough for non-primitives) - if (gc != null) { - builder.gcType(gc.getType().name()); - builder.jvmMemoryHeapUsed(gc.getJvmMemoryHeapUsed()); - builder.jvmMemoryHeapMax(gc.getJvmMemoryHeapMax()); - builder.jvmMemoryNonHeapUsed(gc.getJvmMemoryNonHeapUsed()); - builder.jvmMemoryNonHeapMax(gc.getJvmMemoryNonHeapMax()); - builder.jvmGcOldCount(gc.getJvmGcOldCount()); - builder.jvmGcOldTime(gc.getJvmGcOldTime()); - } else { - builder.gcType(TJvmGcType.UNKNOWN.name()); - } - return builder.build(); - } - -} +package com.nhn.pinpoint.collector.mapper.thrift; + +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; +import com.nhn.pinpoint.thrift.dto.TAgentStat; +import com.nhn.pinpoint.thrift.dto.TJvmGc; +import com.nhn.pinpoint.thrift.dto.TJvmGcType; + +/** + * @author hyungil.jeong + */ +@Component +public class AgentStatMemoryGcBoMapper implements ThriftBoMapper { + + @Override + public AgentStatMemoryGcBo map(TAgentStat thriftObject) { + final String agentId = thriftObject.getAgentId(); + final long startTimestamp = thriftObject.getStartTimestamp(); + final long timestamp = thriftObject.getTimestamp(); + final TJvmGc gc = thriftObject.getGc(); + + final AgentStatMemoryGcBo.Builder builder = new AgentStatMemoryGcBo.Builder(agentId, startTimestamp, timestamp); + // gc is optional (for now, null check is enough for non-primitives) + if (gc != null) { + builder.gcType(gc.getType().name()); + builder.jvmMemoryHeapUsed(gc.getJvmMemoryHeapUsed()); + builder.jvmMemoryHeapMax(gc.getJvmMemoryHeapMax()); + builder.jvmMemoryNonHeapUsed(gc.getJvmMemoryNonHeapUsed()); + builder.jvmMemoryNonHeapMax(gc.getJvmMemoryNonHeapMax()); + builder.jvmGcOldCount(gc.getJvmGcOldCount()); + builder.jvmGcOldTime(gc.getJvmGcOldTime()); + } else { + builder.gcType(TJvmGcType.UNKNOWN.name()); + } + return builder.build(); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/ThriftBoMapper.java b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/ThriftBoMapper.java index 9f1de4993060..cb6c610d14fd 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/ThriftBoMapper.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/ThriftBoMapper.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.collector.mapper.thrift; - -import org.apache.thrift.TBase; - -/** - * @author hyungil.jeong - */ -public interface ThriftBoMapper> { - - public T map(F thriftObject); -} +package com.nhn.pinpoint.collector.mapper.thrift; + +import org.apache.thrift.TBase; + +/** + * @author hyungil.jeong + */ +public interface ThriftBoMapper> { + + public T map(F thriftObject); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/monitor/CollectorMetric.java b/collector/src/main/java/com/navercorp/pinpoint/collector/monitor/CollectorMetric.java index 591f3d19276e..5f4186d67c63 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/monitor/CollectorMetric.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/monitor/CollectorMetric.java @@ -1,70 +1,70 @@ -package com.nhn.pinpoint.collector.monitor; - -import com.codahale.metrics.JvmAttributeGaugeSet; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.ScheduledReporter; -import com.codahale.metrics.Slf4jReporter; -import com.codahale.metrics.jvm.GarbageCollectorMetricSet; -import com.codahale.metrics.jvm.MemoryUsageGaugeSet; -import com.codahale.metrics.jvm.ThreadStatesGaugeSet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - */ -@Component -public class CollectorMetric { - - public static final String REPOTER_LOGGER_NAME = "com.nhn.pinpoint.collector.StateReport"; - - private final Logger reporterLogger = LoggerFactory.getLogger(REPOTER_LOGGER_NAME); - - @Autowired - private MetricRegistry metricRegistry; - - private ScheduledReporter reporter; - - - @PostConstruct - public void start() { - initRegistry(); - initReporters(); - } - - private void initRegistry() { - // add JVM statistics - metricRegistry.register("jvm.memory", new MemoryUsageGaugeSet()); - metricRegistry.register("jvm.vm", new JvmAttributeGaugeSet()); - metricRegistry.register("jvm.garbage-collectors", new GarbageCollectorMetricSet()); - metricRegistry.register("jvm.thread-states", new ThreadStatesGaugeSet()); - } - - - private void initReporters() { - Slf4jReporter.Builder builder = Slf4jReporter.forRegistry(metricRegistry); - builder.convertRatesTo(TimeUnit.SECONDS); - builder.convertDurationsTo(TimeUnit.MILLISECONDS); - - builder.outputTo(reporterLogger); - reporter = builder.build(); - - reporter.start(60, TimeUnit.SECONDS); // print every 1 min. - } - - - @PreDestroy - private void shutdown() { - if (reporter == null) { - return; - } - reporter.stop(); - reporter = null; - } -} +package com.nhn.pinpoint.collector.monitor; + +import com.codahale.metrics.JvmAttributeGaugeSet; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.ScheduledReporter; +import com.codahale.metrics.Slf4jReporter; +import com.codahale.metrics.jvm.GarbageCollectorMetricSet; +import com.codahale.metrics.jvm.MemoryUsageGaugeSet; +import com.codahale.metrics.jvm.ThreadStatesGaugeSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + */ +@Component +public class CollectorMetric { + + public static final String REPOTER_LOGGER_NAME = "com.nhn.pinpoint.collector.StateReport"; + + private final Logger reporterLogger = LoggerFactory.getLogger(REPOTER_LOGGER_NAME); + + @Autowired + private MetricRegistry metricRegistry; + + private ScheduledReporter reporter; + + + @PostConstruct + public void start() { + initRegistry(); + initReporters(); + } + + private void initRegistry() { + // add JVM statistics + metricRegistry.register("jvm.memory", new MemoryUsageGaugeSet()); + metricRegistry.register("jvm.vm", new JvmAttributeGaugeSet()); + metricRegistry.register("jvm.garbage-collectors", new GarbageCollectorMetricSet()); + metricRegistry.register("jvm.thread-states", new ThreadStatesGaugeSet()); + } + + + private void initReporters() { + Slf4jReporter.Builder builder = Slf4jReporter.forRegistry(metricRegistry); + builder.convertRatesTo(TimeUnit.SECONDS); + builder.convertDurationsTo(TimeUnit.MILLISECONDS); + + builder.outputTo(reporterLogger); + reporter = builder.build(); + + reporter.start(60, TimeUnit.SECONDS); // print every 1 min. + } + + + @PreDestroy + private void shutdown() { + if (reporter == null) { + return; + } + reporter.stop(); + reporter = null; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/AbstractDispatchHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/AbstractDispatchHandler.java index 13f5c812f803..616d34e2cf7f 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/AbstractDispatchHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/AbstractDispatchHandler.java @@ -1,81 +1,81 @@ -package com.nhn.pinpoint.collector.receiver; - -import com.nhn.pinpoint.collector.handler.Handler; -import com.nhn.pinpoint.collector.handler.RequestResponseHandler; -import com.nhn.pinpoint.collector.handler.SimpleHandler; -import com.nhn.pinpoint.collector.util.AcceptedTimeService; -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * @author emeroad - * @author koo.taejin - */ -public abstract class AbstractDispatchHandler implements DispatchHandler { - - protected Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private AcceptedTimeService acceptedTimeService; - - public AbstractDispatchHandler() { - } - - - @Override - public void dispatchSendMessage(TBase tBase, byte[] packet, int offset, int length) { - // accepted time 마크 - acceptedTimeService.accept(); - // TODO 수정시 dispatch table은 자동으로 바뀌게 변경해도 될듯하다. - SimpleHandler simpleHandler = getSimpleHandler(tBase); - if (simpleHandler != null) { - if (logger.isTraceEnabled()) { - logger.trace("simpleHandler name:{}", simpleHandler.getClass().getName()); - } - simpleHandler.handleSimple(tBase); - return; - } - - Handler handler = getHandler(tBase); - if (handler != null) { - if (logger.isTraceEnabled()) { - logger.trace("handler name:{}", handler.getClass().getName()); - } - handler.handle(tBase, packet, offset, length); - return; - } - - throw new UnsupportedOperationException("Handler not found. Unknown type of data received. tBase=" + tBase); - } - - public TBase dispatchRequestMessage(org.apache.thrift.TBase tBase, byte[] packet, int offset, int length) { - // accepted time 마크 - acceptedTimeService.accept(); - - RequestResponseHandler requestResponseHandler = getRequestResponseHandler(tBase); - if (requestResponseHandler != null) { - if (logger.isTraceEnabled()) { - logger.trace("requestResponseHandler name:{}", requestResponseHandler.getClass().getName()); - } - return requestResponseHandler.handleRequest(tBase); - } - - throw new UnsupportedOperationException("Handler not found. Unknown type of data received. tBase=" + tBase); - }; - - Handler getHandler(TBase tBase) { - return null; - } - - - RequestResponseHandler getRequestResponseHandler(TBase tBase) { - return null; - } - - - SimpleHandler getSimpleHandler(TBase tBase) { - return null; - } -} +package com.nhn.pinpoint.collector.receiver; + +import com.nhn.pinpoint.collector.handler.Handler; +import com.nhn.pinpoint.collector.handler.RequestResponseHandler; +import com.nhn.pinpoint.collector.handler.SimpleHandler; +import com.nhn.pinpoint.collector.util.AcceptedTimeService; +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author emeroad + * @author koo.taejin + */ +public abstract class AbstractDispatchHandler implements DispatchHandler { + + protected Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private AcceptedTimeService acceptedTimeService; + + public AbstractDispatchHandler() { + } + + + @Override + public void dispatchSendMessage(TBase tBase, byte[] packet, int offset, int length) { + // accepted time 마크 + acceptedTimeService.accept(); + // TODO 수정시 dispatch table은 자동으로 바뀌게 변경해도 될듯하다. + SimpleHandler simpleHandler = getSimpleHandler(tBase); + if (simpleHandler != null) { + if (logger.isTraceEnabled()) { + logger.trace("simpleHandler name:{}", simpleHandler.getClass().getName()); + } + simpleHandler.handleSimple(tBase); + return; + } + + Handler handler = getHandler(tBase); + if (handler != null) { + if (logger.isTraceEnabled()) { + logger.trace("handler name:{}", handler.getClass().getName()); + } + handler.handle(tBase, packet, offset, length); + return; + } + + throw new UnsupportedOperationException("Handler not found. Unknown type of data received. tBase=" + tBase); + } + + public TBase dispatchRequestMessage(org.apache.thrift.TBase tBase, byte[] packet, int offset, int length) { + // accepted time 마크 + acceptedTimeService.accept(); + + RequestResponseHandler requestResponseHandler = getRequestResponseHandler(tBase); + if (requestResponseHandler != null) { + if (logger.isTraceEnabled()) { + logger.trace("requestResponseHandler name:{}", requestResponseHandler.getClass().getName()); + } + return requestResponseHandler.handleRequest(tBase); + } + + throw new UnsupportedOperationException("Handler not found. Unknown type of data received. tBase=" + tBase); + }; + + Handler getHandler(TBase tBase) { + return null; + } + + + RequestResponseHandler getRequestResponseHandler(TBase tBase) { + return null; + } + + + SimpleHandler getSimpleHandler(TBase tBase) { + return null; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DataReceiver.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DataReceiver.java index 9042b68fb839..f26082bb9267 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DataReceiver.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DataReceiver.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.collector.receiver; - -/** - * @author emeroad - */ -public interface DataReceiver { - void start(); - - void shutdown(); -} +package com.nhn.pinpoint.collector.receiver; + +/** + * @author emeroad + */ +public interface DataReceiver { + void start(); + + void shutdown(); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DispatchHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DispatchHandler.java index 71bb5f1a1606..73d4fc4c4e96 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DispatchHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/DispatchHandler.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.collector.receiver; - -import org.apache.thrift.TBase; - -/** - * @author emeroad - * @author koo.taejin - */ -public interface DispatchHandler { - - // Send와 Request를 분리한다. 형태 자체가 썩 맘에 들지는 않지만 이후에 변경하자 - - void dispatchSendMessage(TBase tBase, byte[] packet, int offset, int length); - - TBase dispatchRequestMessage(TBase tBase, byte[] packet, int offset, int length); - -} +package com.nhn.pinpoint.collector.receiver; + +import org.apache.thrift.TBase; + +/** + * @author emeroad + * @author koo.taejin + */ +public interface DispatchHandler { + + // Send와 Request를 분리한다. 형태 자체가 썩 맘에 들지는 않지만 이후에 변경하자 + + void dispatchSendMessage(TBase tBase, byte[] packet, int offset, int length); + + TBase dispatchRequestMessage(TBase tBase, byte[] packet, int offset, int length); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/TcpDispatchHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/TcpDispatchHandler.java index 4616d4105dbf..a97f4b34f564 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/TcpDispatchHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/TcpDispatchHandler.java @@ -1,68 +1,68 @@ -package com.nhn.pinpoint.collector.receiver; - -import com.nhn.pinpoint.collector.handler.AgentInfoHandler; -import com.nhn.pinpoint.collector.handler.RequestResponseHandler; -import com.nhn.pinpoint.collector.handler.SimpleHandler; -import com.nhn.pinpoint.thrift.dto.*; - -import org.apache.thrift.TBase; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; - -/** - * @author emeroad - * @author koo.taejin - */ -public class TcpDispatchHandler extends AbstractDispatchHandler { - - @Autowired() - @Qualifier("agentInfoHandler") - private AgentInfoHandler agentInfoHandler; - - @Autowired() - @Qualifier("sqlMetaDataHandler") - private RequestResponseHandler sqlMetaDataHandler; - - @Autowired() - @Qualifier("apiMetaDataHandler") - private RequestResponseHandler apiMetaDataHandler; - - @Autowired() - @Qualifier("stringMetaDataHandler") - private RequestResponseHandler stringMetaDataHandler; - - - - public TcpDispatchHandler() { - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - - @Override - RequestResponseHandler getRequestResponseHandler(TBase tBase) { - if (tBase instanceof TSqlMetaData) { - return sqlMetaDataHandler; - } - if (tBase instanceof TApiMetaData) { - return apiMetaDataHandler; - } - if (tBase instanceof TStringMetaData) { - return stringMetaDataHandler; - } - if (tBase instanceof TAgentInfo) { - return agentInfoHandler; - } - return null; - } - - @Override - SimpleHandler getSimpleHandler(TBase tBase) { - - if (tBase instanceof TAgentInfo) { - return agentInfoHandler; - } - - return null; - } -} +package com.nhn.pinpoint.collector.receiver; + +import com.nhn.pinpoint.collector.handler.AgentInfoHandler; +import com.nhn.pinpoint.collector.handler.RequestResponseHandler; +import com.nhn.pinpoint.collector.handler.SimpleHandler; +import com.nhn.pinpoint.thrift.dto.*; + +import org.apache.thrift.TBase; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * @author emeroad + * @author koo.taejin + */ +public class TcpDispatchHandler extends AbstractDispatchHandler { + + @Autowired() + @Qualifier("agentInfoHandler") + private AgentInfoHandler agentInfoHandler; + + @Autowired() + @Qualifier("sqlMetaDataHandler") + private RequestResponseHandler sqlMetaDataHandler; + + @Autowired() + @Qualifier("apiMetaDataHandler") + private RequestResponseHandler apiMetaDataHandler; + + @Autowired() + @Qualifier("stringMetaDataHandler") + private RequestResponseHandler stringMetaDataHandler; + + + + public TcpDispatchHandler() { + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + + @Override + RequestResponseHandler getRequestResponseHandler(TBase tBase) { + if (tBase instanceof TSqlMetaData) { + return sqlMetaDataHandler; + } + if (tBase instanceof TApiMetaData) { + return apiMetaDataHandler; + } + if (tBase instanceof TStringMetaData) { + return stringMetaDataHandler; + } + if (tBase instanceof TAgentInfo) { + return agentInfoHandler; + } + return null; + } + + @Override + SimpleHandler getSimpleHandler(TBase tBase) { + + if (tBase instanceof TAgentInfo) { + return agentInfoHandler; + } + + return null; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpDispatchHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpDispatchHandler.java index 28a7a39043aa..2c9f7b6b3b0d 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpDispatchHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpDispatchHandler.java @@ -1,35 +1,35 @@ -package com.nhn.pinpoint.collector.receiver; - -import com.nhn.pinpoint.collector.handler.Handler; -import com.nhn.pinpoint.thrift.dto.*; -import org.apache.thrift.TBase; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; - -/** - * @author emeroad - * @author hyungil.jeong - */ -public class UdpDispatchHandler extends AbstractDispatchHandler { - - @Autowired() - @Qualifier("agentStatHandler") - private Handler agentStatHandler; - - - public UdpDispatchHandler() { - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - Handler getHandler(TBase tBase) { - // code값을 기반으로 switch table로 바꾸면 눈꼽만큼 빨라짐. - // FIXME (2014.08) Legacy - TAgentStats should not be sent over the wire. - if (tBase instanceof TAgentStat || tBase instanceof TAgentStatBatch) { - return agentStatHandler; - } - return null; - } - -} +package com.nhn.pinpoint.collector.receiver; + +import com.nhn.pinpoint.collector.handler.Handler; +import com.nhn.pinpoint.thrift.dto.*; +import org.apache.thrift.TBase; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * @author emeroad + * @author hyungil.jeong + */ +public class UdpDispatchHandler extends AbstractDispatchHandler { + + @Autowired() + @Qualifier("agentStatHandler") + private Handler agentStatHandler; + + + public UdpDispatchHandler() { + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + Handler getHandler(TBase tBase) { + // code값을 기반으로 switch table로 바꾸면 눈꼽만큼 빨라짐. + // FIXME (2014.08) Legacy - TAgentStats should not be sent over the wire. + if (tBase instanceof TAgentStat || tBase instanceof TAgentStatBatch) { + return agentStatHandler; + } + return null; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpSpanDispatchHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpSpanDispatchHandler.java index e0cdd2f7924c..6b2e9aa0f58f 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpSpanDispatchHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/UdpSpanDispatchHandler.java @@ -1,42 +1,42 @@ -package com.nhn.pinpoint.collector.receiver; - -import com.nhn.pinpoint.collector.handler.SimpleHandler; -import com.nhn.pinpoint.thrift.dto.*; -import org.apache.thrift.TBase; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; - -/** - * @author emeroad - */ -public class UdpSpanDispatchHandler extends AbstractDispatchHandler { - - - @Autowired() - @Qualifier("spanHandler") - private SimpleHandler spanDataHandler; - - - @Autowired() - @Qualifier("spanChunkHandler") - private SimpleHandler spanChunkHandler; - - public UdpSpanDispatchHandler() { - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - - - @Override - SimpleHandler getSimpleHandler(TBase tBase) { - if (tBase instanceof TSpan) { - return spanDataHandler; - } - if (tBase instanceof TSpanChunk) { - return spanChunkHandler; - } - - return null; - } -} +package com.nhn.pinpoint.collector.receiver; + +import com.nhn.pinpoint.collector.handler.SimpleHandler; +import com.nhn.pinpoint.thrift.dto.*; +import org.apache.thrift.TBase; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * @author emeroad + */ +public class UdpSpanDispatchHandler extends AbstractDispatchHandler { + + + @Autowired() + @Qualifier("spanHandler") + private SimpleHandler spanDataHandler; + + + @Autowired() + @Qualifier("spanChunkHandler") + private SimpleHandler spanChunkHandler; + + public UdpSpanDispatchHandler() { + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + + + @Override + SimpleHandler getSimpleHandler(TBase tBase) { + if (tBase instanceof TSpan) { + return spanDataHandler; + } + if (tBase instanceof TSpanChunk) { + return spanChunkHandler; + } + + return null; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentProperties.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentProperties.java index b52726eac5f9..4a25c9e8f399 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentProperties.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentProperties.java @@ -1,42 +1,42 @@ -package com.nhn.pinpoint.collector.receiver.tcp; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.util.ClassUtils; - -public class AgentProperties { - - // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 - // 변경시 함께 변경 필요 - // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 - - public static final String KEY_HOSTNAME = "hostName"; - public static final String KEY_IP = "ip"; - public static final String KEY_AGENTID = "agentId"; - public static final String KEY_APPLICATION_NAME = "applicationName"; - public static final String KEY_SERVICE_TYPE = "serviceType"; - public static final String KEY_PID = "pid"; - public static final String KEY_VERSION = "version"; - public static final String KEY_START_TIME_MILLIS = "startTimestamp"; - - private final Map properties; - - public AgentProperties(Map properties) { - this.properties = properties; - } - - public T getProperties(String key, Class returnClazz) { - Object value = properties.get(key); - - if (value == null) { - return null; - } - - if (ClassUtils.isAssignable(value.getClass(), returnClazz)) { - return (T) value; - } - - return null; - } - -} +package com.nhn.pinpoint.collector.receiver.tcp; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.util.ClassUtils; + +public class AgentProperties { + + // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 + // 변경시 함께 변경 필요 + // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 + + public static final String KEY_HOSTNAME = "hostName"; + public static final String KEY_IP = "ip"; + public static final String KEY_AGENTID = "agentId"; + public static final String KEY_APPLICATION_NAME = "applicationName"; + public static final String KEY_SERVICE_TYPE = "serviceType"; + public static final String KEY_PID = "pid"; + public static final String KEY_VERSION = "version"; + public static final String KEY_START_TIME_MILLIS = "startTimestamp"; + + private final Map properties; + + public AgentProperties(Map properties) { + this.properties = properties; + } + + public T getProperties(String key, Class returnClazz) { + Object value = properties.get(key); + + if (value == null) { + return null; + } + + if (ClassUtils.isAssignable(value.getClass(), returnClazz)) { + return (T) value; + } + + return null; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentPropertiesType.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentPropertiesType.java index 054cfe90d789..5b5410e3ce8d 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentPropertiesType.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/AgentPropertiesType.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.collector.receiver.tcp; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.util.ClassUtils; - -public enum AgentPropertiesType { - - // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 - // 변경시 함께 변경 필요 - // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 - - HOSTNAME("hostName", String.class), - IP("ip", String.class), - AGENT_ID("agentId", String.class), - APPLICATION_NAME("applicationName", String.class), - SERVICE_TYPE("serviceType", Integer.class), - PID("pid", Integer.class), - VERSION("version", String.class), - START_TIMESTAMP("startTimestamp", Long.class); - - - private final String name; - private final Class clazzType; - - private AgentPropertiesType(String name, Class clazzType) { - this.name = name; - this.clazzType = clazzType; - } - - public String getName() { - return name; - } - - public Class getClazzType() { - return clazzType; - } - - public static boolean hasAllType(Map properties) { - for (AgentPropertiesType type : AgentPropertiesType.values()) { - Object value = properties.get(type.getName()); - - if (value == null) { - return false; - } - - if (!ClassUtils.isAssignable(value.getClass(), type.getClazzType())) { - return false; - } - } - - return true; - } - -} +package com.nhn.pinpoint.collector.receiver.tcp; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.util.ClassUtils; + +public enum AgentPropertiesType { + + // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 + // 변경시 함께 변경 필요 + // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 + + HOSTNAME("hostName", String.class), + IP("ip", String.class), + AGENT_ID("agentId", String.class), + APPLICATION_NAME("applicationName", String.class), + SERVICE_TYPE("serviceType", Integer.class), + PID("pid", Integer.class), + VERSION("version", String.class), + START_TIMESTAMP("startTimestamp", Long.class); + + + private final String name; + private final Class clazzType; + + private AgentPropertiesType(String name, Class clazzType) { + this.name = name; + this.clazzType = clazzType; + } + + public String getName() { + return name; + } + + public Class getClazzType() { + return clazzType; + } + + public static boolean hasAllType(Map properties) { + for (AgentPropertiesType type : AgentPropertiesType.values()) { + Object value = properties.get(type.getName()); + + if (value == null) { + return false; + } + + if (!ClassUtils.isAssignable(value.getClass(), type.getClazzType())) { + return false; + } + } + + return true; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiver.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiver.java index e54611bf7165..d76015ad267d 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiver.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiver.java @@ -19,6 +19,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; +import com.nhn.pinpoint.collector.cluster.zookeeper.ZookeeperClusterService; import com.nhn.pinpoint.collector.receiver.DispatchHandler; import com.nhn.pinpoint.collector.util.PacketUtils; import com.nhn.pinpoint.common.util.ExecutorFactory; @@ -70,13 +71,23 @@ public class TCPReceiver { public TCPReceiver(DispatchHandler dispatchHandler, String bindAddress, int port) { + this(dispatchHandler, bindAddress, port, null); + } + + public TCPReceiver(DispatchHandler dispatchHandler, String bindAddress, int port, ZookeeperClusterService service) { if (dispatchHandler == null) { throw new NullPointerException("dispatchHandler must not be null"); } if (bindAddress == null) { throw new NullPointerException("bindAddress must not be null"); } - this.pinpointServerSocket = new PinpointServerSocket(); + + if (service == null) { + this.pinpointServerSocket = new PinpointServerSocket(); + } else { + this.pinpointServerSocket = new PinpointServerSocket(service.getChannelStateChangeEventListener()); + } + this.dispatchHandler = dispatchHandler; this.bindAddress = bindAddress; this.port = port; diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/AcceptedTimeService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/AcceptedTimeService.java index 6d930425fca5..c900b6c9529b 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/AcceptedTimeService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/AcceptedTimeService.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.collector.util; - -/** - * @author emeroad - */ -public interface AcceptedTimeService { - - void accept(); - - void accept(long time); - - long getAcceptedTime(); +package com.nhn.pinpoint.collector.util; + +/** + * @author emeroad + */ +public interface AcceptedTimeService { + + void accept(); + + void accept(long time); + + long getAcceptedTime(); } \ No newline at end of file diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/AtomicLongUpdateMap.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/AtomicLongUpdateMap.java index b45ee6136dae..20eb8bd9354f 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/AtomicLongUpdateMap.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/AtomicLongUpdateMap.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.collector.util; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicLong; - -/** - * @author emeroad - */ -public class AtomicLongUpdateMap { - // FIXME 매핑정보 매번 저장하지 말고 30~50초 주기로 한 개만 저장되도록 변경. - // OOM 위험성이 있으니 LRU로 변경할지 검토할것? - private final ConcurrentMap cache = new ConcurrentHashMap(1024, 0.75f, 32); - - - public boolean update(final T cacheKey, final long time) { - if (cacheKey == null) { - throw new NullPointerException("cacheKey must not be null"); - } - final AtomicLong hitSlot = cache.get(cacheKey); - if (hitSlot == null ) { - final AtomicLong newTime = new AtomicLong(time); - final AtomicLong oldTime = cache.putIfAbsent(cacheKey, newTime); - if (oldTime == null) { - // 자신이 새롭게 넣는 주체이다. - return true; - } else { - // 이미 키가 존재한다. - return updateTime(time, oldTime); - } - } else { - // 이미 키가 존재할 경우 update한다. - return updateTime(time, hitSlot); - } - } - - private boolean updateTime(final long newTime, final AtomicLong oldTime) { - final long oldLong = oldTime.get(); - if (newTime > oldLong) { - return oldTime.compareAndSet(oldLong, newTime); - } - return false; - } -} +package com.nhn.pinpoint.collector.util; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; + +/** + * @author emeroad + */ +public class AtomicLongUpdateMap { + // FIXME 매핑정보 매번 저장하지 말고 30~50초 주기로 한 개만 저장되도록 변경. + // OOM 위험성이 있으니 LRU로 변경할지 검토할것? + private final ConcurrentMap cache = new ConcurrentHashMap(1024, 0.75f, 32); + + + public boolean update(final T cacheKey, final long time) { + if (cacheKey == null) { + throw new NullPointerException("cacheKey must not be null"); + } + final AtomicLong hitSlot = cache.get(cacheKey); + if (hitSlot == null ) { + final AtomicLong newTime = new AtomicLong(time); + final AtomicLong oldTime = cache.putIfAbsent(cacheKey, newTime); + if (oldTime == null) { + // 자신이 새롭게 넣는 주체이다. + return true; + } else { + // 이미 키가 존재한다. + return updateTime(time, oldTime); + } + } else { + // 이미 키가 존재할 경우 update한다. + return updateTime(time, hitSlot); + } + } + + private boolean updateTime(final long newTime, final AtomicLong oldTime) { + final long oldLong = oldTime.get(); + if (newTime > oldLong) { + return oldTime.compareAndSet(oldLong, newTime); + } + return false; + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/CollectorUtils.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/CollectorUtils.java new file mode 100644 index 000000000000..ae846878c108 --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/CollectorUtils.java @@ -0,0 +1,20 @@ +package com.nhn.pinpoint.collector.util; + +import java.lang.management.ManagementFactory; + +/** + * @author koo.taejin + */ +public final class CollectorUtils { + + private CollectorUtils() { + } + + public static String getServerIdentifier() { + + // 해당 값이 유일한 값이 아닌 경우 MAC주소나 IP주소 등으로 변경할 예정 + // 요렇게 하면 pid@hostname 으로 나옴 (localhost 요런놈은 겹칠 가능성이 존재함) + return ManagementFactory.getRuntimeMXBean().getName(); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMap.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMap.java index 1c2097fdd9a2..63f489befe87 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMap.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMap.java @@ -1,129 +1,129 @@ -package com.nhn.pinpoint.collector.util; - -import com.nhn.pinpoint.common.util.MathUtils; - -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class ConcurrentCounterMap { - - private final int concurrencyLevel; - - private final AtomicInteger entrySelector; - - private final Entry[] entryArray; - - public ConcurrentCounterMap() { - this(16); - } - - public ConcurrentCounterMap(int concurrencyLevel) { - this(concurrencyLevel, 0); - } - - public ConcurrentCounterMap(int concurrencyLevel, int entrySelectorId) { - this.concurrencyLevel = concurrencyLevel; - this.entryArray = createEntry(); - this.entrySelector = new AtomicInteger(entrySelectorId); - } - - private Entry[] createEntry() { - final int concurrencyLevel = this.concurrencyLevel; - - final Entry[] entry = new Entry[concurrencyLevel]; - for (int i = 0; i < entry.length; i++) { - entry[i] = new Entry(); - } - return entry; - } - - private Entry getEntry() { - final int selectKey = MathUtils.fastAbs(entrySelector.getAndIncrement()); - final int mod = selectKey % concurrencyLevel; - return entryArray[mod]; - } - - public void increment(T key, Long increment) { - Entry entry = getEntry(); - entry.increment(key, increment); - } - - public Map remove() { - // copy 최대한 근처의 정합성을 맞추가 위해서 먼저 한번에 copy한다. - final List> copy = removeAll(); - - // merge - final Map mergeMap = new HashMap(); - for (Map mutableLongMap : copy) { - for (Map.Entry entry : mutableLongMap.entrySet()) { - final T key = entry.getKey(); - LongAdder longAdder = mergeMap.get(key); - if (longAdder == null) { - mergeMap.put(key, entry.getValue()); - } else { - longAdder.increment(entry.getValue().get()); - } - } - } - return mergeMap; - } - - private List> removeAll() { - final List> copy = new ArrayList>(entryArray.length); - final int entryArrayLength = entryArray.length; - for (int i = 0; i < entryArrayLength; i++ ) { - Entry tEntry = entryArray[i]; - Map remove = tEntry.remove(); - copy.add(remove); - } - return copy; - } - - - public static class LongAdder { - private long value = 0; - - public LongAdder(long increase) { - this.value = increase; - } - - public void increment(long increment) { - this.value += increment; - } - - public long get() { - return this.value; - } - } - - private static class Entry { - private static final Map EMPTY = Collections.emptyMap(); - - - private Map map = new HashMap(); - - public synchronized void increment(T key, Long increment) { - LongAdder longAdder = map.get(key); - if (longAdder == null) { - map.put(key, new LongAdder(increment)); - } else { - longAdder.increment(increment); - } - } - - public Map remove() { - Map old; - synchronized (this) { - old = this.map; - if (old.isEmpty()) { - return EMPTY; - } - this.map = new HashMap(); - } - return old; - } - } -} +package com.nhn.pinpoint.collector.util; + +import com.nhn.pinpoint.common.util.MathUtils; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class ConcurrentCounterMap { + + private final int concurrencyLevel; + + private final AtomicInteger entrySelector; + + private final Entry[] entryArray; + + public ConcurrentCounterMap() { + this(16); + } + + public ConcurrentCounterMap(int concurrencyLevel) { + this(concurrencyLevel, 0); + } + + public ConcurrentCounterMap(int concurrencyLevel, int entrySelectorId) { + this.concurrencyLevel = concurrencyLevel; + this.entryArray = createEntry(); + this.entrySelector = new AtomicInteger(entrySelectorId); + } + + private Entry[] createEntry() { + final int concurrencyLevel = this.concurrencyLevel; + + final Entry[] entry = new Entry[concurrencyLevel]; + for (int i = 0; i < entry.length; i++) { + entry[i] = new Entry(); + } + return entry; + } + + private Entry getEntry() { + final int selectKey = MathUtils.fastAbs(entrySelector.getAndIncrement()); + final int mod = selectKey % concurrencyLevel; + return entryArray[mod]; + } + + public void increment(T key, Long increment) { + Entry entry = getEntry(); + entry.increment(key, increment); + } + + public Map remove() { + // copy 최대한 근처의 정합성을 맞추가 위해서 먼저 한번에 copy한다. + final List> copy = removeAll(); + + // merge + final Map mergeMap = new HashMap(); + for (Map mutableLongMap : copy) { + for (Map.Entry entry : mutableLongMap.entrySet()) { + final T key = entry.getKey(); + LongAdder longAdder = mergeMap.get(key); + if (longAdder == null) { + mergeMap.put(key, entry.getValue()); + } else { + longAdder.increment(entry.getValue().get()); + } + } + } + return mergeMap; + } + + private List> removeAll() { + final List> copy = new ArrayList>(entryArray.length); + final int entryArrayLength = entryArray.length; + for (int i = 0; i < entryArrayLength; i++ ) { + Entry tEntry = entryArray[i]; + Map remove = tEntry.remove(); + copy.add(remove); + } + return copy; + } + + + public static class LongAdder { + private long value = 0; + + public LongAdder(long increase) { + this.value = increase; + } + + public void increment(long increment) { + this.value += increment; + } + + public long get() { + return this.value; + } + } + + private static class Entry { + private static final Map EMPTY = Collections.emptyMap(); + + + private Map map = new HashMap(); + + public synchronized void increment(T key, Long increment) { + LongAdder longAdder = map.get(key); + if (longAdder == null) { + map.put(key, new LongAdder(increment)); + } else { + longAdder.increment(increment); + } + } + + public Map remove() { + Map old; + synchronized (this) { + old = this.map; + if (old.isEmpty()) { + return EMPTY; + } + this.map = new HashMap(); + } + return old; + } + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/DatagramPacketFactory.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/DatagramPacketFactory.java index 4b1603274649..1620048ef9c3 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/DatagramPacketFactory.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/DatagramPacketFactory.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.collector.util; - -import java.net.DatagramPacket; - -/** - * @author emeroad - */ -public class DatagramPacketFactory implements ObjectPoolFactory { - - private static final int AcceptedSize = 65507; - - @Override - public DatagramPacket create() { - byte[] bytes = new byte[AcceptedSize]; - return new DatagramPacket(bytes, 0, bytes.length); - } - - @Override - public void beforeReturn(DatagramPacket packet) { - packet.setLength(AcceptedSize); - } -} +package com.nhn.pinpoint.collector.util; + +import java.net.DatagramPacket; + +/** + * @author emeroad + */ +public class DatagramPacketFactory implements ObjectPoolFactory { + + private static final int AcceptedSize = 65507; + + @Override + public DatagramPacket create() { + byte[] bytes = new byte[AcceptedSize]; + return new DatagramPacket(bytes, 0, bytes.length); + } + + @Override + public void beforeReturn(DatagramPacket packet) { + packet.setLength(AcceptedSize); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPool.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPool.java index de21a19f9164..d9018e1313ff 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPool.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPool.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.collector.util; - -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * @author emeroad - */ -public class ObjectPool { - // 구지 blocking 할 필요가 없음. queue안에 충분한 양이 무조껀 있어야 됨. 없으면 뭔가 릭임. - private final Queue queue = new ConcurrentLinkedQueue(); - - private final ObjectPoolFactory factory; - - public ObjectPool(ObjectPoolFactory factory, int size) { - if (factory == null) { - throw new NullPointerException("factory"); - } - this.factory = factory; - fill(size); - } - - private void fill(int size) { - for (int i = 0; i < size; i++) { - T t = this.factory.create(); - queue.offer(t); - } - } - - public T getObject() { - T object = queue.poll(); - if (object == null) { - // 동적생성wm. - return factory.create(); - } - return object; - } - - public void returnObject(T t) { - if (t == null) { - return; - } - factory.beforeReturn(t); - queue.offer(t); - } - - -} +package com.nhn.pinpoint.collector.util; + +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * @author emeroad + */ +public class ObjectPool { + // 구지 blocking 할 필요가 없음. queue안에 충분한 양이 무조껀 있어야 됨. 없으면 뭔가 릭임. + private final Queue queue = new ConcurrentLinkedQueue(); + + private final ObjectPoolFactory factory; + + public ObjectPool(ObjectPoolFactory factory, int size) { + if (factory == null) { + throw new NullPointerException("factory"); + } + this.factory = factory; + fill(size); + } + + private void fill(int size) { + for (int i = 0; i < size; i++) { + T t = this.factory.create(); + queue.offer(t); + } + } + + public T getObject() { + T object = queue.poll(); + if (object == null) { + // 동적생성wm. + return factory.create(); + } + return object; + } + + public void returnObject(T t) { + if (t == null) { + return; + } + factory.beforeReturn(t); + queue.offer(t); + } + + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPoolFactory.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPoolFactory.java index aedf92e9ed70..534eb035a162 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPoolFactory.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ObjectPoolFactory.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.collector.util; - -/** - * @author emeroad - */ -public interface ObjectPoolFactory { - T create(); - - void beforeReturn(T t); -} +package com.nhn.pinpoint.collector.util; + +/** + * @author emeroad + */ +public interface ObjectPoolFactory { + T create(); + + void beforeReturn(T t); +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/PacketUtils.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/PacketUtils.java index 7b9b5d358638..1ddd8769bb44 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/PacketUtils.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/PacketUtils.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.collector.util; - -import org.apache.hadoop.hbase.util.Bytes; - -import java.net.DatagramPacket; - -/** - * @author emeroad - */ -public class PacketUtils { - - public static String dumpDatagramPacket(DatagramPacket datagramPacket) { - if (datagramPacket == null) { - return "null"; - } - return Bytes.toStringBinary(datagramPacket.getData(), 0, datagramPacket.getLength()); - } - - public static String dumpByteArray(byte[] bytes) { - if (bytes == null) { - return "null"; - } - return Bytes.toStringBinary(bytes, 0, bytes.length); - } -} +package com.nhn.pinpoint.collector.util; + +import org.apache.hadoop.hbase.util.Bytes; + +import java.net.DatagramPacket; + +/** + * @author emeroad + */ +public class PacketUtils { + + public static String dumpDatagramPacket(DatagramPacket datagramPacket) { + if (datagramPacket == null) { + return "null"; + } + return Bytes.toStringBinary(datagramPacket.getData(), 0, datagramPacket.getLength()); + } + + public static String dumpByteArray(byte[] bytes) { + if (bytes == null) { + return "null"; + } + return Bytes.toStringBinary(bytes, 0, bytes.length); + } +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ThreadLocalAcceptedTimeService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ThreadLocalAcceptedTimeService.java index 2436260ca8cd..338c04ec9663 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/util/ThreadLocalAcceptedTimeService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/util/ThreadLocalAcceptedTimeService.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.collector.util; - -import org.springframework.core.NamedThreadLocal; -import org.springframework.stereotype.Component; - -/** - * @author emeroad - */ -@Component -public class ThreadLocalAcceptedTimeService implements AcceptedTimeService { - - private final ThreadLocal local = new NamedThreadLocal("AcceptedTimeService"); - - @Override - public void accept() { - accept(System.currentTimeMillis()); - } - - @Override - public void accept(long time) { - local.set(time); - } - - @Override - public long getAcceptedTime() { - Long acceptedTime = local.get(); - if (acceptedTime == null) { - return System.currentTimeMillis(); - } - return acceptedTime; - } -} +package com.nhn.pinpoint.collector.util; + +import org.springframework.core.NamedThreadLocal; +import org.springframework.stereotype.Component; + +/** + * @author emeroad + */ +@Component +public class ThreadLocalAcceptedTimeService implements AcceptedTimeService { + + private final ThreadLocal local = new NamedThreadLocal("AcceptedTimeService"); + + @Override + public void accept() { + accept(System.currentTimeMillis()); + } + + @Override + public void accept(long time) { + local.set(time); + } + + @Override + public long getAcceptedTime() { + Long acceptedTime = local.get(); + if (acceptedTime == null) { + return System.currentTimeMillis(); + } + return acceptedTime; + } +} diff --git a/collector/src/main/resources-dev/hbase.properties b/collector/src/main/resources-dev/hbase.properties index 2a2505951094..da431bf76c85 100644 --- a/collector/src/main/resources-dev/hbase.properties +++ b/collector/src/main/resources-dev/hbase.properties @@ -1,3 +1,3 @@ -hbase.client.host=dev.zk.pinpoint.navercorp.com -hbase.client.port=2181 +hbase.client.host=dev.zk.pinpoint.navercorp.com +hbase.client.port=2181 hbase.htable.threads.max=4 \ No newline at end of file diff --git a/collector/src/main/resources-dev/log4j.xml b/collector/src/main/resources-dev/log4j.xml index dfdebd723ae9..ea6d72a9487e 100644 --- a/collector/src/main/resources-dev/log4j.xml +++ b/collector/src/main/resources-dev/log4j.xml @@ -1,75 +1,75 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collector/src/main/resources-dev/pinpoint-collector.properties b/collector/src/main/resources-dev/pinpoint-collector.properties index c1ba611e63aa..4d3356515848 100644 --- a/collector/src/main/resources-dev/pinpoint-collector.properties +++ b/collector/src/main/resources-dev/pinpoint-collector.properties @@ -1,44 +1,48 @@ -#HBaseTemplate에서 사용하는 HtablePool사이즈 -hbase.hTablePoolSize=1024 - -# tcp listen ip -collector.tcpListenIp=0.0.0.0 -collector.tcpListenPort=9994 - -# udp listen ip -collector.udpStatListenIp=0.0.0.0 -collector.udpStatListenPort=9995 - -# L4 tcp 채널 close 무시를 위한 설정. -collector.l4.ip= - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpStatWorkerThread=256 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpStatWorkerQueueSize=5120 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpStatSocketReceiveBufferSize=4194304 - - -# span listen port --------------------------------------------------------------------- -collector.udpSpanListenIp=0.0.0.0 -collector.udpSpanListenPort=9996 - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpSpanWorkerThread=256 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpSpanWorkerQueueSize=5120 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpSpanSocketReceiveBufferSize=4194304 -#$ /sbin/sysctl -a | grep -e rmem -e wmem -#net.core.wmem_max = 524288 -#net.core.rmem_max = 524288 -#net.core.wmem_default = 229376 -#net.core.rmem_default = 229376 -#위 설정을 다음과 같이 수정합니다. -#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 - -# 통계값 flush 주기 -statistics.flushPeriod=1000 \ No newline at end of file +#HBaseTemplate에서 사용하는 HtablePool사이즈 +hbase.hTablePoolSize=1024 + +# tcp listen ip +collector.tcpListenIp=0.0.0.0 +collector.tcpListenPort=9994 + +# udp listen ip +collector.udpStatListenIp=0.0.0.0 +collector.udpStatListenPort=9995 + +# L4 tcp 채널 close 무시를 위한 설정. +collector.l4.ip= + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpStatWorkerThread=256 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpStatWorkerQueueSize=5120 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpStatSocketReceiveBufferSize=4194304 + + +# span listen port --------------------------------------------------------------------- +collector.udpSpanListenIp=0.0.0.0 +collector.udpSpanListenPort=9996 + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpSpanWorkerThread=256 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpSpanWorkerQueueSize=5120 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpSpanSocketReceiveBufferSize=4194304 +#$ /sbin/sysctl -a | grep -e rmem -e wmem +#net.core.wmem_max = 524288 +#net.core.rmem_max = 524288 +#net.core.wmem_default = 229376 +#net.core.rmem_default = 229376 +#위 설정을 다음과 같이 수정합니다. +#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 + +# 통계값 flush 주기 +statistics.flushPeriod=1000 + +cluster.enable=false +cluster.zookeeper.address= +cluster.zookeeper.sessiontimeout= \ No newline at end of file diff --git a/collector/src/main/resources-local/hbase.properties b/collector/src/main/resources-local/hbase.properties index 9a0cb44b9e38..db5d365e0181 100644 --- a/collector/src/main/resources-local/hbase.properties +++ b/collector/src/main/resources-local/hbase.properties @@ -1,5 +1,10 @@ -#hbase.client.host=localhost -hbase.client.host=10.101.17.108 -#hbase.client.host=10.25.149.61 -hbase.client.port=2181 +# local +#hbase.client.host=localhost +# dev +#hbase.client.host=dev.zk.pinpoint.navercorp.com +# local-dev +hbase.client.host=10.101.17.108 +# ?? +#hbase.client.host=10.25.149.61 +hbase.client.port=2181 hbase.htable.threads.max=4 \ No newline at end of file diff --git a/collector/src/main/resources-local/log4j.xml b/collector/src/main/resources-local/log4j.xml index bbf202820d64..59f3d4fb850c 100644 --- a/collector/src/main/resources-local/log4j.xml +++ b/collector/src/main/resources-local/log4j.xml @@ -1,82 +1,82 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collector/src/main/resources-local/pinpoint-collector.properties b/collector/src/main/resources-local/pinpoint-collector.properties index b3c04663e992..1f0f9d9860c7 100644 --- a/collector/src/main/resources-local/pinpoint-collector.properties +++ b/collector/src/main/resources-local/pinpoint-collector.properties @@ -1,44 +1,48 @@ -#HBaseTemplate에서 사용하는 HtablePool사이즈 -hbase.hTablePoolSize=1024 - -# tcp listen ip -collector.tcpListenIp=0.0.0.0 -collector.tcpListenPort=9994 - -# udp listen ip -collector.udpStatListenIp=0.0.0.0 -collector.udpStatListenPort=9995 - -# L4 tcp 채널 close 무시를 위한 설정. -collector.l4.ip= - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpStatWorkerThread=16 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpStatWorkerQueueSize=512 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpStatSocketReceiveBufferSize=4194304 - - -# span listen port --------------------------------------------------------------------- -collector.udpSpanListenIp=0.0.0.0 -collector.udpSpanListenPort=9996 - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpSpanWorkerThread=32 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpSpanWorkerQueueSize=1024 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpSpanSocketReceiveBufferSize=4194304 -#$ /sbin/sysctl -a | grep -e rmem -e wmem -#net.core.wmem_max = 524288 -#net.core.rmem_max = 524288 -#net.core.wmem_default = 229376 -#net.core.rmem_default = 229376 -#위 설정을 다음과 같이 수정합니다. -#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 - -# 통계값 flush 주기 -statistics.flushPeriod=1000 \ No newline at end of file +#HBaseTemplate에서 사용하는 HtablePool사이즈 +hbase.hTablePoolSize=1024 + +# tcp listen ip +collector.tcpListenIp=0.0.0.0 +collector.tcpListenPort=9994 + +# udp listen ip +collector.udpStatListenIp=0.0.0.0 +collector.udpStatListenPort=9995 + +# L4 tcp 채널 close 무시를 위한 설정. +collector.l4.ip= + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpStatWorkerThread=16 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpStatWorkerQueueSize=512 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpStatSocketReceiveBufferSize=4194304 + + +# span listen port --------------------------------------------------------------------- +collector.udpSpanListenIp=0.0.0.0 +collector.udpSpanListenPort=9996 + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpSpanWorkerThread=32 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpSpanWorkerQueueSize=1024 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpSpanSocketReceiveBufferSize=4194304 +#$ /sbin/sysctl -a | grep -e rmem -e wmem +#net.core.wmem_max = 524288 +#net.core.rmem_max = 524288 +#net.core.wmem_default = 229376 +#net.core.rmem_default = 229376 +#위 설정을 다음과 같이 수정합니다. +#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 + +# 통계값 flush 주기 +statistics.flushPeriod=1000 + +cluster.enable=false +cluster.zookeeper.address= +cluster.zookeeper.sessiontimeout= \ No newline at end of file diff --git a/collector/src/main/resources-release/hbase.properties b/collector/src/main/resources-release/hbase.properties index ca6e2c3edc57..57e9701f63ea 100644 --- a/collector/src/main/resources-release/hbase.properties +++ b/collector/src/main/resources-release/hbase.properties @@ -1,3 +1,3 @@ -hbase.client.host=zk.pinpoint.nhncorp.com -hbase.client.port=2181 +hbase.client.host=zk.pinpoint.nhncorp.com +hbase.client.port=2181 hbase.htable.threads.max=4 \ No newline at end of file diff --git a/collector/src/main/resources-release/log4j.xml b/collector/src/main/resources-release/log4j.xml index 60124bc1c6b0..b71a7f7702a8 100644 --- a/collector/src/main/resources-release/log4j.xml +++ b/collector/src/main/resources-release/log4j.xml @@ -1,75 +1,75 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collector/src/main/resources-release/pinpoint-collector.properties b/collector/src/main/resources-release/pinpoint-collector.properties index 5dc4c0e49d9a..6107066817ef 100644 --- a/collector/src/main/resources-release/pinpoint-collector.properties +++ b/collector/src/main/resources-release/pinpoint-collector.properties @@ -1,44 +1,48 @@ -#HBaseTemplate에서 사용하는 HtablePool사이즈 -hbase.hTablePoolSize=1024 - -# tcp listen ip -collector.tcpListenIp=0.0.0.0 -collector.tcpListenPort=9994 - -# udp listen ip -collector.udpStatListenIp=0.0.0.0 -collector.udpStatListenPort=9995 - -# L4 tcp 채널 close 무시를 위한 설정. -collector.l4.ip=10.118.36.61,10.118.36.62 - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpStatWorkerThread=64 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpStatWorkerQueueSize=5120 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpStatSocketReceiveBufferSize=4194304 - - -# span listen port --------------------------------------------------------------------- -collector.udpSpanListenIp=0.0.0.0 -collector.udpSpanListenPort=9996 - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpSpanWorkerThread=512 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpSpanWorkerQueueSize=20000 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpSpanSocketReceiveBufferSize=4194304 -#$ /sbin/sysctl -a | grep -e rmem -e wmem -#net.core.wmem_max = 524288 -#net.core.rmem_max = 524288 -#net.core.wmem_default = 229376 -#net.core.rmem_default = 229376 -#위 설정을 다음과 같이 수정합니다. -#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 - -# 통계값 flush 주기 -statistics.flushPeriod=1000 \ No newline at end of file +#HBaseTemplate에서 사용하는 HtablePool사이즈 +hbase.hTablePoolSize=1024 + +# tcp listen ip +collector.tcpListenIp=0.0.0.0 +collector.tcpListenPort=9994 + +# udp listen ip +collector.udpStatListenIp=0.0.0.0 +collector.udpStatListenPort=9995 + +# L4 tcp 채널 close 무시를 위한 설정. +collector.l4.ip=10.118.36.61,10.118.36.62 + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpStatWorkerThread=64 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpStatWorkerQueueSize=5120 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpStatSocketReceiveBufferSize=4194304 + + +# span listen port --------------------------------------------------------------------- +collector.udpSpanListenIp=0.0.0.0 +collector.udpSpanListenPort=9996 + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpSpanWorkerThread=512 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpSpanWorkerQueueSize=20000 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpSpanSocketReceiveBufferSize=4194304 +#$ /sbin/sysctl -a | grep -e rmem -e wmem +#net.core.wmem_max = 524288 +#net.core.rmem_max = 524288 +#net.core.wmem_default = 229376 +#net.core.rmem_default = 229376 +#위 설정을 다음과 같이 수정합니다. +#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 + +# 통계값 flush 주기 +statistics.flushPeriod=1000 + +cluster.enable=false +cluster.zookeeper.address= +cluster.zookeeper.sessiontimeout= \ No newline at end of file diff --git a/collector/src/main/resources-test/hbase.properties b/collector/src/main/resources-test/hbase.properties index de753ae721f1..374db246f832 100644 --- a/collector/src/main/resources-test/hbase.properties +++ b/collector/src/main/resources-test/hbase.properties @@ -1,4 +1,4 @@ -#hbase.client.host=test.zk.pinpoint.navercorp.com -hbase.client.host=10.101.17.108 -hbase.client.port=2181 +#hbase.client.host=test.zk.pinpoint.navercorp.com +hbase.client.host=10.101.17.108 +hbase.client.port=2181 hbase.htable.threads.max=4 \ No newline at end of file diff --git a/collector/src/main/resources-test/log4j.xml b/collector/src/main/resources-test/log4j.xml index 4fb47d47e6d1..b721556f721b 100644 --- a/collector/src/main/resources-test/log4j.xml +++ b/collector/src/main/resources-test/log4j.xml @@ -1,79 +1,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collector/src/main/resources-test/pinpoint-collector.properties b/collector/src/main/resources-test/pinpoint-collector.properties index b3c04663e992..1f0f9d9860c7 100644 --- a/collector/src/main/resources-test/pinpoint-collector.properties +++ b/collector/src/main/resources-test/pinpoint-collector.properties @@ -1,44 +1,48 @@ -#HBaseTemplate에서 사용하는 HtablePool사이즈 -hbase.hTablePoolSize=1024 - -# tcp listen ip -collector.tcpListenIp=0.0.0.0 -collector.tcpListenPort=9994 - -# udp listen ip -collector.udpStatListenIp=0.0.0.0 -collector.udpStatListenPort=9995 - -# L4 tcp 채널 close 무시를 위한 설정. -collector.l4.ip= - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpStatWorkerThread=16 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpStatWorkerQueueSize=512 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpStatSocketReceiveBufferSize=4194304 - - -# span listen port --------------------------------------------------------------------- -collector.udpSpanListenIp=0.0.0.0 -collector.udpSpanListenPort=9996 - -# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. -collector.udpSpanWorkerThread=32 -# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? -collector.udpSpanWorkerQueueSize=1024 - -#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. -collector.udpSpanSocketReceiveBufferSize=4194304 -#$ /sbin/sysctl -a | grep -e rmem -e wmem -#net.core.wmem_max = 524288 -#net.core.rmem_max = 524288 -#net.core.wmem_default = 229376 -#net.core.rmem_default = 229376 -#위 설정을 다음과 같이 수정합니다. -#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 - -# 통계값 flush 주기 -statistics.flushPeriod=1000 \ No newline at end of file +#HBaseTemplate에서 사용하는 HtablePool사이즈 +hbase.hTablePoolSize=1024 + +# tcp listen ip +collector.tcpListenIp=0.0.0.0 +collector.tcpListenPort=9994 + +# udp listen ip +collector.udpStatListenIp=0.0.0.0 +collector.udpStatListenPort=9995 + +# L4 tcp 채널 close 무시를 위한 설정. +collector.l4.ip= + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpStatWorkerThread=16 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpStatWorkerQueueSize=512 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpStatSocketReceiveBufferSize=4194304 + + +# span listen port --------------------------------------------------------------------- +collector.udpSpanListenIp=0.0.0.0 +collector.udpSpanListenPort=9996 + +# udp메시지를 처리할 thread 수, hbase.hTablePoolSize사이즈와 같이 조절해야 한다. +collector.udpSpanWorkerThread=32 +# udp메시지를 처리할 thread가 모두 동작중일때 요청을 몇개까지 큐잉할지? +collector.udpSpanWorkerQueueSize=1024 + +#udp socket의 receiveBufferSize설정. 만약 udp 손실율이 심할 경우 아래 사항을 체크해볼것. +collector.udpSpanSocketReceiveBufferSize=4194304 +#$ /sbin/sysctl -a | grep -e rmem -e wmem +#net.core.wmem_max = 524288 +#net.core.rmem_max = 524288 +#net.core.wmem_default = 229376 +#net.core.rmem_default = 229376 +#위 설정을 다음과 같이 수정합니다. +#irteamsu$ sudo sysctl -w net.core.rmem_max=4194304 + +# 통계값 flush 주기 +statistics.flushPeriod=1000 + +cluster.enable=false +cluster.zookeeper.address= +cluster.zookeeper.sessiontimeout= \ No newline at end of file diff --git a/collector/src/main/resources/applicationContext.xml b/collector/src/main/resources/applicationContext-collector.xml similarity index 90% rename from collector/src/main/resources/applicationContext.xml rename to collector/src/main/resources/applicationContext-collector.xml index 5166d6db2269..ab5971395209 100644 --- a/collector/src/main/resources/applicationContext.xml +++ b/collector/src/main/resources/applicationContext-collector.xml @@ -1,118 +1,127 @@ - - - - - - - - - - - classpath:hbase.properties - classpath:pinpoint-collector.properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + classpath:hbase.properties + classpath:pinpoint-collector.properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collector/src/main/resources/applicationContext-hbase.xml b/collector/src/main/resources/applicationContext-hbase.xml index 3cdc101c3e4b..e02a2263fb57 100644 --- a/collector/src/main/resources/applicationContext-hbase.xml +++ b/collector/src/main/resources/applicationContext-hbase.xml @@ -1,89 +1,89 @@ - - - - - - - ${hbase.client.host} - ${hbase.client.port} - ${hbase.htable.threads.max} - true - - 30000 - - 10000 - - - - - - - - - - - - - - - - - - 32 - - - - - - - - - - 64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + ${hbase.client.host} + ${hbase.client.port} + ${hbase.htable.threads.max} + true + + 30000 + + 10000 + + + + + + + + + + + + + + + + + + 32 + + + + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/collector/src/main/webapp/WEB-INF/web.xml b/collector/src/main/webapp/WEB-INF/web.xml index e592b4154b31..06d682961b0a 100644 --- a/collector/src/main/webapp/WEB-INF/web.xml +++ b/collector/src/main/webapp/WEB-INF/web.xml @@ -1,79 +1,79 @@ - - - - - log4jConfigLocation - classpath:log4j.xml - - - - - org.springframework.web.context.ContextLoaderListener - - - - - contextConfigLocation - classpath:applicationContext.xml - - - - - - - - - - - - - - - - - - - - - encodingFilter - org.springframework.web.filter.CharacterEncodingFilter - - encoding - UTF-8 - - - - - - - - - - - encodingFilter - /* - - - - - - - - - default - *.css - *.js - *.gif - *.png - *.ico - *.swf - *.html - - - - index.html - + + + + + log4jConfigLocation + classpath:log4j.xml + + + + + org.springframework.web.context.ContextLoaderListener + + + + + contextConfigLocation + classpath:applicationContext-collector.xml + + + + + + + + + + + + + + + + + + + + + encodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + + + + + + + + + encodingFilter + /* + + + + + + + + + default + *.css + *.js + *.gif + *.png + *.ico + *.swf + *.html + + + + index.html + \ No newline at end of file diff --git a/collector/src/main/webapp/monitor/l7check.html b/collector/src/main/webapp/monitor/l7check.html index 2a0075d7fbaa..0fe69d1cd749 100644 --- a/collector/src/main/webapp/monitor/l7check.html +++ b/collector/src/main/webapp/monitor/l7check.html @@ -1,9 +1,9 @@ - - - - - - - health check Success - + + + + + + + health check Success + \ No newline at end of file diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/LoggerTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/LoggerTest.java index 079cf403e918..024b3b3c172b 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/LoggerTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/LoggerTest.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.collector; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class LoggerTest { - @Test - public void log() { - Logger test = LoggerFactory.getLogger(LoggerTest.class); - test.info("info"); - test.debug("debug"); - } -} +package com.nhn.pinpoint.collector; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class LoggerTest { + @Test + public void log() { + Logger test = LoggerFactory.getLogger(LoggerTest.class); + test.info("info"); + test.debug("debug"); + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouterTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouterTest.java new file mode 100644 index 000000000000..2bfd2d6295a6 --- /dev/null +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouterTest.java @@ -0,0 +1,118 @@ +package com.nhn.pinpoint.collector.cluster; + +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.Assert; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.collector.receiver.tcp.AgentProperties; +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import com.nhn.pinpoint.rpc.server.ServerMessageListener; +import com.nhn.pinpoint.rpc.server.ServerStreamChannel; +import com.nhn.pinpoint.rpc.server.SocketChannel; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class ClusterPointRouterTest { + + private static final int DEFAULT_ACCEPTOR_SOCKET_PORT = 22214; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + ClusterPointRouter clusterPointRouter; + + @Test + public void webClusterPointtest() { + WebClusterPoint webClusterPoint = clusterPointRouter.getWebClusterPoint(); + + PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); + pinpointServerSocket.setMessageListener(new PinpointSocketManagerHandler()); + pinpointServerSocket.bind("127.0.0.1", DEFAULT_ACCEPTOR_SOCKET_PORT); + + InetSocketAddress address = new InetSocketAddress("127.0.0.1", DEFAULT_ACCEPTOR_SOCKET_PORT); + + Assert.assertEquals(0, webClusterPoint.getWebClusterList().size()); + webClusterPoint.connectPointIfAbsent(address); + Assert.assertEquals(1, webClusterPoint.getWebClusterList().size()); + webClusterPoint.connectPointIfAbsent(address); + Assert.assertEquals(1, webClusterPoint.getWebClusterList().size()); + + webClusterPoint.disconnectPoint(address); + Assert.assertEquals(0, webClusterPoint.getWebClusterList().size()); + webClusterPoint.disconnectPoint(address); + Assert.assertEquals(0, webClusterPoint.getWebClusterList().size()); + } + + @Test + public void profilerClusterPointtest() { + ProfilerClusterPoint profilerClusterPoint = clusterPointRouter.getProfilerClusterPoint(); + + ChannelContext channelContext = new ChannelContext(null, null); + channelContext.setChannelProperties(getParams()); + + profilerClusterPoint.registerChannelContext(channelContext); + Assert.assertEquals(1, profilerClusterPoint.getChannelContext().size()); + + Assert.assertNull(profilerClusterPoint.getChannelContext("a", "a")); + Assert.assertNull(profilerClusterPoint.getChannelContext("application", "a")); + Assert.assertEquals(channelContext, profilerClusterPoint.getChannelContext("application", "agent")); + + profilerClusterPoint.unregisterChannelContext(channelContext); + Assert.assertEquals(0, profilerClusterPoint.getChannelContext().size()); + Assert.assertNull(profilerClusterPoint.getChannelContext("application", "agent")); + } + + private class PinpointSocketManagerHandler implements ServerMessageListener { + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.warn("Unsupport send received {} {}", sendPacket, channel); + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.warn("Unsupport request received {} {}", requestPacket, channel); + } + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.warn("unsupported streamPacket received {}", streamPacket); + } + + @Override + public int handleEnableWorker(Map properties) { + logger.warn("do handleEnableWorker {}", properties); + return ControlEnableWorkerConfirmPacket.SUCCESS; + } + } + + private Map getParams() { + Map properties = new HashMap(); + + properties.put(AgentProperties.KEY_AGENTID, "agent"); + properties.put(AgentProperties.KEY_APPLICATION_NAME, "application"); + properties.put(AgentProperties.KEY_HOSTNAME, "hostname"); + properties.put(AgentProperties.KEY_IP, "ip"); + properties.put(AgentProperties.KEY_PID, 1111); + properties.put(AgentProperties.KEY_SERVICE_TYPE, 10); + properties.put(AgentProperties.KEY_START_TIME_MILLIS, System.currentTimeMillis()); + properties.put(AgentProperties.KEY_VERSION, "1.0.3-SNAPSHOT"); + + return properties; + } + +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ZookeeperClusterManagerTest2.java b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperEnsembleProfilerClusterServiceTest.java similarity index 67% rename from collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ZookeeperClusterManagerTest2.java rename to collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperEnsembleProfilerClusterServiceTest.java index f001c890a6bc..372f9b6e3b5a 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ZookeeperClusterManagerTest2.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperEnsembleProfilerClusterServiceTest.java @@ -1,227 +1,264 @@ -package com.nhn.pinpoint.collector.cluster; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.apache.curator.test.InstanceSpec; -import org.apache.curator.test.TestingCluster; -import org.apache.curator.test.TestingZooKeeperServer; -import org.junit.Assert; -import org.junit.Test; - -import com.nhn.pinpoint.collector.cluster.zookeeper.ZookeeperClusterManager; -import com.nhn.pinpoint.collector.receiver.tcp.AgentProperties; -import com.nhn.pinpoint.rpc.server.ChannelContext; -import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; - -public class ZookeeperClusterManagerTest2 { - - @Test - public void simpleTest1() throws Exception { - TestingCluster tcluster = null; - try { - tcluster = createZookeeperCluster(3); - - String connectString = getConnectString(tcluster); - - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager(connectString, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperCluster(tcluster); - } - } - - // 연결되어 있는 쥬키퍼 클러스터가 끊어졌을때 해당 이벤트가 유지되는지 - // 테스트 코드만으로는 정확한 확인은 힘들다. 로그를 봐야함 - @Test - public void simpleTest2() throws Exception { - TestingCluster tcluster = null; - try { - tcluster = createZookeeperCluster(3); - - String connectString = getConnectString(tcluster); - - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager(connectString, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - restart(tcluster); - - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperCluster(tcluster); - } - } - - // 연결되어 있는 쥬키퍼 클러스터가 모두 죽었을 경우 - // 그 이후 해당 이벤트가 유지되는지 - // 테스트 코드만으로는 정확한 확인은 힘들다. 로그를 봐야함 - @Test - public void simpleTest3() throws Exception { - TestingCluster tcluster = null; - try { - tcluster = createZookeeperCluster(3); - - String connectString = getConnectString(tcluster); - - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager(connectString, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - stop(tcluster); - - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - restart(tcluster); - - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperCluster(tcluster); - } - } - - - private TestingCluster createZookeeperCluster(int size) throws Exception { - return createZookeeperCluster(size, true); - } - - private TestingCluster createZookeeperCluster(int size, boolean start) throws Exception { - TestingCluster zookeeperCluster = new TestingCluster(size); - - // 주의 cluster 초기화에 시간이 좀 걸림 그래서 테스트에 sleep을 좀 길게 둠 - // 다 된걸 받는 이벤트도 없음 - if (start) { - zookeeperCluster.start(); - Thread.sleep(5000); - } - - return zookeeperCluster; - } - - private void startZookeeperCluster(TestingCluster zookeeperCluster) throws Exception { - zookeeperCluster.start(); - Thread.sleep(5000); - } - - private void restart(TestingCluster zookeeperCluster) throws Exception { - for (TestingZooKeeperServer zookeeperServer : zookeeperCluster.getServers()) { - zookeeperServer.restart(); - } - Thread.sleep(5000); - } - - private void stop(TestingCluster zookeeperCluster) throws Exception { - zookeeperCluster.stop(); - Thread.sleep(5000); - } - - - private void closeZookeeperCluster(TestingCluster zookeeperCluster) throws Exception { - try { - if (zookeeperCluster != null) { - zookeeperCluster.close(); - } - } catch (Exception e) { - } - } - - private String getConnectString(TestingZooKeeperServer testingZooKeeperServer) { - return testingZooKeeperServer.getInstanceSpec().getConnectString(); - } - - private String getConnectString(TestingCluster zookeeperCluster) { - StringBuilder connectString = new StringBuilder(); - - Iterator instanceSpecIterator = zookeeperCluster.getInstances().iterator(); - while (instanceSpecIterator.hasNext()) { - InstanceSpec instanceSpec = instanceSpecIterator.next(); - connectString.append(instanceSpec.getConnectString()); - - if (instanceSpecIterator.hasNext()) { - connectString.append(","); - } - } - - return connectString.toString(); - } - - private PinpointServerSocketStateCode getCode(Map channelContextData) { - String state = (String) channelContextData.get("state"); - return PinpointServerSocketStateCode.getStateCode(state); - } - - private Map getParams() { - Map properties = new HashMap(); - - properties.put(AgentProperties.KEY_AGENTID, "agent"); - properties.put(AgentProperties.KEY_APPLICATION_NAME, "application"); - properties.put(AgentProperties.KEY_HOSTNAME, "hostname"); - properties.put(AgentProperties.KEY_IP, "ip"); - properties.put(AgentProperties.KEY_PID, 1111); - properties.put(AgentProperties.KEY_SERVICE_TYPE, 10); - properties.put(AgentProperties.KEY_START_TIME_MILLIS, System.currentTimeMillis()); - properties.put(AgentProperties.KEY_VERSION, "1.0"); - - return properties; - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import junit.framework.Assert; + +import org.apache.curator.test.InstanceSpec; +import org.apache.curator.test.TestingCluster; +import org.apache.curator.test.TestingZooKeeperServer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.collector.cluster.ClusterPointRouter; +import com.nhn.pinpoint.collector.config.CollectorConfiguration; +import com.nhn.pinpoint.collector.receiver.tcp.AgentProperties; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class ZookeeperEnsembleProfilerClusterServiceTest { + + @Autowired + ClusterPointRouter clusterPointRouter; + + @Test + public void simpleTest1() throws Exception { + TestingCluster tcluster = null; + try { + tcluster = createZookeeperCluster(3); + + String connectString = getConnectString(tcluster); + + CollectorConfiguration collectorConfig = createConfig(connectString); + + + + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperCluster(tcluster); + } + } + + // 연결되어 있는 쥬키퍼 클러스터가 끊어졌을때 해당 이벤트가 유지되는지 + // 테스트 코드만으로는 정확한 확인은 힘들다. 로그를 봐야함 + @Test + public void simpleTest2() throws Exception { + TestingCluster tcluster = null; + try { + tcluster = createZookeeperCluster(3); + + String connectString = getConnectString(tcluster); + + CollectorConfiguration collectorConfig = createConfig(connectString); + + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + restart(tcluster); + + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperCluster(tcluster); + } + } + + // + // 연결되어 있는 쥬키퍼 클러스터가 모두 죽었을 경우 + // 그 이후 해당 이벤트가 유지되는지 + // 테스트 코드만으로는 정확한 확인은 힘들다. 로그를 봐야함 + @Test + public void simpleTest3() throws Exception { + TestingCluster tcluster = null; + try { + tcluster = createZookeeperCluster(3); + + String connectString = getConnectString(tcluster); + + CollectorConfiguration collectorConfig = createConfig(connectString); + + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + stop(tcluster); + + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + restart(tcluster); + + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperCluster(tcluster); + } + } + + private TestingCluster createZookeeperCluster(int size) throws Exception { + return createZookeeperCluster(size, true); + } + + private TestingCluster createZookeeperCluster(int size, boolean start) throws Exception { + TestingCluster zookeeperCluster = new TestingCluster(size); + + // 주의 cluster 초기화에 시간이 좀 걸림 그래서 테스트에 sleep을 좀 길게 둠 + // 다 된걸 받는 이벤트도 없음 + if (start) { + zookeeperCluster.start(); + Thread.sleep(5000); + } + + return zookeeperCluster; + } + + private void startZookeeperCluster(TestingCluster zookeeperCluster) throws Exception { + zookeeperCluster.start(); + Thread.sleep(5000); + } + + private void restart(TestingCluster zookeeperCluster) throws Exception { + for (TestingZooKeeperServer zookeeperServer : zookeeperCluster.getServers()) { + zookeeperServer.restart(); + } + Thread.sleep(5000); + } + + private void stop(TestingCluster zookeeperCluster) throws Exception { + zookeeperCluster.stop(); + Thread.sleep(5000); + } + + private void closeZookeeperCluster(TestingCluster zookeeperCluster) throws Exception { + try { + if (zookeeperCluster != null) { + zookeeperCluster.close(); + } + } catch (Exception e) { + } + } + + private String getConnectString(TestingZooKeeperServer testingZooKeeperServer) { + return testingZooKeeperServer.getInstanceSpec().getConnectString(); + } + + private String getConnectString(TestingCluster zookeeperCluster) { + StringBuilder connectString = new StringBuilder(); + + Iterator instanceSpecIterator = zookeeperCluster.getInstances().iterator(); + while (instanceSpecIterator.hasNext()) { + InstanceSpec instanceSpec = instanceSpecIterator.next(); + connectString.append(instanceSpec.getConnectString()); + + if (instanceSpecIterator.hasNext()) { + connectString.append(","); + } + } + + return connectString.toString(); + } + + private PinpointServerSocketStateCode getCode(Map channelContextData) { + String state = (String) channelContextData.get("state"); + return PinpointServerSocketStateCode.getStateCode(state); + } + + private Map getParams() { + Map properties = new HashMap(); + + properties.put(AgentProperties.KEY_AGENTID, "agent"); + properties.put(AgentProperties.KEY_APPLICATION_NAME, "application"); + properties.put(AgentProperties.KEY_HOSTNAME, "hostname"); + properties.put(AgentProperties.KEY_IP, "ip"); + properties.put(AgentProperties.KEY_PID, 1111); + properties.put(AgentProperties.KEY_SERVICE_TYPE, 10); + properties.put(AgentProperties.KEY_START_TIME_MILLIS, System.currentTimeMillis()); + properties.put(AgentProperties.KEY_VERSION, "1.0"); + + return properties; + } + + private CollectorConfiguration createConfig(String connectString) { + CollectorConfiguration collectorConfig = new CollectorConfiguration(); + + collectorConfig.setClusterEnable(true); + collectorConfig.setClusterAddress(connectString); + collectorConfig.setClusterSessionTimeout(3000); + + return collectorConfig; + } + +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ZookeeperClusterManagerTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterServiceTest.java similarity index 63% rename from collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ZookeeperClusterManagerTest.java rename to collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterServiceTest.java index 50ff2a39315f..111dc08e0ccb 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ZookeeperClusterManagerTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterServiceTest.java @@ -1,249 +1,285 @@ -package com.nhn.pinpoint.collector.cluster; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.curator.test.TestingServer; -import org.junit.Assert; -import org.junit.Test; - -import com.nhn.pinpoint.collector.cluster.zookeeper.ZookeeperClusterManager; -import com.nhn.pinpoint.collector.receiver.tcp.AgentProperties; -import com.nhn.pinpoint.rpc.server.ChannelContext; -import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; - -public class ZookeeperClusterManagerTest { - - private static final int DEFAULT_ACCEPTOR_PORT = 22213; - - // 심플 쥬키퍼 테스트 - // 상태에 변경에 따라 상태 변경이 제대로 되어있는지 확인 - @Test - public void simpleTest1() throws Exception { - TestingServer ts = null; - try { - ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); - - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager("127.0.0.1:" + DEFAULT_ACCEPTOR_PORT, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperServer(ts); - } - } - - // 심플 쥬키퍼 테스트 - // 쥬키퍼와 연결이 끊어져 있는경우 이벤트가 발생했을때 쥬키퍼와 연결이 될 경우 해당 이벤트가 처리되어 있는지 - @Test - public void simpleTest2() throws Exception { - TestingServer ts = null; - try { - - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager("127.0.0.1:" + DEFAULT_ACCEPTOR_PORT, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperServer(ts); - } - } - - // 심플 쥬키퍼 테스트 - // 쥬키퍼와 연결되었을때 이벤트가 등록되었는데 - // 쥬키퍼가 종료 되고 다시 연결될때 해당 이벤트가 상태를 유지 되는지 - @Test - public void simpleTest3() throws Exception { - TestingServer ts = null; - try { - ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); - - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager("127.0.0.1:" + DEFAULT_ACCEPTOR_PORT, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - ts.stop(); - Thread.sleep(1000); - ts.restart(); - Thread.sleep(1000); - - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperServer(ts); - } - } - - // 심플 쥬키퍼 테스트 - // 쥬키퍼와 연결이 끊어져 있는경우 이벤트가 발생했을때 쥬키퍼와 연결이 될 경우 해당 이벤트가 처리되어 있는지 - @Test - public void simpleTest4() throws Exception { - TestingServer ts = null; - try { - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager("127.0.0.1:" + DEFAULT_ACCEPTOR_PORT, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperServer(ts); - } - } - - // 심플 쥬키퍼 테스트 - // 쥬키퍼와 연결되었을때 이벤트가 등록되었는데 - // 쥬키퍼가 종료 되고 다시 연결될때 해당 이벤트가 상태를 유지 되는지 - @Test - public void simpleTest5() throws Exception { - TestingServer ts = null; - try { - ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); - - ZookeeperClusterManager clusterManager = new ZookeeperClusterManager("127.0.0.1:" + DEFAULT_ACCEPTOR_PORT, 3000); - - ChannelContext channelContext = new ChannelContext(null, null, clusterManager); - channelContext.setChannelProperties(getParams()); - - channelContext.changeStateRun(); - Thread.sleep(1000); - Map result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - channelContext.changeStateRunDuplexCommunication(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); - - channelContext.changeStateShutdown(); - Thread.sleep(1000); - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - ts.stop(); - Thread.sleep(1000); - ts.restart(); - Thread.sleep(1000); - - result = clusterManager.getData(channelContext); - Assert.assertNull(getCode(result)); - - clusterManager.close(); - } finally { - closeZookeeperServer(ts); - } - } - - private TestingServer createZookeeperServer(int port) throws Exception { - TestingServer mockZookeeperServer = new TestingServer(port); - mockZookeeperServer.start(); - - return mockZookeeperServer; - } - - private void closeZookeeperServer(TestingServer mockZookeeperServer) throws Exception { - try { - mockZookeeperServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private PinpointServerSocketStateCode getCode(Map channelContextData) { - String state = (String) channelContextData.get("state"); - return PinpointServerSocketStateCode.getStateCode(state); - } - - private Map getParams() { - Map properties = new HashMap(); - - properties.put(AgentProperties.KEY_AGENTID, "agent"); - properties.put(AgentProperties.KEY_APPLICATION_NAME, "application"); - properties.put(AgentProperties.KEY_HOSTNAME, "hostname"); - properties.put(AgentProperties.KEY_IP, "ip"); - properties.put(AgentProperties.KEY_PID, 1111); - properties.put(AgentProperties.KEY_SERVICE_TYPE, 10); - properties.put(AgentProperties.KEY_START_TIME_MILLIS, System.currentTimeMillis()); - properties.put(AgentProperties.KEY_VERSION, "1.0"); - - return properties; - } - -} +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.curator.test.TestingServer; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.collector.cluster.ClusterPointRouter; +import com.nhn.pinpoint.collector.config.CollectorConfiguration; +import com.nhn.pinpoint.collector.receiver.tcp.AgentProperties; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class ZookeeperProfilerClusterServiceTest { + + private static final int DEFAULT_ACCEPTOR_PORT = 22213; + + private static CollectorConfiguration collectorConfig = null; + + @Autowired + ClusterPointRouter clusterPointRouter; + + @BeforeClass + public static void setUp() { + collectorConfig = new CollectorConfiguration(); + + collectorConfig.setClusterEnable(true); + collectorConfig.setClusterAddress("127.0.0.1:" + DEFAULT_ACCEPTOR_PORT); + collectorConfig.setClusterSessionTimeout(3000); + } + + @Test + public void simpleTest1() throws Exception { + TestingServer ts = null; + try { + ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); + + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperServer(ts); + } + } + + // 심플 쥬키퍼 테스트 + // 쥬키퍼와 연결이 끊어져 있는경우 이벤트가 발생했을때 쥬키퍼와 연결이 될 경우 해당 이벤트가 처리되어 있는지 + @Test + public void simpleTest2() throws Exception { + TestingServer ts = null; + try { + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperServer(ts); + } + } + + // 심플 쥬키퍼 테스트 + // 쥬키퍼와 연결되었을때 이벤트가 등록되었는데 + // 쥬키퍼가 종료 되고 다시 연결될때 해당 이벤트가 상태를 유지 되는지 + @Test + public void simpleTest3() throws Exception { + TestingServer ts = null; + try { + ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); + + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + ts.stop(); + Thread.sleep(1000); + ts.restart(); + Thread.sleep(1000); + + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperServer(ts); + } + } + + // 심플 쥬키퍼 테스트 + // 쥬키퍼와 연결이 끊어져 있는경우 이벤트가 발생했을때 쥬키퍼와 연결이 될 경우 해당 이벤트가 처리되어 있는지 + @Test + public void simpleTest4() throws Exception { + TestingServer ts = null; + try { + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperServer(ts); + } + } + + // + // 심플 쥬키퍼 테스트 + // 쥬키퍼와 연결되었을때 이벤트가 등록되었는데 + // 쥬키퍼가 종료 되고 다시 연결될때 해당 이벤트가 상태를 유지 되는지 + @Test + public void simpleTest5() throws Exception { + TestingServer ts = null; + try { + ts = createZookeeperServer(DEFAULT_ACCEPTOR_PORT); + + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + ChannelContext channelContext = new ChannelContext(null, null, service.getChannelStateChangeEventListener()); + channelContext.setChannelProperties(getParams()); + + ZookeeperProfilerClusterManager profilerClusterManager = service.getProfilerClusterManager(); + + channelContext.changeStateRun(); + Thread.sleep(1000); + Map result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + channelContext.changeStateRunDuplexCommunication(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, getCode(result)); + + channelContext.changeStateShutdown(); + Thread.sleep(1000); + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + ts.stop(); + Thread.sleep(1000); + ts.restart(); + Thread.sleep(1000); + + result = profilerClusterManager.getData(channelContext); + Assert.assertNull(getCode(result)); + + service.tearDown(); + } finally { + closeZookeeperServer(ts); + } + } + + private TestingServer createZookeeperServer(int port) throws Exception { + TestingServer mockZookeeperServer = new TestingServer(port); + mockZookeeperServer.start(); + + return mockZookeeperServer; + } + + private void closeZookeeperServer(TestingServer mockZookeeperServer) throws Exception { + try { + mockZookeeperServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private PinpointServerSocketStateCode getCode(Map channelContextData) { + String state = (String) channelContextData.get("state"); + return PinpointServerSocketStateCode.getStateCode(state); + } + + private Map getParams() { + Map properties = new HashMap(); + + properties.put(AgentProperties.KEY_AGENTID, "agent"); + properties.put(AgentProperties.KEY_APPLICATION_NAME, "application"); + properties.put(AgentProperties.KEY_HOSTNAME, "hostname"); + properties.put(AgentProperties.KEY_IP, "ip"); + properties.put(AgentProperties.KEY_PID, 1111); + properties.put(AgentProperties.KEY_SERVICE_TYPE, 10); + properties.put(AgentProperties.KEY_START_TIME_MILLIS, System.currentTimeMillis()); + properties.put(AgentProperties.KEY_VERSION, "1.0"); + + return properties; + } + +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperWebClusterServiceTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperWebClusterServiceTest.java new file mode 100644 index 000000000000..4fb2b3905136 --- /dev/null +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperWebClusterServiceTest.java @@ -0,0 +1,146 @@ +package com.nhn.pinpoint.collector.cluster.zookeeper; + +import java.util.List; +import java.util.Map; + +import junit.framework.Assert; + +import org.apache.curator.test.TestingServer; +import org.apache.zookeeper.WatchedEvent; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.collector.cluster.ClusterPointRouter; +import com.nhn.pinpoint.collector.config.CollectorConfiguration; +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.server.ChannelContext; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import com.nhn.pinpoint.rpc.server.PinpointServerSocketStateCode; +import com.nhn.pinpoint.rpc.server.ServerMessageListener; +import com.nhn.pinpoint.rpc.server.ServerStreamChannel; +import com.nhn.pinpoint.rpc.server.SocketChannel; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class ZookeeperWebClusterServiceTest { + + private static final String PINPOINT_CLUSTER_PATH = "/pinpoint-cluster"; + private static final String PINPOINT_WEB_CLUSTER_PATH = PINPOINT_CLUSTER_PATH + "/web"; + private static final String PINPOINT_PROFILER_CLUSTER_PATH = PINPOINT_CLUSTER_PATH + "/profiler"; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private static final int DEFAULT_ZOOKEEPER_PORT = 22213; + private static final int DEFAULT_ACCEPTOR_SOCKET_PORT = 22214; + + private static CollectorConfiguration collectorConfig = null; + + @Autowired + ClusterPointRouter clusterPointRouter; + + @BeforeClass + public static void setUp() { + collectorConfig = new CollectorConfiguration(); + + collectorConfig.setClusterEnable(true); + collectorConfig.setClusterAddress("127.0.0.1:" + DEFAULT_ZOOKEEPER_PORT); + collectorConfig.setClusterSessionTimeout(3000); + } + + @Test + public void simpleTest1() throws Exception { + TestingServer ts = null; + try { + ts = createZookeeperServer(DEFAULT_ZOOKEEPER_PORT); + + ZookeeperClusterService service = new ZookeeperClusterService(collectorConfig, clusterPointRouter); + service.setUp(); + + PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); + pinpointServerSocket.setMessageListener(new PinpointSocketManagerHandler()); + pinpointServerSocket.bind("127.0.0.1", DEFAULT_ACCEPTOR_SOCKET_PORT); + + ZookeeperClient client = new ZookeeperClient("127.0.0.1:" + DEFAULT_ZOOKEEPER_PORT, 3000, new ZookeeperEventWatcher() { + + @Override + public void process(WatchedEvent event) { + + } + + @Override + public boolean isConnected() { + return true; + } + }); + client.createPath(PINPOINT_WEB_CLUSTER_PATH, true); + client.createNode(PINPOINT_WEB_CLUSTER_PATH + "/" + "127.0.0.1:" + DEFAULT_ACCEPTOR_SOCKET_PORT, "127.0.0.1".getBytes()); + + Thread.sleep(5000); + + List channelContextList = pinpointServerSocket.getDuplexCommunicationChannelContext(); + Assert.assertEquals(1, channelContextList.size()); + + client.close(); + + Thread.sleep(5000); + channelContextList = pinpointServerSocket.getDuplexCommunicationChannelContext(); + Assert.assertEquals(0, channelContextList.size()); + + service.tearDown(); + } finally { + closeZookeeperServer(ts); + } + } + + private TestingServer createZookeeperServer(int port) throws Exception { + TestingServer mockZookeeperServer = new TestingServer(port); + mockZookeeperServer.start(); + + return mockZookeeperServer; + } + + private void closeZookeeperServer(TestingServer mockZookeeperServer) throws Exception { + try { + mockZookeeperServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private PinpointServerSocketStateCode getCode(Map channelContextData) { + String state = (String) channelContextData.get("state"); + return PinpointServerSocketStateCode.getStateCode(state); + } + + private class PinpointSocketManagerHandler implements ServerMessageListener { + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.warn("Unsupport send received {} {}", sendPacket, channel); + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.warn("Unsupport request received {} {}", requestPacket, channel); + } + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.warn("unsupported streamPacket received {}", streamPacket); + } + + @Override + public int handleEnableWorker(Map properties) { + logger.warn("do handleEnableWorker {}", properties); + return ControlEnableWorkerConfirmPacket.SUCCESS; + } + } + +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/config/CollectorConfigurationTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/config/CollectorConfigurationTest.java index ce36bd5b90e7..6841de039bdb 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/config/CollectorConfigurationTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/config/CollectorConfigurationTest.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.collector.config; - -import org.junit.Test; - -import java.io.InputStream; - -/** - * @author emeroad - */ -public class CollectorConfigurationTest { - @Test - public void testReadConfigFile() throws Exception { - InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("pinpoint-collector.properties"); - - - } -} +package com.nhn.pinpoint.collector.config; + +import org.junit.Test; + +import java.io.InputStream; + +/** + * @author emeroad + */ +public class CollectorConfigurationTest { + @Test + public void testReadConfigFile() throws Exception { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("pinpoint-collector.properties"); + + + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentStatDaoTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentStatDaoTest.java index 8e499dbf7b10..2d63d8b2b6eb 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentStatDaoTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentStatDaoTest.java @@ -1,103 +1,103 @@ -package com.nhn.pinpoint.collector.dao.hbase; - -import static org.mockito.Mockito.*; - -import org.apache.hadoop.hbase.client.Put; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.Spy; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.nhn.pinpoint.collector.dao.AgentStatDao; -import com.nhn.pinpoint.collector.mapper.thrift.ThriftBoMapper; -import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; -import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.thrift.dto.TAgentStat; -import com.nhn.pinpoint.thrift.dto.TCpuLoad; -import com.nhn.pinpoint.thrift.dto.TJvmGc; -import com.nhn.pinpoint.thrift.dto.TJvmGcType; -import com.sematext.hbase.wd.AbstractRowKeyDistributor; - -/** - * @author hyungil.jeong - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("classpath:applicationContext-test.xml") -public class HbaseAgentStatDaoTest { - - @Mock - private HbaseOperations2 hbaseTemplate; - - @Spy - @Autowired - @Qualifier("agentStatMemoryGcBoMapper") - private ThriftBoMapper agentStatMemoryGcBoMapper; - - @Spy - @Autowired - @Qualifier("agentStatCpuLoadBoMapper") - private ThriftBoMapper agentStatCpuLoadBoMapper; - - @Spy - @Autowired - @Qualifier("agentStatRowKeyDistributor") - private AbstractRowKeyDistributor rowKeyDistributor; - - @InjectMocks - private AgentStatDao agentStatDao = new HbaseAgentStatDao(); - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testInsert() { - // Given - final String agentId = "agentId"; - final long startTimestamp = Long.MAX_VALUE; - final TAgentStat agentStat = createAgentStat(agentId, startTimestamp, createTJvmGc(agentId, startTimestamp), createTCpuLoad()); - // When - agentStatDao.insert(agentStat); - // Then - verify(hbaseTemplate).put(eq(HBaseTables.AGENT_STAT), isA(Put.class)); - } - - private TAgentStat createAgentStat(String agentId, long startTimestamp, TJvmGc gc, TCpuLoad cpuLoad) { - final TAgentStat agentStat = new TAgentStat(); - agentStat.setAgentId(agentId); - agentStat.setStartTimestamp(startTimestamp); - agentStat.setGc(gc); - agentStat.setCpuLoad(cpuLoad); - return agentStat; - } - - private TJvmGc createTJvmGc(String agentId, long startTimestamp) { - final TJvmGc jvmGc = new TJvmGc(); - jvmGc.setType(TJvmGcType.G1); - jvmGc.setJvmMemoryHeapUsed(Long.MIN_VALUE); - jvmGc.setJvmMemoryHeapMax(Long.MAX_VALUE); - jvmGc.setJvmMemoryNonHeapUsed(Long.MIN_VALUE); - jvmGc.setJvmMemoryNonHeapMax(Long.MAX_VALUE); - jvmGc.setJvmGcOldCount(1L); - jvmGc.setJvmGcOldTime(1L); - return jvmGc; - } - - private TCpuLoad createTCpuLoad() { - final TCpuLoad cpuLoad = new TCpuLoad(); - cpuLoad.setJvmCpuLoad(Double.MIN_VALUE); - cpuLoad.setSystemCpuLoad(Double.MAX_VALUE); - return cpuLoad; - } - -} +package com.nhn.pinpoint.collector.dao.hbase; + +import static org.mockito.Mockito.*; + +import org.apache.hadoop.hbase.client.Put; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.collector.dao.AgentStatDao; +import com.nhn.pinpoint.collector.mapper.thrift.ThriftBoMapper; +import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; +import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.thrift.dto.TAgentStat; +import com.nhn.pinpoint.thrift.dto.TCpuLoad; +import com.nhn.pinpoint.thrift.dto.TJvmGc; +import com.nhn.pinpoint.thrift.dto.TJvmGcType; +import com.sematext.hbase.wd.AbstractRowKeyDistributor; + +/** + * @author hyungil.jeong + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class HbaseAgentStatDaoTest { + + @Mock + private HbaseOperations2 hbaseTemplate; + + @Spy + @Autowired + @Qualifier("agentStatMemoryGcBoMapper") + private ThriftBoMapper agentStatMemoryGcBoMapper; + + @Spy + @Autowired + @Qualifier("agentStatCpuLoadBoMapper") + private ThriftBoMapper agentStatCpuLoadBoMapper; + + @Spy + @Autowired + @Qualifier("agentStatRowKeyDistributor") + private AbstractRowKeyDistributor rowKeyDistributor; + + @InjectMocks + private AgentStatDao agentStatDao = new HbaseAgentStatDao(); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testInsert() { + // Given + final String agentId = "agentId"; + final long startTimestamp = Long.MAX_VALUE; + final TAgentStat agentStat = createAgentStat(agentId, startTimestamp, createTJvmGc(agentId, startTimestamp), createTCpuLoad()); + // When + agentStatDao.insert(agentStat); + // Then + verify(hbaseTemplate).put(eq(HBaseTables.AGENT_STAT), isA(Put.class)); + } + + private TAgentStat createAgentStat(String agentId, long startTimestamp, TJvmGc gc, TCpuLoad cpuLoad) { + final TAgentStat agentStat = new TAgentStat(); + agentStat.setAgentId(agentId); + agentStat.setStartTimestamp(startTimestamp); + agentStat.setGc(gc); + agentStat.setCpuLoad(cpuLoad); + return agentStat; + } + + private TJvmGc createTJvmGc(String agentId, long startTimestamp) { + final TJvmGc jvmGc = new TJvmGc(); + jvmGc.setType(TJvmGcType.G1); + jvmGc.setJvmMemoryHeapUsed(Long.MIN_VALUE); + jvmGc.setJvmMemoryHeapMax(Long.MAX_VALUE); + jvmGc.setJvmMemoryNonHeapUsed(Long.MIN_VALUE); + jvmGc.setJvmMemoryNonHeapMax(Long.MAX_VALUE); + jvmGc.setJvmGcOldCount(1L); + jvmGc.setJvmGcOldTime(1L); + return jvmGc; + } + + private TCpuLoad createTCpuLoad() { + final TCpuLoad cpuLoad = new TCpuLoad(); + cpuLoad.setJvmCpuLoad(Double.MIN_VALUE); + cpuLoad.setSystemCpuLoad(Double.MAX_VALUE); + return cpuLoad; + } + +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDaoTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDaoTest.java index c3f73f5c72e5..fdfc745f4fde 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDaoTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDaoTest.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.collector.dao.hbase; - -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author emeroad - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("classpath:applicationContext-test.xml") -public class HbaseApplicationTraceIndexDaoTest { - - @Autowired - @Qualifier("applicationTraceIndexDistributor") - private RowKeyDistributorByHashPrefix distributorByHashPrefix; - - @Test - public void testInsert() throws Exception { -// distributorByHashPrefix.getOriginalKey(Bytes.read(1)); - } -} +package com.nhn.pinpoint.collector.dao.hbase; + +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author emeroad + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class HbaseApplicationTraceIndexDaoTest { + + @Autowired + @Qualifier("applicationTraceIndexDistributor") + private RowKeyDistributorByHashPrefix distributorByHashPrefix; + + @Test + public void testInsert() throws Exception { +// distributorByHashPrefix.getOriginalKey(Bytes.read(1)); + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTrraceIndexColumnTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTrraceIndexColumnTest.java index 986c5eb8ac29..29fcdb95f4c5 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTrraceIndexColumnTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTrraceIndexColumnTest.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.collector.dao.hbase; - -import junit.framework.Assert; - -import org.junit.Test; - -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import com.nhn.pinpoint.common.util.BytesUtils; - -/** - * - * @author netspider - * - */ -public class HbaseApplicationTrraceIndexColumnTest { - - @Test - public void indexedColumnName() { - final int elapsed = 1234; - final String agentId = "agentId"; - final long agentStartTime = 1234567890L; - final long transactionSequence = 1234567890L; - - // final Buffer buffer= new AutomaticBuffer(32); - // buffer.putPrefixedString(agentId); - // buffer.putSVar(transactionId.getAgentStartTime()); - // buffer.putVar(transactionId.getTransactionSequence()); - // return buffer.getBuffer(); - - final Buffer originalBuffer = new AutomaticBuffer(16); - originalBuffer.putVar(elapsed); - originalBuffer.putPrefixedString(agentId); - originalBuffer.putSVar(agentStartTime); - originalBuffer.putVar(transactionSequence); - - byte[] source = originalBuffer.getBuffer(); - - final Buffer fetched = new OffsetFixedBuffer(source, 0); - - Assert.assertEquals(elapsed, fetched.readVarInt()); - Assert.assertEquals(agentId, fetched.readPrefixedString()); - Assert.assertEquals(agentStartTime, fetched.readSVarLong()); - Assert.assertEquals(transactionSequence, fetched.readVarLong()); - } - - @Test - public void indexColumnName2() { - final int elapsed = 1234; - final byte[] bytes = "thisisbytes".getBytes(); - - final Buffer columnName = new AutomaticBuffer(16); - columnName.put(elapsed); - columnName.putPrefixedBytes(bytes); - } -} +package com.nhn.pinpoint.collector.dao.hbase; + +import junit.framework.Assert; + +import org.junit.Test; + +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import com.nhn.pinpoint.common.util.BytesUtils; + +/** + * + * @author netspider + * + */ +public class HbaseApplicationTrraceIndexColumnTest { + + @Test + public void indexedColumnName() { + final int elapsed = 1234; + final String agentId = "agentId"; + final long agentStartTime = 1234567890L; + final long transactionSequence = 1234567890L; + + // final Buffer buffer= new AutomaticBuffer(32); + // buffer.putPrefixedString(agentId); + // buffer.putSVar(transactionId.getAgentStartTime()); + // buffer.putVar(transactionId.getTransactionSequence()); + // return buffer.getBuffer(); + + final Buffer originalBuffer = new AutomaticBuffer(16); + originalBuffer.putVar(elapsed); + originalBuffer.putPrefixedString(agentId); + originalBuffer.putSVar(agentStartTime); + originalBuffer.putVar(transactionSequence); + + byte[] source = originalBuffer.getBuffer(); + + final Buffer fetched = new OffsetFixedBuffer(source, 0); + + Assert.assertEquals(elapsed, fetched.readVarInt()); + Assert.assertEquals(agentId, fetched.readPrefixedString()); + Assert.assertEquals(agentStartTime, fetched.readSVarLong()); + Assert.assertEquals(transactionSequence, fetched.readVarLong()); + } + + @Test + public void indexColumnName2() { + final int elapsed = 1234; + final byte[] bytes = "thisisbytes".getBytes(); + + final Buffer columnName = new AutomaticBuffer(16); + columnName.put(elapsed); + columnName.putPrefixedBytes(bytes); + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/handler/AgentStatHandlerTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/handler/AgentStatHandlerTest.java index 0a9db1c93044..b755ea84a68e 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/handler/AgentStatHandlerTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/handler/AgentStatHandlerTest.java @@ -1,94 +1,94 @@ -package com.nhn.pinpoint.collector.handler; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import com.nhn.pinpoint.collector.dao.AgentStatDao; -import com.nhn.pinpoint.thrift.dto.TAgentInfo; -import com.nhn.pinpoint.thrift.dto.TAgentStat; -import com.nhn.pinpoint.thrift.dto.TAgentStatBatch; -import com.nhn.pinpoint.thrift.dto.TCpuLoad; -import com.nhn.pinpoint.thrift.dto.TJvmGc; - -/** - * @author hyungil.jeong - */ -public class AgentStatHandlerTest { - - @Mock - private AgentStatDao agentStatDao; - - @InjectMocks - private AgentStatHandler agentStatHandler = new AgentStatHandler(); - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testHandleForTAgentStat() { - // Given - final String agentId = "agentId"; - final long startTimestamp = Long.MAX_VALUE; - final TAgentStat agentStat = createAgentStat(agentId, startTimestamp); - // When - agentStatHandler.handle(agentStat, new byte[0], 0, 0); - // Then - verify(agentStatDao).insert(any(TAgentStat.class)); - } - - @Test - public void testHandleForTAgentStatBatch() { - // Given - final int numBatches = 6; - final String agentId = "agentId"; - final long startTimestamp = Long.MAX_VALUE; - final TAgentStatBatch agentStatBatch = createAgentStatBatch(agentId, startTimestamp, numBatches); - // When - agentStatHandler.handle(agentStatBatch, new byte[0], 0, 0); - // Then - verify(agentStatDao, times(numBatches)).insert(any(TAgentStat.class)); - } - - @Test(expected=IllegalArgumentException.class) - public void handleShouldThrowIllegalArgumentExceptionForIncorrectTBaseObjects() { - // Given - final TAgentInfo wrongTBaseObject = new TAgentInfo(); - // When - agentStatHandler.handle(wrongTBaseObject, new byte[0], 0, 0); - // Then - fail(); - } - - private TAgentStatBatch createAgentStatBatch(String agentId, long startTimestamp, int numBatches) { - final TAgentStatBatch agentStatBatch = new TAgentStatBatch(); - agentStatBatch.setAgentId(agentId); - agentStatBatch.setStartTimestamp(startTimestamp); - final List agentStats = new ArrayList(numBatches); - for (int i = 0; i < numBatches; ++i) { - agentStats.add(createAgentStat(agentId, startTimestamp)); - } - agentStatBatch.setAgentStats(agentStats); - return agentStatBatch; - } - - private TAgentStat createAgentStat(String agentId, long startTimestamp) { - final TAgentStat agentStat = new TAgentStat(); - agentStat.setAgentId(agentId); - agentStat.setStartTimestamp(startTimestamp); - agentStat.setGc(new TJvmGc()); - agentStat.setCpuLoad(new TCpuLoad()); - return agentStat; - } - -} +package com.nhn.pinpoint.collector.handler; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import com.nhn.pinpoint.collector.dao.AgentStatDao; +import com.nhn.pinpoint.thrift.dto.TAgentInfo; +import com.nhn.pinpoint.thrift.dto.TAgentStat; +import com.nhn.pinpoint.thrift.dto.TAgentStatBatch; +import com.nhn.pinpoint.thrift.dto.TCpuLoad; +import com.nhn.pinpoint.thrift.dto.TJvmGc; + +/** + * @author hyungil.jeong + */ +public class AgentStatHandlerTest { + + @Mock + private AgentStatDao agentStatDao; + + @InjectMocks + private AgentStatHandler agentStatHandler = new AgentStatHandler(); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testHandleForTAgentStat() { + // Given + final String agentId = "agentId"; + final long startTimestamp = Long.MAX_VALUE; + final TAgentStat agentStat = createAgentStat(agentId, startTimestamp); + // When + agentStatHandler.handle(agentStat, new byte[0], 0, 0); + // Then + verify(agentStatDao).insert(any(TAgentStat.class)); + } + + @Test + public void testHandleForTAgentStatBatch() { + // Given + final int numBatches = 6; + final String agentId = "agentId"; + final long startTimestamp = Long.MAX_VALUE; + final TAgentStatBatch agentStatBatch = createAgentStatBatch(agentId, startTimestamp, numBatches); + // When + agentStatHandler.handle(agentStatBatch, new byte[0], 0, 0); + // Then + verify(agentStatDao, times(numBatches)).insert(any(TAgentStat.class)); + } + + @Test(expected=IllegalArgumentException.class) + public void handleShouldThrowIllegalArgumentExceptionForIncorrectTBaseObjects() { + // Given + final TAgentInfo wrongTBaseObject = new TAgentInfo(); + // When + agentStatHandler.handle(wrongTBaseObject, new byte[0], 0, 0); + // Then + fail(); + } + + private TAgentStatBatch createAgentStatBatch(String agentId, long startTimestamp, int numBatches) { + final TAgentStatBatch agentStatBatch = new TAgentStatBatch(); + agentStatBatch.setAgentId(agentId); + agentStatBatch.setStartTimestamp(startTimestamp); + final List agentStats = new ArrayList(numBatches); + for (int i = 0; i < numBatches; ++i) { + agentStats.add(createAgentStat(agentId, startTimestamp)); + } + agentStatBatch.setAgentStats(agentStats); + return agentStatBatch; + } + + private TAgentStat createAgentStat(String agentId, long startTimestamp) { + final TAgentStat agentStat = new TAgentStat(); + agentStat.setAgentId(agentId); + agentStat.setStartTimestamp(startTimestamp); + agentStat.setGc(new TJvmGc()); + agentStat.setCpuLoad(new TCpuLoad()); + return agentStat; + } + +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapperTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapperTest.java index 3330845e5381..98224dacfa2f 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapperTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatCpuLoadBoMapperTest.java @@ -1,118 +1,118 @@ -package com.nhn.pinpoint.collector.mapper.thrift; - -import static org.junit.Assert.*; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; -import com.nhn.pinpoint.thrift.dto.TAgentStat; -import com.nhn.pinpoint.thrift.dto.TCpuLoad; - -/** - * @author hyungil.jeong - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("classpath:applicationContext-test.xml") -public class AgentStatCpuLoadBoMapperTest { - - // CPU 사용량 소수점 2자리 표시 - private static final double DELTA = 1e-4; - - @Autowired - private AgentStatCpuLoadBoMapper mapper; - - @Test - public void testValidMap() { - // Given - final TAgentStat thriftObj = new TAgentStat(); - thriftObj.setAgentId("agentId"); - thriftObj.setStartTimestamp(0L); - thriftObj.setTimestamp(1L); - final TCpuLoad cpuLoad = new TCpuLoad(); - cpuLoad.setJvmCpuLoad(99.0D); - cpuLoad.setSystemCpuLoad(99.9D); - thriftObj.setCpuLoad(cpuLoad); - // When - AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); - // Then - assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); - assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); - assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); - assertEquals(mappedBo.getJvmCpuLoad(), cpuLoad.getJvmCpuLoad(), DELTA); - assertEquals(mappedBo.getSystemCpuLoad(), cpuLoad.getSystemCpuLoad(), DELTA); - } - - @Test(expected=NullPointerException.class) - public void mapShouldThrowNpeForNullThriftObject() { - // Given - final TAgentStat thriftObj = null; - // When - mapper.map(thriftObj); - // Then - fail(); - } - - @Test - public void mapShouldNotThrowExceptionForNullCpuLoad() { - // Given - final TAgentStat thriftObj = new TAgentStat(); - thriftObj.setAgentId("agentId"); - thriftObj.setStartTimestamp(0L); - thriftObj.setTimestamp(1L); - thriftObj.setCpuLoad(null); - // When - AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); - // Then - assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); - assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); - assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); - assertTrue(mappedBo.getJvmCpuLoad() < 0.0D); - assertTrue(mappedBo.getSystemCpuLoad() < 0.0D); - } - - @Test - public void mapShouldNotThrowExceptionForNullJvmCpuLoad() { - // Given - final TAgentStat thriftObj = new TAgentStat(); - thriftObj.setAgentId("agentId"); - thriftObj.setStartTimestamp(0L); - thriftObj.setTimestamp(1L); - final TCpuLoad cpuLoad = new TCpuLoad(); - cpuLoad.setJvmCpuLoadIsSet(false); - cpuLoad.setSystemCpuLoad(99.0D); - thriftObj.setCpuLoad(cpuLoad); - // When - AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); - // Then - assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); - assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); - assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); - assertTrue(mappedBo.getJvmCpuLoad() < 0.0D); - assertEquals(mappedBo.getSystemCpuLoad(), cpuLoad.getSystemCpuLoad(), DELTA); - } - - @Test - public void mapShouldNotThrowExceptionForNullSystemCpuLoad() { - // Given - final TAgentStat thriftObj = new TAgentStat(); - thriftObj.setAgentId("agentId"); - thriftObj.setStartTimestamp(0L); - thriftObj.setTimestamp(1L); - final TCpuLoad cpuLoad = new TCpuLoad(); - cpuLoad.setJvmCpuLoad(99.0D); - cpuLoad.setSystemCpuLoadIsSet(false); - thriftObj.setCpuLoad(cpuLoad); - // When - AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); - // Then - assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); - assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); - assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); - assertEquals(mappedBo.getJvmCpuLoad(), cpuLoad.getJvmCpuLoad(), DELTA); - assertTrue(mappedBo.getSystemCpuLoad() < 0.0D); - } -} +package com.nhn.pinpoint.collector.mapper.thrift; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; +import com.nhn.pinpoint.thrift.dto.TAgentStat; +import com.nhn.pinpoint.thrift.dto.TCpuLoad; + +/** + * @author hyungil.jeong + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class AgentStatCpuLoadBoMapperTest { + + // CPU 사용량 소수점 2자리 표시 + private static final double DELTA = 1e-4; + + @Autowired + private AgentStatCpuLoadBoMapper mapper; + + @Test + public void testValidMap() { + // Given + final TAgentStat thriftObj = new TAgentStat(); + thriftObj.setAgentId("agentId"); + thriftObj.setStartTimestamp(0L); + thriftObj.setTimestamp(1L); + final TCpuLoad cpuLoad = new TCpuLoad(); + cpuLoad.setJvmCpuLoad(99.0D); + cpuLoad.setSystemCpuLoad(99.9D); + thriftObj.setCpuLoad(cpuLoad); + // When + AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); + // Then + assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); + assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); + assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); + assertEquals(mappedBo.getJvmCpuLoad(), cpuLoad.getJvmCpuLoad(), DELTA); + assertEquals(mappedBo.getSystemCpuLoad(), cpuLoad.getSystemCpuLoad(), DELTA); + } + + @Test(expected=NullPointerException.class) + public void mapShouldThrowNpeForNullThriftObject() { + // Given + final TAgentStat thriftObj = null; + // When + mapper.map(thriftObj); + // Then + fail(); + } + + @Test + public void mapShouldNotThrowExceptionForNullCpuLoad() { + // Given + final TAgentStat thriftObj = new TAgentStat(); + thriftObj.setAgentId("agentId"); + thriftObj.setStartTimestamp(0L); + thriftObj.setTimestamp(1L); + thriftObj.setCpuLoad(null); + // When + AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); + // Then + assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); + assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); + assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); + assertTrue(mappedBo.getJvmCpuLoad() < 0.0D); + assertTrue(mappedBo.getSystemCpuLoad() < 0.0D); + } + + @Test + public void mapShouldNotThrowExceptionForNullJvmCpuLoad() { + // Given + final TAgentStat thriftObj = new TAgentStat(); + thriftObj.setAgentId("agentId"); + thriftObj.setStartTimestamp(0L); + thriftObj.setTimestamp(1L); + final TCpuLoad cpuLoad = new TCpuLoad(); + cpuLoad.setJvmCpuLoadIsSet(false); + cpuLoad.setSystemCpuLoad(99.0D); + thriftObj.setCpuLoad(cpuLoad); + // When + AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); + // Then + assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); + assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); + assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); + assertTrue(mappedBo.getJvmCpuLoad() < 0.0D); + assertEquals(mappedBo.getSystemCpuLoad(), cpuLoad.getSystemCpuLoad(), DELTA); + } + + @Test + public void mapShouldNotThrowExceptionForNullSystemCpuLoad() { + // Given + final TAgentStat thriftObj = new TAgentStat(); + thriftObj.setAgentId("agentId"); + thriftObj.setStartTimestamp(0L); + thriftObj.setTimestamp(1L); + final TCpuLoad cpuLoad = new TCpuLoad(); + cpuLoad.setJvmCpuLoad(99.0D); + cpuLoad.setSystemCpuLoadIsSet(false); + thriftObj.setCpuLoad(cpuLoad); + // When + AgentStatCpuLoadBo mappedBo = mapper.map(thriftObj); + // Then + assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); + assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); + assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); + assertEquals(mappedBo.getJvmCpuLoad(), cpuLoad.getJvmCpuLoad(), DELTA); + assertTrue(mappedBo.getSystemCpuLoad() < 0.0D); + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapperTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapperTest.java index 184233319728..29e57d541fbe 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapperTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/mapper/thrift/AgentStatMemoryGcBoMapperTest.java @@ -1,89 +1,89 @@ -package com.nhn.pinpoint.collector.mapper.thrift; - -import static org.junit.Assert.*; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; -import com.nhn.pinpoint.thrift.dto.TAgentStat; -import com.nhn.pinpoint.thrift.dto.TJvmGc; -import com.nhn.pinpoint.thrift.dto.TJvmGcType; - -/** - * @author hyungil.jeong - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("classpath:applicationContext-test.xml") -public class AgentStatMemoryGcBoMapperTest { - - @Autowired - private AgentStatMemoryGcBoMapper mapper; - - @Test - public void testValidMap() { - // Given - final TAgentStat thriftObj = new TAgentStat(); - thriftObj.setAgentId("agentId"); - thriftObj.setStartTimestamp(0L); - thriftObj.setTimestamp(1L); - final TJvmGc gc = new TJvmGc(); - gc.setType(TJvmGcType.UNKNOWN); - gc.setJvmMemoryHeapUsed(999L); - gc.setJvmMemoryHeapMax(1000L); - gc.setJvmMemoryNonHeapUsed(1999L); - gc.setJvmMemoryNonHeapMax(2000L); - gc.setJvmGcOldCount(3L); - gc.setJvmGcOldTime(10L); - thriftObj.setGc(gc); - // When - AgentStatMemoryGcBo mappedBo = mapper.map(thriftObj); - // Then - assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); - assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); - assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); - assertEquals(mappedBo.getGcType(), gc.getType().name()); - assertEquals(mappedBo.getJvmMemoryHeapUsed(), gc.getJvmMemoryHeapUsed()); - assertEquals(mappedBo.getJvmMemoryHeapMax(), gc.getJvmMemoryHeapMax()); - assertEquals(mappedBo.getJvmMemoryNonHeapUsed(), gc.getJvmMemoryNonHeapUsed()); - assertEquals(mappedBo.getJvmMemoryNonHeapMax(), gc.getJvmMemoryNonHeapMax()); - assertEquals(mappedBo.getJvmGcOldCount(), gc.getJvmGcOldCount()); - assertEquals(mappedBo.getJvmGcOldTime(), gc.getJvmGcOldTime()); - } - - @Test(expected=NullPointerException.class) - public void mapShouldThrowNpeForNullThriftObject() { - // Given - final TAgentStat thriftObj = null; - // When - mapper.map(thriftObj); - // Then - fail(); - } - - @Test - public void mapShouldNotThrowExceptionForNullGc() { - // Given - final TAgentStat thriftObj = new TAgentStat(); - thriftObj.setAgentId("agentId"); - thriftObj.setStartTimestamp(0L); - thriftObj.setTimestamp(1L); - thriftObj.setGc(null); - // When - AgentStatMemoryGcBo mappedBo = mapper.map(thriftObj); - // Then - assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); - assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); - assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); - assertEquals(mappedBo.getGcType(), TJvmGcType.UNKNOWN.name()); - assertEquals(mappedBo.getJvmMemoryHeapUsed(), 0L); - assertEquals(mappedBo.getJvmMemoryHeapMax(), 0L); - assertEquals(mappedBo.getJvmMemoryNonHeapUsed(), 0L); - assertEquals(mappedBo.getJvmMemoryNonHeapMax(), 0L); - assertEquals(mappedBo.getJvmGcOldCount(), 0L); - assertEquals(mappedBo.getJvmGcOldTime(), 0L); - } -} +package com.nhn.pinpoint.collector.mapper.thrift; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; +import com.nhn.pinpoint.thrift.dto.TAgentStat; +import com.nhn.pinpoint.thrift.dto.TJvmGc; +import com.nhn.pinpoint.thrift.dto.TJvmGcType; + +/** + * @author hyungil.jeong + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext-test.xml") +public class AgentStatMemoryGcBoMapperTest { + + @Autowired + private AgentStatMemoryGcBoMapper mapper; + + @Test + public void testValidMap() { + // Given + final TAgentStat thriftObj = new TAgentStat(); + thriftObj.setAgentId("agentId"); + thriftObj.setStartTimestamp(0L); + thriftObj.setTimestamp(1L); + final TJvmGc gc = new TJvmGc(); + gc.setType(TJvmGcType.UNKNOWN); + gc.setJvmMemoryHeapUsed(999L); + gc.setJvmMemoryHeapMax(1000L); + gc.setJvmMemoryNonHeapUsed(1999L); + gc.setJvmMemoryNonHeapMax(2000L); + gc.setJvmGcOldCount(3L); + gc.setJvmGcOldTime(10L); + thriftObj.setGc(gc); + // When + AgentStatMemoryGcBo mappedBo = mapper.map(thriftObj); + // Then + assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); + assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); + assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); + assertEquals(mappedBo.getGcType(), gc.getType().name()); + assertEquals(mappedBo.getJvmMemoryHeapUsed(), gc.getJvmMemoryHeapUsed()); + assertEquals(mappedBo.getJvmMemoryHeapMax(), gc.getJvmMemoryHeapMax()); + assertEquals(mappedBo.getJvmMemoryNonHeapUsed(), gc.getJvmMemoryNonHeapUsed()); + assertEquals(mappedBo.getJvmMemoryNonHeapMax(), gc.getJvmMemoryNonHeapMax()); + assertEquals(mappedBo.getJvmGcOldCount(), gc.getJvmGcOldCount()); + assertEquals(mappedBo.getJvmGcOldTime(), gc.getJvmGcOldTime()); + } + + @Test(expected=NullPointerException.class) + public void mapShouldThrowNpeForNullThriftObject() { + // Given + final TAgentStat thriftObj = null; + // When + mapper.map(thriftObj); + // Then + fail(); + } + + @Test + public void mapShouldNotThrowExceptionForNullGc() { + // Given + final TAgentStat thriftObj = new TAgentStat(); + thriftObj.setAgentId("agentId"); + thriftObj.setStartTimestamp(0L); + thriftObj.setTimestamp(1L); + thriftObj.setGc(null); + // When + AgentStatMemoryGcBo mappedBo = mapper.map(thriftObj); + // Then + assertEquals(mappedBo.getAgentId(), thriftObj.getAgentId()); + assertEquals(mappedBo.getStartTimestamp(), thriftObj.getStartTimestamp()); + assertEquals(mappedBo.getTimestamp(), thriftObj.getTimestamp()); + assertEquals(mappedBo.getGcType(), TJvmGcType.UNKNOWN.name()); + assertEquals(mappedBo.getJvmMemoryHeapUsed(), 0L); + assertEquals(mappedBo.getJvmMemoryHeapMax(), 0L); + assertEquals(mappedBo.getJvmMemoryNonHeapUsed(), 0L); + assertEquals(mappedBo.getJvmMemoryNonHeapMax(), 0L); + assertEquals(mappedBo.getJvmGcOldCount(), 0L); + assertEquals(mappedBo.getJvmGcOldTime(), 0L); + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverBOTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverBOTest.java index 5dca2df40c35..d39583b595a0 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverBOTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverBOTest.java @@ -1,126 +1,130 @@ -package com.nhn.pinpoint.collector.receiver.tcp; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.Socket; - -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; -import org.apache.thrift.TBase; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.nhn.pinpoint.rpc.packet.Packet; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.ResponsePacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.thrift.dto.TAgentInfo; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; - -/** - * @author koo.taejin - */ -@ContextConfiguration("classpath:applicationContext.xml") -@RunWith(SpringJUnit4ClassRunner.class) -public class TCPReceiverBOTest { - - @Autowired - private TCPReceiver tcpReceiver; - - @Test - public void agentInfoTest1() throws Exception { - Socket socket = connectTcpReceiver(); - OutputStream os = socket.getOutputStream(); - InputStream is = socket.getInputStream(); - - TAgentInfo agentInfo = getAgentInfo(); - encodeAndWrite(os, agentInfo, false); - ResponsePacket responsePacket = readAndDecode(is, 1000); - Assert.assertNull(responsePacket); - - } - - @Test - public void agentInfoTest2() throws Exception { - Socket socket = connectTcpReceiver(); - OutputStream os = socket.getOutputStream(); - InputStream is = socket.getInputStream(); - - TAgentInfo agentInfo = getAgentInfo(); - encodeAndWrite(os, agentInfo, true); - ResponsePacket responsePacket = readAndDecode(is, 1000); - - HeaderTBaseDeserializer deserializer = new HeaderTBaseDeserializerFactory().createDeserializer(); - TResult result = (TResult) deserializer.deserialize(responsePacket.getPayload()); - - Assert.assertTrue(result.isSuccess()); - } - - private Socket connectTcpReceiver() throws IOException { - Socket socket = new Socket(); - socket.connect(new InetSocketAddress("127.0.0.1", 9994)); - - return socket; - } - - private void encodeAndWrite(OutputStream os, TBase tbase, boolean isReqRes) throws Exception { - HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); - byte[] payload = serializer.serialize(tbase); - - Packet packet = null; - if (isReqRes) { - packet = new RequestPacket(payload); - } else { - packet = new SendPacket(payload); - } - - os.write(packet.toBuffer().toByteBuffer().array()); - os.flush(); - } - - private ResponsePacket readAndDecode(InputStream is, long waitTimeMillis) throws Exception { - long startTimeMillis = System.currentTimeMillis(); - - while (true) { - int avaiableRead = is.available(); - - if (avaiableRead > 0) { - byte[] payload = new byte[avaiableRead]; - is.read(payload); - - for (byte b : payload) { - System.out.print("!!" + b); - } - - ChannelBuffer cb = ChannelBuffers.wrappedBuffer(payload); - cb.readByte(); - cb.readByte(); - - - ResponsePacket responsePacket = ResponsePacket.readBuffer((short) 6, cb); - return responsePacket; - } - - Thread.sleep(20); - if (waitTimeMillis < System.currentTimeMillis() - startTimeMillis) { - return null; - } - } - } - - private TAgentInfo getAgentInfo() { - TAgentInfo agentInfo = new TAgentInfo("hostname", "127.0.0.1", "8081", "agentId", "appName", (short) 2, 1111, "1", System.currentTimeMillis()); - return agentInfo; - } - -} +package com.nhn.pinpoint.collector.receiver.tcp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; + +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; +import org.apache.thrift.TBase; +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.nhn.pinpoint.rpc.packet.Packet; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.ResponsePacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.thrift.dto.TAgentInfo; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; + +/** + * @author koo.taejin + */ +@ContextConfiguration("classpath:applicationContext-collector.xml") +@RunWith(SpringJUnit4ClassRunner.class) +public class TCPReceiverBOTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Autowired + private TCPReceiver tcpReceiver; + + @Test + public void agentInfoTest1() throws Exception { + Socket socket = connectTcpReceiver(); + OutputStream os = socket.getOutputStream(); + InputStream is = socket.getInputStream(); + + TAgentInfo agentInfo = getAgentInfo(); + encodeAndWrite(os, agentInfo, false); + ResponsePacket responsePacket = readAndDecode(is, 1000); + Assert.assertNull(responsePacket); + + } + + @Test + public void agentInfoTest2() throws Exception { + Socket socket = connectTcpReceiver(); + OutputStream os = socket.getOutputStream(); + InputStream is = socket.getInputStream(); + + TAgentInfo agentInfo = getAgentInfo(); + encodeAndWrite(os, agentInfo, true); + ResponsePacket responsePacket = readAndDecode(is, 1000); + + HeaderTBaseDeserializer deserializer = new HeaderTBaseDeserializerFactory().createDeserializer(); + TResult result = (TResult) deserializer.deserialize(responsePacket.getPayload()); + + Assert.assertTrue(result.isSuccess()); + } + + private Socket connectTcpReceiver() throws IOException { + Socket socket = new Socket(); + socket.connect(new InetSocketAddress("127.0.0.1", 9994)); + + return socket; + } + + private void encodeAndWrite(OutputStream os, TBase tbase, boolean isReqRes) throws Exception { + HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); + byte[] payload = serializer.serialize(tbase); + + Packet packet = null; + if (isReqRes) { + packet = new RequestPacket(payload); + } else { + packet = new SendPacket(payload); + } + + os.write(packet.toBuffer().toByteBuffer().array()); + os.flush(); + } + + private ResponsePacket readAndDecode(InputStream is, long waitTimeMillis) throws Exception { + long startTimeMillis = System.currentTimeMillis(); + + while (true) { + int avaiableRead = is.available(); + + if (avaiableRead > 0) { + byte[] payload = new byte[avaiableRead]; + is.read(payload); + + for (byte b : payload) { + logger.warn("!!!{}", b); + } + + ChannelBuffer cb = ChannelBuffers.wrappedBuffer(payload); + cb.readByte(); + cb.readByte(); + + + ResponsePacket responsePacket = ResponsePacket.readBuffer((short) 6, cb); + return responsePacket; + } + + Thread.sleep(20); + if (waitTimeMillis < System.currentTimeMillis() - startTimeMillis) { + return null; + } + } + } + + private TAgentInfo getAgentInfo() { + TAgentInfo agentInfo = new TAgentInfo("hostname", "127.0.0.1", "8081", "agentId", "appName", (short) 2, 1111, "1", System.currentTimeMillis()); + return agentInfo; + } + +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverTest.java index 5ba0f9d0d218..64677881912e 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/tcp/TCPReceiverTest.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.collector.receiver.tcp; - -import com.nhn.pinpoint.collector.receiver.UdpDispatchHandler; -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * @author emeroad - */ -public class TCPReceiverTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void server() throws InterruptedException { - TCPReceiver tcpReceiver = new TCPReceiver(new UdpDispatchHandler(), "0.0.0.0", 9099); - tcpReceiver.start(); - Thread.sleep(1000); - tcpReceiver.stop(); - } - - @Test - public void l4ip() throws UnknownHostException { - InetAddress byName = InetAddress.getByName("10.118.202.30"); - logger.debug("byName:{}", byName); - } - - @Test - public void l4ipList() throws UnknownHostException { - String two = "10.118.202.30,10.118.202.31"; - String[] split = two.split(","); - Assert.assertEquals(split.length, 2); - - // 뒤에 빈공간이 있으면 1인가 2인가? - String twoEmpty = "10.118.202.30,"; - String[] splitEmpty = twoEmpty.split(","); - Assert.assertEquals(splitEmpty.length, 1); - - } -} +package com.nhn.pinpoint.collector.receiver.tcp; + +import com.nhn.pinpoint.collector.receiver.UdpDispatchHandler; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * @author emeroad + */ +public class TCPReceiverTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void server() throws InterruptedException { + TCPReceiver tcpReceiver = new TCPReceiver(new UdpDispatchHandler(), "0.0.0.0", 9099); + tcpReceiver.start(); + Thread.sleep(1000); + tcpReceiver.stop(); + } + + @Test + public void l4ip() throws UnknownHostException { + InetAddress byName = InetAddress.getByName("10.118.202.30"); + logger.debug("byName:{}", byName); + } + + @Test + public void l4ipList() throws UnknownHostException { + String two = "10.118.202.30,10.118.202.31"; + String[] split = two.split(","); + Assert.assertEquals(split.length, 2); + + // 뒤에 빈공간이 있으면 1인가 2인가? + String twoEmpty = "10.118.202.30,"; + String[] splitEmpty = twoEmpty.split(","); + Assert.assertEquals(splitEmpty.length, 1); + + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/NettyUdpReceiverTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/NettyUdpReceiverTest.java index 49488c05a875..4f9a49fd7e14 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/NettyUdpReceiverTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/NettyUdpReceiverTest.java @@ -1,107 +1,107 @@ -package com.nhn.pinpoint.collector.receiver.udp; - -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.*; -import org.jboss.netty.channel.socket.DatagramChannelFactory; -import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetSocketAddress; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; - -/** - * @author emeroad - */ -@Ignore -public class NettyUdpReceiverTest { - - public static final int PORT = 30011; - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - CountDownLatch latch = new CountDownLatch(1); - /* - * netty io thread는 udp에서도 single뿐이 안됨. - * worker를 multi로 돌려서 하라고 되있음. - * */ - @Test - public void server() throws IOException, InterruptedException { - - final ConnectionlessBootstrap udpServer = createUdpServer(); - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - udpServer.bind(new InetSocketAddress("127.0.0.1", PORT)); - try { - System.out.println("server-await"); - latch.await(); - } catch (InterruptedException e) { - } - } - }); - thread.start(); - Thread.sleep(1000); - System.out.println("start--------"); -// ExecutorService executorService = Executors.newFixedThreadPool(10); -// for (int i =0; i< 10; i++) { -// executorService.execute(new Runnable() { -// @Override -// public void run() { -// try { - start(); -// } catch (IOException e) { -// e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. -// } -// } -// }); -// } -// executorService.awaitTermination(120, TimeUnit.SECONDS) ; - - - latch.countDown(); - - } - - private void start() throws IOException, InterruptedException { - DatagramSocket so = new DatagramSocket(); - so.connect(new InetSocketAddress("127.0.0.1", PORT)); - int count = 100000; - for (int i = 0 ; i< count; i++) { - byte[] bytes = new byte[100]; - DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length); - so.send(datagramPacket); - Thread.sleep(100); - } - } - - private ConnectionlessBootstrap createUdpServer() { - DatagramChannelFactory udpFactory = new NioDatagramChannelFactory(Executors.newCachedThreadPool(), 4); - ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() { - @Override - public ChannelPipeline getPipeline() throws Exception { - ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("test", new SimpleChannelHandler() { - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - String name = Thread.currentThread().getName(); - System.out.println("sleep-------------------" + name); - Thread.sleep(10000); -// if (!name.equals("New I/O worker #1")) { - logger.info("messageReceived thread-{} message:", Thread.currentThread().getName()); -// } - } - }); - return pipeline; - } - }; - ConnectionlessBootstrap udpBootstrap = new ConnectionlessBootstrap(udpFactory); - udpBootstrap.setPipelineFactory(pipelineFactory); - return udpBootstrap; - } -} +package com.nhn.pinpoint.collector.receiver.udp; + +import org.jboss.netty.bootstrap.ConnectionlessBootstrap; +import org.jboss.netty.channel.*; +import org.jboss.netty.channel.socket.DatagramChannelFactory; +import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetSocketAddress; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; + +/** + * @author emeroad + */ +@Ignore +public class NettyUdpReceiverTest { + + public static final int PORT = 30011; + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + CountDownLatch latch = new CountDownLatch(1); + /* + * netty io thread는 udp에서도 single뿐이 안됨. + * worker를 multi로 돌려서 하라고 되있음. + * */ + @Test + public void server() throws IOException, InterruptedException { + + final ConnectionlessBootstrap udpServer = createUdpServer(); + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + udpServer.bind(new InetSocketAddress("127.0.0.1", PORT)); + try { + logger.debug("server-await"); + latch.await(); + } catch (InterruptedException e) { + } + } + }); + thread.start(); + Thread.sleep(1000); + logger.debug("start--------"); +// ExecutorService executorService = Executors.newFixedThreadPool(10); +// for (int i =0; i< 10; i++) { +// executorService.execute(new Runnable() { +// @Override +// public void run() { +// try { + start(); +// } catch (IOException e) { +// e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. +// } +// } +// }); +// } +// executorService.awaitTermination(120, TimeUnit.SECONDS) ; + + + latch.countDown(); + + } + + private void start() throws IOException, InterruptedException { + DatagramSocket so = new DatagramSocket(); + so.connect(new InetSocketAddress("127.0.0.1", PORT)); + int count = 100000; + for (int i = 0 ; i< count; i++) { + byte[] bytes = new byte[100]; + DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length); + so.send(datagramPacket); + Thread.sleep(100); + } + } + + private ConnectionlessBootstrap createUdpServer() { + DatagramChannelFactory udpFactory = new NioDatagramChannelFactory(Executors.newCachedThreadPool(), 4); + ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() { + @Override + public ChannelPipeline getPipeline() throws Exception { + ChannelPipeline pipeline = Channels.pipeline(); + pipeline.addLast("test", new SimpleChannelHandler() { + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + String name = Thread.currentThread().getName(); + logger.debug("sleep-------------------{}", name); + Thread.sleep(10000); +// if (!name.equals("New I/O worker #1")) { + logger.info("messageReceived thread-{} message:", Thread.currentThread().getName()); +// } + } + }); + return pipeline; + } + }; + ConnectionlessBootstrap udpBootstrap = new ConnectionlessBootstrap(udpFactory); + udpBootstrap.setPipelineFactory(pipelineFactory); + return udpBootstrap; + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/UDPReceiverTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/UDPReceiverTest.java index e41244d2812b..3328b083d7e2 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/UDPReceiverTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/UDPReceiverTest.java @@ -1,80 +1,80 @@ -package com.nhn.pinpoint.collector.receiver.udp; - -import java.io.IOException; -import java.net.*; - -import com.nhn.pinpoint.collector.receiver.DataReceiver; -import com.nhn.pinpoint.collector.receiver.DispatchHandler; -import junit.framework.Assert; - -import org.apache.thrift.TBase; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.support.GenericApplicationContext; - -/** - * @author emeroad - */ -public class UDPReceiverTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - @Ignore - public void startStop() { - try { - DataReceiver receiver = new UDPReceiver("test", new DispatchHandler() { - @Override - public void dispatchSendMessage(TBase tBase, byte[] packet, int offset, int length) { - } - - @Override - public TBase dispatchRequestMessage(TBase tBase, byte[] packet, int offset, int length) { - // TODO Auto-generated method stub - return null; - } - - }, "127.0.0.1", 10999, 1024, 1, 10); -// receiver.start(); -// start 타이밍을 spring안으로 변경하였음. - // start시점을 좀더 정확히 알수 있어야 될거 같음. - // start한 다음에 바로 셧다운하니. receive thread에서 localaddress를 제대로 못찾는 문제가 있음. -// Thread.sleep(1000); - -// receiver.shutdown(); - } catch (Exception e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - } - - @Test - public void hostNullCheck() { - InetSocketAddress address = new InetSocketAddress((InetAddress) null, 90); - logger.debug(address.toString()); - } - - @Test - public void socketBufferSize() throws SocketException { - DatagramSocket datagramSocket = new DatagramSocket(); - int receiveBufferSize = datagramSocket.getReceiveBufferSize(); - logger.debug("{}", receiveBufferSize); - - datagramSocket.setReceiveBufferSize(64*1024*10); - logger.debug("{}", datagramSocket.getReceiveBufferSize()); - - datagramSocket.close(); - } - - @Test - public void sendSocketBufferSize() throws IOException { - DatagramPacket datagramPacket = new DatagramPacket(new byte[0], 0, 0); - - DatagramSocket datagramSocket = new DatagramSocket(); - datagramSocket.connect(new InetSocketAddress("127.0.0.1", 9995)); - - datagramSocket.send(datagramPacket); - datagramSocket.close(); - } -} +package com.nhn.pinpoint.collector.receiver.udp; + +import java.io.IOException; +import java.net.*; + +import com.nhn.pinpoint.collector.receiver.DataReceiver; +import com.nhn.pinpoint.collector.receiver.DispatchHandler; +import junit.framework.Assert; + +import org.apache.thrift.TBase; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.support.GenericApplicationContext; + +/** + * @author emeroad + */ +public class UDPReceiverTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + @Ignore + public void startStop() { + try { + DataReceiver receiver = new UDPReceiver("test", new DispatchHandler() { + @Override + public void dispatchSendMessage(TBase tBase, byte[] packet, int offset, int length) { + } + + @Override + public TBase dispatchRequestMessage(TBase tBase, byte[] packet, int offset, int length) { + // TODO Auto-generated method stub + return null; + } + + }, "127.0.0.1", 10999, 1024, 1, 10); +// receiver.start(); +// start 타이밍을 spring안으로 변경하였음. + // start시점을 좀더 정확히 알수 있어야 될거 같음. + // start한 다음에 바로 셧다운하니. receive thread에서 localaddress를 제대로 못찾는 문제가 있음. +// Thread.sleep(1000); + +// receiver.shutdown(); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + } + + @Test + public void hostNullCheck() { + InetSocketAddress address = new InetSocketAddress((InetAddress) null, 90); + logger.debug(address.toString()); + } + + @Test + public void socketBufferSize() throws SocketException { + DatagramSocket datagramSocket = new DatagramSocket(); + int receiveBufferSize = datagramSocket.getReceiveBufferSize(); + logger.debug("{}", receiveBufferSize); + + datagramSocket.setReceiveBufferSize(64*1024*10); + logger.debug("{}", datagramSocket.getReceiveBufferSize()); + + datagramSocket.close(); + } + + @Test + public void sendSocketBufferSize() throws IOException { + DatagramPacket datagramPacket = new DatagramPacket(new byte[0], 0, 0); + + DatagramSocket datagramSocket = new DatagramSocket(); + datagramSocket.connect(new InetSocketAddress("127.0.0.1", 9995)); + + datagramSocket.send(datagramPacket); + datagramSocket.close(); + } +} diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMapTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMapTest.java index 742b59440276..1c57be711d9b 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMapTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/util/ConcurrentCounterMapTest.java @@ -1,47 +1,47 @@ -package com.nhn.pinpoint.collector.util; - -import junit.framework.Assert; -import org.junit.Test; - -import java.util.Map; - -/** - * @author emeroad - */ -public class ConcurrentCounterMapTest { - @Test - public void testIncrement() throws Exception { - ConcurrentCounterMap cache = new ConcurrentCounterMap(); - cache.increment("a", 1L); - cache.increment("a", 2L); - cache.increment("b", 5L); - - - Map remove = cache.remove(); - Assert.assertEquals(remove.get("a").get(), 3L); - Assert.assertEquals(remove.get("b").get(), 5L); - - cache.increment("a", 1L); - Map remove2 = cache.remove(); - Assert.assertEquals(remove2.get("a").get(), 1L); - } - - @Test - public void testIntegerMax() throws Exception { - ConcurrentCounterMap cache = new ConcurrentCounterMap(16, Integer.MAX_VALUE); - cache.increment("a", 1L); - cache.increment("a", 2L); - cache.increment("b", 5L); - - } - - @Test - public void testIntegerMin() throws Exception { - ConcurrentCounterMap cache = new ConcurrentCounterMap(16, Integer.MIN_VALUE); - cache.increment("a", 1L); - cache.increment("a", 2L); - cache.increment("b", 5L); - - } - -} +package com.nhn.pinpoint.collector.util; + +import junit.framework.Assert; +import org.junit.Test; + +import java.util.Map; + +/** + * @author emeroad + */ +public class ConcurrentCounterMapTest { + @Test + public void testIncrement() throws Exception { + ConcurrentCounterMap cache = new ConcurrentCounterMap(); + cache.increment("a", 1L); + cache.increment("a", 2L); + cache.increment("b", 5L); + + + Map remove = cache.remove(); + Assert.assertEquals(remove.get("a").get(), 3L); + Assert.assertEquals(remove.get("b").get(), 5L); + + cache.increment("a", 1L); + Map remove2 = cache.remove(); + Assert.assertEquals(remove2.get("a").get(), 1L); + } + + @Test + public void testIntegerMax() throws Exception { + ConcurrentCounterMap cache = new ConcurrentCounterMap(16, Integer.MAX_VALUE); + cache.increment("a", 1L); + cache.increment("a", 2L); + cache.increment("b", 5L); + + } + + @Test + public void testIntegerMin() throws Exception { + ConcurrentCounterMap cache = new ConcurrentCounterMap(16, Integer.MIN_VALUE); + cache.increment("a", 1L); + cache.increment("a", 2L); + cache.increment("b", 5L); + + } + +} diff --git a/collector/src/test/resources/applicationContext-test.xml b/collector/src/test/resources/applicationContext-test.xml index a8e6b2bdadea..676233c4d88d 100644 --- a/collector/src/test/resources/applicationContext-test.xml +++ b/collector/src/test/resources/applicationContext-test.xml @@ -1,72 +1,76 @@ - - - - - - - - - - - hbase.properties - pinpoint-collector.properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + hbase.properties + pinpoint-collector.properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/commons/SPAN Performance.txt b/commons/SPAN Performance.txt index b7aa44889c73..a94da4c6056c 100644 --- a/commons/SPAN Performance.txt +++ b/commons/SPAN Performance.txt @@ -1,37 +1,37 @@ -처음에 한 4k나옴. -TraceID를 -3114 - -annotation을 코드로 변경. -2638 - -Span에 있는 데이터를 좀더 정형화함. -read size:2445 -로 줄음. -대신 추가로 서버 정보를 더 넘기면 약간은 더 증가할듯하다. - -desinationId, destinationAddress로 더 fix하게되어 -jdbc url이 중복되고 있어 개선하면 데이터 사이즈가 상당히 줄듯함. - -jdbc에서 rpc name제거시. -1865 - --Xms512m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m - -com.nhn.pinpoint.collector.TomcatProfileDataReceiverMain - -릴리즈전 - - -1.0.4 annotation에 api레코딩 하였을 경우 -3687 -635 -- 4250 -annotation 말고 apiid를 span이나. spanevent에 넣고, traceAgentId를 agentid와 같을 경우 레코딩하지 않도록 변경한 경우. -5%성능향상. -- 4023 -mysql 최초 connect시 이벤트가 30개 이상 발생한 경우 - -IntString으로 멀티 Value를 가질수 있도록 수정후. -Sql에 대한 metadata를 던질 때, SqlId와 Sql-param을 같이 던지게 변경함. +처음에 한 4k나옴. +TraceID를 +3114 + +annotation을 코드로 변경. +2638 + +Span에 있는 데이터를 좀더 정형화함. +read size:2445 +로 줄음. +대신 추가로 서버 정보를 더 넘기면 약간은 더 증가할듯하다. + +desinationId, destinationAddress로 더 fix하게되어 +jdbc url이 중복되고 있어 개선하면 데이터 사이즈가 상당히 줄듯함. + +jdbc에서 rpc name제거시. +1865 + +-Xms512m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m + +com.nhn.pinpoint.collector.TomcatProfileDataReceiverMain + +릴리즈전 + + +1.0.4 annotation에 api레코딩 하였을 경우 +3687 +635 +- 4250 +annotation 말고 apiid를 span이나. spanevent에 넣고, traceAgentId를 agentid와 같을 경우 레코딩하지 않도록 변경한 경우. +5%성능향상. +- 4023 +mysql 최초 connect시 이벤트가 30개 이상 발생한 경우 + +IntString으로 멀티 Value를 가질수 있도록 수정후. +Sql에 대한 metadata를 던질 때, SqlId와 Sql-param을 같이 던지게 변경함. - 4002 \ No newline at end of file diff --git a/commons/VersionScript.groovy b/commons/VersionScript.groovy index 1542cf3f584a..68c002aa24d7 100644 --- a/commons/VersionScript.groovy +++ b/commons/VersionScript.groovy @@ -1,22 +1,22 @@ -println("==== Creating Version.java ===="); -File mainDir = new File("${pom.basedir}/src/main"); -if (mainDir.exists() && !mainDir.isDirectory()) { - println("Main dir does not exist, wont create Version.java!"); - return; -} -File versionFile = new File("${pom.basedir}/src/main/java/com/nhn/pinpoint/common/Version.java"); -if (versionFile.exists() && versionFile.isDirectory()) { - println("Version file exists and is directory! Wont overwrite"); - return; -} -if (versionFile.exists()) { - println("Version file already exists, overwriting!"); -} -println("Creating Version.java File"); -BufferedWriter writer = new BufferedWriter(new FileWriter(versionFile)); - -writer.write("package com.nhn.pinpoint.common;\n"); -writer.write("public final class Version {\n"); -writer.write(" public static final String VERSION = \"${project.version}\";\n"); -writer.write("}"); +println("==== Creating Version.java ===="); +File mainDir = new File("${pom.basedir}/src/main"); +if (mainDir.exists() && !mainDir.isDirectory()) { + println("Main dir does not exist, wont create Version.java!"); + return; +} +File versionFile = new File("${pom.basedir}/src/main/java/com/nhn/pinpoint/common/Version.java"); +if (versionFile.exists() && versionFile.isDirectory()) { + println("Version file exists and is directory! Wont overwrite"); + return; +} +if (versionFile.exists()) { + println("Version file already exists, overwriting!"); +} +println("Creating Version.java File"); +BufferedWriter writer = new BufferedWriter(new FileWriter(versionFile)); + +writer.write("package com.nhn.pinpoint.common;\n"); +writer.write("public final class Version {\n"); +writer.write(" public static final String VERSION = \"${project.version}\";\n"); +writer.write("}"); writer.close(); \ No newline at end of file diff --git a/commons/alterMapStatisticsCallee.sh b/commons/alterMapStatisticsCallee.sh index e014e82cdd23..aec65e3d3f6d 100644 --- a/commons/alterMapStatisticsCallee.sh +++ b/commons/alterMapStatisticsCallee.sh @@ -1,7 +1,7 @@ -disable 'ApplicationMapStatisticsCallee' -alter 'ApplicationMapStatisticsCallee', {NAME => 'D', TTL => 5184000, VERSION => 1} -enable 'ApplicationMapStatisticsCallee' - -disable 'ApplicationMapStatisticsCallee' -alter 'ApplicationMapStatisticsCallee', {NAME => 'D', TTL => 5184000, VERSION => 1, COMPRESSION => 'SNAPPY'} -enable 'ApplicationMapStatisticsCallee' +disable 'ApplicationMapStatisticsCallee' +alter 'ApplicationMapStatisticsCallee', {NAME => 'D', TTL => 5184000, VERSION => 1} +enable 'ApplicationMapStatisticsCallee' + +disable 'ApplicationMapStatisticsCallee' +alter 'ApplicationMapStatisticsCallee', {NAME => 'D', TTL => 5184000, VERSION => 1, COMPRESSION => 'SNAPPY'} +enable 'ApplicationMapStatisticsCallee' diff --git a/commons/build.xml b/commons/build.xml index 239773b53cdc..fa85e7d67bde 100644 --- a/commons/build.xml +++ b/commons/build.xml @@ -1,29 +1,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/commons/compile.txt b/commons/compile.txt index 658d356631a1..e98f9eddc5b3 100644 --- a/commons/compile.txt +++ b/commons/compile.txt @@ -1,5 +1,5 @@ -mvn package -Dmaven.test.skip -이렇게 하면 그냥 패키징 - -mvn package -Dmaven.test.skip -P withThrift +mvn package -Dmaven.test.skip +이렇게 하면 그냥 패키징 + +mvn package -Dmaven.test.skip -P withThrift antrun 하고 패키징 \ No newline at end of file diff --git a/commons/findbugs-exclude.xml b/commons/findbugs-exclude.xml index a4b4e8251d57..0193409a64e7 100644 --- a/commons/findbugs-exclude.xml +++ b/commons/findbugs-exclude.xml @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/commons/flush_htable.sh b/commons/flush_htable.sh index b8b88219bf47..3631d7a05b7a 100644 --- a/commons/flush_htable.sh +++ b/commons/flush_htable.sh @@ -1,20 +1,20 @@ -#!/bin/sh -exec hbase shell < AGENT_NAME_ASC_COMPARATOR = new Comparator() { - @Override - public int compare(AgentInfoBo that, AgentInfoBo other) { - // null 일때 상황이 애매할수 있어서 그냥 ""으로 처리함. - final String thatAgentId = StringUtils.defaultString(that.agentId); - final String otherAgentId = StringUtils.defaultString(other.agentId); - return thatAgentId.compareTo(otherAgentId); - } - }; - - - private String hostname; - private String ip; - private String ports; - private String agentId; - private String applicationName; - private ServiceType serviceType; - private int pid; - private String version; - - private long startTime; - - private long endTimeStamp; - private int endStatus; - - public AgentInfoBo(TAgentInfo agentInfo) { - if (agentInfo == null) { - throw new NullPointerException("agentInfo must not be null"); - } - this.hostname = agentInfo.getHostname(); - this.ip = agentInfo.getIp(); - this.ports = agentInfo.getPorts(); - this.agentId = agentInfo.getAgentId(); - this.applicationName = agentInfo.getApplicationName(); - this.serviceType = ServiceType.findServiceType(agentInfo.getServiceType()); - this.pid = agentInfo.getPid(); - this.version = agentInfo.getVersion(); - - this.startTime = agentInfo.getStartTimestamp(); - - this.endTimeStamp = agentInfo.getEndTimestamp(); - this.endStatus = agentInfo.getEndStatus(); - } - - public AgentInfoBo() { - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public String getPorts() { - return ports; - } - - public void setPorts(String ports) { - this.ports = ports; - } - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public String getApplicationName() { - return applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - - public long getStartTime() { - return startTime; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } - - public long getEndTimeStamp() { - return endTimeStamp; - } - - public int getEndStatus() { - return endStatus; - } - - public int getPid() { - return pid; - } - - public void setPid(int pid) { - this.pid = pid; - } - - public ServiceType getServiceType() { - return serviceType; - } - - public void setServiceType(ServiceType serviceType) { - this.serviceType = serviceType; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public byte[] writeValue() { - final Buffer buffer = new AutomaticBuffer(); - buffer.putPrefixedString(this.getHostname()); - buffer.putPrefixedString(this.getIp()); - buffer.putPrefixedString(this.getPorts()); - buffer.putPrefixedString(this.getApplicationName()); - buffer.put(this.serviceType.getCode()); - buffer.put(this.getPid()); - buffer.putPrefixedString(this.getVersion());; - - buffer.put(this.getStartTime()); - buffer.put(this.getEndTimeStamp()); - buffer.put(this.getEndStatus()); - - return buffer.getBuffer(); - } - - public int readValue(byte[] value) { - final Buffer buffer = new FixedBuffer(value); - this.hostname = buffer.readPrefixedString(); - this.ip = buffer.readPrefixedString(); - this.ports = buffer.readPrefixedString(); - this.applicationName = buffer.readPrefixedString(); - this.serviceType = ServiceType.findServiceType(buffer.readShort()); - this.pid = buffer.readInt(); - this.version = buffer.readPrefixedString(); - - this.startTime = buffer.readLong(); - this.endTimeStamp = buffer.readLong(); - this.endStatus = buffer.readInt(); - - return buffer.getOffset(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((agentId == null) ? 0 : agentId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AgentInfoBo other = (AgentInfoBo) obj; - if (agentId == null) { - if (other.agentId != null) - return false; - } else if (!agentId.equals(other.agentId)) - return false; - return true; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("AgentInfoBo{"); - sb.append("hostname='").append(hostname).append('\''); - sb.append(", ip='").append(ip).append('\''); - sb.append(", ports='").append(ports).append('\''); - sb.append(", agentId='").append(agentId).append('\''); - sb.append(", applicationName='").append(applicationName).append('\''); - sb.append(", serviceType=").append(serviceType); - sb.append(", pid=").append(pid); - sb.append(", version='").append(version).append('\''); - sb.append(", startTime=").append(startTime); - sb.append(", endTimeStamp=").append(endTimeStamp); - sb.append(", endStatus=").append(endStatus); - sb.append('}'); - return sb.toString(); - } - -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.FixedBuffer; +import com.nhn.pinpoint.thrift.dto.TAgentInfo; + +import java.util.Comparator; + +/** + * @author emeroad + */ +public class AgentInfoBo { + + public static final Comparator AGENT_NAME_ASC_COMPARATOR = new Comparator() { + @Override + public int compare(AgentInfoBo that, AgentInfoBo other) { + // null 일때 상황이 애매할수 있어서 그냥 ""으로 처리함. + final String thatAgentId = defaultString(that.agentId); + final String otherAgentId = defaultString(other.agentId); + return thatAgentId.compareTo(otherAgentId); + } + + private String defaultString(String string) { + return string == null ? "" : string; + } + }; + + + private String hostname; + private String ip; + private String ports; + private String agentId; + private String applicationName; + private ServiceType serviceType; + private int pid; + private String version; + + private long startTime; + + private long endTimeStamp; + private int endStatus; + + public AgentInfoBo(TAgentInfo agentInfo) { + if (agentInfo == null) { + throw new NullPointerException("agentInfo must not be null"); + } + this.hostname = agentInfo.getHostname(); + this.ip = agentInfo.getIp(); + this.ports = agentInfo.getPorts(); + this.agentId = agentInfo.getAgentId(); + this.applicationName = agentInfo.getApplicationName(); + this.serviceType = ServiceType.findServiceType(agentInfo.getServiceType()); + this.pid = agentInfo.getPid(); + this.version = agentInfo.getVersion(); + + this.startTime = agentInfo.getStartTimestamp(); + + this.endTimeStamp = agentInfo.getEndTimestamp(); + this.endStatus = agentInfo.getEndStatus(); + } + + public AgentInfoBo() { + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public String getPorts() { + return ports; + } + + public void setPorts(String ports) { + this.ports = ports; + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public long getEndTimeStamp() { + return endTimeStamp; + } + + public int getEndStatus() { + return endStatus; + } + + public int getPid() { + return pid; + } + + public void setPid(int pid) { + this.pid = pid; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public void setServiceType(ServiceType serviceType) { + this.serviceType = serviceType; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public byte[] writeValue() { + final Buffer buffer = new AutomaticBuffer(); + buffer.putPrefixedString(this.getHostname()); + buffer.putPrefixedString(this.getIp()); + buffer.putPrefixedString(this.getPorts()); + buffer.putPrefixedString(this.getApplicationName()); + buffer.put(this.serviceType.getCode()); + buffer.put(this.getPid()); + buffer.putPrefixedString(this.getVersion()); + + buffer.put(this.getStartTime()); + buffer.put(this.getEndTimeStamp()); + buffer.put(this.getEndStatus()); + + return buffer.getBuffer(); + } + + public int readValue(byte[] value) { + final Buffer buffer = new FixedBuffer(value); + this.hostname = buffer.readPrefixedString(); + this.ip = buffer.readPrefixedString(); + this.ports = buffer.readPrefixedString(); + this.applicationName = buffer.readPrefixedString(); + this.serviceType = ServiceType.findServiceType(buffer.readShort()); + this.pid = buffer.readInt(); + this.version = buffer.readPrefixedString(); + + this.startTime = buffer.readLong(); + this.endTimeStamp = buffer.readLong(); + this.endStatus = buffer.readInt(); + + return buffer.getOffset(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((agentId == null) ? 0 : agentId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AgentInfoBo other = (AgentInfoBo) obj; + if (agentId == null) { + if (other.agentId != null) + return false; + } else if (!agentId.equals(other.agentId)) + return false; + return true; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("AgentInfoBo{"); + sb.append("hostname='").append(hostname).append('\''); + sb.append(", ip='").append(ip).append('\''); + sb.append(", ports='").append(ports).append('\''); + sb.append(", agentId='").append(agentId).append('\''); + sb.append(", applicationName='").append(applicationName).append('\''); + sb.append(", serviceType=").append(serviceType); + sb.append(", pid=").append(pid); + sb.append(", version='").append(version).append('\''); + sb.append(", startTime=").append(startTime); + sb.append(", endTimeStamp=").append(endTimeStamp); + sb.append(", endStatus=").append(endStatus); + sb.append('}'); + return sb.toString(); + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentKeyBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentKeyBo.java index 4409150e56e3..6b1f1277a978 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentKeyBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentKeyBo.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.common.bo; - -/** - * @author emeroad - */ -public class AgentKeyBo { - private String agentId; - private String applicationName; - private long agentStartTime; - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public String getApplicationName() { - return applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public long getAgentStartTime() { - return agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - } -} +package com.nhn.pinpoint.common.bo; + +/** + * @author emeroad + */ +public class AgentKeyBo { + private String agentId; + private String applicationName; + private long agentStartTime; + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public long getAgentStartTime() { + return agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBo.java index b84c4ae92218..e2a3f11e98d1 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBo.java @@ -1,136 +1,136 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.FixedBuffer; - -/** - * @author hyungil.jeong - */ -public class AgentStatCpuLoadBo { - - private final String agentId; - private final long startTimestamp; - private final long timestamp; - private final double jvmCpuLoad; - private final double systemCpuLoad; - - private AgentStatCpuLoadBo(Builder builder) { - this.agentId = builder.agentId; - this.startTimestamp = builder.startTimestamp; - this.timestamp = builder.timestamp; - this.jvmCpuLoad = builder.jvmCpuLoad; - this.systemCpuLoad = builder.systemCpuLoad; - } - - public String getAgentId() { - return agentId; - } - - public long getStartTimestamp() { - return startTimestamp; - } - - public long getTimestamp() { - return timestamp; - } - - public double getJvmCpuLoad() { - return jvmCpuLoad; - } - - public double getSystemCpuLoad() { - return systemCpuLoad; - } - - public byte[] writeValue() { - final Buffer buffer = new AutomaticBuffer(); - buffer.putPrefixedString(this.agentId); - buffer.put(this.startTimestamp); - buffer.put(this.timestamp); - buffer.put(this.jvmCpuLoad); - buffer.put(this.systemCpuLoad); - return buffer.getBuffer(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("AgentStatCpuLoadBo{"); - sb.append("agentId='").append(this.agentId).append('\''); - sb.append(", startTimestamp=").append(this.startTimestamp); - sb.append(", timestamp=").append(this.timestamp); - sb.append(", jvmCpuLoad=").append(this.jvmCpuLoad); - sb.append(", systemCpuLoad=").append(this.systemCpuLoad); - sb.append('}'); - return sb.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((agentId == null) ? 0 : agentId.hashCode()); - result = prime * result + (int)(startTimestamp ^ (startTimestamp >>> 32)); - result = prime * result + (int)(timestamp ^ (timestamp >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AgentStatCpuLoadBo other = (AgentStatCpuLoadBo)obj; - if (agentId == null) { - if (other.agentId != null) - return false; - } else if (!agentId.equals(other.agentId)) - return false; - if (startTimestamp != other.startTimestamp) - return false; - if (timestamp != other.timestamp) - return false; - return true; - } - - public static class Builder { - private static final double UNSUPPORTED = -1.0D; - private final String agentId; - private final long startTimestamp; - private final long timestamp; - private double jvmCpuLoad = UNSUPPORTED; - private double systemCpuLoad = UNSUPPORTED; - - public Builder(final byte[] value) { - final Buffer buffer = new FixedBuffer(value); - this.agentId = buffer.readPrefixedString(); - this.startTimestamp = buffer.readLong(); - this.timestamp = buffer.readLong(); - this.jvmCpuLoad = buffer.readDouble(); - this.systemCpuLoad = buffer.readDouble(); - } - - public Builder(String agentId, long startTimestamp, long timestamp) { - this.agentId = agentId; - this.startTimestamp = startTimestamp; - this.timestamp = timestamp; - } - - public Builder jvmCpuLoad(double jvmCpuLoad) { - this.jvmCpuLoad = jvmCpuLoad; - return this; - } - - public Builder systemCpuLoad(double systemCpuLoad) { - this.systemCpuLoad = systemCpuLoad; - return this; - } - - public AgentStatCpuLoadBo build() { - return new AgentStatCpuLoadBo(this); - } - } -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.FixedBuffer; + +/** + * @author hyungil.jeong + */ +public class AgentStatCpuLoadBo { + + private final String agentId; + private final long startTimestamp; + private final long timestamp; + private final double jvmCpuLoad; + private final double systemCpuLoad; + + private AgentStatCpuLoadBo(Builder builder) { + this.agentId = builder.agentId; + this.startTimestamp = builder.startTimestamp; + this.timestamp = builder.timestamp; + this.jvmCpuLoad = builder.jvmCpuLoad; + this.systemCpuLoad = builder.systemCpuLoad; + } + + public String getAgentId() { + return agentId; + } + + public long getStartTimestamp() { + return startTimestamp; + } + + public long getTimestamp() { + return timestamp; + } + + public double getJvmCpuLoad() { + return jvmCpuLoad; + } + + public double getSystemCpuLoad() { + return systemCpuLoad; + } + + public byte[] writeValue() { + final Buffer buffer = new AutomaticBuffer(); + buffer.putPrefixedString(this.agentId); + buffer.put(this.startTimestamp); + buffer.put(this.timestamp); + buffer.put(this.jvmCpuLoad); + buffer.put(this.systemCpuLoad); + return buffer.getBuffer(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("AgentStatCpuLoadBo{"); + sb.append("agentId='").append(this.agentId).append('\''); + sb.append(", startTimestamp=").append(this.startTimestamp); + sb.append(", timestamp=").append(this.timestamp); + sb.append(", jvmCpuLoad=").append(this.jvmCpuLoad); + sb.append(", systemCpuLoad=").append(this.systemCpuLoad); + sb.append('}'); + return sb.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((agentId == null) ? 0 : agentId.hashCode()); + result = prime * result + (int)(startTimestamp ^ (startTimestamp >>> 32)); + result = prime * result + (int)(timestamp ^ (timestamp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AgentStatCpuLoadBo other = (AgentStatCpuLoadBo)obj; + if (agentId == null) { + if (other.agentId != null) + return false; + } else if (!agentId.equals(other.agentId)) + return false; + if (startTimestamp != other.startTimestamp) + return false; + if (timestamp != other.timestamp) + return false; + return true; + } + + public static class Builder { + private static final double UNSUPPORTED = -1.0D; + private final String agentId; + private final long startTimestamp; + private final long timestamp; + private double jvmCpuLoad = UNSUPPORTED; + private double systemCpuLoad = UNSUPPORTED; + + public Builder(final byte[] value) { + final Buffer buffer = new FixedBuffer(value); + this.agentId = buffer.readPrefixedString(); + this.startTimestamp = buffer.readLong(); + this.timestamp = buffer.readLong(); + this.jvmCpuLoad = buffer.readDouble(); + this.systemCpuLoad = buffer.readDouble(); + } + + public Builder(String agentId, long startTimestamp, long timestamp) { + this.agentId = agentId; + this.startTimestamp = startTimestamp; + this.timestamp = timestamp; + } + + public Builder jvmCpuLoad(double jvmCpuLoad) { + this.jvmCpuLoad = jvmCpuLoad; + return this; + } + + public Builder systemCpuLoad(double systemCpuLoad) { + this.systemCpuLoad = systemCpuLoad; + return this; + } + + public AgentStatCpuLoadBo build() { + return new AgentStatCpuLoadBo(this); + } + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBo.java index 1fd3be4c08ff..ca156a631f7a 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBo.java @@ -1,210 +1,210 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.FixedBuffer; - -/** - * @author hyungil.jeong - */ -public class AgentStatMemoryGcBo { - - private final String agentId; - private final long startTimestamp; - private final long timestamp; - private final String gcType; - private final long jvmMemoryHeapUsed; - private final long jvmMemoryHeapMax; - private final long jvmMemoryNonHeapUsed; - private final long jvmMemoryNonHeapMax; - private final long jvmGcOldCount; - private final long jvmGcOldTime; - - private AgentStatMemoryGcBo(Builder builder) { - this.agentId = builder.agentId; - this.startTimestamp = builder.startTimestamp; - this.timestamp = builder.timestamp; - this.gcType = builder.gcType; - this.jvmMemoryHeapUsed = builder.jvmMemoryHeapUsed; - this.jvmMemoryHeapMax = builder.jvmMemoryHeapMax; - this.jvmMemoryNonHeapUsed = builder.jvmMemoryNonHeapUsed; - this.jvmMemoryNonHeapMax = builder.jvmMemoryNonHeapMax; - this.jvmGcOldCount = builder.jvmGcOldCount; - this.jvmGcOldTime = builder.jvmGcOldTime; - } - - public String getAgentId() { - return agentId; - } - - public long getStartTimestamp() { - return startTimestamp; - } - - public long getTimestamp() { - return timestamp; - } - - public String getGcType() { - return gcType; - } - - public long getJvmMemoryHeapUsed() { - return jvmMemoryHeapUsed; - } - - public long getJvmMemoryHeapMax() { - return jvmMemoryHeapMax; - } - - public long getJvmMemoryNonHeapUsed() { - return jvmMemoryNonHeapUsed; - } - - public long getJvmMemoryNonHeapMax() { - return jvmMemoryNonHeapMax; - } - - public long getJvmGcOldCount() { - return jvmGcOldCount; - } - - public long getJvmGcOldTime() { - return jvmGcOldTime; - } - - public byte[] writeValue() { - final Buffer buffer = new AutomaticBuffer(); - buffer.putPrefixedString(this.agentId); - buffer.put(this.startTimestamp); - buffer.put(this.timestamp); - buffer.putPrefixedString(this.gcType); - buffer.put(this.jvmMemoryHeapUsed); - buffer.put(this.jvmMemoryHeapMax); - buffer.put(this.jvmMemoryNonHeapUsed); - buffer.put(this.jvmMemoryNonHeapMax); - buffer.put(this.jvmGcOldCount); - buffer.put(this.jvmGcOldTime); - return buffer.getBuffer(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((agentId == null) ? 0 : agentId.hashCode()); - result = prime * result + (int)(startTimestamp ^ (startTimestamp >>> 32)); - result = prime * result + (int)(timestamp ^ (timestamp >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AgentStatMemoryGcBo other = (AgentStatMemoryGcBo)obj; - if (agentId == null) { - if (other.agentId != null) - return false; - } else if (!agentId.equals(other.agentId)) - return false; - if (startTimestamp != other.startTimestamp) - return false; - if (timestamp != other.timestamp) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("AgentStatMemoryGcBo{"); - sb.append("agentId='").append(this.agentId).append('\''); - sb.append(", startTimestamp=").append(this.startTimestamp); - sb.append(", timestamp=").append(this.timestamp); - sb.append(", gcType='").append(this.gcType).append('\''); - sb.append(", jvmMemoryHeapUsed=").append(this.jvmMemoryHeapUsed); - sb.append(", jvmMemoryHeapMax=").append(this.jvmMemoryHeapMax); - sb.append(", jvmMemoryNonHeapUsed=").append(this.jvmMemoryNonHeapUsed); - sb.append(", jvmMemoryNonHeapMax=").append(this.jvmMemoryNonHeapMax); - sb.append(", jvmGcOldCount=").append(this.jvmGcOldCount); - sb.append(", jvmGcOldTime=").append(this.jvmGcOldTime); - sb.append('}'); - return sb.toString(); - } - - public static class Builder { - private final String agentId; - private final long startTimestamp; - private final long timestamp; - private String gcType; - private long jvmMemoryHeapUsed; - private long jvmMemoryHeapMax; - private long jvmMemoryNonHeapUsed; - private long jvmMemoryNonHeapMax; - private long jvmGcOldCount; - private long jvmGcOldTime; - - public Builder(final byte[] value) { - final Buffer buffer = new FixedBuffer(value); - this.agentId = buffer.readPrefixedString(); - this.startTimestamp = buffer.readLong(); - this.timestamp = buffer.readLong(); - this.gcType = buffer.readPrefixedString(); - this.jvmMemoryHeapUsed = buffer.readLong(); - this.jvmMemoryHeapMax = buffer.readLong(); - this.jvmMemoryNonHeapUsed = buffer.readLong(); - this.jvmMemoryNonHeapMax = buffer.readLong(); - this.jvmGcOldCount = buffer.readLong(); - this.jvmGcOldTime = buffer.readLong(); - } - - public Builder(String agentId, long startTimestamp, long timestamp) { - this.agentId = agentId; - this.startTimestamp = startTimestamp; - this.timestamp = timestamp; - } - - public Builder gcType(String gcType) { - this.gcType = gcType; - return this; - } - - public Builder jvmMemoryHeapUsed(long jvmMemoryHeapUsed) { - this.jvmMemoryHeapUsed = jvmMemoryHeapUsed; - return this; - } - - public Builder jvmMemoryHeapMax(long jvmMemoryHeapMax) { - this.jvmMemoryHeapMax = jvmMemoryHeapMax; - return this; - } - - public Builder jvmMemoryNonHeapUsed(long jvmMemoryNonHeapUsed) { - this.jvmMemoryNonHeapUsed = jvmMemoryNonHeapUsed; - return this; - } - - public Builder jvmMemoryNonHeapMax(long jvmMemoryNonHeapMax) { - this.jvmMemoryNonHeapMax = jvmMemoryNonHeapMax; - return this; - } - - public Builder jvmGcOldCount(long jvmGcOldCount) { - this.jvmGcOldCount = jvmGcOldCount; - return this; - } - - public Builder jvmGcOldTime(long jvmGcOldTime) { - this.jvmGcOldTime = jvmGcOldTime; - return this; - } - - public AgentStatMemoryGcBo build() { - return new AgentStatMemoryGcBo(this); - } - } -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.FixedBuffer; + +/** + * @author hyungil.jeong + */ +public class AgentStatMemoryGcBo { + + private final String agentId; + private final long startTimestamp; + private final long timestamp; + private final String gcType; + private final long jvmMemoryHeapUsed; + private final long jvmMemoryHeapMax; + private final long jvmMemoryNonHeapUsed; + private final long jvmMemoryNonHeapMax; + private final long jvmGcOldCount; + private final long jvmGcOldTime; + + private AgentStatMemoryGcBo(Builder builder) { + this.agentId = builder.agentId; + this.startTimestamp = builder.startTimestamp; + this.timestamp = builder.timestamp; + this.gcType = builder.gcType; + this.jvmMemoryHeapUsed = builder.jvmMemoryHeapUsed; + this.jvmMemoryHeapMax = builder.jvmMemoryHeapMax; + this.jvmMemoryNonHeapUsed = builder.jvmMemoryNonHeapUsed; + this.jvmMemoryNonHeapMax = builder.jvmMemoryNonHeapMax; + this.jvmGcOldCount = builder.jvmGcOldCount; + this.jvmGcOldTime = builder.jvmGcOldTime; + } + + public String getAgentId() { + return agentId; + } + + public long getStartTimestamp() { + return startTimestamp; + } + + public long getTimestamp() { + return timestamp; + } + + public String getGcType() { + return gcType; + } + + public long getJvmMemoryHeapUsed() { + return jvmMemoryHeapUsed; + } + + public long getJvmMemoryHeapMax() { + return jvmMemoryHeapMax; + } + + public long getJvmMemoryNonHeapUsed() { + return jvmMemoryNonHeapUsed; + } + + public long getJvmMemoryNonHeapMax() { + return jvmMemoryNonHeapMax; + } + + public long getJvmGcOldCount() { + return jvmGcOldCount; + } + + public long getJvmGcOldTime() { + return jvmGcOldTime; + } + + public byte[] writeValue() { + final Buffer buffer = new AutomaticBuffer(); + buffer.putPrefixedString(this.agentId); + buffer.put(this.startTimestamp); + buffer.put(this.timestamp); + buffer.putPrefixedString(this.gcType); + buffer.put(this.jvmMemoryHeapUsed); + buffer.put(this.jvmMemoryHeapMax); + buffer.put(this.jvmMemoryNonHeapUsed); + buffer.put(this.jvmMemoryNonHeapMax); + buffer.put(this.jvmGcOldCount); + buffer.put(this.jvmGcOldTime); + return buffer.getBuffer(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((agentId == null) ? 0 : agentId.hashCode()); + result = prime * result + (int)(startTimestamp ^ (startTimestamp >>> 32)); + result = prime * result + (int)(timestamp ^ (timestamp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AgentStatMemoryGcBo other = (AgentStatMemoryGcBo)obj; + if (agentId == null) { + if (other.agentId != null) + return false; + } else if (!agentId.equals(other.agentId)) + return false; + if (startTimestamp != other.startTimestamp) + return false; + if (timestamp != other.timestamp) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("AgentStatMemoryGcBo{"); + sb.append("agentId='").append(this.agentId).append('\''); + sb.append(", startTimestamp=").append(this.startTimestamp); + sb.append(", timestamp=").append(this.timestamp); + sb.append(", gcType='").append(this.gcType).append('\''); + sb.append(", jvmMemoryHeapUsed=").append(this.jvmMemoryHeapUsed); + sb.append(", jvmMemoryHeapMax=").append(this.jvmMemoryHeapMax); + sb.append(", jvmMemoryNonHeapUsed=").append(this.jvmMemoryNonHeapUsed); + sb.append(", jvmMemoryNonHeapMax=").append(this.jvmMemoryNonHeapMax); + sb.append(", jvmGcOldCount=").append(this.jvmGcOldCount); + sb.append(", jvmGcOldTime=").append(this.jvmGcOldTime); + sb.append('}'); + return sb.toString(); + } + + public static class Builder { + private final String agentId; + private final long startTimestamp; + private final long timestamp; + private String gcType; + private long jvmMemoryHeapUsed; + private long jvmMemoryHeapMax; + private long jvmMemoryNonHeapUsed; + private long jvmMemoryNonHeapMax; + private long jvmGcOldCount; + private long jvmGcOldTime; + + public Builder(final byte[] value) { + final Buffer buffer = new FixedBuffer(value); + this.agentId = buffer.readPrefixedString(); + this.startTimestamp = buffer.readLong(); + this.timestamp = buffer.readLong(); + this.gcType = buffer.readPrefixedString(); + this.jvmMemoryHeapUsed = buffer.readLong(); + this.jvmMemoryHeapMax = buffer.readLong(); + this.jvmMemoryNonHeapUsed = buffer.readLong(); + this.jvmMemoryNonHeapMax = buffer.readLong(); + this.jvmGcOldCount = buffer.readLong(); + this.jvmGcOldTime = buffer.readLong(); + } + + public Builder(String agentId, long startTimestamp, long timestamp) { + this.agentId = agentId; + this.startTimestamp = startTimestamp; + this.timestamp = timestamp; + } + + public Builder gcType(String gcType) { + this.gcType = gcType; + return this; + } + + public Builder jvmMemoryHeapUsed(long jvmMemoryHeapUsed) { + this.jvmMemoryHeapUsed = jvmMemoryHeapUsed; + return this; + } + + public Builder jvmMemoryHeapMax(long jvmMemoryHeapMax) { + this.jvmMemoryHeapMax = jvmMemoryHeapMax; + return this; + } + + public Builder jvmMemoryNonHeapUsed(long jvmMemoryNonHeapUsed) { + this.jvmMemoryNonHeapUsed = jvmMemoryNonHeapUsed; + return this; + } + + public Builder jvmMemoryNonHeapMax(long jvmMemoryNonHeapMax) { + this.jvmMemoryNonHeapMax = jvmMemoryNonHeapMax; + return this; + } + + public Builder jvmGcOldCount(long jvmGcOldCount) { + this.jvmGcOldCount = jvmGcOldCount; + return this; + } + + public Builder jvmGcOldTime(long jvmGcOldTime) { + this.jvmGcOldTime = jvmGcOldTime; + return this; + } + + public AgentStatMemoryGcBo build() { + return new AgentStatMemoryGcBo(this); + } + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBo.java index 148b9041675d..4df5c009b0cb 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBo.java @@ -1,138 +1,138 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.thrift.dto.TAnnotation; -import com.nhn.pinpoint.common.util.AnnotationTranscoder; -import com.nhn.pinpoint.common.buffer.Buffer; - -/** - * @author emeroad - */ -public class AnnotationBo { - - private static final AnnotationTranscoder transcoder = new AnnotationTranscoder(); - - private static final int VERSION_SIZE = 1; - - private byte version = 0; - private long spanId; - - private int key; - - private byte valueType; - private byte[] byteValue; - private Object value; - - public AnnotationBo() { - } - - public AnnotationBo(TAnnotation annotation) { - if (annotation == null) { - throw new NullPointerException("annotation must not be null"); - } - this.key = annotation.getKey(); - Object value = transcoder.getMappingValue(annotation); - this.valueType = transcoder.getTypeCode(value); - this.byteValue = transcoder.encode(value, this.valueType); - } - - public long getSpanId() { - return spanId; - } - - public void setSpanId(long spanId) { - this.spanId = spanId; - } - - public int getVersion() { - return version & 0xFF; - } - - public void setVersion(int version) { - if (version < 0 || version > 255) { - throw new IllegalArgumentException("out of range (0~255) " + version); - } - // range 체크 - this.version = (byte) (version & 0xFF); - } - - public int getKey() { - return key; - } - - public String getKeyName() { - return AnnotationKey.findAnnotationKey(this.key).getValue(); - } - - public void setKey(int key) { - this.key = key; - } - - - public int getValueType() { - return valueType; - } - - public void setValueType(byte valueType) { - this.valueType = valueType; - } - - public byte[] getByteValue() { - return byteValue; - } - - public void setByteValue(byte[] byteValue) { - this.byteValue = byteValue; - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - public void writeValue(Buffer buffer) { - // long timestamp; // required 8 - // long duration; // optional 8 - // int key; // required 4 - // int valueTypeCode; // required 4 - // ByteBuffer value; // optional 4 + buf.length - buffer.put(this.version); - buffer.putSVar(this.key); - buffer.put(this.valueType); - buffer.putPrefixedBytes(this.byteValue); - } - -// public int getBufferSize() { -// // int key; // required 4+string.length -// // int valueTypeCode; // required 4 -// // ByteBuffer value; // optional 4 + buf.length -// int size = 0; -// size += 1 + 4 + 4 + 4; -// size += 4; -// if (this.getByteValue() != null) { -// size += this.getByteValue().length; -// } -// return size; -// } - - - public void readValue(Buffer buffer) { - this.version = buffer.readByte(); - this.key = buffer.readSVarInt(); - this.valueType = buffer.readByte(); - this.byteValue = buffer.readPrefixedBytes(); - this.value = transcoder.decode(valueType, byteValue); - } - - @Override - public String toString() { - if (value == null) { - return "AnnotationBo{" + "version=" + version + ", spanId=" + spanId + ", key='" + key + '\'' + ", valueType=" + valueType + '}'; - } - return "AnnotationBo{" + "version=" + version + ", spanId=" + spanId + ", key='" + key + '\'' + ", value=" + value + '}'; - } - -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.thrift.dto.TAnnotation; +import com.nhn.pinpoint.common.util.AnnotationTranscoder; +import com.nhn.pinpoint.common.buffer.Buffer; + +/** + * @author emeroad + */ +public class AnnotationBo { + + private static final AnnotationTranscoder transcoder = new AnnotationTranscoder(); + + private static final int VERSION_SIZE = 1; + + private byte version = 0; + private long spanId; + + private int key; + + private byte valueType; + private byte[] byteValue; + private Object value; + + public AnnotationBo() { + } + + public AnnotationBo(TAnnotation annotation) { + if (annotation == null) { + throw new NullPointerException("annotation must not be null"); + } + this.key = annotation.getKey(); + Object value = transcoder.getMappingValue(annotation); + this.valueType = transcoder.getTypeCode(value); + this.byteValue = transcoder.encode(value, this.valueType); + } + + public long getSpanId() { + return spanId; + } + + public void setSpanId(long spanId) { + this.spanId = spanId; + } + + public int getVersion() { + return version & 0xFF; + } + + public void setVersion(int version) { + if (version < 0 || version > 255) { + throw new IllegalArgumentException("out of range (0~255) " + version); + } + // range 체크 + this.version = (byte) (version & 0xFF); + } + + public int getKey() { + return key; + } + + public String getKeyName() { + return AnnotationKey.findAnnotationKey(this.key).getValue(); + } + + public void setKey(int key) { + this.key = key; + } + + + public int getValueType() { + return valueType; + } + + public void setValueType(byte valueType) { + this.valueType = valueType; + } + + public byte[] getByteValue() { + return byteValue; + } + + public void setByteValue(byte[] byteValue) { + this.byteValue = byteValue; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public void writeValue(Buffer buffer) { + // long timestamp; // required 8 + // long duration; // optional 8 + // int key; // required 4 + // int valueTypeCode; // required 4 + // ByteBuffer value; // optional 4 + buf.length + buffer.put(this.version); + buffer.putSVar(this.key); + buffer.put(this.valueType); + buffer.putPrefixedBytes(this.byteValue); + } + +// public int getBufferSize() { +// // int key; // required 4+string.length +// // int valueTypeCode; // required 4 +// // ByteBuffer value; // optional 4 + buf.length +// int size = 0; +// size += 1 + 4 + 4 + 4; +// size += 4; +// if (this.getByteValue() != null) { +// size += this.getByteValue().length; +// } +// return size; +// } + + + public void readValue(Buffer buffer) { + this.version = buffer.readByte(); + this.key = buffer.readSVarInt(); + this.valueType = buffer.readByte(); + this.byteValue = buffer.readPrefixedBytes(); + this.value = transcoder.decode(valueType, byteValue); + } + + @Override + public String toString() { + if (value == null) { + return "AnnotationBo{" + "version=" + version + ", spanId=" + spanId + ", key='" + key + '\'' + ", valueType=" + valueType + '}'; + } + return "AnnotationBo{" + "version=" + version + ", spanId=" + spanId + ", key='" + key + '\'' + ", value=" + value + '}'; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBoList.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBoList.java index 540f2643c347..2323fc34d27b 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBoList.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/AnnotationBoList.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.buffer.Buffer; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * @author emeroad - */ -public class AnnotationBoList { - private List annotationBoList; - - public AnnotationBoList() { - this.annotationBoList = new ArrayList(); - } - - - public AnnotationBoList(int annotationBoListSize) { - this.annotationBoList = new ArrayList(annotationBoListSize); - } - - public AnnotationBoList(List annotationBoList) { - if (annotationBoList == null) { - this.annotationBoList = Collections.emptyList(); - return; - } - this.annotationBoList = annotationBoList; - } - - public List getAnnotationBoList() { - return annotationBoList; - } - - public void addAnnotationBo(AnnotationBo annotationBo) { - this.annotationBoList.add(annotationBo); - } - - public void writeValue(Buffer writer){ - - int size = this.annotationBoList.size(); - writer.putVar(size); - for (AnnotationBo annotationBo : this.annotationBoList) { - annotationBo.writeValue(writer); - } - } - - public void readValue(Buffer reader) { - int size = reader.readVarInt(); - if (size == 0) { - return; - } - this.annotationBoList = new ArrayList(size); - for (int i = 0; i < size; i++) { - AnnotationBo bo = new AnnotationBo(); - bo.readValue(reader); - this.annotationBoList.add(bo); - } - } - - public int size() { - return this.annotationBoList.size(); - } - - - public void setSpanId(long spanId) { - for (AnnotationBo annotationBo : this.annotationBoList) { - annotationBo.setSpanId(spanId); - } - } -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.buffer.Buffer; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author emeroad + */ +public class AnnotationBoList { + private List annotationBoList; + + public AnnotationBoList() { + this.annotationBoList = new ArrayList(); + } + + + public AnnotationBoList(int annotationBoListSize) { + this.annotationBoList = new ArrayList(annotationBoListSize); + } + + public AnnotationBoList(List annotationBoList) { + if (annotationBoList == null) { + this.annotationBoList = Collections.emptyList(); + return; + } + this.annotationBoList = annotationBoList; + } + + public List getAnnotationBoList() { + return annotationBoList; + } + + public void addAnnotationBo(AnnotationBo annotationBo) { + this.annotationBoList.add(annotationBo); + } + + public void writeValue(Buffer writer){ + + int size = this.annotationBoList.size(); + writer.putVar(size); + for (AnnotationBo annotationBo : this.annotationBoList) { + annotationBo.writeValue(writer); + } + } + + public void readValue(Buffer reader) { + int size = reader.readVarInt(); + if (size == 0) { + return; + } + this.annotationBoList = new ArrayList(size); + for (int i = 0; i < size; i++) { + AnnotationBo bo = new AnnotationBo(); + bo.readValue(reader); + this.annotationBoList.add(bo); + } + } + + public int size() { + return this.annotationBoList.size(); + } + + + public void setSpanId(long spanId) { + for (AnnotationBo annotationBo : this.annotationBoList) { + annotationBo.setSpanId(spanId); + } + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/ApiMetaDataBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/ApiMetaDataBo.java index 83a4d5a33413..ea5ce8a1726d 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/ApiMetaDataBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/ApiMetaDataBo.java @@ -1,106 +1,106 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.RowKeyUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import org.apache.hadoop.hbase.util.Bytes; - -import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; -import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; - -/** - * @author emeroad - */ -public class ApiMetaDataBo { - private String agentId; - private long startTime; - - private int apiId; - - private String apiInfo; - private int lineNumber; - - public ApiMetaDataBo() { - } - - public ApiMetaDataBo(String agentId, long startTime, int apiId) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - - this.agentId = agentId; - this.startTime = startTime; - this.apiId = apiId; - } - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public int getApiId() { - return apiId; - } - - public void setApiId(int apiId) { - this.apiId = apiId; - } - - - public long getStartTime() { - return startTime; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } - - public String getApiInfo() { - return apiInfo; - } - - public void setApiInfo(String apiInfo) { - this.apiInfo = apiInfo; - } - - public int getLineNumber() { - return lineNumber; - } - - public void setLineNumber(int lineNumber) { - this.lineNumber = lineNumber; - } - - public void readRowKey(byte[] bytes) { - this.agentId = Bytes.toString(bytes, 0, AGENT_NAME_MAX_LEN).trim(); - this.startTime = TimeUtils.recoveryTimeMillis(readTime(bytes)); - this.apiId = readKeyCode(bytes); - } - - private static long readTime(byte[] rowKey) { - return BytesUtils.bytesToLong(rowKey, AGENT_NAME_MAX_LEN); - } - - private static int readKeyCode(byte[] rowKey) { - return BytesUtils.bytesToInt(rowKey, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); - } - - public byte[] toRowKey() { - return RowKeyUtils.getMetaInfoRowKey(this.agentId, this.startTime, this.apiId); - } - - @Override - public String toString() { - return "ApiMetaDataBo{" + - "agentId='" + agentId + '\'' + - ", apiId=" + apiId + - ", startTime=" + startTime + - ", apiInfo='" + apiInfo + '\'' + - ", lineNumber=" + lineNumber + - '}'; - } - -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.RowKeyUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import org.apache.hadoop.hbase.util.Bytes; + +import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; +import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; + +/** + * @author emeroad + */ +public class ApiMetaDataBo { + private String agentId; + private long startTime; + + private int apiId; + + private String apiInfo; + private int lineNumber; + + public ApiMetaDataBo() { + } + + public ApiMetaDataBo(String agentId, long startTime, int apiId) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + + this.agentId = agentId; + this.startTime = startTime; + this.apiId = apiId; + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public int getApiId() { + return apiId; + } + + public void setApiId(int apiId) { + this.apiId = apiId; + } + + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public String getApiInfo() { + return apiInfo; + } + + public void setApiInfo(String apiInfo) { + this.apiInfo = apiInfo; + } + + public int getLineNumber() { + return lineNumber; + } + + public void setLineNumber(int lineNumber) { + this.lineNumber = lineNumber; + } + + public void readRowKey(byte[] bytes) { + this.agentId = Bytes.toString(bytes, 0, AGENT_NAME_MAX_LEN).trim(); + this.startTime = TimeUtils.recoveryTimeMillis(readTime(bytes)); + this.apiId = readKeyCode(bytes); + } + + private static long readTime(byte[] rowKey) { + return BytesUtils.bytesToLong(rowKey, AGENT_NAME_MAX_LEN); + } + + private static int readKeyCode(byte[] rowKey) { + return BytesUtils.bytesToInt(rowKey, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); + } + + public byte[] toRowKey() { + return RowKeyUtils.getMetaInfoRowKey(this.agentId, this.startTime, this.apiId); + } + + @Override + public String toString() { + return "ApiMetaDataBo{" + + "agentId='" + agentId + '\'' + + ", apiId=" + apiId + + ", startTime=" + startTime + + ", apiInfo='" + apiInfo + '\'' + + ", lineNumber=" + lineNumber + + '}'; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringStringValue.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringStringValue.java index 9f4febe550be..9054ad11e010 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringStringValue.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringStringValue.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.common.bo; - -/** - * @author emeroad - */ -public class IntStringStringValue { - private final int intValue; - private final String stringValue1; - private final String stringValue2; - - public IntStringStringValue(int intValue, String stringValue1, String stringValue2) { - this.intValue = intValue; - this.stringValue1 = stringValue1; - this.stringValue2 = stringValue2; - } - - public int getIntValue() { - return intValue; - } - - public String getStringValue1() { - return stringValue1; - } - - public String getStringValue2() { - return stringValue2; - } -} +package com.nhn.pinpoint.common.bo; + +/** + * @author emeroad + */ +public class IntStringStringValue { + private final int intValue; + private final String stringValue1; + private final String stringValue2; + + public IntStringStringValue(int intValue, String stringValue1, String stringValue2) { + this.intValue = intValue; + this.stringValue1 = stringValue1; + this.stringValue2 = stringValue2; + } + + public int getIntValue() { + return intValue; + } + + public String getStringValue1() { + return stringValue1; + } + + public String getStringValue2() { + return stringValue2; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringValue.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringValue.java index 2fc3e68f42ad..9573d3deed0c 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringValue.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/IntStringValue.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.common.bo; - -/** - * @author emeroad - */ -public class IntStringValue { - private final int intValue; - private final String stringValue; - - public IntStringValue(int intValue, String stringValue) { - this.intValue = intValue; - this.stringValue = stringValue; - } - - public String getStringValue() { - return stringValue; - } - - public int getIntValue() { - return intValue; - } -} +package com.nhn.pinpoint.common.bo; + +/** + * @author emeroad + */ +public class IntStringValue { + private final int intValue; + private final String stringValue; + + public IntStringValue(int intValue, String stringValue) { + this.intValue = intValue; + this.stringValue = stringValue; + } + + public String getStringValue() { + return stringValue; + } + + public int getIntValue() { + return intValue; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanBo.java index cc994ac1f241..60912d7a4958 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanBo.java @@ -1,463 +1,463 @@ -package com.nhn.pinpoint.common.bo; - -import java.util.ArrayList; -import java.util.List; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import com.nhn.pinpoint.common.util.TransactionId; -import com.nhn.pinpoint.common.util.TransactionIdUtils; -import com.nhn.pinpoint.thrift.dto.TAnnotation; -import com.nhn.pinpoint.thrift.dto.TIntStringValue; -import com.nhn.pinpoint.thrift.dto.TSpan; -import com.nhn.pinpoint.common.buffer.Buffer; - -/** - * @author emeroad - */ -public class SpanBo implements com.nhn.pinpoint.common.bo.Span { - - private static final int VERSION_SIZE = 1; - // version 0 = prefix의 사이즈를 int로 - - private byte version = 0; - - -// private AgentKeyBo agentKeyBo; - private String agentId; - private String applicationId; - private long agentStartTime; - - private String traceAgentId; - private long traceAgentStartTime; - private long traceTransactionSequence; - private long spanId; - private long parentSpanId; - - private long startTime; - private int elapsed; - - private String rpc; - private ServiceType serviceType; - private String endPoint; - private int apiId; - - private List annotationBoList; - private short flag; // optional - private int errCode; - - private List spanEventBoList; - - private long collectorAcceptTime; - - private boolean hasException = false; - private int exceptionId; - private String exceptionMessage; - private String exceptionClass; - - - private String remoteAddr; // optional - - public SpanBo(TSpan span) { - if (span == null) { - throw new NullPointerException("span must not be null"); - } - this.agentId = span.getAgentId(); - this.applicationId = span.getApplicationName(); - this.agentStartTime = span.getAgentStartTime(); - - final TransactionId transactionId = TransactionIdUtils.parseTransactionId(span.getTransactionId()); - this.traceAgentId = transactionId.getAgentId(); - if (traceAgentId == null) { - traceAgentId = this.agentId; - } - this.traceAgentStartTime = transactionId.getAgentStartTime(); - this.traceTransactionSequence = transactionId.getTransactionSequence(); - - this.spanId = span.getSpanId(); - this.parentSpanId = span.getParentSpanId(); - - this.startTime = span.getStartTime(); - this.elapsed = span.getElapsed(); - - this.rpc = span.getRpc(); - - this.serviceType = ServiceType.findServiceType(span.getServiceType()); - this.endPoint = span.getEndPoint(); - this.flag = span.getFlag(); - this.apiId = span.getApiId(); - - this.errCode = span.getErr(); - - this.remoteAddr = span.getRemoteAddr(); - - - // FIXME span.errCode는 span과 spanEvent의 에러를 모두 포함한 값. - // exceptionInfo는 span자체의 에러정보이기 때문에 errCode가 0이 아니더라도 exceptionInfo는 null일 수 있음. - final TIntStringValue exceptionInfo = span.getExceptionInfo(); - if (exceptionInfo != null) { - this.hasException = true; - this.exceptionId = exceptionInfo.getIntValue(); - this.exceptionMessage = exceptionInfo.getStringValue(); - } - - setAnnotationList(span.getAnnotations()); - } - - public SpanBo(String traceAgentId, long traceAgentStartTime, long traceTransactionSequence, long startTime, int elapsed, long spanId) { - if (traceAgentId == null) { - throw new NullPointerException("traceAgentId must not be null"); - } - this.traceAgentId = traceAgentId; - this.traceAgentStartTime = traceAgentStartTime; - this.traceTransactionSequence = traceTransactionSequence; - - this.startTime = startTime; - this.elapsed = elapsed; - - this.spanId = spanId; - } - - public SpanBo() { - } - - public int getVersion() { - return version & 0xFF; - } - - public void setVersion(int version) { - if (version < 0 || version > 255) { - throw new IllegalArgumentException("out of range (0~255)"); - } - // range 체크 - this.version = (byte) (version & 0xFF); - } - - public String getTransactionId() { - return TransactionIdUtils.formatString(traceAgentId, traceAgentStartTime, traceTransactionSequence); - } - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public String getApplicationId() { - return applicationId; - } - - public void setApplicationId(String applicationId) { - this.applicationId = applicationId; - } - - public long getAgentStartTime() { - return agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - } - - public long getStartTime() { - return startTime; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } - - - public int getElapsed() { - return elapsed; - } - - public void setElapsed(int elapsed) { - this.elapsed = elapsed; - } - - - public String getTraceAgentId() { - return traceAgentId; - } - - public void setTraceAgentId(String traceAgentId) { - this.traceAgentId = traceAgentId; - } - - public long getTraceAgentStartTime() { - return traceAgentStartTime; - } - - public void setTraceAgentStartTime(long traceAgentStartTime) { - this.traceAgentStartTime = traceAgentStartTime; - } - - - public long getTraceTransactionSequence() { - return traceTransactionSequence; - } - - public void setTraceTransactionSequence(long traceTransactionSequence) { - this.traceTransactionSequence = traceTransactionSequence; - } - - - public String getRpc() { - return rpc; - } - - public void setRpc(String rpc) { - this.rpc = rpc; - } - - - public long getSpanId() { - return spanId; - } - - public void setSpanID(long spanId) { - this.spanId = spanId; - } - - public long getParentSpanId() { - return parentSpanId; - } - - public void setParentSpanId(long parentSpanId) { - this.parentSpanId = parentSpanId; - } - - public int getFlag() { - return flag; - } - - public void setFlag(short flag) { - this.flag = flag; - } - - public String getEndPoint() { - return endPoint; - } - - public void setEndPoint(String endPoint) { - this.endPoint = endPoint; - } - - public int getApiId() { - return apiId; - } - - public void setApiId(int apiId) { - this.apiId = apiId; - } - - public List getAnnotationBoList() { - return annotationBoList; - } - - public void setAnnotationList(List anoList) { - if (anoList == null) { - return; - } - List boList = new ArrayList(anoList.size()); - for (TAnnotation ano : anoList) { - boList.add(new AnnotationBo(ano)); - } - this.annotationBoList = boList; - } - - public void setAnnotationBoList(List anoList) { - if (anoList == null) { - return; - } - this.annotationBoList = anoList; - } - - public void addSpanEvent(SpanEventBo spanEventBo) { - if (spanEventBoList == null) { - spanEventBoList = new ArrayList(); - } - spanEventBoList.add(spanEventBo); - } - - public List getSpanEventBoList() { - return spanEventBoList; - } - - public ServiceType getServiceType() { - return serviceType; - } - - public void setServiceType(ServiceType serviceType) { - this.serviceType = serviceType; - } - - public int getErrCode() { - return errCode; - } - - public void setErrCode(int errCode) { - this.errCode = errCode; - } - - public String getRemoteAddr() { - return remoteAddr; - } - - public void setRemoteAddr(String remoteAddr) { - this.remoteAddr = remoteAddr; - } - - public long getCollectorAcceptTime() { - return collectorAcceptTime; - } - - public void setCollectorAcceptTime(long collectorAcceptTime) { - this.collectorAcceptTime = collectorAcceptTime; - } - - public boolean isRoot() { - return -1L == parentSpanId; - } - - public boolean hasException() { - return hasException; - } - - public int getExceptionId() { - return exceptionId; - } - - public String getExceptionMessage() { - return exceptionMessage; - } - - public String getExceptionClass() { - return exceptionClass; - } - - public void setExceptionClass(String exceptionClass) { - this.exceptionClass = exceptionClass; - } - - - // io wirte시 variable encoding을 추가함. - // 약 10%정도 byte 사이즈가 줄어드는 효과가 있음. - public byte[] writeValue() { - // var encoding 사용시 사이즈를 측정하기 어려움. 안되는것음 아님 편의상 그냥 자동 증가 buffer를 사용한다. - // 향후 더 효율적으로 메모리를 사용하게 한다면 getBufferLength를 다시 부활 시키는것을 고려한다. - final Buffer buffer = new AutomaticBuffer(256); - - buffer.put(version); - - // buffer.put(mostTraceID); - // buffer.put(leastTraceID); - - buffer.putPrefixedString(agentId); - // time의 경우도 현재 시간을 기준으로 var를 사용하는게 사이즈가 더 작음 6byte를 먹음. - buffer.putVar(agentStartTime); - - // rowkey에 들어감. - // buffer.put(spanID); - buffer.put(parentSpanId); - - // 현재 시간이 기준이므로 var encoding - buffer.putVar(startTime); - buffer.putVar(elapsed); - - buffer.putPrefixedString(rpc); - buffer.putPrefixedString(applicationId); - buffer.put(serviceType.getCode()); - buffer.putPrefixedString(endPoint); - buffer.putPrefixedString(remoteAddr); - buffer.putSVar(apiId); - - // errCode code는 음수가 될수 있음. - buffer.putSVar(errCode); - - if (hasException){ - buffer.put(true); - buffer.putSVar(exceptionId); - buffer.putPrefixedString(exceptionMessage); - } else { - buffer.put(false); - } - - buffer.put(flag); - - return buffer.getBuffer(); - } - - public int readValue(byte[] bytes, int offset) { - final Buffer buffer = new OffsetFixedBuffer(bytes, offset); - - this.version = buffer.readByte(); - - // this.mostTraceID = buffer.readLong(); - // this.leastTraceID = buffer.readLong(); - - this.agentId = buffer.readPrefixedString(); - this.agentStartTime = buffer.readVarLong(); - - // this.spanID = buffer.readLong(); - this.parentSpanId = buffer.readLong(); - - this.startTime = buffer.readVarLong(); - this.elapsed = buffer.readVarInt(); - - this.rpc = buffer.readPrefixedString(); - this.applicationId = buffer.readPrefixedString(); - this.serviceType = ServiceType.findServiceType(buffer.readShort()); - this.endPoint = buffer.readPrefixedString(); - this.remoteAddr = buffer.readPrefixedString(); - this.apiId = buffer.readSVarInt(); - - this.errCode = buffer.readSVarInt(); - - this.hasException = buffer.readBoolean(); - if (hasException) { - this.exceptionId = buffer.readSVarInt(); - this.exceptionMessage = buffer.readPrefixedString(); - } - - this.flag = buffer.readShort(); - - return buffer.getOffset(); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(256); - sb.append("SpanBo{"); - sb.append("version=").append(version); - sb.append(", agentId='").append(agentId).append('\''); - sb.append(", applicationId='").append(applicationId).append('\''); - sb.append(", agentStartTime=").append(agentStartTime); - sb.append(", traceAgentId='").append(traceAgentId).append('\''); - sb.append(", traceAgentStartTime=").append(traceAgentStartTime); - sb.append(", traceTransactionSequence=").append(traceTransactionSequence); - sb.append(", spanId=").append(spanId); - sb.append(", parentSpanId=").append(parentSpanId); - sb.append(", startTime=").append(startTime); - sb.append(", elapsed=").append(elapsed); - sb.append(", rpc='").append(rpc).append('\''); - sb.append(", serviceType=").append(serviceType); - sb.append(", endPoint='").append(endPoint).append('\''); - sb.append(", apiId=").append(apiId); - sb.append(", annotationBoList=").append(annotationBoList); - sb.append(", flag=").append(flag); - sb.append(", errCode=").append(errCode); - sb.append(", spanEventBoList=").append(spanEventBoList); - sb.append(", collectorAcceptTime=").append(collectorAcceptTime); - sb.append(", hasException=").append(hasException); - sb.append(", exceptionId=").append(exceptionId); - sb.append(", exceptionMessage='").append(exceptionMessage).append('\''); - sb.append(", remoteAddr='").append(remoteAddr).append('\''); - sb.append('}'); - return sb.toString(); - } +package com.nhn.pinpoint.common.bo; + +import java.util.ArrayList; +import java.util.List; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import com.nhn.pinpoint.common.util.TransactionId; +import com.nhn.pinpoint.common.util.TransactionIdUtils; +import com.nhn.pinpoint.thrift.dto.TAnnotation; +import com.nhn.pinpoint.thrift.dto.TIntStringValue; +import com.nhn.pinpoint.thrift.dto.TSpan; +import com.nhn.pinpoint.common.buffer.Buffer; + +/** + * @author emeroad + */ +public class SpanBo implements com.nhn.pinpoint.common.bo.Span { + + private static final int VERSION_SIZE = 1; + // version 0 = prefix의 사이즈를 int로 + + private byte version = 0; + + +// private AgentKeyBo agentKeyBo; + private String agentId; + private String applicationId; + private long agentStartTime; + + private String traceAgentId; + private long traceAgentStartTime; + private long traceTransactionSequence; + private long spanId; + private long parentSpanId; + + private long startTime; + private int elapsed; + + private String rpc; + private ServiceType serviceType; + private String endPoint; + private int apiId; + + private List annotationBoList; + private short flag; // optional + private int errCode; + + private List spanEventBoList; + + private long collectorAcceptTime; + + private boolean hasException = false; + private int exceptionId; + private String exceptionMessage; + private String exceptionClass; + + + private String remoteAddr; // optional + + public SpanBo(TSpan span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + this.agentId = span.getAgentId(); + this.applicationId = span.getApplicationName(); + this.agentStartTime = span.getAgentStartTime(); + + final TransactionId transactionId = TransactionIdUtils.parseTransactionId(span.getTransactionId()); + this.traceAgentId = transactionId.getAgentId(); + if (traceAgentId == null) { + traceAgentId = this.agentId; + } + this.traceAgentStartTime = transactionId.getAgentStartTime(); + this.traceTransactionSequence = transactionId.getTransactionSequence(); + + this.spanId = span.getSpanId(); + this.parentSpanId = span.getParentSpanId(); + + this.startTime = span.getStartTime(); + this.elapsed = span.getElapsed(); + + this.rpc = span.getRpc(); + + this.serviceType = ServiceType.findServiceType(span.getServiceType()); + this.endPoint = span.getEndPoint(); + this.flag = span.getFlag(); + this.apiId = span.getApiId(); + + this.errCode = span.getErr(); + + this.remoteAddr = span.getRemoteAddr(); + + + // FIXME span.errCode는 span과 spanEvent의 에러를 모두 포함한 값. + // exceptionInfo는 span자체의 에러정보이기 때문에 errCode가 0이 아니더라도 exceptionInfo는 null일 수 있음. + final TIntStringValue exceptionInfo = span.getExceptionInfo(); + if (exceptionInfo != null) { + this.hasException = true; + this.exceptionId = exceptionInfo.getIntValue(); + this.exceptionMessage = exceptionInfo.getStringValue(); + } + + setAnnotationList(span.getAnnotations()); + } + + public SpanBo(String traceAgentId, long traceAgentStartTime, long traceTransactionSequence, long startTime, int elapsed, long spanId) { + if (traceAgentId == null) { + throw new NullPointerException("traceAgentId must not be null"); + } + this.traceAgentId = traceAgentId; + this.traceAgentStartTime = traceAgentStartTime; + this.traceTransactionSequence = traceTransactionSequence; + + this.startTime = startTime; + this.elapsed = elapsed; + + this.spanId = spanId; + } + + public SpanBo() { + } + + public int getVersion() { + return version & 0xFF; + } + + public void setVersion(int version) { + if (version < 0 || version > 255) { + throw new IllegalArgumentException("out of range (0~255)"); + } + // range 체크 + this.version = (byte) (version & 0xFF); + } + + public String getTransactionId() { + return TransactionIdUtils.formatString(traceAgentId, traceAgentStartTime, traceTransactionSequence); + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public String getApplicationId() { + return applicationId; + } + + public void setApplicationId(String applicationId) { + this.applicationId = applicationId; + } + + public long getAgentStartTime() { + return agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + + public int getElapsed() { + return elapsed; + } + + public void setElapsed(int elapsed) { + this.elapsed = elapsed; + } + + + public String getTraceAgentId() { + return traceAgentId; + } + + public void setTraceAgentId(String traceAgentId) { + this.traceAgentId = traceAgentId; + } + + public long getTraceAgentStartTime() { + return traceAgentStartTime; + } + + public void setTraceAgentStartTime(long traceAgentStartTime) { + this.traceAgentStartTime = traceAgentStartTime; + } + + + public long getTraceTransactionSequence() { + return traceTransactionSequence; + } + + public void setTraceTransactionSequence(long traceTransactionSequence) { + this.traceTransactionSequence = traceTransactionSequence; + } + + + public String getRpc() { + return rpc; + } + + public void setRpc(String rpc) { + this.rpc = rpc; + } + + + public long getSpanId() { + return spanId; + } + + public void setSpanID(long spanId) { + this.spanId = spanId; + } + + public long getParentSpanId() { + return parentSpanId; + } + + public void setParentSpanId(long parentSpanId) { + this.parentSpanId = parentSpanId; + } + + public int getFlag() { + return flag; + } + + public void setFlag(short flag) { + this.flag = flag; + } + + public String getEndPoint() { + return endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public int getApiId() { + return apiId; + } + + public void setApiId(int apiId) { + this.apiId = apiId; + } + + public List getAnnotationBoList() { + return annotationBoList; + } + + public void setAnnotationList(List anoList) { + if (anoList == null) { + return; + } + List boList = new ArrayList(anoList.size()); + for (TAnnotation ano : anoList) { + boList.add(new AnnotationBo(ano)); + } + this.annotationBoList = boList; + } + + public void setAnnotationBoList(List anoList) { + if (anoList == null) { + return; + } + this.annotationBoList = anoList; + } + + public void addSpanEvent(SpanEventBo spanEventBo) { + if (spanEventBoList == null) { + spanEventBoList = new ArrayList(); + } + spanEventBoList.add(spanEventBo); + } + + public List getSpanEventBoList() { + return spanEventBoList; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public void setServiceType(ServiceType serviceType) { + this.serviceType = serviceType; + } + + public int getErrCode() { + return errCode; + } + + public void setErrCode(int errCode) { + this.errCode = errCode; + } + + public String getRemoteAddr() { + return remoteAddr; + } + + public void setRemoteAddr(String remoteAddr) { + this.remoteAddr = remoteAddr; + } + + public long getCollectorAcceptTime() { + return collectorAcceptTime; + } + + public void setCollectorAcceptTime(long collectorAcceptTime) { + this.collectorAcceptTime = collectorAcceptTime; + } + + public boolean isRoot() { + return -1L == parentSpanId; + } + + public boolean hasException() { + return hasException; + } + + public int getExceptionId() { + return exceptionId; + } + + public String getExceptionMessage() { + return exceptionMessage; + } + + public String getExceptionClass() { + return exceptionClass; + } + + public void setExceptionClass(String exceptionClass) { + this.exceptionClass = exceptionClass; + } + + + // io wirte시 variable encoding을 추가함. + // 약 10%정도 byte 사이즈가 줄어드는 효과가 있음. + public byte[] writeValue() { + // var encoding 사용시 사이즈를 측정하기 어려움. 안되는것음 아님 편의상 그냥 자동 증가 buffer를 사용한다. + // 향후 더 효율적으로 메모리를 사용하게 한다면 getBufferLength를 다시 부활 시키는것을 고려한다. + final Buffer buffer = new AutomaticBuffer(256); + + buffer.put(version); + + // buffer.put(mostTraceID); + // buffer.put(leastTraceID); + + buffer.putPrefixedString(agentId); + // time의 경우도 현재 시간을 기준으로 var를 사용하는게 사이즈가 더 작음 6byte를 먹음. + buffer.putVar(agentStartTime); + + // rowkey에 들어감. + // buffer.put(spanID); + buffer.put(parentSpanId); + + // 현재 시간이 기준이므로 var encoding + buffer.putVar(startTime); + buffer.putVar(elapsed); + + buffer.putPrefixedString(rpc); + buffer.putPrefixedString(applicationId); + buffer.put(serviceType.getCode()); + buffer.putPrefixedString(endPoint); + buffer.putPrefixedString(remoteAddr); + buffer.putSVar(apiId); + + // errCode code는 음수가 될수 있음. + buffer.putSVar(errCode); + + if (hasException){ + buffer.put(true); + buffer.putSVar(exceptionId); + buffer.putPrefixedString(exceptionMessage); + } else { + buffer.put(false); + } + + buffer.put(flag); + + return buffer.getBuffer(); + } + + public int readValue(byte[] bytes, int offset) { + final Buffer buffer = new OffsetFixedBuffer(bytes, offset); + + this.version = buffer.readByte(); + + // this.mostTraceID = buffer.readLong(); + // this.leastTraceID = buffer.readLong(); + + this.agentId = buffer.readPrefixedString(); + this.agentStartTime = buffer.readVarLong(); + + // this.spanID = buffer.readLong(); + this.parentSpanId = buffer.readLong(); + + this.startTime = buffer.readVarLong(); + this.elapsed = buffer.readVarInt(); + + this.rpc = buffer.readPrefixedString(); + this.applicationId = buffer.readPrefixedString(); + this.serviceType = ServiceType.findServiceType(buffer.readShort()); + this.endPoint = buffer.readPrefixedString(); + this.remoteAddr = buffer.readPrefixedString(); + this.apiId = buffer.readSVarInt(); + + this.errCode = buffer.readSVarInt(); + + this.hasException = buffer.readBoolean(); + if (hasException) { + this.exceptionId = buffer.readSVarInt(); + this.exceptionMessage = buffer.readPrefixedString(); + } + + this.flag = buffer.readShort(); + + return buffer.getOffset(); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(256); + sb.append("SpanBo{"); + sb.append("version=").append(version); + sb.append(", agentId='").append(agentId).append('\''); + sb.append(", applicationId='").append(applicationId).append('\''); + sb.append(", agentStartTime=").append(agentStartTime); + sb.append(", traceAgentId='").append(traceAgentId).append('\''); + sb.append(", traceAgentStartTime=").append(traceAgentStartTime); + sb.append(", traceTransactionSequence=").append(traceTransactionSequence); + sb.append(", spanId=").append(spanId); + sb.append(", parentSpanId=").append(parentSpanId); + sb.append(", startTime=").append(startTime); + sb.append(", elapsed=").append(elapsed); + sb.append(", rpc='").append(rpc).append('\''); + sb.append(", serviceType=").append(serviceType); + sb.append(", endPoint='").append(endPoint).append('\''); + sb.append(", apiId=").append(apiId); + sb.append(", annotationBoList=").append(annotationBoList); + sb.append(", flag=").append(flag); + sb.append(", errCode=").append(errCode); + sb.append(", spanEventBoList=").append(spanEventBoList); + sb.append(", collectorAcceptTime=").append(collectorAcceptTime); + sb.append(", hasException=").append(hasException); + sb.append(", exceptionId=").append(exceptionId); + sb.append(", exceptionMessage='").append(exceptionMessage).append('\''); + sb.append(", remoteAddr='").append(remoteAddr).append('\''); + sb.append('}'); + return sb.toString(); + } } \ No newline at end of file diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanEventBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanEventBo.java index f5b2b76e06c5..101bda4ff095 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanEventBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/SpanEventBo.java @@ -1,460 +1,460 @@ -package com.nhn.pinpoint.common.bo; - -import java.util.ArrayList; -import java.util.List; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import com.nhn.pinpoint.common.util.TransactionId; -import com.nhn.pinpoint.common.util.TransactionIdUtils; -import com.nhn.pinpoint.thrift.dto.*; -import com.nhn.pinpoint.common.buffer.Buffer; - -/** - * @author emeroad - */ -public class SpanEventBo implements Span { - private static final int VERSION_SIZE = 1; - // version 0 = prefix의 사이즈를 int로 - - private byte version = 0; - - private String agentId; - private String applicationId; - private long agentStartTime; - - private String traceAgentId; - private long traceAgentStartTime; - private long traceTransactionSequence; - - private long spanId; - private short sequence; - - private int startElapsed; - private int endElapsed; - - private String rpc; - private ServiceType serviceType; - - private String destinationId; - private String endPoint; - private int apiId; - - private List annotationBoList; - - private int depth = -1; - private long nextSpanId = -1; - - private boolean hasException; - private int exceptionId; - private String exceptionMessage; - // dao에서 찾아야 함. - private String exceptionClass; - - - public SpanEventBo() { - } - - public SpanEventBo(TSpan tSpan, TSpanEvent tSpanEvent) { - if (tSpan == null) { - throw new NullPointerException("tSpan must not be null"); - } - if (tSpanEvent == null) { - throw new NullPointerException("tSpanEvent must not be null"); - } - - this.agentId = tSpan.getAgentId(); - this.applicationId = tSpan.getApplicationName(); - this.agentStartTime = tSpan.getAgentStartTime(); - - final TransactionId transactionId = TransactionIdUtils.parseTransactionId(tSpan.getTransactionId()); - this.traceAgentId = transactionId.getAgentId(); - if (traceAgentId == null) { - traceAgentId = this.agentId; - } - this.traceAgentStartTime = transactionId.getAgentStartTime(); - this.traceTransactionSequence = transactionId.getTransactionSequence(); - - this.spanId = tSpan.getSpanId(); - this.sequence = tSpanEvent.getSequence(); - - this.startElapsed = tSpanEvent.getStartElapsed(); - this.endElapsed = tSpanEvent.getEndElapsed(); - - this.rpc = tSpanEvent.getRpc(); - this.serviceType = ServiceType.findServiceType(tSpanEvent.getServiceType()); - - - this.destinationId = tSpanEvent.getDestinationId(); - - this.endPoint = tSpanEvent.getEndPoint(); - this.apiId = tSpanEvent.getApiId(); - - if (tSpanEvent.isSetDepth()) { - this.depth = tSpanEvent.getDepth(); - } - - if (tSpanEvent.isSetNextSpanId()) { - this.nextSpanId = tSpanEvent.getNextSpanId(); - } - - setAnnotationBoList(tSpanEvent.getAnnotations()); - - final TIntStringValue exceptionInfo = tSpanEvent.getExceptionInfo(); - if (exceptionInfo != null) { - this.hasException = true; - this.exceptionId = exceptionInfo.getIntValue(); - this.exceptionMessage = exceptionInfo.getStringValue(); - } - } - - public SpanEventBo(TSpanChunk spanChunk, TSpanEvent spanEvent) { - if (spanChunk == null) { - throw new NullPointerException("spanChunk must not be null"); - } - if (spanEvent == null) { - throw new NullPointerException("spanEvent must not be null"); - } - - this.agentId = spanChunk.getAgentId(); - this.applicationId = spanChunk.getApplicationName(); - this.agentStartTime = spanChunk.getAgentStartTime(); - - final TransactionId transactionId = TransactionIdUtils.parseTransactionId(spanChunk.getTransactionId()); - this.traceAgentId = transactionId.getAgentId(); - if (traceAgentId == null) { - traceAgentId = this.agentId; - } - this.traceAgentStartTime = transactionId.getAgentStartTime(); - this.traceTransactionSequence = transactionId.getTransactionSequence(); - - this.spanId = spanChunk.getSpanId(); - this.sequence = spanEvent.getSequence(); - - this.startElapsed = spanEvent.getStartElapsed(); - this.endElapsed = spanEvent.getEndElapsed(); - - this.rpc = spanEvent.getRpc(); - this.serviceType = ServiceType.findServiceType(spanEvent.getServiceType()); - - this.destinationId = spanEvent.getDestinationId(); - - this.endPoint = spanEvent.getEndPoint(); - this.apiId = spanEvent.getApiId(); - - if (spanEvent.isSetDepth()) { - this.depth = spanEvent.getDepth(); - } - - if (spanEvent.isSetNextSpanId()) { - this.nextSpanId = spanEvent.getNextSpanId(); - } - - setAnnotationBoList(spanEvent.getAnnotations()); - - final TIntStringValue exceptionInfo = spanEvent.getExceptionInfo(); - if (exceptionInfo != null) { - this.hasException = true; - this.exceptionId = exceptionInfo.getIntValue(); - this.exceptionMessage = exceptionInfo.getStringValue(); - } - } - - - - public byte getVersion() { - return version; - } - - public void setVersion(byte version) { - this.version = version; - } - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public long getAgentStartTime() { - return this.agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - } - - public String getTraceAgentId() { - return traceAgentId; - } - - public void setTraceAgentId(String traceAgentId) { - this.traceAgentId = traceAgentId; - } - - public long getTraceAgentStartTime() { - return traceAgentStartTime; - } - - public void setTraceAgentStartTime(long traceAgentStartTime) { - this.traceAgentStartTime = traceAgentStartTime; - } - - public long getTraceTransactionSequence() { - return traceTransactionSequence; - } - - public void setTraceTransactionSequence(long traceTransactionSequence) { - this.traceTransactionSequence = traceTransactionSequence; - } - - public void setSpanId(long spanId) { - this.spanId = spanId; - } - - public long getSpanId() { - return this.spanId; - } - - public short getSequence() { - return sequence; - } - - public void setSequence(short sequence) { - this.sequence = sequence; - } - - public int getStartElapsed() { - return startElapsed; - } - - public void setStartElapsed(int startElapsed) { - this.startElapsed = startElapsed; - } - - public int getEndElapsed() { - return endElapsed; - } - - public void setEndElapsed(int endElapsed) { - this.endElapsed = endElapsed; - } - - public String getRpc() { - return rpc; - } - - public void setRpc(String rpc) { - this.rpc = rpc; - } - - public ServiceType getServiceType() { - return serviceType; - } - - public void setServiceType(ServiceType serviceType) { - this.serviceType = serviceType; - } - - public String getEndPoint() { - return endPoint; - } - - public void setEndPoint(String endPoint) { - this.endPoint = endPoint; - } - - public int getApiId() { - return apiId; - } - - public void setApiId(int apiId) { - this.apiId = apiId; - } - - public String getDestinationId() { - return destinationId; - } - - public void setDestinationId(String destinationId) { - this.destinationId = destinationId; - } - - - public List getAnnotationBoList() { - return annotationBoList; - } - - public int getDepth() { - return depth; - } - - public void setDepth(int depth) { - this.depth = depth; - } - - public long getNextSpanId() { - return nextSpanId; - } - - public void setNextSpanId(long nextSpanId) { - this.nextSpanId = nextSpanId; - } - - private void setAnnotationBoList(List annotations) { - if (annotations == null) { - return; - } - List boList = new ArrayList(annotations.size()); - for (TAnnotation ano : annotations) { - boList.add(new AnnotationBo(ano)); - } - this.annotationBoList = boList; - } - - public boolean hasException() { - return hasException; - } - - public int getExceptionId() { - return exceptionId; - } - - public String getExceptionMessage() { - return exceptionMessage; - } - - public String getExceptionClass() { - return exceptionClass; - } - - public void setExceptionClass(String exceptionClass) { - this.exceptionClass = exceptionClass; - } - - - - public byte[] writeValue() { - final Buffer buffer = new AutomaticBuffer(512); - - buffer.put(version); - - // buffer.put(mostTraceID); - // buffer.put(leastTraceID); - - buffer.putPrefixedString(agentId); - buffer.putPrefixedString(applicationId); - buffer.putVar(agentStartTime); - - buffer.putVar(startElapsed); - buffer.putVar(endElapsed); - // Qualifier에서 읽어서 set하므로 필요 없음. - // buffer.put(sequence); - - buffer.putPrefixedString(rpc); - buffer.put(serviceType.getCode()); - buffer.putPrefixedString(endPoint); - buffer.putPrefixedString(destinationId); - buffer.putSVar(apiId); - - buffer.putSVar(depth); - buffer.put(nextSpanId); - - if (hasException) { - buffer.put(true); - buffer.putSVar(exceptionId); - buffer.putPrefixedString(exceptionMessage); - } else { - buffer.put(false); - } - - writeAnnotation(buffer); - - - return buffer.getBuffer(); - } - - - - private void writeAnnotation(Buffer buffer) { - AnnotationBoList annotationBo = new AnnotationBoList(this.annotationBoList); - annotationBo.writeValue(buffer); - } - - - public int readValue(byte[] bytes, int offset) { - final Buffer buffer = new OffsetFixedBuffer(bytes, offset); - - this.version = buffer.readByte(); - - // this.mostTraceID = buffer.readLong(); - // this.leastTraceID = buffer.readLong(); - - this.agentId = buffer.readPrefixedString(); - this.applicationId = buffer.readPrefixedString(); - this.agentStartTime = buffer.readVarLong(); - - this.startElapsed = buffer.readVarInt(); - this.endElapsed = buffer.readVarInt(); - // Qualifier에서 읽어서 가져오므로 하지 않아도 됨. - // this.sequence = buffer.readShort(); - - - this.rpc = buffer.readPrefixedString(); - this.serviceType = ServiceType.findServiceType(buffer.readShort()); - this.endPoint = buffer.readPrefixedString(); - this.destinationId = buffer.readPrefixedString(); - this.apiId = buffer.readSVarInt(); - - this.depth = buffer.readSVarInt(); - this.nextSpanId = buffer.readLong(); - - this.hasException = buffer.readBoolean(); - if (hasException) { - this.exceptionId = buffer.readSVarInt(); - this.exceptionMessage = buffer.readPrefixedString(); - } - - this.annotationBoList = readAnnotation(buffer); - return buffer.getOffset(); - } - - private List readAnnotation(Buffer buffer) { - AnnotationBoList annotationBoList = new AnnotationBoList(); - annotationBoList.readValue(buffer); - return annotationBoList.getAnnotationBoList(); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(256); - sb.append("SpanEventBo{"); - sb.append("version=").append(version); - sb.append(", agentId='").append(agentId).append('\''); - sb.append(", applicationId='").append(applicationId).append('\''); - sb.append(", agentStartTime=").append(agentStartTime); - sb.append(", traceAgentId='").append(traceAgentId).append('\''); - sb.append(", traceAgentStartTime=").append(traceAgentStartTime); - sb.append(", traceTransactionSequence=").append(traceTransactionSequence); - sb.append(", spanId=").append(spanId); - sb.append(", sequence=").append(sequence); - sb.append(", startElapsed=").append(startElapsed); - sb.append(", endElapsed=").append(endElapsed); - sb.append(", rpc='").append(rpc).append('\''); - sb.append(", serviceType=").append(serviceType); - sb.append(", destinationId='").append(destinationId).append('\''); - sb.append(", endPoint='").append(endPoint).append('\''); - sb.append(", apiId=").append(apiId); - sb.append(", annotationBoList=").append(annotationBoList); - sb.append(", depth=").append(depth); - sb.append(", nextSpanId=").append(nextSpanId); - sb.append(", hasException=").append(hasException); - sb.append(", exceptionId=").append(exceptionId); - sb.append(", exceptionMessage='").append(exceptionMessage).append('\''); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.common.bo; + +import java.util.ArrayList; +import java.util.List; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import com.nhn.pinpoint.common.util.TransactionId; +import com.nhn.pinpoint.common.util.TransactionIdUtils; +import com.nhn.pinpoint.thrift.dto.*; +import com.nhn.pinpoint.common.buffer.Buffer; + +/** + * @author emeroad + */ +public class SpanEventBo implements Span { + private static final int VERSION_SIZE = 1; + // version 0 = prefix의 사이즈를 int로 + + private byte version = 0; + + private String agentId; + private String applicationId; + private long agentStartTime; + + private String traceAgentId; + private long traceAgentStartTime; + private long traceTransactionSequence; + + private long spanId; + private short sequence; + + private int startElapsed; + private int endElapsed; + + private String rpc; + private ServiceType serviceType; + + private String destinationId; + private String endPoint; + private int apiId; + + private List annotationBoList; + + private int depth = -1; + private long nextSpanId = -1; + + private boolean hasException; + private int exceptionId; + private String exceptionMessage; + // dao에서 찾아야 함. + private String exceptionClass; + + + public SpanEventBo() { + } + + public SpanEventBo(TSpan tSpan, TSpanEvent tSpanEvent) { + if (tSpan == null) { + throw new NullPointerException("tSpan must not be null"); + } + if (tSpanEvent == null) { + throw new NullPointerException("tSpanEvent must not be null"); + } + + this.agentId = tSpan.getAgentId(); + this.applicationId = tSpan.getApplicationName(); + this.agentStartTime = tSpan.getAgentStartTime(); + + final TransactionId transactionId = TransactionIdUtils.parseTransactionId(tSpan.getTransactionId()); + this.traceAgentId = transactionId.getAgentId(); + if (traceAgentId == null) { + traceAgentId = this.agentId; + } + this.traceAgentStartTime = transactionId.getAgentStartTime(); + this.traceTransactionSequence = transactionId.getTransactionSequence(); + + this.spanId = tSpan.getSpanId(); + this.sequence = tSpanEvent.getSequence(); + + this.startElapsed = tSpanEvent.getStartElapsed(); + this.endElapsed = tSpanEvent.getEndElapsed(); + + this.rpc = tSpanEvent.getRpc(); + this.serviceType = ServiceType.findServiceType(tSpanEvent.getServiceType()); + + + this.destinationId = tSpanEvent.getDestinationId(); + + this.endPoint = tSpanEvent.getEndPoint(); + this.apiId = tSpanEvent.getApiId(); + + if (tSpanEvent.isSetDepth()) { + this.depth = tSpanEvent.getDepth(); + } + + if (tSpanEvent.isSetNextSpanId()) { + this.nextSpanId = tSpanEvent.getNextSpanId(); + } + + setAnnotationBoList(tSpanEvent.getAnnotations()); + + final TIntStringValue exceptionInfo = tSpanEvent.getExceptionInfo(); + if (exceptionInfo != null) { + this.hasException = true; + this.exceptionId = exceptionInfo.getIntValue(); + this.exceptionMessage = exceptionInfo.getStringValue(); + } + } + + public SpanEventBo(TSpanChunk spanChunk, TSpanEvent spanEvent) { + if (spanChunk == null) { + throw new NullPointerException("spanChunk must not be null"); + } + if (spanEvent == null) { + throw new NullPointerException("spanEvent must not be null"); + } + + this.agentId = spanChunk.getAgentId(); + this.applicationId = spanChunk.getApplicationName(); + this.agentStartTime = spanChunk.getAgentStartTime(); + + final TransactionId transactionId = TransactionIdUtils.parseTransactionId(spanChunk.getTransactionId()); + this.traceAgentId = transactionId.getAgentId(); + if (traceAgentId == null) { + traceAgentId = this.agentId; + } + this.traceAgentStartTime = transactionId.getAgentStartTime(); + this.traceTransactionSequence = transactionId.getTransactionSequence(); + + this.spanId = spanChunk.getSpanId(); + this.sequence = spanEvent.getSequence(); + + this.startElapsed = spanEvent.getStartElapsed(); + this.endElapsed = spanEvent.getEndElapsed(); + + this.rpc = spanEvent.getRpc(); + this.serviceType = ServiceType.findServiceType(spanEvent.getServiceType()); + + this.destinationId = spanEvent.getDestinationId(); + + this.endPoint = spanEvent.getEndPoint(); + this.apiId = spanEvent.getApiId(); + + if (spanEvent.isSetDepth()) { + this.depth = spanEvent.getDepth(); + } + + if (spanEvent.isSetNextSpanId()) { + this.nextSpanId = spanEvent.getNextSpanId(); + } + + setAnnotationBoList(spanEvent.getAnnotations()); + + final TIntStringValue exceptionInfo = spanEvent.getExceptionInfo(); + if (exceptionInfo != null) { + this.hasException = true; + this.exceptionId = exceptionInfo.getIntValue(); + this.exceptionMessage = exceptionInfo.getStringValue(); + } + } + + + + public byte getVersion() { + return version; + } + + public void setVersion(byte version) { + this.version = version; + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public long getAgentStartTime() { + return this.agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + } + + public String getTraceAgentId() { + return traceAgentId; + } + + public void setTraceAgentId(String traceAgentId) { + this.traceAgentId = traceAgentId; + } + + public long getTraceAgentStartTime() { + return traceAgentStartTime; + } + + public void setTraceAgentStartTime(long traceAgentStartTime) { + this.traceAgentStartTime = traceAgentStartTime; + } + + public long getTraceTransactionSequence() { + return traceTransactionSequence; + } + + public void setTraceTransactionSequence(long traceTransactionSequence) { + this.traceTransactionSequence = traceTransactionSequence; + } + + public void setSpanId(long spanId) { + this.spanId = spanId; + } + + public long getSpanId() { + return this.spanId; + } + + public short getSequence() { + return sequence; + } + + public void setSequence(short sequence) { + this.sequence = sequence; + } + + public int getStartElapsed() { + return startElapsed; + } + + public void setStartElapsed(int startElapsed) { + this.startElapsed = startElapsed; + } + + public int getEndElapsed() { + return endElapsed; + } + + public void setEndElapsed(int endElapsed) { + this.endElapsed = endElapsed; + } + + public String getRpc() { + return rpc; + } + + public void setRpc(String rpc) { + this.rpc = rpc; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public void setServiceType(ServiceType serviceType) { + this.serviceType = serviceType; + } + + public String getEndPoint() { + return endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public int getApiId() { + return apiId; + } + + public void setApiId(int apiId) { + this.apiId = apiId; + } + + public String getDestinationId() { + return destinationId; + } + + public void setDestinationId(String destinationId) { + this.destinationId = destinationId; + } + + + public List getAnnotationBoList() { + return annotationBoList; + } + + public int getDepth() { + return depth; + } + + public void setDepth(int depth) { + this.depth = depth; + } + + public long getNextSpanId() { + return nextSpanId; + } + + public void setNextSpanId(long nextSpanId) { + this.nextSpanId = nextSpanId; + } + + private void setAnnotationBoList(List annotations) { + if (annotations == null) { + return; + } + List boList = new ArrayList(annotations.size()); + for (TAnnotation ano : annotations) { + boList.add(new AnnotationBo(ano)); + } + this.annotationBoList = boList; + } + + public boolean hasException() { + return hasException; + } + + public int getExceptionId() { + return exceptionId; + } + + public String getExceptionMessage() { + return exceptionMessage; + } + + public String getExceptionClass() { + return exceptionClass; + } + + public void setExceptionClass(String exceptionClass) { + this.exceptionClass = exceptionClass; + } + + + + public byte[] writeValue() { + final Buffer buffer = new AutomaticBuffer(512); + + buffer.put(version); + + // buffer.put(mostTraceID); + // buffer.put(leastTraceID); + + buffer.putPrefixedString(agentId); + buffer.putPrefixedString(applicationId); + buffer.putVar(agentStartTime); + + buffer.putVar(startElapsed); + buffer.putVar(endElapsed); + // Qualifier에서 읽어서 set하므로 필요 없음. + // buffer.put(sequence); + + buffer.putPrefixedString(rpc); + buffer.put(serviceType.getCode()); + buffer.putPrefixedString(endPoint); + buffer.putPrefixedString(destinationId); + buffer.putSVar(apiId); + + buffer.putSVar(depth); + buffer.put(nextSpanId); + + if (hasException) { + buffer.put(true); + buffer.putSVar(exceptionId); + buffer.putPrefixedString(exceptionMessage); + } else { + buffer.put(false); + } + + writeAnnotation(buffer); + + + return buffer.getBuffer(); + } + + + + private void writeAnnotation(Buffer buffer) { + AnnotationBoList annotationBo = new AnnotationBoList(this.annotationBoList); + annotationBo.writeValue(buffer); + } + + + public int readValue(byte[] bytes, int offset) { + final Buffer buffer = new OffsetFixedBuffer(bytes, offset); + + this.version = buffer.readByte(); + + // this.mostTraceID = buffer.readLong(); + // this.leastTraceID = buffer.readLong(); + + this.agentId = buffer.readPrefixedString(); + this.applicationId = buffer.readPrefixedString(); + this.agentStartTime = buffer.readVarLong(); + + this.startElapsed = buffer.readVarInt(); + this.endElapsed = buffer.readVarInt(); + // Qualifier에서 읽어서 가져오므로 하지 않아도 됨. + // this.sequence = buffer.readShort(); + + + this.rpc = buffer.readPrefixedString(); + this.serviceType = ServiceType.findServiceType(buffer.readShort()); + this.endPoint = buffer.readPrefixedString(); + this.destinationId = buffer.readPrefixedString(); + this.apiId = buffer.readSVarInt(); + + this.depth = buffer.readSVarInt(); + this.nextSpanId = buffer.readLong(); + + this.hasException = buffer.readBoolean(); + if (hasException) { + this.exceptionId = buffer.readSVarInt(); + this.exceptionMessage = buffer.readPrefixedString(); + } + + this.annotationBoList = readAnnotation(buffer); + return buffer.getOffset(); + } + + private List readAnnotation(Buffer buffer) { + AnnotationBoList annotationBoList = new AnnotationBoList(); + annotationBoList.readValue(buffer); + return annotationBoList.getAnnotationBoList(); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(256); + sb.append("SpanEventBo{"); + sb.append("version=").append(version); + sb.append(", agentId='").append(agentId).append('\''); + sb.append(", applicationId='").append(applicationId).append('\''); + sb.append(", agentStartTime=").append(agentStartTime); + sb.append(", traceAgentId='").append(traceAgentId).append('\''); + sb.append(", traceAgentStartTime=").append(traceAgentStartTime); + sb.append(", traceTransactionSequence=").append(traceTransactionSequence); + sb.append(", spanId=").append(spanId); + sb.append(", sequence=").append(sequence); + sb.append(", startElapsed=").append(startElapsed); + sb.append(", endElapsed=").append(endElapsed); + sb.append(", rpc='").append(rpc).append('\''); + sb.append(", serviceType=").append(serviceType); + sb.append(", destinationId='").append(destinationId).append('\''); + sb.append(", endPoint='").append(endPoint).append('\''); + sb.append(", apiId=").append(apiId); + sb.append(", annotationBoList=").append(annotationBoList); + sb.append(", depth=").append(depth); + sb.append(", nextSpanId=").append(nextSpanId); + sb.append(", hasException=").append(hasException); + sb.append(", exceptionId=").append(exceptionId); + sb.append(", exceptionMessage='").append(exceptionMessage).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/SqlMetaDataBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/SqlMetaDataBo.java index ad7968e57de3..5eef0ef822b3 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/SqlMetaDataBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/SqlMetaDataBo.java @@ -1,97 +1,97 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.RowKeyUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import org.apache.hadoop.hbase.util.Bytes; - -import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; -import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; - -/** - * @author emeroad - */ -public class SqlMetaDataBo { - private String agentId; - private long startTime; - - private int hashCode; - - private String sql; - - public SqlMetaDataBo() { - } - - - public SqlMetaDataBo(String agentId, long startTime, int hashCode) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - this.agentId = agentId; - this.hashCode = hashCode; - this.startTime = startTime; - } - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - - public int getHashCode() { - return hashCode; - } - - public void setHashCode(int hashCode) { - this.hashCode = hashCode; - } - - public long getStartTime() { - return startTime; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } - - public String getSql() { - return sql; - } - - public void setSql(String sql) { - this.sql = sql; - } - - public void readRowKey(byte[] rowKey) { - this.agentId = Bytes.toString(rowKey, 0, AGENT_NAME_MAX_LEN).trim(); - this.startTime = TimeUtils.recoveryTimeMillis(readTime(rowKey)); - this.hashCode = readKeyCode(rowKey); - } - - - private static long readTime(byte[] rowKey) { - return BytesUtils.bytesToLong(rowKey, AGENT_NAME_MAX_LEN); - } - - private static int readKeyCode(byte[] rowKey) { - return BytesUtils.bytesToInt(rowKey, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); - } - - public byte[] toRowKey() { - return RowKeyUtils.getMetaInfoRowKey(this.agentId, this.startTime, this.hashCode); - } - - @Override - public String toString() { - return "SqlMetaDataBo{" + - "agentId='" + agentId + '\'' + - ", startTime=" + startTime + - ", hashCode=" + hashCode + - ", sql='" + sql + '\'' + - '}'; - } - -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.RowKeyUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import org.apache.hadoop.hbase.util.Bytes; + +import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; +import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; + +/** + * @author emeroad + */ +public class SqlMetaDataBo { + private String agentId; + private long startTime; + + private int hashCode; + + private String sql; + + public SqlMetaDataBo() { + } + + + public SqlMetaDataBo(String agentId, long startTime, int hashCode) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + this.agentId = agentId; + this.hashCode = hashCode; + this.startTime = startTime; + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + + public int getHashCode() { + return hashCode; + } + + public void setHashCode(int hashCode) { + this.hashCode = hashCode; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public String getSql() { + return sql; + } + + public void setSql(String sql) { + this.sql = sql; + } + + public void readRowKey(byte[] rowKey) { + this.agentId = Bytes.toString(rowKey, 0, AGENT_NAME_MAX_LEN).trim(); + this.startTime = TimeUtils.recoveryTimeMillis(readTime(rowKey)); + this.hashCode = readKeyCode(rowKey); + } + + + private static long readTime(byte[] rowKey) { + return BytesUtils.bytesToLong(rowKey, AGENT_NAME_MAX_LEN); + } + + private static int readKeyCode(byte[] rowKey) { + return BytesUtils.bytesToInt(rowKey, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); + } + + public byte[] toRowKey() { + return RowKeyUtils.getMetaInfoRowKey(this.agentId, this.startTime, this.hashCode); + } + + @Override + public String toString() { + return "SqlMetaDataBo{" + + "agentId='" + agentId + '\'' + + ", startTime=" + startTime + + ", hashCode=" + hashCode + + ", sql='" + sql + '\'' + + '}'; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/bo/StringMetaDataBo.java b/commons/src/main/java/com/navercorp/pinpoint/common/bo/StringMetaDataBo.java index 90fe4dbba63c..9c25cd91b1d0 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/bo/StringMetaDataBo.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/bo/StringMetaDataBo.java @@ -1,97 +1,97 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.RowKeyUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import org.apache.hadoop.hbase.util.Bytes; - -import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; -import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; - -/** - * @author emeroad - */ -public class StringMetaDataBo { - private String agentId; - private long startTime; - - private int stringId; - - private String stringValue; - - public StringMetaDataBo() { - } - - - public StringMetaDataBo(String agentId, long startTime, int stringId) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - this.agentId = agentId; - this.stringId = stringId; - this.startTime = startTime; - } - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - - public int getStringId() { - return stringId; - } - - public void setStringId(int stringId) { - this.stringId = stringId; - } - - public long getStartTime() { - return startTime; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } - - public String getStringValue() { - return stringValue; - } - - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - public void readRowKey(byte[] rowKey) { - this.agentId = Bytes.toString(rowKey, 0, AGENT_NAME_MAX_LEN).trim(); - this.startTime = TimeUtils.recoveryTimeMillis(readTime(rowKey)); - this.stringId = readKeyCode(rowKey); - } - - - private static long readTime(byte[] rowKey) { - return BytesUtils.bytesToLong(rowKey, AGENT_NAME_MAX_LEN); - } - - private static int readKeyCode(byte[] rowKey) { - return BytesUtils.bytesToInt(rowKey, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); - } - - public byte[] toRowKey() { - return RowKeyUtils.getMetaInfoRowKey(this.agentId, this.startTime, this.stringId); - } - - @Override - public String toString() { - return "StringMetaDataBo{" + - "agentId='" + agentId + '\'' + - ", startTime=" + startTime + - ", stringId=" + stringId + - ", stringValue='" + stringValue + '\'' + - '}'; - } - -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.RowKeyUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import org.apache.hadoop.hbase.util.Bytes; + +import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; +import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; + +/** + * @author emeroad + */ +public class StringMetaDataBo { + private String agentId; + private long startTime; + + private int stringId; + + private String stringValue; + + public StringMetaDataBo() { + } + + + public StringMetaDataBo(String agentId, long startTime, int stringId) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + this.agentId = agentId; + this.stringId = stringId; + this.startTime = startTime; + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + + public int getStringId() { + return stringId; + } + + public void setStringId(int stringId) { + this.stringId = stringId; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + public void readRowKey(byte[] rowKey) { + this.agentId = Bytes.toString(rowKey, 0, AGENT_NAME_MAX_LEN).trim(); + this.startTime = TimeUtils.recoveryTimeMillis(readTime(rowKey)); + this.stringId = readKeyCode(rowKey); + } + + + private static long readTime(byte[] rowKey) { + return BytesUtils.bytesToLong(rowKey, AGENT_NAME_MAX_LEN); + } + + private static int readKeyCode(byte[] rowKey) { + return BytesUtils.bytesToInt(rowKey, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); + } + + public byte[] toRowKey() { + return RowKeyUtils.getMetaInfoRowKey(this.agentId, this.startTime, this.stringId); + } + + @Override + public String toString() { + return "StringMetaDataBo{" + + "agentId='" + agentId + '\'' + + ", startTime=" + startTime + + ", stringId=" + stringId + + ", stringValue='" + stringValue + '\'' + + '}'; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/AutomaticBuffer.java b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/AutomaticBuffer.java index de004a3143c5..96e7419e9a99 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/AutomaticBuffer.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/AutomaticBuffer.java @@ -1,182 +1,182 @@ -package com.nhn.pinpoint.common.buffer; - -import com.nhn.pinpoint.common.util.BytesUtils; - -/** - * 버퍼사이즈가 자동으로 확장되는 buffer - * @author emeroad - */ -public class AutomaticBuffer extends FixedBuffer { - - public AutomaticBuffer() { - super(32); - } - - public AutomaticBuffer(final int size) { - super(size); - } - - public AutomaticBuffer(final byte[] buffer) { - super(buffer); - } - - - private void checkExpend(final int size) { - int length = buffer.length; - final int remain = length - offset; - if (remain >= size) { - return; - } - - if (length == 0) { - length = 1; - } - - // 사이즈 계산을 먼저한 후에 buffer를 한번만 할당하도록 변경. - final int expendBufferSize = computeExpendBufferSize(size, length, remain); - // allocate buffer - final byte[] expendBuffer = new byte[expendBufferSize]; - System.arraycopy(buffer, 0, expendBuffer, 0, buffer.length); - buffer = expendBuffer; - } - - private int computeExpendBufferSize(final int size, int length, int remain) { - int expendBufferSize = 0; - while (remain < size) { - length <<= 2; - expendBufferSize = length; - remain = expendBufferSize - offset; - } - return expendBufferSize; - } - - @Override - public void putPadBytes(byte[] bytes, int totalLength) { - checkExpend(totalLength); - super.putPadBytes(bytes, totalLength); - } - - - @Override - public void putPrefixedBytes(final byte[] bytes) { - if (bytes == null) { - checkExpend(1); - super.putSVar(NULL); - } else { - checkExpend(bytes.length + BytesUtils.VINT_MAX_SIZE); - super.putSVar(bytes.length); - super.put(bytes); - } - } - - @Override - public void put2PrefixedBytes(final byte[] bytes) { - if (bytes == null) { - checkExpend(BytesUtils.SHORT_BYTE_LENGTH); - super.put((short)NULL); - } else { - if (bytes.length > Short.MAX_VALUE) { - throw new IllegalArgumentException("too large bytes length:" + bytes.length); - } - checkExpend(bytes.length + BytesUtils.SHORT_BYTE_LENGTH); - super.put((short)bytes.length); - super.put(bytes); - } - } - - @Override - public void put4PrefixedBytes(final byte[] bytes) { - if (bytes == null) { - checkExpend(BytesUtils.INT_BYTE_LENGTH); - super.put(NULL); - } else { - checkExpend(bytes.length + BytesUtils.INT_BYTE_LENGTH); - super.put(bytes.length); - super.put(bytes); - } - } - - @Override - public void putPadString(String string, int totalLength) { - checkExpend(totalLength); - super.putPadString(string, totalLength); - } - - - @Override - public void putPrefixedString(final String string) { - byte[] bytes = BytesUtils.toBytes(string); - this.putPrefixedBytes(bytes); - } - - @Override - public void put2PrefixedString(final String string) { - byte[] bytes = BytesUtils.toBytes(string); - this.put2PrefixedBytes(bytes); - } - - @Override - public void put4PrefixedString(final String string) { - byte[] bytes = BytesUtils.toBytes(string); - this.put4PrefixedBytes(bytes); - } - - @Override - public void put(final byte v) { - checkExpend(1); - super.put(v); - } - - @Override - public void put(final boolean v) { - checkExpend(1); - super.put(v); - } - - @Override - public void put(final short v) { - checkExpend(2); - super.put(v); - } - - @Override - public void put(final int v) { - checkExpend(4); - super.put(v); - } - - public void putVar(final int v) { - checkExpend(BytesUtils.VLONG_MAX_SIZE); - super.putVar(v); - } - - public void putSVar(final int v) { - checkExpend(BytesUtils.VINT_MAX_SIZE); - super.putSVar(v); - } - - public void putVar(final long v) { - checkExpend(BytesUtils.VLONG_MAX_SIZE); - super.putVar(v); - } - - public void putSVar(final long v) { - checkExpend(BytesUtils.VLONG_MAX_SIZE); - super.putSVar(v); - } - - @Override - public void put(final long v) { - checkExpend(8); - super.put(v); - } - - @Override - public void put(final byte[] v) { - if (v == null) { - throw new NullPointerException("v must not be null"); - } - checkExpend(v.length); - super.put(v); - } -} +package com.nhn.pinpoint.common.buffer; + +import com.nhn.pinpoint.common.util.BytesUtils; + +/** + * 버퍼사이즈가 자동으로 확장되는 buffer + * @author emeroad + */ +public class AutomaticBuffer extends FixedBuffer { + + public AutomaticBuffer() { + super(32); + } + + public AutomaticBuffer(final int size) { + super(size); + } + + public AutomaticBuffer(final byte[] buffer) { + super(buffer); + } + + + private void checkExpend(final int size) { + int length = buffer.length; + final int remain = length - offset; + if (remain >= size) { + return; + } + + if (length == 0) { + length = 1; + } + + // 사이즈 계산을 먼저한 후에 buffer를 한번만 할당하도록 변경. + final int expendBufferSize = computeExpendBufferSize(size, length, remain); + // allocate buffer + final byte[] expendBuffer = new byte[expendBufferSize]; + System.arraycopy(buffer, 0, expendBuffer, 0, buffer.length); + buffer = expendBuffer; + } + + private int computeExpendBufferSize(final int size, int length, int remain) { + int expendBufferSize = 0; + while (remain < size) { + length <<= 2; + expendBufferSize = length; + remain = expendBufferSize - offset; + } + return expendBufferSize; + } + + @Override + public void putPadBytes(byte[] bytes, int totalLength) { + checkExpend(totalLength); + super.putPadBytes(bytes, totalLength); + } + + + @Override + public void putPrefixedBytes(final byte[] bytes) { + if (bytes == null) { + checkExpend(1); + super.putSVar(NULL); + } else { + checkExpend(bytes.length + BytesUtils.VINT_MAX_SIZE); + super.putSVar(bytes.length); + super.put(bytes); + } + } + + @Override + public void put2PrefixedBytes(final byte[] bytes) { + if (bytes == null) { + checkExpend(BytesUtils.SHORT_BYTE_LENGTH); + super.put((short)NULL); + } else { + if (bytes.length > Short.MAX_VALUE) { + throw new IllegalArgumentException("too large bytes length:" + bytes.length); + } + checkExpend(bytes.length + BytesUtils.SHORT_BYTE_LENGTH); + super.put((short)bytes.length); + super.put(bytes); + } + } + + @Override + public void put4PrefixedBytes(final byte[] bytes) { + if (bytes == null) { + checkExpend(BytesUtils.INT_BYTE_LENGTH); + super.put(NULL); + } else { + checkExpend(bytes.length + BytesUtils.INT_BYTE_LENGTH); + super.put(bytes.length); + super.put(bytes); + } + } + + @Override + public void putPadString(String string, int totalLength) { + checkExpend(totalLength); + super.putPadString(string, totalLength); + } + + + @Override + public void putPrefixedString(final String string) { + byte[] bytes = BytesUtils.toBytes(string); + this.putPrefixedBytes(bytes); + } + + @Override + public void put2PrefixedString(final String string) { + byte[] bytes = BytesUtils.toBytes(string); + this.put2PrefixedBytes(bytes); + } + + @Override + public void put4PrefixedString(final String string) { + byte[] bytes = BytesUtils.toBytes(string); + this.put4PrefixedBytes(bytes); + } + + @Override + public void put(final byte v) { + checkExpend(1); + super.put(v); + } + + @Override + public void put(final boolean v) { + checkExpend(1); + super.put(v); + } + + @Override + public void put(final short v) { + checkExpend(2); + super.put(v); + } + + @Override + public void put(final int v) { + checkExpend(4); + super.put(v); + } + + public void putVar(final int v) { + checkExpend(BytesUtils.VLONG_MAX_SIZE); + super.putVar(v); + } + + public void putSVar(final int v) { + checkExpend(BytesUtils.VINT_MAX_SIZE); + super.putSVar(v); + } + + public void putVar(final long v) { + checkExpend(BytesUtils.VLONG_MAX_SIZE); + super.putVar(v); + } + + public void putSVar(final long v) { + checkExpend(BytesUtils.VLONG_MAX_SIZE); + super.putSVar(v); + } + + @Override + public void put(final long v) { + checkExpend(8); + super.put(v); + } + + @Override + public void put(final byte[] v) { + if (v == null) { + throw new NullPointerException("v must not be null"); + } + checkExpend(v.length); + super.put(v); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/Buffer.java b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/Buffer.java index 9a7e2115be66..69892ec19a9c 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/Buffer.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/Buffer.java @@ -1,154 +1,154 @@ -package com.nhn.pinpoint.common.buffer; - -/** - * @author emeroad - */ -public interface Buffer { - - public static final int BOOLEAN_FALSE = 0; - public static final int BOOLEAN_TRUE = 1; - - public static final byte[] EMPTY = new byte[0]; - - public static final String UTF8 = "UTF-8"; - - void putPadBytes(byte[] bytes, int totalLength); - - void putPrefixedBytes(byte[] bytes); - - void put2PrefixedBytes(byte[] bytes); - - void put4PrefixedBytes(byte[] bytes); - - void putPadString(String string, int totalLength); - - void putPrefixedString(String string); - - void put2PrefixedString(String string); - - void put4PrefixedString(String string); - - void put(byte v); - - void put(boolean v); - - void put(int v); - - /** - * 가변인코딩을 사용하여 저장한다. - * 상수값에 강한 인코딩을 한다. - * 음수값이 들어갈 경우 사이즈가 fixint 인코딩 보다 더 커짐, 음수값의 분포가 많을 경우 매우 비효율적임. - * 이 경우 putSVar를 사용한다. putSVar에 비해서 zigzag연산이 없어 cpu를 약간 덜사용하는 이점 뿐이 없음. - * 음수가 조금이라도 들어갈 가능성이 있다면 putSVar를 사용하는 것이 이득이다.. - * 1~10 byte사용 - * max : 5, min 10 - * @param v - */ - void putVar(int v); - - /** - * 가변인코딩을 사용하여 저장한다. - * 상수, 음수의 분포가 동일한 데이터 일 경우 사용한다. - * 1~5 사용 - * max : 5, min :5 - * @param v - */ - void putSVar(int v); - - void put(short v); - - void put(long v); - - /** - * 가변인코딩을 사용하여 저장한다. - * 상수값에 강한 인코딩을 한다. - * 음수값이 들어갈 경우 사이즈가 fixint 인코딩 보다 더 커짐 - * 이경우 putSVar를 사용한다. - * @param v - */ - void putVar(long v); - - /** - * 가변인코딩을 사용하여 저장한다. - * 상수, 음수의 분포가 동일한 데이터 일 경우 사용한다. - * @param v - */ - void putSVar(long v); - - void put(double v); - - /** - * 가변인코딩을 사용하여 저장한다. - * 상수값에 강한 인코딩을 한다. - * 음수값이 들어갈 경우 사이즈가 fixint 인코딩 보다 더 커짐 - * 이경우 putSVar를 사용한다. - * @param v - */ - void putVar(double v); - - /** - * 가변인코딩을 사용하여 저장한다. - * 상수, 음수의 분포가 동일한 데이터 일 경우 사용한다. - * @param v - */ - void putSVar(double v); - - void put(byte[] v); - - byte readByte(); - - int readUnsignedByte(); - - boolean readBoolean(); - - int readInt(); - - int readVarInt(); - - int readSVarInt(); - - - short readShort(); - - long readLong(); - - long readVarLong(); - - long readSVarLong(); - - double readDouble(); - - double readVarDouble(); - - double readSVarDouble(); - - byte[] readPadBytes(int totalLength); - - String readPadString(int totalLength); - - String readPadStringAndRightTrim(int totalLength); - - byte[] readPrefixedBytes(); - - byte[] read2PrefixedBytes(); - - byte[] read4PrefixedBytes(); - - String readPrefixedString(); - - String read2PrefixedString(); - - String read4PrefixedString(); - - byte[] getBuffer(); - - byte[] copyBuffer(); - - byte[] getInternalBuffer(); - - void setOffset(int offset); - - int getOffset(); - - int limit(); -} +package com.nhn.pinpoint.common.buffer; + +/** + * @author emeroad + */ +public interface Buffer { + + public static final int BOOLEAN_FALSE = 0; + public static final int BOOLEAN_TRUE = 1; + + public static final byte[] EMPTY = new byte[0]; + + public static final String UTF8 = "UTF-8"; + + void putPadBytes(byte[] bytes, int totalLength); + + void putPrefixedBytes(byte[] bytes); + + void put2PrefixedBytes(byte[] bytes); + + void put4PrefixedBytes(byte[] bytes); + + void putPadString(String string, int totalLength); + + void putPrefixedString(String string); + + void put2PrefixedString(String string); + + void put4PrefixedString(String string); + + void put(byte v); + + void put(boolean v); + + void put(int v); + + /** + * 가변인코딩을 사용하여 저장한다. + * 상수값에 강한 인코딩을 한다. + * 음수값이 들어갈 경우 사이즈가 fixint 인코딩 보다 더 커짐, 음수값의 분포가 많을 경우 매우 비효율적임. + * 이 경우 putSVar를 사용한다. putSVar에 비해서 zigzag연산이 없어 cpu를 약간 덜사용하는 이점 뿐이 없음. + * 음수가 조금이라도 들어갈 가능성이 있다면 putSVar를 사용하는 것이 이득이다.. + * 1~10 byte사용 + * max : 5, min 10 + * @param v + */ + void putVar(int v); + + /** + * 가변인코딩을 사용하여 저장한다. + * 상수, 음수의 분포가 동일한 데이터 일 경우 사용한다. + * 1~5 사용 + * max : 5, min :5 + * @param v + */ + void putSVar(int v); + + void put(short v); + + void put(long v); + + /** + * 가변인코딩을 사용하여 저장한다. + * 상수값에 강한 인코딩을 한다. + * 음수값이 들어갈 경우 사이즈가 fixint 인코딩 보다 더 커짐 + * 이경우 putSVar를 사용한다. + * @param v + */ + void putVar(long v); + + /** + * 가변인코딩을 사용하여 저장한다. + * 상수, 음수의 분포가 동일한 데이터 일 경우 사용한다. + * @param v + */ + void putSVar(long v); + + void put(double v); + + /** + * 가변인코딩을 사용하여 저장한다. + * 상수값에 강한 인코딩을 한다. + * 음수값이 들어갈 경우 사이즈가 fixint 인코딩 보다 더 커짐 + * 이경우 putSVar를 사용한다. + * @param v + */ + void putVar(double v); + + /** + * 가변인코딩을 사용하여 저장한다. + * 상수, 음수의 분포가 동일한 데이터 일 경우 사용한다. + * @param v + */ + void putSVar(double v); + + void put(byte[] v); + + byte readByte(); + + int readUnsignedByte(); + + boolean readBoolean(); + + int readInt(); + + int readVarInt(); + + int readSVarInt(); + + + short readShort(); + + long readLong(); + + long readVarLong(); + + long readSVarLong(); + + double readDouble(); + + double readVarDouble(); + + double readSVarDouble(); + + byte[] readPadBytes(int totalLength); + + String readPadString(int totalLength); + + String readPadStringAndRightTrim(int totalLength); + + byte[] readPrefixedBytes(); + + byte[] read2PrefixedBytes(); + + byte[] read4PrefixedBytes(); + + String readPrefixedString(); + + String read2PrefixedString(); + + String read4PrefixedString(); + + byte[] getBuffer(); + + byte[] copyBuffer(); + + byte[] getInternalBuffer(); + + void setOffset(int offset); + + int getOffset(); + + int limit(); +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/FixedBuffer.java b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/FixedBuffer.java index 804f37e3f2d0..a97e2ca16344 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/FixedBuffer.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/FixedBuffer.java @@ -1,479 +1,479 @@ -package com.nhn.pinpoint.common.buffer; - -import com.nhn.pinpoint.common.util.BytesUtils; - -import java.io.UnsupportedEncodingException; - -/** - * @author emeroad - */ -public class FixedBuffer implements Buffer { - protected static final int NULL = -1; - protected byte[] buffer; - protected int offset; - - public FixedBuffer() { - this(32); - } - - public FixedBuffer(final int bufferSize) { - if (bufferSize < 0) { - throw new IllegalArgumentException("negative bufferSize:" + bufferSize); - } - this.buffer = new byte[bufferSize]; - this.offset = 0; - } - - public FixedBuffer(final byte[] buffer) { - if (buffer == null) { - throw new NullPointerException("buffer must not be null"); - } - this.buffer = buffer; - this.offset = 0; - } - - @Override - public void putPadBytes(byte[] bytes, int totalLength) { - if (bytes == null) { - bytes = EMPTY; - } - if (bytes.length > totalLength) { - throw new IllegalArgumentException("bytes too big:" + bytes.length + " totalLength:" + totalLength); - } - put(bytes); - final int padSize = totalLength - bytes.length; - if (padSize > 0) { - putPad(padSize); - } - } - - private void putPad(int padSize) { - for (int i = 0; i < padSize; i++) { - put((byte)0); - } - } - - - @Override - public void putPrefixedBytes(final byte[] bytes) { - if (bytes == null) { - putSVar(NULL); - } else { - putSVar(bytes.length); - put(bytes); - } - } - - @Override - public void put2PrefixedBytes(final byte[] bytes) { - if (bytes == null) { - put((short)NULL); - } else { - if (bytes.length > Short.MAX_VALUE) { - throw new IllegalArgumentException("too large bytes length:" + bytes.length); - } - put((short)bytes.length); - put(bytes); - } - } - - @Override - public void put4PrefixedBytes(final byte[] bytes) { - if (bytes == null) { - put(NULL); - } else { - put(bytes.length); - put(bytes); - } - } - - @Override - public void putPadString(String string, int totalLength) { - final byte[] bytes = BytesUtils.toBytes(string); - putPadBytes(bytes, totalLength); - } - - @Override - public void putPrefixedString(final String string) { - final byte[] bytes = BytesUtils.toBytes(string); - putPrefixedBytes(bytes); - } - - @Override - public void put2PrefixedString(final String string) { - final byte[] bytes = BytesUtils.toBytes(string); - if (bytes == null) { - put((short)NULL); - return; - } - if (bytes.length > Short.MAX_VALUE) { - throw new IllegalArgumentException("too large String size:" + bytes.length); - } - put2PrefixedBytes(bytes); - } - - @Override - public void put4PrefixedString(final String string) { - final byte[] bytes = BytesUtils.toBytes(string); - if (bytes == null) { - put(NULL); - return; - } - put4PrefixedBytes(bytes); - } - - @Override - public void put(final byte v) { - this.buffer[offset++] = v; - } - - @Override - public void put(final boolean v) { - if (v) { - this.buffer[offset++] = BOOLEAN_TRUE; - } else { - this.buffer[offset++] = BOOLEAN_FALSE; - } - } - - @Override - public void put(final int v) { - this.offset = BytesUtils.writeInt(v, buffer, offset); - } - - public void putVar(int v) { - if (v >= 0) { - putVar32(v); - } else { - putVar64((long) v); - } - } - - public void putSVar(int v) { - this.offset = BytesUtils.writeSVar32(v, buffer, offset); - } - - private void putVar32(int v) { - this.offset = BytesUtils.writeVar32(v, buffer, offset); - } - - @Override - public void put(final short v) { - this.offset = BytesUtils.writeShort(v, buffer, offset); - } - - @Override - public void put(final long v) { - this.offset = BytesUtils.writeLong(v, buffer, offset); - } - - @Override - public void putVar(long v) { - putVar64(v); - } - - @Override - public void putSVar(long v) { - putVar64(BytesUtils.longToZigZag(v)); - } - - private void putVar64(long v) { - this.offset = BytesUtils.writeVar64(v, buffer, offset); - } - - @Override - public void put(double v) { - put(Double.doubleToRawLongBits(v)); - } - - @Override - public void putVar(double v) { - putVar(Double.doubleToRawLongBits(v)); - } - - @Override - public void putSVar(double v) { - putSVar(Double.doubleToRawLongBits(v)); - } - - @Override - public void put(final byte[] v) { - if (v == null) { - throw new NullPointerException("v must not be null"); - } - System.arraycopy(v, 0, buffer, offset, v.length); - this.offset = offset + v.length; - } - - @Override - public byte readByte() { - return this.buffer[offset++]; - } - - @Override - public int readUnsignedByte() { - return readByte() & 0xff; - } - - @Override - public boolean readBoolean() { - final byte b = readByte(); - return b == BOOLEAN_TRUE; - } - - @Override - public int readInt() { - final int i = BytesUtils.bytesToInt(buffer, offset); - this.offset = this.offset + 4; - return i; - } - - @Override - public int readVarInt() { - // protocol buffer의 var encoding 차용. - byte v = readByte(); - if (v >= 0) { - return v; - } - int result = v & 0x7f; - if ((v = readByte()) >= 0) { - result |= v << 7; - } else { - result |= (v & 0x7f) << 7; - if ((v = readByte()) >= 0) { - result |= v << 14; - } else { - result |= (v & 0x7f) << 14; - if ((v = readByte()) >= 0) { - result |= v << 21; - } else { - result |= (v & 0x7f) << 21; - result |= (v = readByte()) << 28; - if (v < 0) { - for (int i = 0; i < 5; i++) { - if (readByte() >= 0) { - return result; - } - } - throw new IllegalArgumentException("invalid varInt"); - } - } - } - } - return result; - } - - public int readSVarInt() { - return BytesUtils.zigzagToInt(readVarInt()); - } - - @Override - public short readShort() { - final short i = BytesUtils.bytesToShort(buffer, offset); - this.offset = this.offset + 2; - return i; - } - - public int readUnsignedShort() { - return readShort() & 0xFFFF; - } - - @Override - public long readLong() { - final long l = BytesUtils.bytesToLong(buffer, offset); - this.offset = this.offset + 8; - return l; - } - - @Override - public long readVarLong() { - int shift = 0; - long result = 0; - while (shift < 64) { - final byte v = readByte(); - result |= (long)(v & 0x7F) << shift; - if ((v & 0x80) == 0) { - return result; - } - shift += 7; - } - throw new IllegalArgumentException("invalid varLong"); - } - - @Override - public long readSVarLong() { - return BytesUtils.zigzagToLong(readVarLong()); - } - - @Override - public double readDouble() { - return Double.longBitsToDouble(this.readLong()); - } - - @Override - public double readVarDouble() { - return Double.longBitsToDouble(this.readVarLong()); - } - - @Override - public double readSVarDouble() { - return Double.longBitsToDouble(this.readSVarLong()); - } - - @Override - public byte[] readPadBytes(int totalLength) { - return readBytes(totalLength); - } - - @Override - public String readPadString(int totalLength) { - return readString(totalLength); - } - - @Override - public String readPadStringAndRightTrim(int totalLength) { - String string = BytesUtils.toStringAndRightTrim(buffer, offset, totalLength); - this.offset = offset + totalLength; - return string ; - } - - - @Override - public byte[] readPrefixedBytes() { - final int size = readSVarInt(); - if (size == NULL) { - return null; - } - if (size == 0) { - return EMPTY; - } - return readBytes(size); - } - - @Override - public byte[] read2PrefixedBytes() { - final int size = readShort(); - if (size == NULL) { - return null; - } - if (size == 0) { - return EMPTY; - } - return readBytes(size); - } - - @Override - public byte[] read4PrefixedBytes() { - final int size = readInt(); - if (size == NULL) { - return null; - } - if (size == 0) { - return EMPTY; - } - return readBytes(size); - } - - - private byte[] readBytes(int size) { - final byte[] b = new byte[size]; - System.arraycopy(buffer, offset, b, 0, size); - this.offset = offset + size; - return b; - } - - @Override - public String readPrefixedString() { - final int size = readSVarInt(); - if (size == NULL) { - return null; - } - if (size == 0) { - return ""; - } - return readString(size); - } - - @Override - public String read2PrefixedString() { - final int size = readShort(); - if (size == NULL) { - return null; - } - if (size == 0) { - return ""; - } - return readString(size); - } - - @Override - public String read4PrefixedString() { - final int size = readInt(); - if (size == NULL) { - return null; - } - if (size == 0) { - return ""; - } - return readString(size); - } - - - private String readString(final int size) { - final String s = newString(size); - this.offset = offset + size; - return s; - } - - private String newString(final int size) { - try { - return new String(buffer, offset, size, UTF8); - } catch (UnsupportedEncodingException ue) { - throw new RuntimeException(ue.getMessage(), ue); - } - } - - /** - * 암묵적으로 성능을 내부 buffe length와 offset의 사이즈가 같으면 메모리 copy를 하지 않고 그냥 internal buffer를 리턴하므로 주의해야 한다. - * @return - */ - @Override - public byte[] getBuffer() { - if (offset == buffer.length) { - return this.buffer; - } else { - return copyBuffer(); - } - } - - @Override - public byte[] copyBuffer() { - final byte[] copy = new byte[offset]; - System.arraycopy(buffer, 0, copy, 0, offset); - return copy; - } - - /** - * 내부 buffer를 리턴한다. - * @return - */ - @Override - public byte[] getInternalBuffer() { - return this.buffer; - } - - @Override - public void setOffset(int offset) { - this.offset = offset; - } - - @Override - public int getOffset() { - return offset; - } - - @Override - public int limit() { - return buffer.length - offset; - } -} +package com.nhn.pinpoint.common.buffer; + +import com.nhn.pinpoint.common.util.BytesUtils; + +import java.io.UnsupportedEncodingException; + +/** + * @author emeroad + */ +public class FixedBuffer implements Buffer { + protected static final int NULL = -1; + protected byte[] buffer; + protected int offset; + + public FixedBuffer() { + this(32); + } + + public FixedBuffer(final int bufferSize) { + if (bufferSize < 0) { + throw new IllegalArgumentException("negative bufferSize:" + bufferSize); + } + this.buffer = new byte[bufferSize]; + this.offset = 0; + } + + public FixedBuffer(final byte[] buffer) { + if (buffer == null) { + throw new NullPointerException("buffer must not be null"); + } + this.buffer = buffer; + this.offset = 0; + } + + @Override + public void putPadBytes(byte[] bytes, int totalLength) { + if (bytes == null) { + bytes = EMPTY; + } + if (bytes.length > totalLength) { + throw new IllegalArgumentException("bytes too big:" + bytes.length + " totalLength:" + totalLength); + } + put(bytes); + final int padSize = totalLength - bytes.length; + if (padSize > 0) { + putPad(padSize); + } + } + + private void putPad(int padSize) { + for (int i = 0; i < padSize; i++) { + put((byte)0); + } + } + + + @Override + public void putPrefixedBytes(final byte[] bytes) { + if (bytes == null) { + putSVar(NULL); + } else { + putSVar(bytes.length); + put(bytes); + } + } + + @Override + public void put2PrefixedBytes(final byte[] bytes) { + if (bytes == null) { + put((short)NULL); + } else { + if (bytes.length > Short.MAX_VALUE) { + throw new IllegalArgumentException("too large bytes length:" + bytes.length); + } + put((short)bytes.length); + put(bytes); + } + } + + @Override + public void put4PrefixedBytes(final byte[] bytes) { + if (bytes == null) { + put(NULL); + } else { + put(bytes.length); + put(bytes); + } + } + + @Override + public void putPadString(String string, int totalLength) { + final byte[] bytes = BytesUtils.toBytes(string); + putPadBytes(bytes, totalLength); + } + + @Override + public void putPrefixedString(final String string) { + final byte[] bytes = BytesUtils.toBytes(string); + putPrefixedBytes(bytes); + } + + @Override + public void put2PrefixedString(final String string) { + final byte[] bytes = BytesUtils.toBytes(string); + if (bytes == null) { + put((short)NULL); + return; + } + if (bytes.length > Short.MAX_VALUE) { + throw new IllegalArgumentException("too large String size:" + bytes.length); + } + put2PrefixedBytes(bytes); + } + + @Override + public void put4PrefixedString(final String string) { + final byte[] bytes = BytesUtils.toBytes(string); + if (bytes == null) { + put(NULL); + return; + } + put4PrefixedBytes(bytes); + } + + @Override + public void put(final byte v) { + this.buffer[offset++] = v; + } + + @Override + public void put(final boolean v) { + if (v) { + this.buffer[offset++] = BOOLEAN_TRUE; + } else { + this.buffer[offset++] = BOOLEAN_FALSE; + } + } + + @Override + public void put(final int v) { + this.offset = BytesUtils.writeInt(v, buffer, offset); + } + + public void putVar(int v) { + if (v >= 0) { + putVar32(v); + } else { + putVar64((long) v); + } + } + + public void putSVar(int v) { + this.offset = BytesUtils.writeSVar32(v, buffer, offset); + } + + private void putVar32(int v) { + this.offset = BytesUtils.writeVar32(v, buffer, offset); + } + + @Override + public void put(final short v) { + this.offset = BytesUtils.writeShort(v, buffer, offset); + } + + @Override + public void put(final long v) { + this.offset = BytesUtils.writeLong(v, buffer, offset); + } + + @Override + public void putVar(long v) { + putVar64(v); + } + + @Override + public void putSVar(long v) { + putVar64(BytesUtils.longToZigZag(v)); + } + + private void putVar64(long v) { + this.offset = BytesUtils.writeVar64(v, buffer, offset); + } + + @Override + public void put(double v) { + put(Double.doubleToRawLongBits(v)); + } + + @Override + public void putVar(double v) { + putVar(Double.doubleToRawLongBits(v)); + } + + @Override + public void putSVar(double v) { + putSVar(Double.doubleToRawLongBits(v)); + } + + @Override + public void put(final byte[] v) { + if (v == null) { + throw new NullPointerException("v must not be null"); + } + System.arraycopy(v, 0, buffer, offset, v.length); + this.offset = offset + v.length; + } + + @Override + public byte readByte() { + return this.buffer[offset++]; + } + + @Override + public int readUnsignedByte() { + return readByte() & 0xff; + } + + @Override + public boolean readBoolean() { + final byte b = readByte(); + return b == BOOLEAN_TRUE; + } + + @Override + public int readInt() { + final int i = BytesUtils.bytesToInt(buffer, offset); + this.offset = this.offset + 4; + return i; + } + + @Override + public int readVarInt() { + // protocol buffer의 var encoding 차용. + byte v = readByte(); + if (v >= 0) { + return v; + } + int result = v & 0x7f; + if ((v = readByte()) >= 0) { + result |= v << 7; + } else { + result |= (v & 0x7f) << 7; + if ((v = readByte()) >= 0) { + result |= v << 14; + } else { + result |= (v & 0x7f) << 14; + if ((v = readByte()) >= 0) { + result |= v << 21; + } else { + result |= (v & 0x7f) << 21; + result |= (v = readByte()) << 28; + if (v < 0) { + for (int i = 0; i < 5; i++) { + if (readByte() >= 0) { + return result; + } + } + throw new IllegalArgumentException("invalid varInt"); + } + } + } + } + return result; + } + + public int readSVarInt() { + return BytesUtils.zigzagToInt(readVarInt()); + } + + @Override + public short readShort() { + final short i = BytesUtils.bytesToShort(buffer, offset); + this.offset = this.offset + 2; + return i; + } + + public int readUnsignedShort() { + return readShort() & 0xFFFF; + } + + @Override + public long readLong() { + final long l = BytesUtils.bytesToLong(buffer, offset); + this.offset = this.offset + 8; + return l; + } + + @Override + public long readVarLong() { + int shift = 0; + long result = 0; + while (shift < 64) { + final byte v = readByte(); + result |= (long)(v & 0x7F) << shift; + if ((v & 0x80) == 0) { + return result; + } + shift += 7; + } + throw new IllegalArgumentException("invalid varLong"); + } + + @Override + public long readSVarLong() { + return BytesUtils.zigzagToLong(readVarLong()); + } + + @Override + public double readDouble() { + return Double.longBitsToDouble(this.readLong()); + } + + @Override + public double readVarDouble() { + return Double.longBitsToDouble(this.readVarLong()); + } + + @Override + public double readSVarDouble() { + return Double.longBitsToDouble(this.readSVarLong()); + } + + @Override + public byte[] readPadBytes(int totalLength) { + return readBytes(totalLength); + } + + @Override + public String readPadString(int totalLength) { + return readString(totalLength); + } + + @Override + public String readPadStringAndRightTrim(int totalLength) { + String string = BytesUtils.toStringAndRightTrim(buffer, offset, totalLength); + this.offset = offset + totalLength; + return string ; + } + + + @Override + public byte[] readPrefixedBytes() { + final int size = readSVarInt(); + if (size == NULL) { + return null; + } + if (size == 0) { + return EMPTY; + } + return readBytes(size); + } + + @Override + public byte[] read2PrefixedBytes() { + final int size = readShort(); + if (size == NULL) { + return null; + } + if (size == 0) { + return EMPTY; + } + return readBytes(size); + } + + @Override + public byte[] read4PrefixedBytes() { + final int size = readInt(); + if (size == NULL) { + return null; + } + if (size == 0) { + return EMPTY; + } + return readBytes(size); + } + + + private byte[] readBytes(int size) { + final byte[] b = new byte[size]; + System.arraycopy(buffer, offset, b, 0, size); + this.offset = offset + size; + return b; + } + + @Override + public String readPrefixedString() { + final int size = readSVarInt(); + if (size == NULL) { + return null; + } + if (size == 0) { + return ""; + } + return readString(size); + } + + @Override + public String read2PrefixedString() { + final int size = readShort(); + if (size == NULL) { + return null; + } + if (size == 0) { + return ""; + } + return readString(size); + } + + @Override + public String read4PrefixedString() { + final int size = readInt(); + if (size == NULL) { + return null; + } + if (size == 0) { + return ""; + } + return readString(size); + } + + + private String readString(final int size) { + final String s = newString(size); + this.offset = offset + size; + return s; + } + + private String newString(final int size) { + try { + return new String(buffer, offset, size, UTF8); + } catch (UnsupportedEncodingException ue) { + throw new RuntimeException(ue.getMessage(), ue); + } + } + + /** + * 암묵적으로 성능을 내부 buffe length와 offset의 사이즈가 같으면 메모리 copy를 하지 않고 그냥 internal buffer를 리턴하므로 주의해야 한다. + * @return + */ + @Override + public byte[] getBuffer() { + if (offset == buffer.length) { + return this.buffer; + } else { + return copyBuffer(); + } + } + + @Override + public byte[] copyBuffer() { + final byte[] copy = new byte[offset]; + System.arraycopy(buffer, 0, copy, 0, offset); + return copy; + } + + /** + * 내부 buffer를 리턴한다. + * @return + */ + @Override + public byte[] getInternalBuffer() { + return this.buffer; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public int limit() { + return buffer.length - offset; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBuffer.java b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBuffer.java index 4c2b9ba33b9c..7d46e3ae5150 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBuffer.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBuffer.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.common.buffer; - -/** - * @author emeroad - */ -public class OffsetAutomaticBuffer extends AutomaticBuffer { - - protected final int startOffset; - - public OffsetAutomaticBuffer(final byte[] buffer, final int offset) { - if (buffer == null) { - throw new NullPointerException("buffer must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (offset > buffer.length) { - throw new IllegalArgumentException("offset:" + offset + " > buffer.length:" + buffer.length); - } - this.buffer = buffer; - this.offset = offset; - this.startOffset = offset; - } - - @Override - public byte[] getBuffer() { - final int bufferSize = offset - startOffset; - final byte[] copy = new byte[bufferSize]; - System.arraycopy(buffer, startOffset, copy, 0, bufferSize); - return copy; - } -} +package com.nhn.pinpoint.common.buffer; + +/** + * @author emeroad + */ +public class OffsetAutomaticBuffer extends AutomaticBuffer { + + protected final int startOffset; + + public OffsetAutomaticBuffer(final byte[] buffer, final int offset) { + if (buffer == null) { + throw new NullPointerException("buffer must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (offset > buffer.length) { + throw new IllegalArgumentException("offset:" + offset + " > buffer.length:" + buffer.length); + } + this.buffer = buffer; + this.offset = offset; + this.startOffset = offset; + } + + @Override + public byte[] getBuffer() { + final int bufferSize = offset - startOffset; + final byte[] copy = new byte[bufferSize]; + System.arraycopy(buffer, startOffset, copy, 0, bufferSize); + return copy; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBuffer.java b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBuffer.java index ee3f6c60c846..847ce5421ab4 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBuffer.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBuffer.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.common.buffer; - -/** - * @author emeroad - */ -public class OffsetFixedBuffer extends FixedBuffer { - - protected final int startOffset; - - public OffsetFixedBuffer(final byte[] buffer, final int offset) { - if (buffer == null) { - throw new NullPointerException("buffer must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (offset > buffer.length) { - throw new IllegalArgumentException("offset:" + offset + " > buffer.length:" + buffer.length); - } - this.buffer = buffer; - this.offset = offset; - this.startOffset = offset; - } - - @Override - public byte[] getBuffer() { - final int bufferSize = offset - startOffset; - final byte[] copy = new byte[bufferSize]; - System.arraycopy(buffer, startOffset, copy, 0, bufferSize); - return copy; - } -} +package com.nhn.pinpoint.common.buffer; + +/** + * @author emeroad + */ +public class OffsetFixedBuffer extends FixedBuffer { + + protected final int startOffset; + + public OffsetFixedBuffer(final byte[] buffer, final int offset) { + if (buffer == null) { + throw new NullPointerException("buffer must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (offset > buffer.length) { + throw new IllegalArgumentException("offset:" + offset + " > buffer.length:" + buffer.length); + } + this.buffer = buffer; + this.offset = offset; + this.startOffset = offset; + } + + @Override + public byte[] getBuffer() { + final int bufferSize = offset - startOffset; + final byte[] copy = new byte[bufferSize]; + System.arraycopy(buffer, startOffset, copy, 0, bufferSize); + return copy; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/EmptyLimitEventHandler.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/EmptyLimitEventHandler.java index f05b771cc60d..a7e35dcbfe2c 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/EmptyLimitEventHandler.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/EmptyLimitEventHandler.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.common.hbase; - -import org.apache.hadoop.hbase.client.Result; - -/** - * @author emeroad - */ -public class EmptyLimitEventHandler implements LimitEventHandler{ - - @Override - public void handleLastResult(Result lastResult) { - } -} +package com.nhn.pinpoint.common.hbase; + +import org.apache.hadoop.hbase.client.Result; + +/** + * @author emeroad + */ +public class EmptyLimitEventHandler implements LimitEventHandler{ + + @Override + public void handleLastResult(Result lastResult) { + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HBaseAdminTemplate.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HBaseAdminTemplate.java index 784f14d8a95b..315eaf75c698 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HBaseAdminTemplate.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HBaseAdminTemplate.java @@ -1,78 +1,78 @@ -package com.nhn.pinpoint.common.hbase; - -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.HTableDescriptor; -import org.apache.hadoop.hbase.MasterNotRunningException; -import org.apache.hadoop.hbase.ZooKeeperConnectionException; -import org.apache.hadoop.hbase.client.HBaseAdmin; -import org.springframework.data.hadoop.hbase.HbaseSystemException; - -import java.io.IOException; - -/** - * @author emeroad - */ -public class HBaseAdminTemplate { - - private final HBaseAdmin hBaseAdmin; - - public HBaseAdminTemplate(Configuration configuration) { - try { - this.hBaseAdmin = new HBaseAdmin(configuration); - } catch (MasterNotRunningException e) { - throw new HbaseSystemException(e); - } catch (ZooKeeperConnectionException e) { - throw new HbaseSystemException(e); - } - } - - public boolean createTableIfNotExist(HTableDescriptor htd) { - try { - if (!hBaseAdmin.tableExists(htd.getName())) { - this.hBaseAdmin.createTable(htd); - return true; - } - return false; - } catch (IOException e) { - throw new HbaseSystemException(e); - } - } - - public boolean tableExists(String tableName) { - try { - return hBaseAdmin.tableExists(tableName); - } catch (IOException e) { - throw new HbaseSystemException(e); - } - } - - public boolean dropTableIfExist(String tableName) { - try { - if (hBaseAdmin.tableExists(tableName)) { - this.hBaseAdmin.disableTable(tableName); - this.hBaseAdmin.deleteTable(tableName); - return true; - } - return false; - } catch (IOException e) { - throw new HbaseSystemException(e); - } - } - - public void dropTable(String tableName) { - try { - this.hBaseAdmin.disableTable(tableName); - this.hBaseAdmin.deleteTable(tableName); - } catch (IOException e) { - throw new HbaseSystemException(e); - } - } - - public void close() { - try { - this.hBaseAdmin.close(); - } catch (IOException e) { - throw new HbaseSystemException(e); - } - } -} +package com.nhn.pinpoint.common.hbase; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.MasterNotRunningException; +import org.apache.hadoop.hbase.ZooKeeperConnectionException; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.springframework.data.hadoop.hbase.HbaseSystemException; + +import java.io.IOException; + +/** + * @author emeroad + */ +public class HBaseAdminTemplate { + + private final HBaseAdmin hBaseAdmin; + + public HBaseAdminTemplate(Configuration configuration) { + try { + this.hBaseAdmin = new HBaseAdmin(configuration); + } catch (MasterNotRunningException e) { + throw new HbaseSystemException(e); + } catch (ZooKeeperConnectionException e) { + throw new HbaseSystemException(e); + } + } + + public boolean createTableIfNotExist(HTableDescriptor htd) { + try { + if (!hBaseAdmin.tableExists(htd.getName())) { + this.hBaseAdmin.createTable(htd); + return true; + } + return false; + } catch (IOException e) { + throw new HbaseSystemException(e); + } + } + + public boolean tableExists(String tableName) { + try { + return hBaseAdmin.tableExists(tableName); + } catch (IOException e) { + throw new HbaseSystemException(e); + } + } + + public boolean dropTableIfExist(String tableName) { + try { + if (hBaseAdmin.tableExists(tableName)) { + this.hBaseAdmin.disableTable(tableName); + this.hBaseAdmin.deleteTable(tableName); + return true; + } + return false; + } catch (IOException e) { + throw new HbaseSystemException(e); + } + } + + public void dropTable(String tableName) { + try { + this.hBaseAdmin.disableTable(tableName); + this.hBaseAdmin.deleteTable(tableName); + } catch (IOException e) { + throw new HbaseSystemException(e); + } + } + + public void close() { + try { + this.hBaseAdmin.close(); + } catch (IOException e) { + throw new HbaseSystemException(e); + } + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HTableCallBack.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HTableCallBack.java index 83b213720ff3..c77b5cdcf228 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HTableCallBack.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HTableCallBack.java @@ -1,14 +1,14 @@ -package com.nhn.pinpoint.common.hbase; - -import org.apache.hadoop.hbase.client.HTable; - -import java.io.IOException; - -/** - * @author emeroad - */ -public interface HTableCallBack { - void doExecute(HTable hTable) throws IOException; - -// void doMultiExecute(HTable... tables) throws IOException; -} +package com.nhn.pinpoint.common.hbase; + +import org.apache.hadoop.hbase.client.HTable; + +import java.io.IOException; + +/** + * @author emeroad + */ +public interface HTableCallBack { + void doExecute(HTable hTable) throws IOException; + +// void doMultiExecute(HTable... tables) throws IOException; +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseOperations2.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseOperations2.java index a330bc5f8ab5..304a5c954fba 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseOperations2.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseOperations2.java @@ -1,96 +1,96 @@ -package com.nhn.pinpoint.common.hbase; - -import java.util.List; - -import com.sematext.hbase.wd.AbstractRowKeyDistributor; -import org.apache.hadoop.hbase.client.*; -import org.springframework.data.hadoop.hbase.HbaseOperations; -import org.springframework.data.hadoop.hbase.ResultsExtractor; -import org.springframework.data.hadoop.hbase.RowMapper; - -/** - * @author emeroad - */ -public interface HbaseOperations2 extends HbaseOperations { - /** - * Gets an individual row from the given table. The content is mapped by the given action. - * - * @param tableName target table - * @param rowName row name - * @param mapper row mapper - * @return object mapping the target row - */ - T get(String tableName, byte[] rowName, final RowMapper mapper); - - /** - * Gets an individual row from the given table. The content is mapped by the given action. - * - * @param tableName target table - * @param rowName row name - * @param familyName column family - * @param mapper row mapper - * @return object mapping the target row - */ - T get(String tableName, byte[] rowName, byte[] familyName, final RowMapper mapper); - - /** - * Gets an individual row from the given table. The content is mapped by the given action. - * - * @param tableName target table - * @param rowName row name - * @param familyName family - * @param qualifier column qualifier - * @param mapper row mapper - * @return object mapping the target row - */ - T get(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final RowMapper mapper); - - T get(String tableName, final Get get, final RowMapper mapper); - - List get(String tableName, final List get, final RowMapper mapper); - - - void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final byte[] value); - - void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final byte[] value); - - void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final T value, final ValueMapper mapper); - - void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final T value, final ValueMapper mapper); - - void put(String tableName, final Put put); - - void put(String tableName, final List puts); - - void delete(String tableName, final Delete delete); - - void delete(String tableName, final List deletes); - - List find(String tableName, final List scans, final ResultsExtractor action); - - List> find(String tableName, final List scans, final RowMapper action); - - List find(String tableName, final Scan scan, AbstractRowKeyDistributor rowKeyDistributor, final RowMapper action); - - List find(String tableName, final Scan scan, AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action); - - List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action, final LimitEventHandler limitEventHandler); - - T find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, final ResultsExtractor action); - - Result increment(String tableName, final Increment increment); - - /** - * increment list는 부분적으로 exception이 throw될수 있다. 이 경우 lastException이 사용에게 던져진다. - * 특정 increment에서 오류를 감지 해서 재시도 한다하는 로직의 경우 lastException던지는 문제 인해 어느게 실패 했는지 알수 없는 한계가 있다. - * @param tableName - * @param incrementList - * @return - */ - List increment(String tableName, final List incrementList); - - long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount); - - long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount, final boolean writeToWAL); - -} +package com.nhn.pinpoint.common.hbase; + +import java.util.List; + +import com.sematext.hbase.wd.AbstractRowKeyDistributor; +import org.apache.hadoop.hbase.client.*; +import org.springframework.data.hadoop.hbase.HbaseOperations; +import org.springframework.data.hadoop.hbase.ResultsExtractor; +import org.springframework.data.hadoop.hbase.RowMapper; + +/** + * @author emeroad + */ +public interface HbaseOperations2 extends HbaseOperations { + /** + * Gets an individual row from the given table. The content is mapped by the given action. + * + * @param tableName target table + * @param rowName row name + * @param mapper row mapper + * @return object mapping the target row + */ + T get(String tableName, byte[] rowName, final RowMapper mapper); + + /** + * Gets an individual row from the given table. The content is mapped by the given action. + * + * @param tableName target table + * @param rowName row name + * @param familyName column family + * @param mapper row mapper + * @return object mapping the target row + */ + T get(String tableName, byte[] rowName, byte[] familyName, final RowMapper mapper); + + /** + * Gets an individual row from the given table. The content is mapped by the given action. + * + * @param tableName target table + * @param rowName row name + * @param familyName family + * @param qualifier column qualifier + * @param mapper row mapper + * @return object mapping the target row + */ + T get(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final RowMapper mapper); + + T get(String tableName, final Get get, final RowMapper mapper); + + List get(String tableName, final List get, final RowMapper mapper); + + + void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final byte[] value); + + void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final byte[] value); + + void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final T value, final ValueMapper mapper); + + void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final T value, final ValueMapper mapper); + + void put(String tableName, final Put put); + + void put(String tableName, final List puts); + + void delete(String tableName, final Delete delete); + + void delete(String tableName, final List deletes); + + List find(String tableName, final List scans, final ResultsExtractor action); + + List> find(String tableName, final List scans, final RowMapper action); + + List find(String tableName, final Scan scan, AbstractRowKeyDistributor rowKeyDistributor, final RowMapper action); + + List find(String tableName, final Scan scan, AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action); + + List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action, final LimitEventHandler limitEventHandler); + + T find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, final ResultsExtractor action); + + Result increment(String tableName, final Increment increment); + + /** + * increment list는 부분적으로 exception이 throw될수 있다. 이 경우 lastException이 사용에게 던져진다. + * 특정 increment에서 오류를 감지 해서 재시도 한다하는 로직의 경우 lastException던지는 문제 인해 어느게 실패 했는지 알수 없는 한계가 있다. + * @param tableName + * @param incrementList + * @return + */ + List increment(String tableName, final List incrementList); + + long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount); + + long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount, final boolean writeToWAL); + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2.java index fdfd4f80e1ab..91dd31b86710 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2.java @@ -1,560 +1,560 @@ -package com.nhn.pinpoint.common.hbase; - -import com.nhn.pinpoint.common.util.StopWatch; -import com.sematext.hbase.wd.AbstractRowKeyDistributor; -import com.sematext.hbase.wd.DistributedScanner; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.client.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.data.hadoop.hbase.*; -import org.springframework.util.Assert; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.*; - -/** - * @author emeroad - */ -public class HbaseTemplate2 extends HbaseTemplate implements HbaseOperations2, InitializingBean, DisposableBean { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private PooledHTableFactory pooledHTableFactory; - private int poolSize = PooledHTableFactory.DEFAULT_POOL_SIZE; - - private ExecutorService executor = newCachedThreadPool(); - - public HbaseTemplate2() { - } - - public ExecutorService newCachedThreadPool() { - return new ThreadPoolExecutor(0, 128, - 60L, TimeUnit.SECONDS, - new LinkedBlockingQueue()); - } - -// public Executor getExecutor() { -// return executor; -// } - -// public void setExecutor(Executor executor) { -// this.executor = executor; -// } - - public HbaseTemplate2(Configuration configuration) { - Assert.notNull(configuration); - } - - public HbaseTemplate2(Configuration configuration, int poolSize) { - Assert.notNull(configuration); - this.poolSize = poolSize; - } - - public int getPoolSize() { - return poolSize; - } - - public void setPoolSize(int hTablePoolSize) { - this.poolSize = hTablePoolSize; - } - - @Override - public void afterPropertiesSet() { - Configuration configuration = getConfiguration(); - Assert.notNull(configuration, "configuration is required"); - this.pooledHTableFactory = new PooledHTableFactory(configuration, poolSize); - this.setTableFactory(pooledHTableFactory); - } - - @Override - public void destroy() throws Exception { - if (pooledHTableFactory != null) { - this.pooledHTableFactory.destroy(); - } - - final ExecutorService executor = this.executor; - if (executor != null) { - executor.shutdown(); - try { - executor.awaitTermination(2000, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - - @Override - public T find(String tableName, String family, final ResultsExtractor action) { - Scan scan = new Scan(); - scan.addFamily(family.getBytes(getCharset())); - return find(tableName, scan, action); - } - - @Override - public T find(String tableName, String family, String qualifier, final ResultsExtractor action) { - Scan scan = new Scan(); - scan.addColumn(family.getBytes(getCharset()), qualifier.getBytes(getCharset())); - return find(tableName, scan, action); - } - - @Override - public T find(String tableName, final Scan scan, final ResultsExtractor action) { - return execute(tableName, new TableCallback() { - @Override - public T doInTable(HTableInterface htable) throws Throwable { - final ResultScanner scanner = htable.getScanner(scan); - try { - return action.extractData(scanner); - } finally { - scanner.close(); - } - } - }); - } - - @Override - public List find(String tableName, String family, final RowMapper action) { - Scan scan = new Scan(); - scan.addFamily(family.getBytes(getCharset())); - return find(tableName, scan, action); - } - - @Override - public List find(String tableName, String family, String qualifier, final RowMapper action) { - Scan scan = new Scan(); - scan.addColumn(family.getBytes(getCharset()), qualifier.getBytes(getCharset())); - return find(tableName, scan, action); - } - - @Override - public List find(String tableName, final Scan scan, final RowMapper action) { - return find(tableName, scan, new RowMapperResultsExtractor(action)); - } - -// public class ParallelScan { -// private String tableName; -// private Scan scan; -// private RowMapper mapper; -// -// public String getTableName() { -// return tableName; -// } -// -// public void setTableName(String tableName) { -// this.tableName = tableName; -// } -// -// public Scan getScan() { -// return scan; -// } -// -// public void setScan(Scan scan) { -// this.scan = scan; -// } -// -// public RowMapper getMapper() { -// return mapper; -// } -// -// public void setMapper(RowMapper action) { -// this.mapper = action; -// } -// } -// -// /** -// * sanner를 병렬로 돌리기 위한 api -// * scanner 구현 자체가 얼마나 병렬인지 애매해서 무조껀 만들기도 그러니 일단 주석처리. -// * @return -// */ -// public List>> findParallel(final ParallelScan parallelScans) { -// Callable> tCallable = new Callable>() { -// @Override -// public List call() throws Exception { -// return find(parallelScans.getTableName(), parallelScans.getScan(), parallelScans.getMapper()); -// } -// }; -// ArrayList>> callables = new ArrayList>>(); -// callables.add(tCallable); -// -// List>> futures = null; -// try { -// futures = this.executor.invokeAll(callables); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// } -// return futures; -// } - - @Override - public T get(String tableName, String rowName, final RowMapper mapper) { - return get(tableName, rowName, null, null, mapper); - } - - @Override - public T get(String tableName, String rowName, String familyName, final RowMapper mapper) { - return get(tableName, rowName, familyName, null, mapper); - } - - @Override - public T get(String tableName, final String rowName, final String familyName, final String qualifier, final RowMapper mapper) { - return execute(tableName, new TableCallback() { - @Override - public T doInTable(HTableInterface htable) throws Throwable { - Get get = new Get(rowName.getBytes(getCharset())); - if (familyName != null) { - byte[] family = familyName.getBytes(getCharset()); - - if (qualifier != null) { - get.addColumn(family, qualifier.getBytes(getCharset())); - } else { - get.addFamily(family); - } - } - Result result = htable.get(get); - return mapper.mapRow(result, 0); - } - }); - } - - - @Override - public T get(String tableName, byte[] rowName, RowMapper mapper) { - return get(tableName, rowName, null, null, mapper); - } - - @Override - public T get(String tableName, byte[] rowName, byte[] familyName, RowMapper mapper) { - return get(tableName, rowName, familyName, null, mapper); - } - - @Override - public T get(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final RowMapper mapper) { - return execute(tableName, new TableCallback() { - @Override - public T doInTable(HTableInterface htable) throws Throwable { - Get get = new Get(rowName); - if (familyName != null) { - if (qualifier != null) { - get.addColumn(familyName, qualifier); - } else { - get.addFamily(familyName); - } - } - Result result = htable.get(get); - return mapper.mapRow(result, 0); - } - }); - } - - @Override - public T get(String tableName, final Get get, final RowMapper mapper) { - return execute(tableName, new TableCallback() { - @Override - public T doInTable(HTableInterface htable) throws Throwable { - Result result = htable.get(get); - return mapper.mapRow(result, 0); - } - }); - } - - @Override - public List get(String tableName, final List getList, final RowMapper mapper) { - return execute(tableName, new TableCallback>() { - @Override - public List doInTable(HTableInterface htable) throws Throwable { - Result[] result = htable.get(getList); - List list = new ArrayList(result.length); - for (int i = 0; i < result.length; i++) { - T t = mapper.mapRow(result[i], i); - list.add(t); - } - return list; - } - }); - } - - - public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final byte[] value) { - put(tableName, rowName, familyName, qualifier, null, value); - } - - public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final byte[] value) { - execute(tableName, new TableCallback() { - @Override - public Object doInTable(HTableInterface htable) throws Throwable { - Put put = new Put(rowName); - if (familyName != null) { - if (timestamp == null) { - put.add(familyName, qualifier, value); - } else { - put.add(familyName, qualifier, timestamp, value); - } - } - htable.put(put); - return null; - } - }); - } - - public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final T value, final ValueMapper mapper) { - put(tableName, rowName, familyName, qualifier, null, value, mapper); - } - - public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final T value, final ValueMapper mapper) { - execute(tableName, new TableCallback() { - @Override - public T doInTable(HTableInterface htable) throws Throwable { - Put put = new Put(rowName); - byte[] bytes = mapper.mapValue(value); - if (familyName != null) { - if (timestamp == null) { - put.add(familyName, qualifier, bytes); - } else { - put.add(familyName, qualifier, timestamp, bytes); - } - } - htable.put(put); - return null; - } - }); - } - - public void put(String tableName, final Put put) { - execute(tableName, new TableCallback() { - @Override - public Object doInTable(HTableInterface htable) throws Throwable { - htable.put(put); - return null; - } - }); - } - - public void put(String tableName, final List puts) { - execute(tableName, new TableCallback() { - @Override - public Object doInTable(HTableInterface htable) throws Throwable { - htable.put(puts); - return null; - } - }); - } - - public void delete(String tableName, final Delete delete) { - execute(tableName, new TableCallback() { - @Override - public Object doInTable(HTableInterface htable) throws Throwable { - htable.delete(delete); - return null; - } - }); - } - - public void delete(String tableName, final List deletes) { - execute(tableName, new TableCallback() { - @Override - public Object doInTable(HTableInterface htable) throws Throwable { - htable.delete(deletes); - return null; - } - }); - } - - @Override - public List find(String tableName, final List scanList, final ResultsExtractor action) { - return execute(tableName, new TableCallback>() { - @Override - public List doInTable(HTableInterface htable) throws Throwable { - List result = new ArrayList(scanList.size()); - for (Scan scan : scanList) { - final ResultScanner scanner = htable.getScanner(scan); - try { - T t = action.extractData(scanner); - result.add(t); - } finally { - scanner.close(); - } - } - return result; - } - }); - } - - @Override - public List> find(String tableName, List scanList, RowMapper action) { - return find(tableName, scanList, new RowMapperResultsExtractor(action)); - } - - public List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, final RowMapper action) { - final ResultsExtractor> resultsExtractor = new RowMapperResultsExtractor(action); - return execute(tableName, new TableCallback>() { - @Override - public List doInTable(HTableInterface htable) throws Throwable { - final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); - try { - return resultsExtractor.extractData(scanner); - } finally { - scanner.close(); - } - } - }); - } - - public List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action) { - final ResultsExtractor> resultsExtractor = new LimitRowMapperResultsExtractor(action, limit); - return execute(tableName, new TableCallback>() { - @Override - public List doInTable(HTableInterface htable) throws Throwable { - final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); - try { - return resultsExtractor.extractData(scanner); - } finally { - scanner.close(); - } - } - }); - } - - public List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action, final LimitEventHandler limitEventHandler) { - final LimitRowMapperResultsExtractor resultsExtractor = new LimitRowMapperResultsExtractor(action, limit, limitEventHandler); - return execute(tableName, new TableCallback>() { - @Override - public List doInTable(HTableInterface htable) throws Throwable { - final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); - try { - return resultsExtractor.extractData(scanner); - } finally { - scanner.close(); - } - } - }); - } - - - @Override - public T find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, final ResultsExtractor action) { - - return execute(tableName, new TableCallback() { - @Override - public T doInTable(HTableInterface htable) throws Throwable { - final boolean debugEnabled = logger.isDebugEnabled(); - StopWatch watch = null; - if (debugEnabled) { - watch = new StopWatch(); - watch.start(); - } - final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); - if (debugEnabled) { - logger.debug("DistributeScanner createTime:{}", watch.stop()); - } - if (debugEnabled) { - watch.start(); - } - try { - return action.extractData(scanner); - } finally { - scanner.close(); - if (debugEnabled) { - logger.debug("DistributeScanner scanTime:{}", watch.stop()); - } - } - } - }); - } - - public ResultScanner createDistributeScanner(HTableInterface htable, Scan originalScan, AbstractRowKeyDistributor rowKeyDistributor) throws IOException { - - Scan[] scans = rowKeyDistributor.getDistributedScans(originalScan); - final int length = scans.length; - for(int i = 0; i < length; i++) { - Scan scan = scans[i]; - scan.setId(originalScan.getId() + "-" + i); - // caching만 넣으면 되나? - scan.setCaching(originalScan.getCaching()); - } - - ResultScanner[] scanner = new ResultScanner[length]; - boolean success = false; - try { - for (int i = 0; i < length; i++) { - scanner[i] = htable.getScanner(scans[i]); - } - success = true; - } finally { - if (!success) { - closeScanner(scanner); - } - } - - return new DistributedScanner(rowKeyDistributor, scanner); - } - - private void closeScanner(ResultScanner[] scannerList ) { - for (ResultScanner scanner : scannerList) { - if (scanner != null) { - try { - scanner.close(); - } catch (Exception e) { - logger.warn("Scanner.close() error Caused:{}", e.getMessage(), e); - } - } - } - } - - public Result increment(String tableName, final Increment increment) { - return execute(tableName, new TableCallback() { - @Override - public Result doInTable(HTableInterface htable) throws Throwable { - return htable.increment(increment); - } - }); - } - - public List increment(final String tableName, final List incrementList) { - return execute(tableName, new TableCallback>() { - @Override - public List doInTable(HTableInterface htable) throws Throwable { - final List resultList = new ArrayList(incrementList.size()); - - Exception lastException = null; - for (Increment increment : incrementList) { - try { - Result result = htable.increment(increment); - resultList.add(result); - } catch (IOException e) { - logger.warn("{} increment error Caused:{}", tableName, e.getMessage(), e); - lastException = e; - } - } - if (lastException != null) { - throw lastException; - } - return resultList; - } - }); - } - - public long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount) { - return execute(tableName, new TableCallback() { - @Override - public Long doInTable(HTableInterface htable) throws Throwable { - return htable.incrementColumnValue(rowName, familyName, qualifier, amount); - } - }); - } - - public long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount, final boolean writeToWAL) { - return execute(tableName, new TableCallback() { - @Override - public Long doInTable(HTableInterface htable) throws Throwable { - return htable.incrementColumnValue(rowName, familyName, qualifier, amount, writeToWAL); - } - }); - } - - -} +package com.nhn.pinpoint.common.hbase; + +import com.nhn.pinpoint.common.util.StopWatch; +import com.sematext.hbase.wd.AbstractRowKeyDistributor; +import com.sematext.hbase.wd.DistributedScanner; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.client.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.data.hadoop.hbase.*; +import org.springframework.util.Assert; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; + +/** + * @author emeroad + */ +public class HbaseTemplate2 extends HbaseTemplate implements HbaseOperations2, InitializingBean, DisposableBean { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private PooledHTableFactory pooledHTableFactory; + private int poolSize = PooledHTableFactory.DEFAULT_POOL_SIZE; + + private ExecutorService executor = newCachedThreadPool(); + + public HbaseTemplate2() { + } + + public ExecutorService newCachedThreadPool() { + return new ThreadPoolExecutor(0, 128, + 60L, TimeUnit.SECONDS, + new LinkedBlockingQueue()); + } + +// public Executor getExecutor() { +// return executor; +// } + +// public void setExecutor(Executor executor) { +// this.executor = executor; +// } + + public HbaseTemplate2(Configuration configuration) { + Assert.notNull(configuration); + } + + public HbaseTemplate2(Configuration configuration, int poolSize) { + Assert.notNull(configuration); + this.poolSize = poolSize; + } + + public int getPoolSize() { + return poolSize; + } + + public void setPoolSize(int hTablePoolSize) { + this.poolSize = hTablePoolSize; + } + + @Override + public void afterPropertiesSet() { + Configuration configuration = getConfiguration(); + Assert.notNull(configuration, "configuration is required"); + this.pooledHTableFactory = new PooledHTableFactory(configuration, poolSize); + this.setTableFactory(pooledHTableFactory); + } + + @Override + public void destroy() throws Exception { + if (pooledHTableFactory != null) { + this.pooledHTableFactory.destroy(); + } + + final ExecutorService executor = this.executor; + if (executor != null) { + executor.shutdown(); + try { + executor.awaitTermination(2000, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + + @Override + public T find(String tableName, String family, final ResultsExtractor action) { + Scan scan = new Scan(); + scan.addFamily(family.getBytes(getCharset())); + return find(tableName, scan, action); + } + + @Override + public T find(String tableName, String family, String qualifier, final ResultsExtractor action) { + Scan scan = new Scan(); + scan.addColumn(family.getBytes(getCharset()), qualifier.getBytes(getCharset())); + return find(tableName, scan, action); + } + + @Override + public T find(String tableName, final Scan scan, final ResultsExtractor action) { + return execute(tableName, new TableCallback() { + @Override + public T doInTable(HTableInterface htable) throws Throwable { + final ResultScanner scanner = htable.getScanner(scan); + try { + return action.extractData(scanner); + } finally { + scanner.close(); + } + } + }); + } + + @Override + public List find(String tableName, String family, final RowMapper action) { + Scan scan = new Scan(); + scan.addFamily(family.getBytes(getCharset())); + return find(tableName, scan, action); + } + + @Override + public List find(String tableName, String family, String qualifier, final RowMapper action) { + Scan scan = new Scan(); + scan.addColumn(family.getBytes(getCharset()), qualifier.getBytes(getCharset())); + return find(tableName, scan, action); + } + + @Override + public List find(String tableName, final Scan scan, final RowMapper action) { + return find(tableName, scan, new RowMapperResultsExtractor(action)); + } + +// public class ParallelScan { +// private String tableName; +// private Scan scan; +// private RowMapper mapper; +// +// public String getTableName() { +// return tableName; +// } +// +// public void setTableName(String tableName) { +// this.tableName = tableName; +// } +// +// public Scan getScan() { +// return scan; +// } +// +// public void setScan(Scan scan) { +// this.scan = scan; +// } +// +// public RowMapper getMapper() { +// return mapper; +// } +// +// public void setMapper(RowMapper action) { +// this.mapper = action; +// } +// } +// +// /** +// * sanner를 병렬로 돌리기 위한 api +// * scanner 구현 자체가 얼마나 병렬인지 애매해서 무조껀 만들기도 그러니 일단 주석처리. +// * @return +// */ +// public List>> findParallel(final ParallelScan parallelScans) { +// Callable> tCallable = new Callable>() { +// @Override +// public List call() throws Exception { +// return find(parallelScans.getTableName(), parallelScans.getScan(), parallelScans.getMapper()); +// } +// }; +// ArrayList>> callables = new ArrayList>>(); +// callables.add(tCallable); +// +// List>> futures = null; +// try { +// futures = this.executor.invokeAll(callables); +// } catch (InterruptedException e) { +// Thread.currentThread().interrupt(); +// } +// return futures; +// } + + @Override + public T get(String tableName, String rowName, final RowMapper mapper) { + return get(tableName, rowName, null, null, mapper); + } + + @Override + public T get(String tableName, String rowName, String familyName, final RowMapper mapper) { + return get(tableName, rowName, familyName, null, mapper); + } + + @Override + public T get(String tableName, final String rowName, final String familyName, final String qualifier, final RowMapper mapper) { + return execute(tableName, new TableCallback() { + @Override + public T doInTable(HTableInterface htable) throws Throwable { + Get get = new Get(rowName.getBytes(getCharset())); + if (familyName != null) { + byte[] family = familyName.getBytes(getCharset()); + + if (qualifier != null) { + get.addColumn(family, qualifier.getBytes(getCharset())); + } else { + get.addFamily(family); + } + } + Result result = htable.get(get); + return mapper.mapRow(result, 0); + } + }); + } + + + @Override + public T get(String tableName, byte[] rowName, RowMapper mapper) { + return get(tableName, rowName, null, null, mapper); + } + + @Override + public T get(String tableName, byte[] rowName, byte[] familyName, RowMapper mapper) { + return get(tableName, rowName, familyName, null, mapper); + } + + @Override + public T get(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final RowMapper mapper) { + return execute(tableName, new TableCallback() { + @Override + public T doInTable(HTableInterface htable) throws Throwable { + Get get = new Get(rowName); + if (familyName != null) { + if (qualifier != null) { + get.addColumn(familyName, qualifier); + } else { + get.addFamily(familyName); + } + } + Result result = htable.get(get); + return mapper.mapRow(result, 0); + } + }); + } + + @Override + public T get(String tableName, final Get get, final RowMapper mapper) { + return execute(tableName, new TableCallback() { + @Override + public T doInTable(HTableInterface htable) throws Throwable { + Result result = htable.get(get); + return mapper.mapRow(result, 0); + } + }); + } + + @Override + public List get(String tableName, final List getList, final RowMapper mapper) { + return execute(tableName, new TableCallback>() { + @Override + public List doInTable(HTableInterface htable) throws Throwable { + Result[] result = htable.get(getList); + List list = new ArrayList(result.length); + for (int i = 0; i < result.length; i++) { + T t = mapper.mapRow(result[i], i); + list.add(t); + } + return list; + } + }); + } + + + public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final byte[] value) { + put(tableName, rowName, familyName, qualifier, null, value); + } + + public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final byte[] value) { + execute(tableName, new TableCallback() { + @Override + public Object doInTable(HTableInterface htable) throws Throwable { + Put put = new Put(rowName); + if (familyName != null) { + if (timestamp == null) { + put.add(familyName, qualifier, value); + } else { + put.add(familyName, qualifier, timestamp, value); + } + } + htable.put(put); + return null; + } + }); + } + + public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final T value, final ValueMapper mapper) { + put(tableName, rowName, familyName, qualifier, null, value, mapper); + } + + public void put(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final Long timestamp, final T value, final ValueMapper mapper) { + execute(tableName, new TableCallback() { + @Override + public T doInTable(HTableInterface htable) throws Throwable { + Put put = new Put(rowName); + byte[] bytes = mapper.mapValue(value); + if (familyName != null) { + if (timestamp == null) { + put.add(familyName, qualifier, bytes); + } else { + put.add(familyName, qualifier, timestamp, bytes); + } + } + htable.put(put); + return null; + } + }); + } + + public void put(String tableName, final Put put) { + execute(tableName, new TableCallback() { + @Override + public Object doInTable(HTableInterface htable) throws Throwable { + htable.put(put); + return null; + } + }); + } + + public void put(String tableName, final List puts) { + execute(tableName, new TableCallback() { + @Override + public Object doInTable(HTableInterface htable) throws Throwable { + htable.put(puts); + return null; + } + }); + } + + public void delete(String tableName, final Delete delete) { + execute(tableName, new TableCallback() { + @Override + public Object doInTable(HTableInterface htable) throws Throwable { + htable.delete(delete); + return null; + } + }); + } + + public void delete(String tableName, final List deletes) { + execute(tableName, new TableCallback() { + @Override + public Object doInTable(HTableInterface htable) throws Throwable { + htable.delete(deletes); + return null; + } + }); + } + + @Override + public List find(String tableName, final List scanList, final ResultsExtractor action) { + return execute(tableName, new TableCallback>() { + @Override + public List doInTable(HTableInterface htable) throws Throwable { + List result = new ArrayList(scanList.size()); + for (Scan scan : scanList) { + final ResultScanner scanner = htable.getScanner(scan); + try { + T t = action.extractData(scanner); + result.add(t); + } finally { + scanner.close(); + } + } + return result; + } + }); + } + + @Override + public List> find(String tableName, List scanList, RowMapper action) { + return find(tableName, scanList, new RowMapperResultsExtractor(action)); + } + + public List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, final RowMapper action) { + final ResultsExtractor> resultsExtractor = new RowMapperResultsExtractor(action); + return execute(tableName, new TableCallback>() { + @Override + public List doInTable(HTableInterface htable) throws Throwable { + final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); + try { + return resultsExtractor.extractData(scanner); + } finally { + scanner.close(); + } + } + }); + } + + public List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action) { + final ResultsExtractor> resultsExtractor = new LimitRowMapperResultsExtractor(action, limit); + return execute(tableName, new TableCallback>() { + @Override + public List doInTable(HTableInterface htable) throws Throwable { + final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); + try { + return resultsExtractor.extractData(scanner); + } finally { + scanner.close(); + } + } + }); + } + + public List find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, int limit, final RowMapper action, final LimitEventHandler limitEventHandler) { + final LimitRowMapperResultsExtractor resultsExtractor = new LimitRowMapperResultsExtractor(action, limit, limitEventHandler); + return execute(tableName, new TableCallback>() { + @Override + public List doInTable(HTableInterface htable) throws Throwable { + final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); + try { + return resultsExtractor.extractData(scanner); + } finally { + scanner.close(); + } + } + }); + } + + + @Override + public T find(String tableName, final Scan scan, final AbstractRowKeyDistributor rowKeyDistributor, final ResultsExtractor action) { + + return execute(tableName, new TableCallback() { + @Override + public T doInTable(HTableInterface htable) throws Throwable { + final boolean debugEnabled = logger.isDebugEnabled(); + StopWatch watch = null; + if (debugEnabled) { + watch = new StopWatch(); + watch.start(); + } + final ResultScanner scanner = createDistributeScanner(htable, scan, rowKeyDistributor); + if (debugEnabled) { + logger.debug("DistributeScanner createTime:{}", watch.stop()); + } + if (debugEnabled) { + watch.start(); + } + try { + return action.extractData(scanner); + } finally { + scanner.close(); + if (debugEnabled) { + logger.debug("DistributeScanner scanTime:{}", watch.stop()); + } + } + } + }); + } + + public ResultScanner createDistributeScanner(HTableInterface htable, Scan originalScan, AbstractRowKeyDistributor rowKeyDistributor) throws IOException { + + Scan[] scans = rowKeyDistributor.getDistributedScans(originalScan); + final int length = scans.length; + for(int i = 0; i < length; i++) { + Scan scan = scans[i]; + scan.setId(originalScan.getId() + "-" + i); + // caching만 넣으면 되나? + scan.setCaching(originalScan.getCaching()); + } + + ResultScanner[] scanner = new ResultScanner[length]; + boolean success = false; + try { + for (int i = 0; i < length; i++) { + scanner[i] = htable.getScanner(scans[i]); + } + success = true; + } finally { + if (!success) { + closeScanner(scanner); + } + } + + return new DistributedScanner(rowKeyDistributor, scanner); + } + + private void closeScanner(ResultScanner[] scannerList ) { + for (ResultScanner scanner : scannerList) { + if (scanner != null) { + try { + scanner.close(); + } catch (Exception e) { + logger.warn("Scanner.close() error Caused:{}", e.getMessage(), e); + } + } + } + } + + public Result increment(String tableName, final Increment increment) { + return execute(tableName, new TableCallback() { + @Override + public Result doInTable(HTableInterface htable) throws Throwable { + return htable.increment(increment); + } + }); + } + + public List increment(final String tableName, final List incrementList) { + return execute(tableName, new TableCallback>() { + @Override + public List doInTable(HTableInterface htable) throws Throwable { + final List resultList = new ArrayList(incrementList.size()); + + Exception lastException = null; + for (Increment increment : incrementList) { + try { + Result result = htable.increment(increment); + resultList.add(result); + } catch (IOException e) { + logger.warn("{} increment error Caused:{}", tableName, e.getMessage(), e); + lastException = e; + } + } + if (lastException != null) { + throw lastException; + } + return resultList; + } + }); + } + + public long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount) { + return execute(tableName, new TableCallback() { + @Override + public Long doInTable(HTableInterface htable) throws Throwable { + return htable.incrementColumnValue(rowName, familyName, qualifier, amount); + } + }); + } + + public long incrementColumnValue(String tableName, final byte[] rowName, final byte[] familyName, final byte[] qualifier, final long amount, final boolean writeToWAL) { + return execute(tableName, new TableCallback() { + @Override + public Long doInTable(HTableInterface htable) throws Throwable { + return htable.incrementColumnValue(rowName, familyName, qualifier, amount, writeToWAL); + } + }); + } + + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitEventHandler.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitEventHandler.java index cd95e45737fa..011c27992c4e 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitEventHandler.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitEventHandler.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.common.hbase; - -import org.apache.hadoop.hbase.client.Result; - -/** - * @author emeroad - */ -public interface LimitEventHandler { - void handleLastResult(Result lastResult); -} +package com.nhn.pinpoint.common.hbase; + +import org.apache.hadoop.hbase.client.Result; + +/** + * @author emeroad + */ +public interface LimitEventHandler { + void handleLastResult(Result lastResult); +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitRowMapperResultsExtractor.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitRowMapperResultsExtractor.java index df3f60ca11b9..f48989c1eb44 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitRowMapperResultsExtractor.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/LimitRowMapperResultsExtractor.java @@ -1,84 +1,84 @@ -package com.nhn.pinpoint.common.hbase; - -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.client.ResultScanner; -import org.springframework.data.hadoop.hbase.ResultsExtractor; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.util.Assert; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * @author emeroad - */ -public class LimitRowMapperResultsExtractor implements ResultsExtractor> { - - private static final LimitEventHandler EMPTY = new EmptyLimitEventHandler(); - - private int limit = Integer.MAX_VALUE; - private final RowMapper rowMapper; - private LimitEventHandler eventHandler; - - public int getLimit() { - return limit; - } - - public void setLimit(int limit) { - this.limit = limit; - } - - /** - * Create a new RowMapperResultSetExtractor. - * - * @param rowMapper the RowMapper which creates an object for each row - */ - public LimitRowMapperResultsExtractor(RowMapper rowMapper, int limit) { - this(rowMapper, limit, EMPTY); - } - - /** - * Create a new RowMapperResultSetExtractor. - * - * @param rowMapper the RowMapper which creates an object for each row - */ - public LimitRowMapperResultsExtractor(RowMapper rowMapper, int limit, LimitEventHandler eventHandler) { - Assert.notNull(rowMapper, "RowMapper is required"); - Assert.notNull(eventHandler, "LimitEventHandler is required"); - this.rowMapper = rowMapper; - this.limit = limit; - this.eventHandler = eventHandler; - } - - public List extractData(ResultScanner results) throws Exception { - final List rs = new ArrayList(); - int rowNum = 0; - Result lastResult = null; - - for (Result result : results) { - final T t = this.rowMapper.mapRow(result, rowNum); - lastResult = result; - if (t instanceof Collection) { - rowNum += ((Collection) t).size(); - } else if (t instanceof Map) { - rowNum += ((Map) t).size(); - } else if (t == null) { - // empty - } else if (t.getClass().isArray()) { - rowNum += Array.getLength(t); - } else { - rowNum++; - } - rs.add(t); - if (rowNum >= limit) { - break; - } - } - - eventHandler.handleLastResult(lastResult); - return rs; - } -} +package com.nhn.pinpoint.common.hbase; + +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.springframework.data.hadoop.hbase.ResultsExtractor; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.util.Assert; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * @author emeroad + */ +public class LimitRowMapperResultsExtractor implements ResultsExtractor> { + + private static final LimitEventHandler EMPTY = new EmptyLimitEventHandler(); + + private int limit = Integer.MAX_VALUE; + private final RowMapper rowMapper; + private LimitEventHandler eventHandler; + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + /** + * Create a new RowMapperResultSetExtractor. + * + * @param rowMapper the RowMapper which creates an object for each row + */ + public LimitRowMapperResultsExtractor(RowMapper rowMapper, int limit) { + this(rowMapper, limit, EMPTY); + } + + /** + * Create a new RowMapperResultSetExtractor. + * + * @param rowMapper the RowMapper which creates an object for each row + */ + public LimitRowMapperResultsExtractor(RowMapper rowMapper, int limit, LimitEventHandler eventHandler) { + Assert.notNull(rowMapper, "RowMapper is required"); + Assert.notNull(eventHandler, "LimitEventHandler is required"); + this.rowMapper = rowMapper; + this.limit = limit; + this.eventHandler = eventHandler; + } + + public List extractData(ResultScanner results) throws Exception { + final List rs = new ArrayList(); + int rowNum = 0; + Result lastResult = null; + + for (Result result : results) { + final T t = this.rowMapper.mapRow(result, rowNum); + lastResult = result; + if (t instanceof Collection) { + rowNum += ((Collection) t).size(); + } else if (t instanceof Map) { + rowNum += ((Map) t).size(); + } else if (t == null) { + // empty + } else if (t.getClass().isArray()) { + rowNum += Array.getLength(t); + } else { + rowNum++; + } + rs.add(t); + if (rowNum >= limit) { + break; + } + } + + eventHandler.handleLastResult(lastResult); + return rs; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/PooledHTableFactory.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/PooledHTableFactory.java index dd3ab4f2cf37..5ed4c72aa1c4 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/PooledHTableFactory.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/PooledHTableFactory.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.common.hbase; - -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.client.HTableInterface; -import org.apache.hadoop.hbase.client.HTableInterfaceFactory; -import org.apache.hadoop.hbase.client.HTablePool; -import org.springframework.beans.factory.DisposableBean; - -import java.io.IOException; - -/** - * HTablePool 기반의 HTableInterfaceFactory. - * @author emeroad - */ -public class PooledHTableFactory implements HTableInterfaceFactory, DisposableBean { - - private HTablePool hTablePool; - public static final int DEFAULT_POOL_SIZE = 256; - - public PooledHTableFactory(Configuration config) { - this.hTablePool = new HTablePool(config, DEFAULT_POOL_SIZE); - } - - public PooledHTableFactory(Configuration config, int poolSize) { - this.hTablePool = new HTablePool(config, poolSize); - } - - - @Override - public HTableInterface createHTableInterface(Configuration config, byte[] tableName) { - return hTablePool.getTable(tableName); - } - - @Override - public void releaseHTableInterface(HTableInterface table) throws IOException { - if (table != null) { - table.close(); - } - } - - - @Override - public void destroy() throws Exception { - if (hTablePool != null) { - this.hTablePool.close(); - } - } -} +package com.nhn.pinpoint.common.hbase; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.HTableInterfaceFactory; +import org.apache.hadoop.hbase.client.HTablePool; +import org.springframework.beans.factory.DisposableBean; + +import java.io.IOException; + +/** + * HTablePool 기반의 HTableInterfaceFactory. + * @author emeroad + */ +public class PooledHTableFactory implements HTableInterfaceFactory, DisposableBean { + + private HTablePool hTablePool; + public static final int DEFAULT_POOL_SIZE = 256; + + public PooledHTableFactory(Configuration config) { + this.hTablePool = new HTablePool(config, DEFAULT_POOL_SIZE); + } + + public PooledHTableFactory(Configuration config, int poolSize) { + this.hTablePool = new HTablePool(config, poolSize); + } + + + @Override + public HTableInterface createHTableInterface(Configuration config, byte[] tableName) { + return hTablePool.getTable(tableName); + } + + @Override + public void releaseHTableInterface(HTableInterface table) throws IOException { + if (table != null) { + table.close(); + } + } + + + @Override + public void destroy() throws Exception { + if (hTablePool != null) { + this.hTablePool.close(); + } + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/RowMapperResultsExtractor.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/RowMapperResultsExtractor.java index 960fc82b9daa..4f2ea6d53f83 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/RowMapperResultsExtractor.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/RowMapperResultsExtractor.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.common.hbase; - -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.client.ResultScanner; -import org.springframework.data.hadoop.hbase.ResultsExtractor; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.util.Assert; - -import java.util.ArrayList; -import java.util.List; - -/** - * Spring꺼가 package라서 그냥 복사해옴. - * copy->Spring - * Adapter encapsulating the RowMapper callback. - * - * @author Costin Leau - */ -class RowMapperResultsExtractor implements ResultsExtractor> { - - private final RowMapper rowMapper; - - /** - * Create a new RowMapperResultSetExtractor. - * - * @param rowMapper the RowMapper which creates an object for each row - */ - public RowMapperResultsExtractor(RowMapper rowMapper) { - Assert.notNull(rowMapper, "RowMapper is required"); - this.rowMapper = rowMapper; - } - - public List extractData(ResultScanner results) throws Exception { - List rs = new ArrayList(); - int rowNum = 0; - for (Result result : results) { - rs.add(this.rowMapper.mapRow(result, rowNum++)); - } - return rs; - } -} +package com.nhn.pinpoint.common.hbase; + +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.springframework.data.hadoop.hbase.ResultsExtractor; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.util.Assert; + +import java.util.ArrayList; +import java.util.List; + +/** + * Spring꺼가 package라서 그냥 복사해옴. + * copy->Spring + * Adapter encapsulating the RowMapper callback. + * + * @author Costin Leau + */ +class RowMapperResultsExtractor implements ResultsExtractor> { + + private final RowMapper rowMapper; + + /** + * Create a new RowMapperResultSetExtractor. + * + * @param rowMapper the RowMapper which creates an object for each row + */ + public RowMapperResultsExtractor(RowMapper rowMapper) { + Assert.notNull(rowMapper, "RowMapper is required"); + this.rowMapper = rowMapper; + } + + public List extractData(ResultScanner results) throws Exception { + List rs = new ArrayList(); + int rowNum = 0; + for (Result result : results) { + rs.add(this.rowMapper.mapRow(result, rowNum++)); + } + return rs; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/ValueMapper.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/ValueMapper.java index e41551d698cb..1330c4496715 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/ValueMapper.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/ValueMapper.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.common.hbase; - -/** - * @author emeroad - */ -public interface ValueMapper { - byte[] mapValue(T value); -} +package com.nhn.pinpoint.common.hbase; + +/** + * @author emeroad + */ +public interface ValueMapper { + byte[] mapValue(T value); +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/distributor/RangeOneByteSimpleHash.java b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/distributor/RangeOneByteSimpleHash.java index cf2b453b20a0..c3bf0489f926 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/hbase/distributor/RangeOneByteSimpleHash.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/hbase/distributor/RangeOneByteSimpleHash.java @@ -1,74 +1,74 @@ -package com.nhn.pinpoint.common.hbase.distributor; - - -import com.nhn.pinpoint.common.util.MathUtils; -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; - -import java.util.Arrays; - -/** - * @author emeroad - */ -public class RangeOneByteSimpleHash implements RowKeyDistributorByHashPrefix.Hasher { - private final int start; - private final int end; - private int mod; - - // Used to minimize # of created object instances - // Should not be changed. TODO: secure that - private static final byte[][] PREFIXES; - - static { - PREFIXES = new byte[256][]; - for (int i = 0; i < 256; i++) { - PREFIXES[i] = new byte[] {(byte) i}; - } - } - - - public RangeOneByteSimpleHash(int start, int end, int maxBuckets) { - if (maxBuckets < 1 || maxBuckets > 256) { - throw new IllegalArgumentException("maxBuckets should be in 1..256 range"); - } - this.start = start; - this.end = end; - // i.e. "real" maxBuckets value = maxBuckets or maxBuckets-1 - this.mod = maxBuckets; - } - - @Override - public byte[] getHashPrefix(byte[] originalKey) { - long hash = MathUtils.fastAbs(hashBytes(originalKey)); - return new byte[] {(byte) (hash % mod)}; - } - - /** Compute hash for binary data. */ - private int hashBytes(byte[] bytes) { - int min = Math.min(bytes.length, end); - int hash = 1; - for (int i = start; i < min; i++) - hash = (31 * hash) + (int) bytes[i]; - return hash; - } - - @Override - public byte[][] getAllPossiblePrefixes() { - return Arrays.copyOfRange(PREFIXES, 0, mod); - } - - @Override - public int getPrefixLength(byte[] adjustedKey) { - return 1; - } - - @Override - public String getParamsToStore() { - return String.valueOf(mod); - } - - @Override - public void init(String storedParams) { - this.mod = Integer.valueOf(storedParams); - } - -} +package com.nhn.pinpoint.common.hbase.distributor; + + +import com.nhn.pinpoint.common.util.MathUtils; +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; + +import java.util.Arrays; + +/** + * @author emeroad + */ +public class RangeOneByteSimpleHash implements RowKeyDistributorByHashPrefix.Hasher { + private final int start; + private final int end; + private int mod; + + // Used to minimize # of created object instances + // Should not be changed. TODO: secure that + private static final byte[][] PREFIXES; + + static { + PREFIXES = new byte[256][]; + for (int i = 0; i < 256; i++) { + PREFIXES[i] = new byte[] {(byte) i}; + } + } + + + public RangeOneByteSimpleHash(int start, int end, int maxBuckets) { + if (maxBuckets < 1 || maxBuckets > 256) { + throw new IllegalArgumentException("maxBuckets should be in 1..256 range"); + } + this.start = start; + this.end = end; + // i.e. "real" maxBuckets value = maxBuckets or maxBuckets-1 + this.mod = maxBuckets; + } + + @Override + public byte[] getHashPrefix(byte[] originalKey) { + long hash = MathUtils.fastAbs(hashBytes(originalKey)); + return new byte[] {(byte) (hash % mod)}; + } + + /** Compute hash for binary data. */ + private int hashBytes(byte[] bytes) { + int min = Math.min(bytes.length, end); + int hash = 1; + for (int i = start; i < min; i++) + hash = (31 * hash) + (int) bytes[i]; + return hash; + } + + @Override + public byte[][] getAllPossiblePrefixes() { + return Arrays.copyOfRange(PREFIXES, 0, mod); + } + + @Override + public int getPrefixLength(byte[] adjustedKey) { + return 1; + } + + @Override + public String getParamsToStore() { + return String.valueOf(mod); + } + + @Override + public void init(String storedParams) { + this.mod = Integer.valueOf(storedParams); + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescription.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescription.java index 3e84fa32ca08..a62e81d1ec34 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescription.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescription.java @@ -1,80 +1,80 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public class ApiDescription { - - private String className; - - private String methodName; - - private String[] simpleParameter; - - private int line = -1; - - public void setClassName(String className) { - this.className = className; - } - - public String getClassName() { - return className; - } - - public String getSimpleClassName() { - int classNameStartIndex = className.lastIndexOf('.') + 1; - return className.substring(classNameStartIndex, className.length()); - } - - public String getPackageNameName() { - int packageNameIndex = className.lastIndexOf('.'); - if (packageNameIndex == -1) { - return ""; - } - return className.substring(0, packageNameIndex); - } - - - public void setMethodName(String methodName) { - this.methodName = methodName; - } - - public String getMethodName() { - return this.methodName; - } - - public void setSimpleParameter(String[] simpleParameter) { - this.simpleParameter = simpleParameter; - } - - public String[] getSimpleParameter() { - return simpleParameter; - } - - public void setLine(int line) { - this.line = line; - } - - public String getSimpleMethodDescription() { - String simpleParameterDescription = concateLine(simpleParameter, ", "); - return methodName + simpleParameterDescription; - } - - public String concateLine(String[] stringList, String separator) { - if (stringList == null || stringList.length == 0) { - return "()"; - } - - StringBuilder sb = new StringBuilder(); - if (stringList.length > 0) { - sb.append('('); - sb.append(stringList[0]); - for (int i = 1; i < stringList.length; i++) { - sb.append(separator); - sb.append(stringList[i]); - } - sb.append(')'); - } - return sb.toString(); - } -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public class ApiDescription { + + private String className; + + private String methodName; + + private String[] simpleParameter; + + private int line = -1; + + public void setClassName(String className) { + this.className = className; + } + + public String getClassName() { + return className; + } + + public String getSimpleClassName() { + int classNameStartIndex = className.lastIndexOf('.') + 1; + return className.substring(classNameStartIndex, className.length()); + } + + public String getPackageNameName() { + int packageNameIndex = className.lastIndexOf('.'); + if (packageNameIndex == -1) { + return ""; + } + return className.substring(0, packageNameIndex); + } + + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public String getMethodName() { + return this.methodName; + } + + public void setSimpleParameter(String[] simpleParameter) { + this.simpleParameter = simpleParameter; + } + + public String[] getSimpleParameter() { + return simpleParameter; + } + + public void setLine(int line) { + this.line = line; + } + + public String getSimpleMethodDescription() { + String simpleParameterDescription = concateLine(simpleParameter, ", "); + return methodName + simpleParameterDescription; + } + + public String concateLine(String[] stringList, String separator) { + if (stringList == null || stringList.length == 0) { + return "()"; + } + + StringBuilder sb = new StringBuilder(); + if (stringList.length > 0) { + sb.append('('); + sb.append(stringList[0]); + for (int i = 1; i < stringList.length; i++) { + sb.append(separator); + sb.append(stringList[i]); + } + sb.append(')'); + } + return sb.toString(); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescriptionParser.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescriptionParser.java index 9da123105ab2..c3143110c78e 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescriptionParser.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/ApiDescriptionParser.java @@ -1,109 +1,109 @@ -package com.nhn.pinpoint.common.util; - -import org.slf4j.LoggerFactory; - -import java.util.regex.Pattern; - -/** - * MethodDescriptor 과 비슷한데. 문자열을 기반으로 parsing하여 생성하므로 따로 만들었음. - * @author emeroad - */ -public class ApiDescriptionParser { - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - private static final char DOT = '.'; - private static final char METHOD_PARAM_START = '('; - private static final char METHOD_PARAM_END = ')'; - private static final char PARAMETER_SP = ','; - private static Pattern PARAMETER_REGEX = Pattern.compile(", |,"); - // org.springframework.web.servlet.FrameworkServlet.doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) -// com.mysql.jdbc.ConnectionImpl.setAutoCommit(boolean autoCommitFlag) -// com.mysql.jdbc.ConnectionImpl.commit() - - // org.apache.catalina.core.StandardHostValve.invoke(org.apache.catalina.connector.Request request, org.apache.catalina.connector.Response response):110 - public ApiDescription parse(String apiDescriptionString) { - if (apiDescriptionString == null) { - throw new NullPointerException("apiDescriptionString must not be null"); - } - - final int methodStart = apiDescriptionString.lastIndexOf(METHOD_PARAM_START); - if (methodStart == -1) { - throw new IllegalArgumentException("'(' not found. invalid apiDescriptionString:" + apiDescriptionString); - } - - final int methodEnd = apiDescriptionString.lastIndexOf(METHOD_PARAM_END); - if (methodEnd == -1) { - throw new IllegalArgumentException("')' not found. invalid apiDescriptionString:" + apiDescriptionString); - } - - final int classIndex = apiDescriptionString.lastIndexOf(DOT, methodStart); - if (classIndex == -1) { - throw new IllegalArgumentException("'.' not found. invalid apiDescriptionString:" + apiDescriptionString); - } - - String className = parseClassName(apiDescriptionString, classIndex); - ApiDescription api = new ApiDescription(); - api.setClassName(className); - - String methodName = parseMethodName(apiDescriptionString, methodStart, classIndex); - api.setMethodName(methodName); - - String parameterDescriptor = apiDescriptionString.substring(methodStart + 1, methodEnd); - String[] parameterList = parseParameter(parameterDescriptor); - String[] simpleParameterList = parseSimpleParameter(parameterList); - api.setSimpleParameter(simpleParameterList); - - int lineIndex = apiDescriptionString.lastIndexOf(':'); - // 일단 땜방으로 lineNumber체크해서 lineNumber를 뿌려주도록 하자. - if (lineIndex != -1) { - try { - int line = Integer.parseInt(apiDescriptionString.substring(lineIndex + 1, apiDescriptionString.length())); - api.setLine(line); - } catch (NumberFormatException e) { - LoggerFactory.getLogger(this.getClass()).warn("line number parse error {}", e); - } - } - - return api; - } - - private String[] parseSimpleParameter(String[] parameterList) { - if (parameterList == null || parameterList.length == 0) { - return EMPTY_STRING_ARRAY; - } - String[] simple = new String[parameterList.length]; - for (int i = 0; i < parameterList.length; i++) { - simple[i] = simepleParameter(parameterList[i]); - } - return simple; - } - - private String simepleParameter(String parameter) { - int packageIndex = parameter.lastIndexOf(DOT); - if (packageIndex == -1) { - // 없을 경우 아래 로직가 동일하나 추후 뭔가 변경사항이 생길수 있어 명시적으로 체크하는 로직으로 구현. - packageIndex = 0; - } else { - packageIndex += 1; - } - - - return parameter.substring(packageIndex, parameter.length()); - } - - private String[] parseParameter(String parameterDescriptor) { - if (parameterDescriptor == null || parameterDescriptor.length() == 0) { - return EMPTY_STRING_ARRAY; - } - return PARAMETER_REGEX.split(parameterDescriptor); - - } - - private String parseClassName(String apiDescriptionString, int classIndex) { - return apiDescriptionString.substring(0, classIndex); - } - - private String parseMethodName(String apiDescriptionString, int methodStart, int classIndex) { - return apiDescriptionString.substring(classIndex + 1, methodStart); - } - -} +package com.nhn.pinpoint.common.util; + +import org.slf4j.LoggerFactory; + +import java.util.regex.Pattern; + +/** + * MethodDescriptor 과 비슷한데. 문자열을 기반으로 parsing하여 생성하므로 따로 만들었음. + * @author emeroad + */ +public class ApiDescriptionParser { + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + private static final char DOT = '.'; + private static final char METHOD_PARAM_START = '('; + private static final char METHOD_PARAM_END = ')'; + private static final char PARAMETER_SP = ','; + private static Pattern PARAMETER_REGEX = Pattern.compile(", |,"); + // org.springframework.web.servlet.FrameworkServlet.doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) +// com.mysql.jdbc.ConnectionImpl.setAutoCommit(boolean autoCommitFlag) +// com.mysql.jdbc.ConnectionImpl.commit() + + // org.apache.catalina.core.StandardHostValve.invoke(org.apache.catalina.connector.Request request, org.apache.catalina.connector.Response response):110 + public ApiDescription parse(String apiDescriptionString) { + if (apiDescriptionString == null) { + throw new NullPointerException("apiDescriptionString must not be null"); + } + + final int methodStart = apiDescriptionString.lastIndexOf(METHOD_PARAM_START); + if (methodStart == -1) { + throw new IllegalArgumentException("'(' not found. invalid apiDescriptionString:" + apiDescriptionString); + } + + final int methodEnd = apiDescriptionString.lastIndexOf(METHOD_PARAM_END); + if (methodEnd == -1) { + throw new IllegalArgumentException("')' not found. invalid apiDescriptionString:" + apiDescriptionString); + } + + final int classIndex = apiDescriptionString.lastIndexOf(DOT, methodStart); + if (classIndex == -1) { + throw new IllegalArgumentException("'.' not found. invalid apiDescriptionString:" + apiDescriptionString); + } + + String className = parseClassName(apiDescriptionString, classIndex); + ApiDescription api = new ApiDescription(); + api.setClassName(className); + + String methodName = parseMethodName(apiDescriptionString, methodStart, classIndex); + api.setMethodName(methodName); + + String parameterDescriptor = apiDescriptionString.substring(methodStart + 1, methodEnd); + String[] parameterList = parseParameter(parameterDescriptor); + String[] simpleParameterList = parseSimpleParameter(parameterList); + api.setSimpleParameter(simpleParameterList); + + int lineIndex = apiDescriptionString.lastIndexOf(':'); + // 일단 땜방으로 lineNumber체크해서 lineNumber를 뿌려주도록 하자. + if (lineIndex != -1) { + try { + int line = Integer.parseInt(apiDescriptionString.substring(lineIndex + 1, apiDescriptionString.length())); + api.setLine(line); + } catch (NumberFormatException e) { + LoggerFactory.getLogger(this.getClass()).warn("line number parse error {}", e); + } + } + + return api; + } + + private String[] parseSimpleParameter(String[] parameterList) { + if (parameterList == null || parameterList.length == 0) { + return EMPTY_STRING_ARRAY; + } + String[] simple = new String[parameterList.length]; + for (int i = 0; i < parameterList.length; i++) { + simple[i] = simepleParameter(parameterList[i]); + } + return simple; + } + + private String simepleParameter(String parameter) { + int packageIndex = parameter.lastIndexOf(DOT); + if (packageIndex == -1) { + // 없을 경우 아래 로직가 동일하나 추후 뭔가 변경사항이 생길수 있어 명시적으로 체크하는 로직으로 구현. + packageIndex = 0; + } else { + packageIndex += 1; + } + + + return parameter.substring(packageIndex, parameter.length()); + } + + private String[] parseParameter(String parameterDescriptor) { + if (parameterDescriptor == null || parameterDescriptor.length() == 0) { + return EMPTY_STRING_ARRAY; + } + return PARAMETER_REGEX.split(parameterDescriptor); + + } + + private String parseClassName(String apiDescriptionString, int classIndex) { + return apiDescriptionString.substring(0, classIndex); + } + + private String parseMethodName(String apiDescriptionString, int methodStart, int classIndex) { + return apiDescriptionString.substring(classIndex + 1, methodStart); + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java index e2b0f986f4c0..d82e53cf84da 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java @@ -1,530 +1,421 @@ -package com.nhn.pinpoint.common.util; - - -import java.io.UnsupportedEncodingException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author emeroad - */ -public final class BytesUtils { - public static final int SHORT_BYTE_LENGTH = 2; - public static final int INT_BYTE_LENGTH = 4; - public static final int LONG_BYTE_LENGTH = 8; - public static final int LONG_LONG_BYTE_LENGTH = 16; - - public static final int VLONG_MAX_SIZE = 10; - public static final int VINT_MAX_SIZE = 5; - - private static final byte[] EMPTY_BYTES = new byte[0]; - private static final String UTF8 = "UTF-8"; - private static final Logger LOGGER = Logger.getLogger(BytesUtils.class.getName()); - - @Deprecated - public static byte[] longLongToBytes(final long value1, final long value2) { - final byte[] buffer = new byte[LONG_LONG_BYTE_LENGTH]; - writeFirstLong0(value1, buffer); - writeSecondLong0(value2, buffer); - return buffer; - } - - public static byte[] stringLongLongToBytes(final String string, final int maxStringSize, final long value1, final long value2) { - if (string == null) { - throw new NullPointerException("string must not be null"); - } - if (maxStringSize < 0) { - throw new IllegalArgumentException("maxStringSize"); - } - final byte[] stringBytes = toBytes(string); - if (stringBytes.length > maxStringSize) { - throw new IllegalArgumentException("string is max " + stringBytes.length + ", string='" + string + "'"); - } - final byte[] buffer = new byte[LONG_LONG_BYTE_LENGTH + maxStringSize]; - writeBytes(buffer, 0, stringBytes); - writeFirstLong0(value1, buffer, maxStringSize); - writeSecondLong0(value2, buffer, maxStringSize); - return buffer; - } - - public static void writeBytes(final byte[] buffer, int offset, final byte[] stringBytes) { - if (buffer == null) { - throw new NullPointerException("buffer must not be null"); - } - if (stringBytes == null) { - throw new NullPointerException("stringBytes must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - System.arraycopy(stringBytes, 0, buffer, offset, stringBytes.length); - } - - @Deprecated - public static long[] bytesToLongLong(final byte[] buf) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (buf.length < LONG_LONG_BYTE_LENGTH) { - throw new IllegalArgumentException("Illegal buf size."); - } - final long[] result = new long[2]; - - result[0] = bytesToFirstLong0(buf); - result[1] = bytesToSecondLong0(buf); - - return result; - } - - public static long bytesToLong(final byte[] buf, final int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (buf.length < offset + LONG_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 8)); - } - - final long rv = (((long) buf[offset] & 0xff) << 56) - | (((long) buf[offset + 1] & 0xff) << 48) - | (((long) buf[offset + 2] & 0xff) << 40) - | (((long) buf[offset + 3] & 0xff) << 32) - | (((long) buf[offset + 4] & 0xff) << 24) - | (((long) buf[offset + 5] & 0xff) << 16) - | (((long) buf[offset + 6] & 0xff) << 8) - | (((long) buf[offset + 7] & 0xff)); - return rv; - } - - public static int bytesToInt(final byte[] buf, final int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (buf.length < offset + INT_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 4)); - } - - final int v = ((buf[offset] & 0xff) << 24) - | ((buf[offset + 1] & 0xff) << 16) - | ((buf[offset + 2] & 0xff) << 8) - | ((buf[offset + 3] & 0xff)); - - return v; - } - - public static short bytesToShort(final byte[] buf, final int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (buf.length < offset + SHORT_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 2)); - } - - final short v = (short) (((buf[offset] & 0xff) << 8) | ((buf[offset + 1] & 0xff))); - - return v; - } - - public static short bytesToShort(final byte byte1, final byte byte2) { - return (short) (((byte1 & 0xff) << 8) | ((byte2 & 0xff))); - } - - public static long bytesToFirstLong(final byte[] buf) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (buf.length < LONG_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small(8). buf.length:" + buf.length); - } - - return bytesToFirstLong0(buf); - } - - private static long bytesToFirstLong0(byte[] buf) { - final long rv = (((long) buf[0] & 0xff) << 56) - | (((long) buf[1] & 0xff) << 48) - | (((long) buf[2] & 0xff) << 40) - | (((long) buf[3] & 0xff) << 32) - | (((long) buf[4] & 0xff) << 24) - | (((long) buf[5] & 0xff) << 16) - | (((long) buf[6] & 0xff) << 8) - | (((long) buf[7] & 0xff)); - return rv; - } - - public static long bytesToSecondLong(final byte[] buf) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (buf.length < LONG_LONG_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small(16). buf.length:" + buf.length); - } - - return bytesToSecondLong0(buf); - } - - private static long bytesToSecondLong0(final byte[] buf) { - final long rv = (((long) buf[8] & 0xff) << 56) - | (((long) buf[9] & 0xff) << 48) - | (((long) buf[10] & 0xff) << 40) - | (((long) buf[11] & 0xff) << 32) - | (((long) buf[12] & 0xff) << 24) - | (((long) buf[13] & 0xff) << 16) - | (((long) buf[14] & 0xff) << 8) - | (((long) buf[15] & 0xff)); - return rv; - } - - public static int writeLong(final long value, final byte[] buf, int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (buf.length < offset + LONG_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 8)); - } - buf[offset++] = (byte) (value >> 56); - buf[offset++] = (byte) (value >> 48); - buf[offset++] = (byte) (value >> 40); - buf[offset++] = (byte) (value >> 32); - buf[offset++] = (byte) (value >> 24); - buf[offset++] = (byte) (value >> 16); - buf[offset++] = (byte) (value >> 8); - buf[offset++] = (byte) (value); - return offset; - } - - public static byte writeShort1(final short value) { - return (byte) (value >> 8); - } - - public static byte writeShort2(final short value) { - return (byte) (value); - } - - public static int writeShort(final short value, final byte[] buf, int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (buf.length < offset + SHORT_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 2)); - } - buf[offset++] = (byte) (value >> 8); - buf[offset++] = (byte) (value); - return offset; - } - - public static int writeInt(final int value, final byte[] buf, int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (buf.length < offset + INT_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 4)); - } - buf[offset++] = (byte) (value >> 24); - buf[offset++] = (byte) (value >> 16); - buf[offset++] = (byte) (value >> 8); - buf[offset++] = (byte) (value); - return offset; - } - - public static int writeSVar32(final int value, final byte[] buf, final int offset) { - return writeVar32(intToZigZag(value), buf, offset); - } - - public static int writeVar32(int value, final byte[] buf, int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - while (true) { - if ((value & ~0x7F) == 0) { - buf[offset++] = (byte)value; - return offset; - } else { - buf[offset++] = (byte)((value & 0x7F) | 0x80); - value >>>= 7; - } - } - } - - public static int writeVar64(long value, final byte[] buf, int offset) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - while (true) { - if ((value & ~0x7FL) == 0) { - buf[offset++] = (byte)value; - return offset; - } else { - buf[offset++] = (byte)(((int)value & 0x7F) | 0x80); - value >>>= 7; - } - } - } - - @Deprecated - public static void writeFirstLong(final long value, final byte[] buf) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (buf.length < LONG_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small(8). buf.length:" + buf.length); - } - writeFirstLong0(value, buf); - } - - private static void writeFirstLong0(final long value, final byte[] buf) { - buf[0] = (byte) (value >> 56); - buf[1] = (byte) (value >> 48); - buf[2] = (byte) (value >> 40); - buf[3] = (byte) (value >> 32); - buf[4] = (byte) (value >> 24); - buf[5] = (byte) (value >> 16); - buf[6] = (byte) (value >> 8); - buf[7] = (byte) (value); - } - - private static void writeFirstLong0(final long value, final byte[] buf, int offset) { - buf[0 + offset] = (byte) (value >> 56); - buf[1 + offset] = (byte) (value >> 48); - buf[2 + offset] = (byte) (value >> 40); - buf[3 + offset] = (byte) (value >> 32); - buf[4 + offset] = (byte) (value >> 24); - buf[5 + offset] = (byte) (value >> 16); - buf[6 + offset] = (byte) (value >> 8); - buf[7 + offset] = (byte) (value); - } - - @Deprecated - public static void writeSecondLong(final long value, final byte[] buf) { - if (buf == null) { - throw new NullPointerException("buf must not be null"); - } - if (buf.length < LONG_LONG_BYTE_LENGTH) { - throw new IllegalArgumentException("buf.length is too small(16). buf.length:" + buf.length); - } - writeSecondLong0(value, buf); - } - - - private static Logger getLogger() { - return Logger.getLogger(BytesUtils.class.getName()); - } - - private static void writeSecondLong0(final long value, final byte[] buf) { - buf[8] = (byte) (value >> 56); - buf[9] = (byte) (value >> 48); - buf[10] = (byte) (value >> 40); - buf[11] = (byte) (value >> 32); - buf[12] = (byte) (value >> 24); - buf[13] = (byte) (value >> 16); - buf[14] = (byte) (value >> 8); - buf[15] = (byte) (value); - } - - private static void writeSecondLong0(final long value, final byte[] buf, int offset) { - buf[8 + offset] = (byte) (value >> 56); - buf[9 + offset] = (byte) (value >> 48); - buf[10 + offset] = (byte) (value >> 40); - buf[11 + offset] = (byte) (value >> 32); - buf[12 + offset] = (byte) (value >> 24); - buf[13 + offset] = (byte) (value >> 16); - buf[14 + offset] = (byte) (value >> 8); - buf[15 + offset] = (byte) (value); - } - - public static byte[] add(final String prefix, final long postfix) { - if (prefix == null) { - throw new NullPointerException("prefix must not be null"); - } - byte[] agentByte = toBytes(prefix); - return add(agentByte, postfix); - } - - public static byte[] add(final byte[] preFix, final long postfix) { - byte[] buf = new byte[preFix.length + LONG_BYTE_LENGTH]; - System.arraycopy(preFix, 0, buf, 0, preFix.length); - writeLong(postfix, buf, preFix.length); - return buf; - } - - public static byte[] add(final byte[] preFix, final short postfix) { - byte[] buf = new byte[preFix.length + SHORT_BYTE_LENGTH]; - System.arraycopy(preFix, 0, buf, 0, preFix.length); - writeShort(postfix, buf, preFix.length); - return buf; - } - - public static byte[] add(final int preFix, final short postFix) { - byte[] buf = new byte[INT_BYTE_LENGTH + SHORT_BYTE_LENGTH]; - writeInt(preFix, buf, 0); - writeShort(postFix, buf, 4); - return buf; - } - - - public static byte[] add(final long preFix, final short postFix) { - byte[] buf = new byte[LONG_BYTE_LENGTH + SHORT_BYTE_LENGTH]; - writeLong(preFix, buf, 0); - writeShort(postFix, buf, 8); - return buf; - } - - public static byte[] toBytes(final String value) { - if (value == null) { - return null; - } - try { - return value.getBytes(UTF8); - } catch (UnsupportedEncodingException e) { - final Logger logger = getLogger(); - logger.log(Level.SEVERE, "String encoding fail. value:" + value + " Caused:" + e.getMessage(), e); - return EMPTY_BYTES; - } - } - - public static byte[] merge(final byte[] b1, final byte[] b2) { - if (b1 == null) { - throw new NullPointerException("b1 must not be null"); - } - if (b2 == null) { - throw new NullPointerException("b2 must not be null"); - } - final byte[] result = new byte[b1.length + b2.length]; - - System.arraycopy(b1, 0, result, 0, b1.length); - System.arraycopy(b2, 0, result, b1.length, b2.length); - - return result; - } - - public static byte[] toFixedLengthBytes(final String str, final int length) { - if (length < 0) { - throw new IllegalArgumentException("negative length:" + length); - } - final byte[] b1 = toBytes(str); - if (b1 == null) { - return new byte[length]; - } - - if (b1.length > length) { - throw new IllegalArgumentException("String is longer then target length of bytes."); - } - byte[] b = new byte[length]; - System.arraycopy(b1, 0, b, 0, b1.length); - - return b; - } - - - public static int intToZigZag(final int n) { - return (n << 1) ^ (n >> 31); - } - - public static int zigzagToInt(final int n) { - return (n >>> 1) ^ -(n & 1); - } - - - public static long longToZigZag(final long n) { - return (n << 1) ^ (n >> 63); - } - - public static long zigzagToLong(final long n) { - return (n >>> 1) ^ -(n & 1); - } - - public static byte[] concat(final byte[]... arrays) { - int totalLength = 0; - - for (int i = 0; i < arrays.length; i++) { - totalLength += arrays[i].length; - } - - byte[] result = new byte[totalLength]; - - int currentIndex = 0; - for (int i = 0; i < arrays.length; i++) { - System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length); - currentIndex += arrays[i].length; - } - - return result; - } - - public static String safeTrim(final String string) { - if (string == null) { - return null; - } - return string.trim(); - } - - public static String toString(final byte[] bytes) { - if (bytes == null) { - return null; - } - return toString(bytes, 0, bytes.length); - } - - public static String toString(final byte [] bytes, final int offset, final int length) { - if (bytes == null) { - return null; - } - if (offset < 0) { - throw new IllegalArgumentException("negative offset:" + offset); - } - if (length == 0) { - return ""; - } - try { - return new String(bytes, offset, length, UTF8); - } catch (UnsupportedEncodingException e) { - LOGGER.log(Level.SEVERE, "UTF-8 encoding fail.", e); - return null; - } - } - - public static String toStringAndRightTrim(final byte[] bytes, final int offset, final int length) { - String string = toString(bytes, offset, length); - return trimRight(string); - } - - public static String trimRight(final String string) { - if (string == null) { - return null; - } - final int length = string.length(); - int index = length; -// Character.isWhitespace() 로 해야 하는 의문이 생김?? 안해도 될것 같기는 함. - while (string.charAt(index - 1) <= ' ') { - index--; - } - if (index == length) { - return string; - } else { - return string.substring(0, index); - } - } -} +package com.nhn.pinpoint.common.util; + + +import java.io.UnsupportedEncodingException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author emeroad + */ +public final class BytesUtils { + public static final int SHORT_BYTE_LENGTH = 2; + public static final int INT_BYTE_LENGTH = 4; + public static final int LONG_BYTE_LENGTH = 8; + public static final int LONG_LONG_BYTE_LENGTH = 16; + + public static final int VLONG_MAX_SIZE = 10; + public static final int VINT_MAX_SIZE = 5; + + private static final byte[] EMPTY_BYTES = new byte[0]; + private static final String UTF8 = "UTF-8"; + private static final Logger LOGGER = Logger.getLogger(BytesUtils.class.getName()); + + + public static byte[] stringLongLongToBytes(final String string, final int maxStringSize, final long value1, final long value2) { + if (string == null) { + throw new NullPointerException("string must not be null"); + } + if (maxStringSize < 0) { + throw new IllegalArgumentException("maxStringSize"); + } + final byte[] stringBytes = toBytes(string); + if (stringBytes.length > maxStringSize) { + throw new IllegalArgumentException("string is max " + stringBytes.length + ", string='" + string + "'"); + } + final byte[] buffer = new byte[LONG_LONG_BYTE_LENGTH + maxStringSize]; + writeBytes(buffer, 0, stringBytes); + writeFirstLong0(value1, buffer, maxStringSize); + writeSecondLong0(value2, buffer, maxStringSize); + return buffer; + } + + public static void writeBytes(final byte[] buffer, int offset, final byte[] stringBytes) { + if (buffer == null) { + throw new NullPointerException("buffer must not be null"); + } + if (stringBytes == null) { + throw new NullPointerException("stringBytes must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + System.arraycopy(stringBytes, 0, buffer, offset, stringBytes.length); + } + + public static long bytesToLong(final byte[] buf, final int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (buf.length < offset + LONG_BYTE_LENGTH) { + throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 8)); + } + + final long rv = (((long) buf[offset] & 0xff) << 56) + | (((long) buf[offset + 1] & 0xff) << 48) + | (((long) buf[offset + 2] & 0xff) << 40) + | (((long) buf[offset + 3] & 0xff) << 32) + | (((long) buf[offset + 4] & 0xff) << 24) + | (((long) buf[offset + 5] & 0xff) << 16) + | (((long) buf[offset + 6] & 0xff) << 8) + | (((long) buf[offset + 7] & 0xff)); + return rv; + } + + public static int bytesToInt(final byte[] buf, final int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (buf.length < offset + INT_BYTE_LENGTH) { + throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 4)); + } + + final int v = ((buf[offset] & 0xff) << 24) + | ((buf[offset + 1] & 0xff) << 16) + | ((buf[offset + 2] & 0xff) << 8) + | ((buf[offset + 3] & 0xff)); + + return v; + } + + public static short bytesToShort(final byte[] buf, final int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (buf.length < offset + SHORT_BYTE_LENGTH) { + throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 2)); + } + + final short v = (short) (((buf[offset] & 0xff) << 8) | ((buf[offset + 1] & 0xff))); + + return v; + } + + public static short bytesToShort(final byte byte1, final byte byte2) { + return (short) (((byte1 & 0xff) << 8) | ((byte2 & 0xff))); + } + + + public static int writeLong(final long value, final byte[] buf, int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (buf.length < offset + LONG_BYTE_LENGTH) { + throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 8)); + } + buf[offset++] = (byte) (value >> 56); + buf[offset++] = (byte) (value >> 48); + buf[offset++] = (byte) (value >> 40); + buf[offset++] = (byte) (value >> 32); + buf[offset++] = (byte) (value >> 24); + buf[offset++] = (byte) (value >> 16); + buf[offset++] = (byte) (value >> 8); + buf[offset++] = (byte) (value); + return offset; + } + + public static byte writeShort1(final short value) { + return (byte) (value >> 8); + } + + public static byte writeShort2(final short value) { + return (byte) (value); + } + + public static int writeShort(final short value, final byte[] buf, int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (buf.length < offset + SHORT_BYTE_LENGTH) { + throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 2)); + } + buf[offset++] = (byte) (value >> 8); + buf[offset++] = (byte) (value); + return offset; + } + + public static int writeInt(final int value, final byte[] buf, int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (buf.length < offset + INT_BYTE_LENGTH) { + throw new IllegalArgumentException("buf.length is too small. buf.length:" + buf.length + " offset:" + (offset + 4)); + } + buf[offset++] = (byte) (value >> 24); + buf[offset++] = (byte) (value >> 16); + buf[offset++] = (byte) (value >> 8); + buf[offset++] = (byte) (value); + return offset; + } + + public static int writeSVar32(final int value, final byte[] buf, final int offset) { + return writeVar32(intToZigZag(value), buf, offset); + } + + public static int writeVar32(int value, final byte[] buf, int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + while (true) { + if ((value & ~0x7F) == 0) { + buf[offset++] = (byte)value; + return offset; + } else { + buf[offset++] = (byte)((value & 0x7F) | 0x80); + value >>>= 7; + } + } + } + + public static int writeVar64(long value, final byte[] buf, int offset) { + if (buf == null) { + throw new NullPointerException("buf must not be null"); + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + while (true) { + if ((value & ~0x7FL) == 0) { + buf[offset++] = (byte)value; + return offset; + } else { + buf[offset++] = (byte)(((int)value & 0x7F) | 0x80); + value >>>= 7; + } + } + } + + + private static void writeFirstLong0(final long value, final byte[] buf, int offset) { + buf[offset] = (byte) (value >> 56); + buf[1 + offset] = (byte) (value >> 48); + buf[2 + offset] = (byte) (value >> 40); + buf[3 + offset] = (byte) (value >> 32); + buf[4 + offset] = (byte) (value >> 24); + buf[5 + offset] = (byte) (value >> 16); + buf[6 + offset] = (byte) (value >> 8); + buf[7 + offset] = (byte) (value); + } + + + private static Logger getLogger() { + return Logger.getLogger(BytesUtils.class.getName()); + } + + + private static void writeSecondLong0(final long value, final byte[] buf, int offset) { + buf[8 + offset] = (byte) (value >> 56); + buf[9 + offset] = (byte) (value >> 48); + buf[10 + offset] = (byte) (value >> 40); + buf[11 + offset] = (byte) (value >> 32); + buf[12 + offset] = (byte) (value >> 24); + buf[13 + offset] = (byte) (value >> 16); + buf[14 + offset] = (byte) (value >> 8); + buf[15 + offset] = (byte) (value); + } + + public static byte[] add(final String prefix, final long postfix) { + if (prefix == null) { + throw new NullPointerException("prefix must not be null"); + } + byte[] agentByte = toBytes(prefix); + return add(agentByte, postfix); + } + + public static byte[] add(final byte[] preFix, final long postfix) { + byte[] buf = new byte[preFix.length + LONG_BYTE_LENGTH]; + System.arraycopy(preFix, 0, buf, 0, preFix.length); + writeLong(postfix, buf, preFix.length); + return buf; + } + + public static byte[] add(final byte[] preFix, final short postfix) { + byte[] buf = new byte[preFix.length + SHORT_BYTE_LENGTH]; + System.arraycopy(preFix, 0, buf, 0, preFix.length); + writeShort(postfix, buf, preFix.length); + return buf; + } + + public static byte[] add(final int preFix, final short postFix) { + byte[] buf = new byte[INT_BYTE_LENGTH + SHORT_BYTE_LENGTH]; + writeInt(preFix, buf, 0); + writeShort(postFix, buf, 4); + return buf; + } + + + public static byte[] add(final long preFix, final short postFix) { + byte[] buf = new byte[LONG_BYTE_LENGTH + SHORT_BYTE_LENGTH]; + writeLong(preFix, buf, 0); + writeShort(postFix, buf, 8); + return buf; + } + + public static byte[] toBytes(final String value) { + if (value == null) { + return null; + } + try { + return value.getBytes(UTF8); + } catch (UnsupportedEncodingException e) { + final Logger logger = getLogger(); + logger.log(Level.SEVERE, "String encoding fail. value:" + value + " Caused:" + e.getMessage(), e); + return EMPTY_BYTES; + } + } + + public static byte[] merge(final byte[] b1, final byte[] b2) { + if (b1 == null) { + throw new NullPointerException("b1 must not be null"); + } + if (b2 == null) { + throw new NullPointerException("b2 must not be null"); + } + final byte[] result = new byte[b1.length + b2.length]; + + System.arraycopy(b1, 0, result, 0, b1.length); + System.arraycopy(b2, 0, result, b1.length, b2.length); + + return result; + } + + public static byte[] toFixedLengthBytes(final String str, final int length) { + if (length < 0) { + throw new IllegalArgumentException("negative length:" + length); + } + final byte[] b1 = toBytes(str); + if (b1 == null) { + return new byte[length]; + } + + if (b1.length > length) { + throw new IllegalArgumentException("String is longer then target length of bytes."); + } + byte[] b = new byte[length]; + System.arraycopy(b1, 0, b, 0, b1.length); + + return b; + } + + + public static int intToZigZag(final int n) { + return (n << 1) ^ (n >> 31); + } + + public static int zigzagToInt(final int n) { + return (n >>> 1) ^ -(n & 1); + } + + + public static long longToZigZag(final long n) { + return (n << 1) ^ (n >> 63); + } + + public static long zigzagToLong(final long n) { + return (n >>> 1) ^ -(n & 1); + } + + public static byte[] concat(final byte[]... arrays) { + int totalLength = 0; + + final int length = arrays.length; + for (int i = 0; i < length; i++) { + totalLength += arrays[i].length; + } + + byte[] result = new byte[totalLength]; + + int currentIndex = 0; + for (int i = 0; i < length; i++) { + System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length); + currentIndex += arrays[i].length; + } + + return result; + } + + public static String safeTrim(final String string) { + if (string == null) { + return null; + } + return string.trim(); + } + + public static String toString(final byte[] bytes) { + if (bytes == null) { + return null; + } + return toString(bytes, 0, bytes.length); + } + + public static String toString(final byte [] bytes, final int offset, final int length) { + if (bytes == null) { + return null; + } + if (offset < 0) { + throw new IllegalArgumentException("negative offset:" + offset); + } + if (length == 0) { + return ""; + } + try { + return new String(bytes, offset, length, UTF8); + } catch (UnsupportedEncodingException e) { + LOGGER.log(Level.SEVERE, "UTF-8 encoding fail.", e); + return null; + } + } + + public static String toStringAndRightTrim(final byte[] bytes, final int offset, final int length) { + String string = toString(bytes, offset, length); + return trimRight(string); + } + + public static String trimRight(final String string) { + if (string == null) { + return null; + } + final int length = string.length(); + int index = length; +// Character.isWhitespace() 로 해야 하는 의문이 생김?? 안해도 될것 같기는 함. + while (string.charAt(index - 1) <= ' ') { + index--; + } + if (index == length) { + return string; + } else { + return string.substring(0, index); + } + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/ClassLoaderUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/ClassLoaderUtils.java new file mode 100644 index 000000000000..fcd1e7b7e9a8 --- /dev/null +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/ClassLoaderUtils.java @@ -0,0 +1,26 @@ +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public final class ClassLoaderUtils { + + public static ClassLoader getClassLoader() { + return getDefaultClassLoader(ClassLoaderUtils.class.getClassLoader()); + } + + public static ClassLoader getDefaultClassLoader(ClassLoader defaultClassLoader) { + ClassLoader classLoader = null; + try { + final Thread th = Thread.currentThread(); + classLoader = th.getContextClassLoader(); + } catch (Throwable e) { + // skip + } + if (classLoader == null) { + return defaultClassLoader; + } + return classLoader; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/DateUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/DateUtils.java index 55309bf9502a..ae728c15b5f9 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/DateUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/DateUtils.java @@ -1,36 +1,36 @@ -package com.nhn.pinpoint.common.util; - -import org.springframework.core.NamedThreadLocal; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * @author emeroad - */ -public final class DateUtils { - - private static final NamedThreadLocal CACHE = new NamedThreadLocal(DateUtils.class.getName()) { - @Override - protected DateFormat initialValue() { - return new SimpleDateFormat(FORMAT); - } - }; - - private static final String FORMAT = "yyyy-MM-dd HH:mm:ss SSS"; - - private DateUtils() { - } - - public static String longToDateStr(long date) { - final DateFormat dateFormat = CACHE.get(); - return dateFormat.format(date); - } - - public static String longToDateStr(long date, String fmt) { - String pattern = (fmt == null) ? FORMAT : fmt; - final SimpleDateFormat format = new SimpleDateFormat(pattern); - return format.format(new Date(date)); - } -} +package com.nhn.pinpoint.common.util; + +import org.springframework.core.NamedThreadLocal; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author emeroad + */ +public final class DateUtils { + + private static final NamedThreadLocal CACHE = new NamedThreadLocal(DateUtils.class.getName()) { + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat(FORMAT); + } + }; + + private static final String FORMAT = "yyyy-MM-dd HH:mm:ss SSS"; + + private DateUtils() { + } + + public static String longToDateStr(long date) { + final DateFormat dateFormat = CACHE.get(); + return dateFormat.format(date); + } + + public static String longToDateStr(long date, String fmt) { + String pattern = (fmt == null) ? FORMAT : fmt; + final SimpleDateFormat format = new SimpleDateFormat(pattern); + return format.format(new Date(date)); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/DefaultParsingResult.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/DefaultParsingResult.java index 60db1765b86b..89830d3e943d 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/DefaultParsingResult.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/DefaultParsingResult.java @@ -1,83 +1,83 @@ -package com.nhn.pinpoint.common.util; - - -/** - * @author emeroad - */ -public class DefaultParsingResult implements ParsingResult { - public static final char SEPARATOR = ','; - private String sql; - private StringBuilder output; - private int id; - - - public DefaultParsingResult() { - - } - - public DefaultParsingResult(String sql, StringBuilder output) { - this.output = output; - this.sql = sql; - } - - @Override - public String getSql() { - return sql; - } - - public void setSql(String sql) { - this.sql = sql; - } - - @Override - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - @Override - public String getOutput() { - if (output == null) { - return ""; - } - return output.toString(); - } - - /** - * 최초 한번은 불려야 된다 안불리고 appendOutputParam을 호출하면 nullpointer exception - */ - void appendOutputSeparator() { - if (output == null) { - this.output = new StringBuilder(); - } else { - this.output.append(SEPARATOR); - } - } - - void appendOutputParam(String str) { - this.output.append(str); - } - - void appendSeparatorCheckOutputParam(char ch) { - if (ch == ',') { - this.output.append(",,"); - } else { - this.output.append(ch); - } - } - - void appendOutputParam(char ch) { - this.output.append(ch); - } - - @Override - public String toString() { - return "ParsingResult{" + - "sql='" + sql + '\'' + - ", output=" + output + - '}'; - } -} +package com.nhn.pinpoint.common.util; + + +/** + * @author emeroad + */ +public class DefaultParsingResult implements ParsingResult { + public static final char SEPARATOR = ','; + private String sql; + private StringBuilder output; + private int id; + + + public DefaultParsingResult() { + + } + + public DefaultParsingResult(String sql, StringBuilder output) { + this.output = output; + this.sql = sql; + } + + @Override + public String getSql() { + return sql; + } + + public void setSql(String sql) { + this.sql = sql; + } + + @Override + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @Override + public String getOutput() { + if (output == null) { + return ""; + } + return output.toString(); + } + + /** + * 최초 한번은 불려야 된다 안불리고 appendOutputParam을 호출하면 nullpointer exception + */ + void appendOutputSeparator() { + if (output == null) { + this.output = new StringBuilder(); + } else { + this.output.append(SEPARATOR); + } + } + + void appendOutputParam(String str) { + this.output.append(str); + } + + void appendSeparatorCheckOutputParam(char ch) { + if (ch == ',') { + this.output.append(",,"); + } else { + this.output.append(ch); + } + } + + void appendOutputParam(char ch) { + this.output.append(ch); + } + + @Override + public String toString() { + return "ParsingResult{" + + "sql='" + sql + '\'' + + ", output=" + output + + '}'; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/ExecutorFactory.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/ExecutorFactory.java index ac6333b86447..a448f177e17f 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/ExecutorFactory.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/ExecutorFactory.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.common.util; - -import java.util.concurrent.*; - -/** - * @author emeroad - */ -public final class ExecutorFactory { - - private static final ThreadFactory DEFAULT_THREAD_FACTORY = new PinpointThreadFactory("Pinpoint-defaultThreadFactory", true); - - private ExecutorFactory() { - } - - public static ThreadPoolExecutor newFixedThreadPool(int nThreads, int workQueueMaxSize, ThreadFactory threadFactory) { - return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(workQueueMaxSize), threadFactory); - } - - public static ThreadPoolExecutor newFixedThreadPool(int nThreads, int workQueueMaxSize) { - return newFixedThreadPool(nThreads, workQueueMaxSize, DEFAULT_THREAD_FACTORY); - } - - public static ThreadPoolExecutor newFixedThreadPool(int nThreads, int workQueueMaxSize, String threadFactoryName, boolean daemon) { - ThreadFactory threadFactory = new PinpointThreadFactory(threadFactoryName, daemon); - return newFixedThreadPool(nThreads, workQueueMaxSize, threadFactory); - } - -} +package com.nhn.pinpoint.common.util; + +import java.util.concurrent.*; + +/** + * @author emeroad + */ +public final class ExecutorFactory { + + private static final ThreadFactory DEFAULT_THREAD_FACTORY = new PinpointThreadFactory("Pinpoint-defaultThreadFactory", true); + + private ExecutorFactory() { + } + + public static ThreadPoolExecutor newFixedThreadPool(int nThreads, int workQueueMaxSize, ThreadFactory threadFactory) { + return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(workQueueMaxSize), threadFactory); + } + + public static ThreadPoolExecutor newFixedThreadPool(int nThreads, int workQueueMaxSize) { + return newFixedThreadPool(nThreads, workQueueMaxSize, DEFAULT_THREAD_FACTORY); + } + + public static ThreadPoolExecutor newFixedThreadPool(int nThreads, int workQueueMaxSize, String threadFactoryName, boolean daemon) { + ThreadFactory threadFactory = new PinpointThreadFactory(threadFactoryName, daemon); + return newFixedThreadPool(nThreads, workQueueMaxSize, threadFactory); + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java index 865aa51f7564..ed4a73af19a3 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java @@ -1,36 +1,36 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public class HttpUtils { - - private static final String UTF8 = "UTF-8"; - - private static final String CHARSET = "charset="; - - public static String parseContentTypeCharset(String contentType) { - return parseContentTypeCharset(contentType, UTF8); - } - - public static String parseContentTypeCharset(String contentType, String defaultCharset) { - if (contentType == null) { - // 스펙상으로는 iso-8859-1 이나 요즘 대부분 was에서 UTF-8 고치기 때문에 애매하다. 옵션 설정에서 고칠수 있게 해야 될지도 모름. - return defaultCharset; - } - int charsetStart = contentType.indexOf(CHARSET); - if (charsetStart == -1) { - // 없음. - return defaultCharset; - } - // 요기가 시작점. - charsetStart = charsetStart + CHARSET.length(); - int charsetEnd = contentType.indexOf(';', charsetStart); - if (charsetEnd == -1) { - charsetEnd = contentType.length(); - } - contentType = contentType.substring(charsetStart, charsetEnd); - - return contentType.trim(); - } -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public class HttpUtils { + + private static final String UTF8 = "UTF-8"; + + private static final String CHARSET = "charset="; + + public static String parseContentTypeCharset(String contentType) { + return parseContentTypeCharset(contentType, UTF8); + } + + public static String parseContentTypeCharset(String contentType, String defaultCharset) { + if (contentType == null) { + // 스펙상으로는 iso-8859-1 이나 요즘 대부분 was에서 UTF-8 고치기 때문에 애매하다. 옵션 설정에서 고칠수 있게 해야 될지도 모름. + return defaultCharset; + } + int charsetStart = contentType.indexOf(CHARSET); + if (charsetStart == -1) { + // 없음. + return defaultCharset; + } + // 요기가 시작점. + charsetStart = charsetStart + CHARSET.length(); + int charsetEnd = contentType.indexOf(';', charsetStart); + if (charsetEnd == -1) { + charsetEnd = contentType.length(); + } + contentType = contentType.substring(charsetStart, charsetEnd); + + return contentType.trim(); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/JvmUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/JvmUtils.java index 7d248e2e2a4e..7bfb09024a68 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/JvmUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/JvmUtils.java @@ -1,43 +1,40 @@ -package com.nhn.pinpoint.common.util; - -import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; -import java.util.Map; - -import com.nhn.pinpoint.common.SystemPropertyKey; -import com.nhn.pinpoint.common.JvmVersion; - -/** - * @author hyungil.jeong - */ -public class JvmUtils { - private static final RuntimeMXBean RUNTIME_MX_BEAN = ManagementFactory.getRuntimeMXBean(); - private static final Map SYSTEM_PROPERTIES = RUNTIME_MX_BEAN.getSystemProperties(); - - private static final JvmVersion JVM_VERSION = _getVersion(); - - private JvmUtils() { - throw new IllegalAccessError(); - } - - public static JvmVersion getVersion() { - return JVM_VERSION; - } - - public static boolean supportsVersion(JvmVersion other) { - return JVM_VERSION.onOrAfter(other); - } - - public static String getSystemProperty(SystemPropertyKey systemPropertyKey) { - String key = systemPropertyKey.getKey(); - if (SYSTEM_PROPERTIES.containsKey(key)) { - return SYSTEM_PROPERTIES.get(key); - } - return ""; - } - - private static JvmVersion _getVersion() { - String javaVersion = getSystemProperty(SystemPropertyKey.JAVA_SPECIFICATION_VERSION); - return JvmVersion.getFromVersion(javaVersion); - } -} +package com.nhn.pinpoint.common.util; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.Map; + +/** + * @author hyungil.jeong + */ +public class JvmUtils { + private static final RuntimeMXBean RUNTIME_MX_BEAN = ManagementFactory.getRuntimeMXBean(); + private static final Map SYSTEM_PROPERTIES = RUNTIME_MX_BEAN.getSystemProperties(); + + private static final JvmVersion JVM_VERSION = _getVersion(); + + private JvmUtils() { + throw new IllegalAccessError(); + } + + public static JvmVersion getVersion() { + return JVM_VERSION; + } + + public static boolean supportsVersion(JvmVersion other) { + return JVM_VERSION.onOrAfter(other); + } + + public static String getSystemProperty(SystemPropertyKey systemPropertyKey) { + String key = systemPropertyKey.getKey(); + if (SYSTEM_PROPERTIES.containsKey(key)) { + return SYSTEM_PROPERTIES.get(key); + } + return ""; + } + + private static JvmVersion _getVersion() { + String javaVersion = getSystemProperty(SystemPropertyKey.JAVA_SPECIFICATION_VERSION); + return JvmVersion.getFromVersion(javaVersion); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/JvmVersion.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/JvmVersion.java similarity index 93% rename from commons/src/main/java/com/navercorp/pinpoint/common/JvmVersion.java rename to commons/src/main/java/com/navercorp/pinpoint/common/util/JvmVersion.java index 8873f4b3efcc..8a049665f6a8 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/JvmVersion.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/JvmVersion.java @@ -1,54 +1,54 @@ -package com.nhn.pinpoint.common; - -/** - * @author hyungil.jeong - */ -public enum JvmVersion { - JAVA_5(1.5, 49), - JAVA_6(1.6, 50), - JAVA_7(1.7, 51), - JAVA_8(1.8, 52), - UNSUPPORTED(-1, -1); - - private final double version; - private final int classVersion; - - private JvmVersion(double version, int classVersion) { - this.version = version; - this.classVersion = classVersion; - } - - public boolean onOrAfter(JvmVersion other) { - if (this == UNSUPPORTED || other == UNSUPPORTED) { - return false; - } - return this == other || this.version > other.version; - } - - public static JvmVersion getFromVersion(String javaVersion) { - try { - double version = Double.parseDouble(javaVersion); - return getFromVersion(version); - } catch (NumberFormatException e) { - return UNSUPPORTED; - } - } - - public static JvmVersion getFromVersion(double javaVersion) { - for (JvmVersion version : JvmVersion.values()) { - if (version.version == javaVersion) { - return version; - } - } - return JvmVersion.UNSUPPORTED; - } - - public static JvmVersion getFromClassVersion(int classVersion) { - for (JvmVersion version : JvmVersion.values()) { - if (version.classVersion == classVersion) { - return version; - } - } - return JvmVersion.UNSUPPORTED; - } -} +package com.nhn.pinpoint.common.util; + +/** + * @author hyungil.jeong + */ +public enum JvmVersion { + JAVA_5(1.5, 49), + JAVA_6(1.6, 50), + JAVA_7(1.7, 51), + JAVA_8(1.8, 52), + UNSUPPORTED(-1, -1); + + private final double version; + private final int classVersion; + + private JvmVersion(double version, int classVersion) { + this.version = version; + this.classVersion = classVersion; + } + + public boolean onOrAfter(JvmVersion other) { + if (this == UNSUPPORTED || other == UNSUPPORTED) { + return false; + } + return this == other || this.version > other.version; + } + + public static JvmVersion getFromVersion(String javaVersion) { + try { + double version = Double.parseDouble(javaVersion); + return getFromVersion(version); + } catch (NumberFormatException e) { + return UNSUPPORTED; + } + } + + public static JvmVersion getFromVersion(double javaVersion) { + for (JvmVersion version : JvmVersion.values()) { + if (version.version == javaVersion) { + return version; + } + } + return JvmVersion.UNSUPPORTED; + } + + public static JvmVersion getFromClassVersion(int classVersion) { + for (JvmVersion version : JvmVersion.values()) { + if (version.classVersion == classVersion) { + return version; + } + } + return JvmVersion.UNSUPPORTED; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/MathUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/MathUtils.java index e5f1c76c1382..58b49346212f 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/MathUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/MathUtils.java @@ -1,14 +1,14 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public final class MathUtils { - private MathUtils() { - } - - public static int fastAbs(final int value) { - return value & Integer.MAX_VALUE; - } - -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public final class MathUtils { + private MathUtils() { + } + + public static int fastAbs(final int value) { + return value & Integer.MAX_VALUE; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/OutputParameterParser.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/OutputParameterParser.java index aa89dd43408f..7e1821a39489 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/OutputParameterParser.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/OutputParameterParser.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.common.util; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** - * @author emeroad - */ -public class OutputParameterParser { - - public static final char SEPARATOR = DefaultParsingResult.SEPARATOR; - - public List parseOutputParameter(String outputParams) { - // 추가적으로 parsing result를 알수 있어야 될거 같음. - if (outputParams == null || outputParams.length() == 0) { - return Collections.emptyList(); - } - - final List result = new LinkedList(); - StringBuilder params = new StringBuilder(); - for (int index = 0; index < outputParams.length(); index++) { - final char ch = outputParams.charAt(index); - if (ch == SEPARATOR) { - if (lookAhead1(outputParams, index) == SEPARATOR) { - params.append(SEPARATOR); - index++; - } else { - result.add(params.toString()); - params = new StringBuilder(); - } - } else { - params.append(ch); - } - } - - result.add(params.toString()); - - return result; - } - - private int lookAhead1(String sql, int index) { - index++; - if (index < sql.length()) { - return sql.charAt(index); - } else { - return -1; - } - } - -} +package com.nhn.pinpoint.common.util; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * @author emeroad + */ +public class OutputParameterParser { + + public static final char SEPARATOR = DefaultParsingResult.SEPARATOR; + + public List parseOutputParameter(String outputParams) { + // 추가적으로 parsing result를 알수 있어야 될거 같음. + if (outputParams == null || outputParams.length() == 0) { + return Collections.emptyList(); + } + + final List result = new LinkedList(); + StringBuilder params = new StringBuilder(); + for (int index = 0; index < outputParams.length(); index++) { + final char ch = outputParams.charAt(index); + if (ch == SEPARATOR) { + if (lookAhead1(outputParams, index) == SEPARATOR) { + params.append(SEPARATOR); + index++; + } else { + result.add(params.toString()); + params = new StringBuilder(); + } + } else { + params.append(ch); + } + } + + result.add(params.toString()); + + return result; + } + + private int lookAhead1(String sql, int index) { + index++; + if (index < sql.length()) { + return sql.charAt(index); + } else { + return -1; + } + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/ParsingResult.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/ParsingResult.java index 0d924beadbfd..4534af688411 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/ParsingResult.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/ParsingResult.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public interface ParsingResult { - String getSql(); - - String getOutput(); - - int getId(); -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public interface ParsingResult { + String getSql(); + + String getOutput(); + + int getId(); +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/PinpointThreadFactory.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/PinpointThreadFactory.java index 3bd00836c4b2..dbb6e95cac49 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/PinpointThreadFactory.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/PinpointThreadFactory.java @@ -1,68 +1,68 @@ -package com.nhn.pinpoint.common.util; - -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class PinpointThreadFactory implements ThreadFactory { - - private final static AtomicInteger FACTORY_NUMBER = new AtomicInteger(0); - private final AtomicInteger threadNumber = new AtomicInteger(0); - - private final String threadPrefix; - private final boolean daemon; - - - public PinpointThreadFactory() { - this("Pinpoint", false); - } - - public PinpointThreadFactory(String threadName) { - this(threadName, false); - } - - public PinpointThreadFactory(String threadName, boolean daemon) { - if (threadName == null) { - throw new NullPointerException("threadName"); - } - this.threadPrefix = prefix(threadName, FACTORY_NUMBER.getAndIncrement()); - this.daemon = daemon; - } - - private String prefix(String threadName, int factoryId) { - final StringBuilder buffer = new StringBuilder(32); - buffer.append(threadName); - buffer.append('('); - buffer.append(factoryId); - buffer.append('-'); - return buffer.toString(); - } - - @Override - public Thread newThread(Runnable job) { - String newThreadName = createThreadName(); - Thread thread = new Thread(job, newThreadName); - if (daemon) { - thread.setDaemon(daemon); - } - return thread; - } - - private String createThreadName() { - StringBuilder buffer = new StringBuilder(threadPrefix.length() + 8); - buffer.append(threadPrefix); - buffer.append(threadNumber.getAndIncrement()); - buffer.append(')'); - return buffer.toString(); - } - - public static ThreadFactory createThreadFactory(String threadName) { - return createThreadFactory(threadName, false); - } - - public static ThreadFactory createThreadFactory(String threadName, boolean daemon) { - return new PinpointThreadFactory(threadName, daemon); - } -} +package com.nhn.pinpoint.common.util; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class PinpointThreadFactory implements ThreadFactory { + + private final static AtomicInteger FACTORY_NUMBER = new AtomicInteger(0); + private final AtomicInteger threadNumber = new AtomicInteger(0); + + private final String threadPrefix; + private final boolean daemon; + + + public PinpointThreadFactory() { + this("Pinpoint", false); + } + + public PinpointThreadFactory(String threadName) { + this(threadName, false); + } + + public PinpointThreadFactory(String threadName, boolean daemon) { + if (threadName == null) { + throw new NullPointerException("threadName"); + } + this.threadPrefix = prefix(threadName, FACTORY_NUMBER.getAndIncrement()); + this.daemon = daemon; + } + + private String prefix(String threadName, int factoryId) { + final StringBuilder buffer = new StringBuilder(32); + buffer.append(threadName); + buffer.append('('); + buffer.append(factoryId); + buffer.append('-'); + return buffer.toString(); + } + + @Override + public Thread newThread(Runnable job) { + String newThreadName = createThreadName(); + Thread thread = new Thread(job, newThreadName); + if (daemon) { + thread.setDaemon(daemon); + } + return thread; + } + + private String createThreadName() { + StringBuilder buffer = new StringBuilder(threadPrefix.length() + 8); + buffer.append(threadPrefix); + buffer.append(threadNumber.getAndIncrement()); + buffer.append(')'); + return buffer.toString(); + } + + public static ThreadFactory createThreadFactory(String threadName) { + return createThreadFactory(threadName, false); + } + + public static ThreadFactory createThreadFactory(String threadName, boolean daemon) { + return new PinpointThreadFactory(threadName, daemon); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java index ba4d2483c517..f5d47f85aa32 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java @@ -1,35 +1,75 @@ -package com.nhn.pinpoint.common.util; - -import java.io.*; -import java.util.Properties; - -/** - * @author emeroad - */ -public class PropertyUtils { - - public static Properties readProperties(String propertyPath) throws IOException { - Properties properties = new Properties(); - InputStream in = null; - Reader reader = null; - try { - in = new FileInputStream(propertyPath); - reader = new InputStreamReader(in, "UTF-8"); - properties.load(reader); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException ignore) { - } - } - if (reader != null) { - try { - reader.close(); - } catch (IOException ignore) { - } - } - } - return properties; - } -} +package com.nhn.pinpoint.common.util; + +import java.io.*; +import java.util.Properties; + +/** + * @author emeroad + */ +public class PropertyUtils { + public static final String DEFAULT_ENCODING = "UTF-8"; + + public static interface InputStreamFactory { + InputStream openInputStream() throws IOException; + } + + public static Properties loadProperty(final String filePath) throws IOException { + if (filePath == null) { + throw new NullPointerException("filePath must not be null"); + } + final InputStreamFactory inputStreamFactory = new InputStreamFactory() { + @Override + public InputStream openInputStream() throws IOException { + return new FileInputStream(filePath); + } + }; + return loadProperty(new Properties(), inputStreamFactory, DEFAULT_ENCODING); + } + + public static Properties loadPropertyFromClassPath(final String classPath) throws IOException { + if (classPath == null) { + throw new NullPointerException("classPath must not be null"); + } + final InputStreamFactory inputStreamFactory = new InputStreamFactory() { + @Override + public InputStream openInputStream() throws IOException { + return ClassLoaderUtils.getDefaultClassLoader(PropertyUtils.class.getClassLoader()).getResourceAsStream(classPath); + } + }; + return loadProperty(new Properties(), inputStreamFactory, DEFAULT_ENCODING); + } + + + public static Properties loadProperty(Properties properties, InputStreamFactory inputStreamFactory, String encoding) throws IOException { + if (properties == null) { + throw new NullPointerException("properties must not be null"); + } + if (inputStreamFactory == null) { + throw new NullPointerException("inputStreamFactory must not be null"); + } + if (encoding == null) { + throw new NullPointerException("encoding must not be null"); + } + InputStream in = null; + Reader reader = null; + try { + in = inputStreamFactory.openInputStream(); + reader = new InputStreamReader(in, encoding); + properties.load(reader); + } finally { + close(reader); + close(in); + } + return properties; + } + + private static void close(Closeable closeable) { + if (closeable != null) { + try { + closeable.close(); + } catch (IOException ignore) { + } + } + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/RowKeyUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/RowKeyUtils.java index 88a4cba72f3e..15decba0d5ba 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/RowKeyUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/RowKeyUtils.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.common.util; - -import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; -import static com.nhn.pinpoint.common.util.BytesUtils.INT_BYTE_LENGTH; -import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; - -import org.apache.hadoop.hbase.util.Bytes; - -/** - * @author emeroad - */ -public class RowKeyUtils { - - public static byte[] concatFixedByteAndLong(byte[] fixedBytes, int maxFixedLength, long l) { - if (fixedBytes == null) { - throw new NullPointerException("fixedBytes must not null"); - } - if (fixedBytes.length > maxFixedLength) { - throw new IllegalArgumentException("fixedBytes.length too big. length:" + fixedBytes.length); - } - byte[] rowKey = new byte[maxFixedLength + LONG_BYTE_LENGTH]; - Bytes.putBytes(rowKey, 0, fixedBytes, 0, fixedBytes.length); - BytesUtils.writeLong(l, rowKey, maxFixedLength); - return rowKey; - } - - - public static byte[] getMetaInfoRowKey(String agentId, long agentStartTime, int keyCode) { - // TODO 일단 agent의 조회 시간 로직을 따로 만들어야 되므로 그냥0으로 하자. - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - - final byte[] agentBytes = Bytes.toBytes(agentId); - if (agentBytes.length > AGENT_NAME_MAX_LEN) { - throw new IllegalArgumentException("agent.length too big. agent:" + agentId + " length:" + agentId.length()); - } - - final byte[] buffer = new byte[AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH + INT_BYTE_LENGTH]; - Bytes.putBytes(buffer, 0, agentBytes, 0, agentBytes.length); - - long reverseCurrentTimeMillis = TimeUtils.reverseTimeMillis(agentStartTime); - BytesUtils.writeLong(reverseCurrentTimeMillis, buffer, AGENT_NAME_MAX_LEN); - - BytesUtils.writeInt(keyCode, buffer, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); - return buffer; - } - - -} +package com.nhn.pinpoint.common.util; + +import static com.nhn.pinpoint.common.PinpointConstants.AGENT_NAME_MAX_LEN; +import static com.nhn.pinpoint.common.util.BytesUtils.INT_BYTE_LENGTH; +import static com.nhn.pinpoint.common.util.BytesUtils.LONG_BYTE_LENGTH; + +import org.apache.hadoop.hbase.util.Bytes; + +/** + * @author emeroad + */ +public class RowKeyUtils { + + public static byte[] concatFixedByteAndLong(byte[] fixedBytes, int maxFixedLength, long l) { + if (fixedBytes == null) { + throw new NullPointerException("fixedBytes must not null"); + } + if (fixedBytes.length > maxFixedLength) { + throw new IllegalArgumentException("fixedBytes.length too big. length:" + fixedBytes.length); + } + byte[] rowKey = new byte[maxFixedLength + LONG_BYTE_LENGTH]; + Bytes.putBytes(rowKey, 0, fixedBytes, 0, fixedBytes.length); + BytesUtils.writeLong(l, rowKey, maxFixedLength); + return rowKey; + } + + + public static byte[] getMetaInfoRowKey(String agentId, long agentStartTime, int keyCode) { + // TODO 일단 agent의 조회 시간 로직을 따로 만들어야 되므로 그냥0으로 하자. + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + + final byte[] agentBytes = Bytes.toBytes(agentId); + if (agentBytes.length > AGENT_NAME_MAX_LEN) { + throw new IllegalArgumentException("agent.length too big. agent:" + agentId + " length:" + agentId.length()); + } + + final byte[] buffer = new byte[AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH + INT_BYTE_LENGTH]; + Bytes.putBytes(buffer, 0, agentBytes, 0, agentBytes.length); + + long reverseCurrentTimeMillis = TimeUtils.reverseTimeMillis(agentStartTime); + BytesUtils.writeLong(reverseCurrentTimeMillis, buffer, AGENT_NAME_MAX_LEN); + + BytesUtils.writeInt(keyCode, buffer, AGENT_NAME_MAX_LEN + LONG_BYTE_LENGTH); + return buffer; + } + + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/RpcCodeRange.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/RpcCodeRange.java index d5c4ab0f90b9..f52adffd8c04 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/RpcCodeRange.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/RpcCodeRange.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public final class RpcCodeRange { - - public static final short RPC_START = 9000; - public static final short RPC_END = 10000; - - public static boolean isRpcRange(short code) { - return code >= RPC_START && code < RPC_END; - } - -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public final class RpcCodeRange { + + public static final short RPC_START = 9000; + public static final short RPC_END = 10000; + + public static boolean isRpcRange(short code) { + return code >= RPC_START && code < RPC_END; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/SpanEventUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/SpanEventUtils.java index 4f76bd653da3..ef89cfc22d8b 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/SpanEventUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/SpanEventUtils.java @@ -1,20 +1,20 @@ -package com.nhn.pinpoint.common.util; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.thrift.dto.TAnnotation; -import com.nhn.pinpoint.thrift.dto.TSpanEvent; - -import java.util.List; - -/** - * @author emeroad - */ -public class SpanEventUtils { - - public static boolean hasException(TSpanEvent spanEvent) { - if (spanEvent.isSetExceptionInfo()) { - return true; - } - return false; - } -} +package com.nhn.pinpoint.common.util; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.thrift.dto.TAnnotation; +import com.nhn.pinpoint.thrift.dto.TSpanEvent; + +import java.util.List; + +/** + * @author emeroad + */ +public class SpanEventUtils { + + public static boolean hasException(TSpanEvent spanEvent) { + if (spanEvent.isSetExceptionInfo()) { + return true; + } + return false; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/SqlParser.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/SqlParser.java index 41a398d4b9de..bdce3abeae70 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/SqlParser.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/SqlParser.java @@ -1,415 +1,415 @@ -package com.nhn.pinpoint.common.util; - -import java.util.List; - -/** - * @author emeroad - */ -public class SqlParser { - - public static final char SYMBOL_REPLACE = '$'; - public static final char NUMBER_REPLACE = '#'; - - private static final DefaultParsingResult NULL = new DefaultParsingResult("", new StringBuilder()); - private static final int NEXT_TOKEN_NOT_EXIST = -1; - - - public SqlParser() { - } - - public DefaultParsingResult normalizedSql(String sql) { - if (sql == null) { - return NULL; - } - - DefaultParsingResult parsingResult = new DefaultParsingResult(); - final int length = sql.length(); - final StringBuilder normalized = new StringBuilder(length + 16); - boolean change = false; - int replaceIndex = 0; - boolean numberTokenStartEnable = true; - for (int i = 0; i < length; i++) { - final char ch = sql.charAt(i); - switch (ch) { - // COMMENT start check - case '/': - // comment state - int lookAhead1Char = lookAhead1(sql, i); - // multi line comment and oracle hint /*+ */ - if (lookAhead1Char == '*') { - normalized.append("/*"); - i += 2; - for (; i < length; i++) { - char stateCh = sql.charAt(i); - if (stateCh == '*') { - if (lookAhead1(sql, i) == '/') { - normalized.append("*/"); - i++; - break; - } - } - normalized.append(stateCh); - } - break; - // single line comment - } else if (lookAhead1Char == '/') { - normalized.append("//"); - i += 2; - i = readLine(sql, normalized, i); - break; - - } else { - // unary operator - numberTokenStartEnable = true; - normalized.append(ch); - break; - } -// case '#' -// mysql 에서는 #도 한줄 짜리 comment이다. - case '-': - // single line comment state - if (lookAhead1(sql, i) == '-') { - normalized.append("--"); - i += 2; - i = readLine(sql, normalized, i); - break; - } else { - // unary operator - numberTokenStartEnable = true; - normalized.append(ch); - break; - } - - // SYMBOL start check - case '\'': - // empty symbol - if (lookAhead1(sql, i) == '\'') { - normalized.append("''"); - // $로 치환하지 않으므로 output에 파라미터를 넣을필요가 없다 - i += 2; - break; - } else { - change = true; - normalized.append('\''); - i++; - parsingResult.appendOutputSeparator(); - for (; i < length; i++) { - char stateCh = sql.charAt(i); - if (stateCh == '\'') { - // '' 이 연속으로 나왔을 경우는 \' 이므로 그대로 넣는다. - if (lookAhead1(sql, i) == '\'') { - i++; - parsingResult.appendOutputParam("''"); - continue; - } else { - normalized.append(replaceIndex++); - normalized.append(SYMBOL_REPLACE); - normalized.append('\''); -// outputParam.append(','); - break; - } - } - parsingResult.appendSeparatorCheckOutputParam(stateCh); - } - break; - } - - // number start check - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - // http://www.h2database.com/html/grammar.html 추가로 state machine을 더볼것. - if (numberTokenStartEnable) { - change = true; - normalized.append(replaceIndex++); - normalized.append(NUMBER_REPLACE); - // number token start - parsingResult.appendOutputSeparator(); - parsingResult.appendOutputParam(ch); - i++; - tokenEnd: - for (; i < length; i++) { - char stateCh = sql.charAt(i); - switch (stateCh) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '.': - case 'E': - case 'e': - parsingResult.appendOutputParam(stateCh); - break; - default: - // 여기서 처리하지 말고 루프 바깥으로 나가서 다시 token을 봐야 된다. -// outputParam.append(SEPARATOR); - i--; - break tokenEnd; - } - } - break; - } else { - normalized.append(ch); - break; - } - - // 공백 space를 만남 - case ' ': - case '\t': - case '\n': - case '\r': - numberTokenStartEnable = true; - normalized.append(ch); - break; - // http://msdn.microsoft.com/en-us/library/ms174986.aspx 참조. - case '*': - case '+': - case '%': - case '=': - case '<': - case '>': - case '&': - case '|': - case '^': - case '~': - case '!': - numberTokenStartEnable = true; - normalized.append(ch); - break; - - case '(': - case ')': - case ',': - case ';': - numberTokenStartEnable = true; - normalized.append(ch); - break; - - case '.': - case '_': - case '@': // Assignment Operator - case ':': // 오라클쪽의 bind 변수는 :bindvalue로도 가능. - numberTokenStartEnable = false; - normalized.append(ch); - break; - - default: - // 한글이면 ?? - if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') { - numberTokenStartEnable = false; - } else { - numberTokenStartEnable = true; - } - normalized.append(ch); - break; - } - } - if (change) { - parsingResult.setSql(normalized.toString()); - return parsingResult; - } else { - // 수정되지 않았을 경우의 재활용. - // 1. 성능향상을 위해 string을 생성하지 않도록. - // 2. hash code재활용. - parsingResult.setSql(sql); - return parsingResult; - } - } - - private int readLine(String sql, StringBuilder normalized, int index) { - final int length = sql.length(); - for (; index < length; index++) { - char ch = sql.charAt(index); - normalized.append(ch); - if (ch == '\n') { - break; - } - } - return index; - } - - /** - * 미리 다음 문자열 하나를 까본다. - * - * @param sql - * @param index - * @return - */ - private int lookAhead1(String sql, int index) { - index++; - if (index < sql.length()) { - return sql.charAt(index); - } else { - return NEXT_TOKEN_NOT_EXIST; - } - } - - public String combineOutputParams(String sql, List outputParams) { - - final int length = sql.length(); - final StringBuilder normalized = new StringBuilder(length + 16); - for (int i = 0; i < length; i++) { - final char ch = sql.charAt(i); - switch (ch) { - // COMMENT start check - case '/': - // comment state - int lookAhead1Char = lookAhead1(sql, i); - // multi line comment and oracle hint /*+ */ - if (lookAhead1Char == '*') { - normalized.append("/*"); - i += 2; - for (; i < length; i++) { - char stateCh = sql.charAt(i); - if (stateCh == '*') { - if (lookAhead1(sql, i) == '/') { - normalized.append("*/"); - i++; - break; - } - } - normalized.append(stateCh); - } - break; - // single line comment - } else if (lookAhead1Char == '/') { - normalized.append("//"); - i += 2; - i = readLine(sql, normalized, i); - break; - - } else { - // unary operator -// numberTokenStartEnable = true; - normalized.append(ch); - break; - } -// case '#' -// mysql 에서는 #도 한줄 짜리 comment이다. - case '-': - // single line comment state - if (lookAhead1(sql, i) == '-') { - normalized.append("--"); - i += 2; - i = readLine(sql, normalized, i); - break; - } else { - // unary operator -// numberTokenStartEnable = true; - normalized.append(ch); - break; - } - - // number start check - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - // http://www.h2database.com/html/grammar.html 추가로 state machine을 더볼것. - if (lookAhead1(sql, i) == NEXT_TOKEN_NOT_EXIST) { - normalized.append(ch); - break; - } - StringBuilder outputIndex = new StringBuilder(); - outputIndex.append(ch); - // number token start - i++; - tokenEnd: - for (; i < length; i++) { - char stateCh = sql.charAt(i); - switch (stateCh) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (lookAhead1(sql, i) == NEXT_TOKEN_NOT_EXIST) { - outputIndex.append(stateCh); - normalized.append(outputIndex.toString()); - break tokenEnd; - } - outputIndex.append(stateCh); - break; - case NUMBER_REPLACE: - int numberIndex = 0; - try { - numberIndex = Integer.parseInt(outputIndex.toString()); - } catch (NumberFormatException e) { - // 잘못된 파라미터일 경우 그냥 쓰자. - normalized.append(outputIndex.toString()); - normalized.append(NUMBER_REPLACE); - break tokenEnd; - } - try { - String replaceNumber = outputParams.get(numberIndex); - normalized.append(replaceNumber); - } catch (IndexOutOfBoundsException e) { - // 잘못된 파라미터일 경우 그냥 쓰자. - normalized.append(outputIndex.toString()); - normalized.append(NUMBER_REPLACE); - break tokenEnd; - } - break tokenEnd; - - case SYMBOL_REPLACE: - int symbolIndex = 0; - try { - symbolIndex = Integer.parseInt(outputIndex.toString()); - } catch (NumberFormatException e) { - // 잘못된 파라미터일 경우 그냥 쓰자. - normalized.append(outputIndex.toString()); - normalized.append(SYMBOL_REPLACE); - } - try { - String replaceSymbol = outputParams.get(symbolIndex); - normalized.append(replaceSymbol); - } catch (IndexOutOfBoundsException e) { - normalized.append(outputIndex.toString()); - normalized.append(SYMBOL_REPLACE); - } - break tokenEnd; - - default: - // 여기서 처리하지 말고 루프 바깥으로 나가서 다시 token을 봐야 된다. -// outputParam.append(SEPARATOR); - normalized.append(outputIndex.toString()); - i--; - break tokenEnd; - } - } - break; - - default: - normalized.append(ch); - break; - } - } - - return normalized.toString(); - } - -} +package com.nhn.pinpoint.common.util; + +import java.util.List; + +/** + * @author emeroad + */ +public class SqlParser { + + public static final char SYMBOL_REPLACE = '$'; + public static final char NUMBER_REPLACE = '#'; + + private static final DefaultParsingResult NULL = new DefaultParsingResult("", new StringBuilder()); + private static final int NEXT_TOKEN_NOT_EXIST = -1; + + + public SqlParser() { + } + + public DefaultParsingResult normalizedSql(String sql) { + if (sql == null) { + return NULL; + } + + DefaultParsingResult parsingResult = new DefaultParsingResult(); + final int length = sql.length(); + final StringBuilder normalized = new StringBuilder(length + 16); + boolean change = false; + int replaceIndex = 0; + boolean numberTokenStartEnable = true; + for (int i = 0; i < length; i++) { + final char ch = sql.charAt(i); + switch (ch) { + // COMMENT start check + case '/': + // comment state + int lookAhead1Char = lookAhead1(sql, i); + // multi line comment and oracle hint /*+ */ + if (lookAhead1Char == '*') { + normalized.append("/*"); + i += 2; + for (; i < length; i++) { + char stateCh = sql.charAt(i); + if (stateCh == '*') { + if (lookAhead1(sql, i) == '/') { + normalized.append("*/"); + i++; + break; + } + } + normalized.append(stateCh); + } + break; + // single line comment + } else if (lookAhead1Char == '/') { + normalized.append("//"); + i += 2; + i = readLine(sql, normalized, i); + break; + + } else { + // unary operator + numberTokenStartEnable = true; + normalized.append(ch); + break; + } +// case '#' +// mysql 에서는 #도 한줄 짜리 comment이다. + case '-': + // single line comment state + if (lookAhead1(sql, i) == '-') { + normalized.append("--"); + i += 2; + i = readLine(sql, normalized, i); + break; + } else { + // unary operator + numberTokenStartEnable = true; + normalized.append(ch); + break; + } + + // SYMBOL start check + case '\'': + // empty symbol + if (lookAhead1(sql, i) == '\'') { + normalized.append("''"); + // $로 치환하지 않으므로 output에 파라미터를 넣을필요가 없다 + i += 2; + break; + } else { + change = true; + normalized.append('\''); + i++; + parsingResult.appendOutputSeparator(); + for (; i < length; i++) { + char stateCh = sql.charAt(i); + if (stateCh == '\'') { + // '' 이 연속으로 나왔을 경우는 \' 이므로 그대로 넣는다. + if (lookAhead1(sql, i) == '\'') { + i++; + parsingResult.appendOutputParam("''"); + continue; + } else { + normalized.append(replaceIndex++); + normalized.append(SYMBOL_REPLACE); + normalized.append('\''); +// outputParam.append(','); + break; + } + } + parsingResult.appendSeparatorCheckOutputParam(stateCh); + } + break; + } + + // number start check + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // http://www.h2database.com/html/grammar.html 추가로 state machine을 더볼것. + if (numberTokenStartEnable) { + change = true; + normalized.append(replaceIndex++); + normalized.append(NUMBER_REPLACE); + // number token start + parsingResult.appendOutputSeparator(); + parsingResult.appendOutputParam(ch); + i++; + tokenEnd: + for (; i < length; i++) { + char stateCh = sql.charAt(i); + switch (stateCh) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + case 'E': + case 'e': + parsingResult.appendOutputParam(stateCh); + break; + default: + // 여기서 처리하지 말고 루프 바깥으로 나가서 다시 token을 봐야 된다. +// outputParam.append(SEPARATOR); + i--; + break tokenEnd; + } + } + break; + } else { + normalized.append(ch); + break; + } + + // 공백 space를 만남 + case ' ': + case '\t': + case '\n': + case '\r': + numberTokenStartEnable = true; + normalized.append(ch); + break; + // http://msdn.microsoft.com/en-us/library/ms174986.aspx 참조. + case '*': + case '+': + case '%': + case '=': + case '<': + case '>': + case '&': + case '|': + case '^': + case '~': + case '!': + numberTokenStartEnable = true; + normalized.append(ch); + break; + + case '(': + case ')': + case ',': + case ';': + numberTokenStartEnable = true; + normalized.append(ch); + break; + + case '.': + case '_': + case '@': // Assignment Operator + case ':': // 오라클쪽의 bind 변수는 :bindvalue로도 가능. + numberTokenStartEnable = false; + normalized.append(ch); + break; + + default: + // 한글이면 ?? + if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') { + numberTokenStartEnable = false; + } else { + numberTokenStartEnable = true; + } + normalized.append(ch); + break; + } + } + if (change) { + parsingResult.setSql(normalized.toString()); + return parsingResult; + } else { + // 수정되지 않았을 경우의 재활용. + // 1. 성능향상을 위해 string을 생성하지 않도록. + // 2. hash code재활용. + parsingResult.setSql(sql); + return parsingResult; + } + } + + private int readLine(String sql, StringBuilder normalized, int index) { + final int length = sql.length(); + for (; index < length; index++) { + char ch = sql.charAt(index); + normalized.append(ch); + if (ch == '\n') { + break; + } + } + return index; + } + + /** + * 미리 다음 문자열 하나를 까본다. + * + * @param sql + * @param index + * @return + */ + private int lookAhead1(String sql, int index) { + index++; + if (index < sql.length()) { + return sql.charAt(index); + } else { + return NEXT_TOKEN_NOT_EXIST; + } + } + + public String combineOutputParams(String sql, List outputParams) { + + final int length = sql.length(); + final StringBuilder normalized = new StringBuilder(length + 16); + for (int i = 0; i < length; i++) { + final char ch = sql.charAt(i); + switch (ch) { + // COMMENT start check + case '/': + // comment state + int lookAhead1Char = lookAhead1(sql, i); + // multi line comment and oracle hint /*+ */ + if (lookAhead1Char == '*') { + normalized.append("/*"); + i += 2; + for (; i < length; i++) { + char stateCh = sql.charAt(i); + if (stateCh == '*') { + if (lookAhead1(sql, i) == '/') { + normalized.append("*/"); + i++; + break; + } + } + normalized.append(stateCh); + } + break; + // single line comment + } else if (lookAhead1Char == '/') { + normalized.append("//"); + i += 2; + i = readLine(sql, normalized, i); + break; + + } else { + // unary operator +// numberTokenStartEnable = true; + normalized.append(ch); + break; + } +// case '#' +// mysql 에서는 #도 한줄 짜리 comment이다. + case '-': + // single line comment state + if (lookAhead1(sql, i) == '-') { + normalized.append("--"); + i += 2; + i = readLine(sql, normalized, i); + break; + } else { + // unary operator +// numberTokenStartEnable = true; + normalized.append(ch); + break; + } + + // number start check + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // http://www.h2database.com/html/grammar.html 추가로 state machine을 더볼것. + if (lookAhead1(sql, i) == NEXT_TOKEN_NOT_EXIST) { + normalized.append(ch); + break; + } + StringBuilder outputIndex = new StringBuilder(); + outputIndex.append(ch); + // number token start + i++; + tokenEnd: + for (; i < length; i++) { + char stateCh = sql.charAt(i); + switch (stateCh) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (lookAhead1(sql, i) == NEXT_TOKEN_NOT_EXIST) { + outputIndex.append(stateCh); + normalized.append(outputIndex.toString()); + break tokenEnd; + } + outputIndex.append(stateCh); + break; + case NUMBER_REPLACE: + int numberIndex = 0; + try { + numberIndex = Integer.parseInt(outputIndex.toString()); + } catch (NumberFormatException e) { + // 잘못된 파라미터일 경우 그냥 쓰자. + normalized.append(outputIndex.toString()); + normalized.append(NUMBER_REPLACE); + break tokenEnd; + } + try { + String replaceNumber = outputParams.get(numberIndex); + normalized.append(replaceNumber); + } catch (IndexOutOfBoundsException e) { + // 잘못된 파라미터일 경우 그냥 쓰자. + normalized.append(outputIndex.toString()); + normalized.append(NUMBER_REPLACE); + break tokenEnd; + } + break tokenEnd; + + case SYMBOL_REPLACE: + int symbolIndex = 0; + try { + symbolIndex = Integer.parseInt(outputIndex.toString()); + } catch (NumberFormatException e) { + // 잘못된 파라미터일 경우 그냥 쓰자. + normalized.append(outputIndex.toString()); + normalized.append(SYMBOL_REPLACE); + } + try { + String replaceSymbol = outputParams.get(symbolIndex); + normalized.append(replaceSymbol); + } catch (IndexOutOfBoundsException e) { + normalized.append(outputIndex.toString()); + normalized.append(SYMBOL_REPLACE); + } + break tokenEnd; + + default: + // 여기서 처리하지 말고 루프 바깥으로 나가서 다시 token을 봐야 된다. +// outputParam.append(SEPARATOR); + normalized.append(outputIndex.toString()); + i--; + break tokenEnd; + } + } + break; + + default: + normalized.append(ch); + break; + } + } + + return normalized.toString(); + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/StopWatch.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/StopWatch.java index 81c97048cb2c..a6d4796cde6d 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/StopWatch.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/StopWatch.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.common.util; - -/** - * 단순한 stopwatch - * @author emeroad - */ -public class StopWatch { - private long start; - - public void start() { - this.start = System.currentTimeMillis(); - } - - public long stop() { - return System.currentTimeMillis() - this.start; - } - -} +package com.nhn.pinpoint.common.util; + +/** + * 단순한 stopwatch + * @author emeroad + */ +public class StopWatch { + private long start; + + public void start() { + this.start = System.currentTimeMillis(); + } + + public long stop() { + return System.currentTimeMillis() - this.start; + } + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParser.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParser.java index 1a379eee04e9..da994c3f0be3 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParser.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParser.java @@ -1,71 +1,71 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public class StringTraceHeaderParser { - - // request.addHeader(Header.HTTP_TRACE_ID.toString(), nextId.getId().toString()); -// request.addHeader(Header.HTTP_SPAN_ID.toString(), Long.toString(nextId.getSpanId())); -// request.addHeader(Header.HTTP_PARENT_SPAN_ID.toString(), Long.toString(nextId.getParentSpanId())); -// request.addHeader(Header.HTTP_SAMPLED.toString(), String.valueOf(nextId.isSampled())); -// request.addHeader(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); - public static final char DELIMITER_STRING = ':'; - public static final int ID_INDEX = 36; - - public String createHeader(String uuid, int spanId, int parentSpanId, int sampling, short flag) { - StringBuilder sb = new StringBuilder(128); - sb.append(uuid); - sb.append(DELIMITER_STRING); - sb.append(spanId); - sb.append(DELIMITER_STRING); - sb.append(parentSpanId); - sb.append(DELIMITER_STRING); - sb.append(sampling); - sb.append(DELIMITER_STRING); - sb.append(flag); - return sb.toString(); - } - - public TraceHeader parseHeader(String traceHeader) { - if (traceHeader == null) { - return null; - } - - char c = traceHeader.charAt(ID_INDEX); - if (c != DELIMITER_STRING) { - return null; - } - String id = traceHeader.substring(0, ID_INDEX); - - int spanIdStartIndex = ID_INDEX + 1; - int spanIdEndIndex = traceHeader.indexOf(DELIMITER_STRING, spanIdStartIndex); - String spanId = traceHeader.substring(spanIdStartIndex, spanIdEndIndex); - - int parentSpanIdStartIndex = spanIdEndIndex + 1; - int parentSpanIdEndIndex = traceHeader.indexOf(DELIMITER_STRING, parentSpanIdStartIndex); - String parentSpanId = traceHeader.substring(parentSpanIdStartIndex, parentSpanIdEndIndex); - - int samplingStartIndex = parentSpanIdEndIndex + 1; - int samplingEndIndex = traceHeader.indexOf(DELIMITER_STRING, samplingStartIndex); - if (samplingEndIndex == -1) { - return new TraceHeader(id, spanId, parentSpanId, "", ""); - } - String sampling = traceHeader.substring(samplingStartIndex, samplingEndIndex); - - - int flagStartIndex = samplingEndIndex + 1; - if (flagStartIndex == -1) { - return new TraceHeader(id, spanId, parentSpanId, sampling, ""); - } - int flagEndIndex = traceHeader.indexOf(DELIMITER_STRING, flagStartIndex); - if (flagEndIndex == -1) { - String flag = traceHeader.substring(flagStartIndex); - return new TraceHeader(id, spanId, parentSpanId, sampling, flag); - } - String flag = traceHeader.substring(flagStartIndex, flagEndIndex); - return new TraceHeader(id, spanId, parentSpanId, sampling, flag); - } - - -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public class StringTraceHeaderParser { + + // request.addHeader(Header.HTTP_TRACE_ID.toString(), nextId.getId().toString()); +// request.addHeader(Header.HTTP_SPAN_ID.toString(), Long.toString(nextId.getSpanId())); +// request.addHeader(Header.HTTP_PARENT_SPAN_ID.toString(), Long.toString(nextId.getParentSpanId())); +// request.addHeader(Header.HTTP_SAMPLED.toString(), String.valueOf(nextId.isSampled())); +// request.addHeader(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); + public static final char DELIMITER_STRING = ':'; + public static final int ID_INDEX = 36; + + public String createHeader(String uuid, int spanId, int parentSpanId, int sampling, short flag) { + StringBuilder sb = new StringBuilder(128); + sb.append(uuid); + sb.append(DELIMITER_STRING); + sb.append(spanId); + sb.append(DELIMITER_STRING); + sb.append(parentSpanId); + sb.append(DELIMITER_STRING); + sb.append(sampling); + sb.append(DELIMITER_STRING); + sb.append(flag); + return sb.toString(); + } + + public TraceHeader parseHeader(String traceHeader) { + if (traceHeader == null) { + return null; + } + + char c = traceHeader.charAt(ID_INDEX); + if (c != DELIMITER_STRING) { + return null; + } + String id = traceHeader.substring(0, ID_INDEX); + + int spanIdStartIndex = ID_INDEX + 1; + int spanIdEndIndex = traceHeader.indexOf(DELIMITER_STRING, spanIdStartIndex); + String spanId = traceHeader.substring(spanIdStartIndex, spanIdEndIndex); + + int parentSpanIdStartIndex = spanIdEndIndex + 1; + int parentSpanIdEndIndex = traceHeader.indexOf(DELIMITER_STRING, parentSpanIdStartIndex); + String parentSpanId = traceHeader.substring(parentSpanIdStartIndex, parentSpanIdEndIndex); + + int samplingStartIndex = parentSpanIdEndIndex + 1; + int samplingEndIndex = traceHeader.indexOf(DELIMITER_STRING, samplingStartIndex); + if (samplingEndIndex == -1) { + return new TraceHeader(id, spanId, parentSpanId, "", ""); + } + String sampling = traceHeader.substring(samplingStartIndex, samplingEndIndex); + + + int flagStartIndex = samplingEndIndex + 1; + if (flagStartIndex == -1) { + return new TraceHeader(id, spanId, parentSpanId, sampling, ""); + } + int flagEndIndex = traceHeader.indexOf(DELIMITER_STRING, flagStartIndex); + if (flagEndIndex == -1) { + String flag = traceHeader.substring(flagStartIndex); + return new TraceHeader(id, spanId, parentSpanId, sampling, flag); + } + String flag = traceHeader.substring(flagStartIndex, flagEndIndex); + return new TraceHeader(id, spanId, parentSpanId, sampling, flag); + } + + +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/SystemPropertyKey.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/SystemPropertyKey.java similarity index 90% rename from commons/src/main/java/com/navercorp/pinpoint/common/SystemPropertyKey.java rename to commons/src/main/java/com/navercorp/pinpoint/common/util/SystemPropertyKey.java index 9c07db3efdd0..3b8a496778f6 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/SystemPropertyKey.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/SystemPropertyKey.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.common; - -/** - * @author hyungil.jeong - */ -public enum SystemPropertyKey { - - JAVA_VERSION("java.version"), - JAVA_RUNTIME_VERSION("java.runtime.version"), - JAVA_RUNTIME_NAME("java.runtime.name"), - JAVA_SPECIFICATION_VERSION("java.specification.version"), - JAVA_CLASS_VERSION("java.class.version"), - JAVA_VM_NAME("java.vm.name"), - JAVA_VM_VERSION("java.vm.version"), - JAVA_VM_INFO("java.vm.info"), - JAVA_VM_SPECIFICATION_VERSION("java.vm.specification.version"); - - private final String key; - - private SystemPropertyKey(String key) { - this.key = key; - } - - public String getKey() { - return this.key; - } -} +package com.nhn.pinpoint.common.util; + +/** + * @author hyungil.jeong + */ +public enum SystemPropertyKey { + + JAVA_VERSION("java.version"), + JAVA_RUNTIME_VERSION("java.runtime.version"), + JAVA_RUNTIME_NAME("java.runtime.name"), + JAVA_SPECIFICATION_VERSION("java.specification.version"), + JAVA_CLASS_VERSION("java.class.version"), + JAVA_VM_NAME("java.vm.name"), + JAVA_VM_VERSION("java.vm.version"), + JAVA_VM_INFO("java.vm.info"), + JAVA_VM_SPECIFICATION_VERSION("java.vm.specification.version"); + + private final String key; + + private SystemPropertyKey(String key) { + this.key = key; + } + + public String getKey() { + return this.key; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/TimeUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/TimeUtils.java index fa357ffe81be..4fab72c9293d 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/TimeUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/TimeUtils.java @@ -1,19 +1,19 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public final class TimeUtils { - - public static long reverseTimeMillis(long currentTimeMillis) { - return Long.MAX_VALUE - currentTimeMillis; - } - - public static long reverseCurrentTimeMillis() { - return reverseTimeMillis(System.currentTimeMillis()); - } - - public static long recoveryTimeMillis(long reverseCurrentTimeMillis) { - return Long.MAX_VALUE - reverseCurrentTimeMillis; - } -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public final class TimeUtils { + + public static long reverseTimeMillis(long currentTimeMillis) { + return Long.MAX_VALUE - currentTimeMillis; + } + + public static long reverseCurrentTimeMillis() { + return reverseTimeMillis(System.currentTimeMillis()); + } + + public static long recoveryTimeMillis(long reverseCurrentTimeMillis) { + return Long.MAX_VALUE - reverseCurrentTimeMillis; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/TraceHeader.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/TraceHeader.java index 7674a5486c74..58aec2e98327 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/TraceHeader.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/TraceHeader.java @@ -1,74 +1,74 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public class TraceHeader { - private String id; - private String spanId; - private String parentSpanId; - private String sampling; - private String flag; - - public TraceHeader() { - } - - public TraceHeader(String id, String spanId, String parentSpanId, String sampling, String flag) { - this.id = id; - this.spanId = spanId; - this.parentSpanId = parentSpanId; - this.sampling = sampling; - this.flag = flag; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getSpanId() { - return spanId; - } - - public void setSpanId(String spanId) { - this.spanId = spanId; - } - - public String getParentSpanId() { - return parentSpanId; - } - - public void setParentSpanId(String parentSpanId) { - this.parentSpanId = parentSpanId; - } - - public String getSampling() { - return sampling; - } - - public void setSampling(String sampling) { - this.sampling = sampling; - } - - public String getFlag() { - return flag; - } - - public void setFlag(String flag) { - this.flag = flag; - } - - @Override - public String toString() { - return "TraceHeader{" + - "id='" + id + '\'' + - ", spanId='" + spanId + '\'' + - ", parentSpanId='" + parentSpanId + '\'' + - ", sampling='" + sampling + '\'' + - ", flag='" + flag + '\'' + - '}'; - } -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public class TraceHeader { + private String id; + private String spanId; + private String parentSpanId; + private String sampling; + private String flag; + + public TraceHeader() { + } + + public TraceHeader(String id, String spanId, String parentSpanId, String sampling, String flag) { + this.id = id; + this.spanId = spanId; + this.parentSpanId = parentSpanId; + this.sampling = sampling; + this.flag = flag; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSpanId() { + return spanId; + } + + public void setSpanId(String spanId) { + this.spanId = spanId; + } + + public String getParentSpanId() { + return parentSpanId; + } + + public void setParentSpanId(String parentSpanId) { + this.parentSpanId = parentSpanId; + } + + public String getSampling() { + return sampling; + } + + public void setSampling(String sampling) { + this.sampling = sampling; + } + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + @Override + public String toString() { + return "TraceHeader{" + + "id='" + id + '\'' + + ", spanId='" + spanId + '\'' + + ", parentSpanId='" + parentSpanId + '\'' + + ", sampling='" + sampling + '\'' + + ", flag='" + flag + '\'' + + '}'; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionId.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionId.java index 9484e4b0b7dc..1d395c46f2f6 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionId.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionId.java @@ -1,70 +1,70 @@ -package com.nhn.pinpoint.common.util; - -/** - * @author emeroad - */ -public class TransactionId { - - protected String agentId; - protected long agentStartTime; - protected long transactionSequence; - - public TransactionId(String agentId, long agentStartTime, long transactionSequence) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - this.agentId = agentId; - this.agentStartTime = agentStartTime; - this.transactionSequence = transactionSequence; - } - - public TransactionId(long agentStartTime, long transactionSequence) { - this.agentStartTime = agentStartTime; - this.transactionSequence = transactionSequence; - } - - public String getAgentId() { - return agentId; - } - - public long getAgentStartTime() { - return agentStartTime; - } - - public long getTransactionSequence() { - return transactionSequence; - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TransactionId that = (TransactionId) o; - - if (agentStartTime != that.agentStartTime) return false; - if (transactionSequence != that.transactionSequence) return false; - if (!agentId.equals(that.agentId)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = agentId.hashCode(); - result = 31 * result + (int) (agentStartTime ^ (agentStartTime >>> 32)); - result = 31 * result + (int) (transactionSequence ^ (transactionSequence >>> 32)); - return result; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("TransactionId{"); - sb.append("agentId='").append(agentId).append('\''); - sb.append(", agentStartTime=").append(agentStartTime); - sb.append(", transactionSequence=").append(transactionSequence); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.common.util; + +/** + * @author emeroad + */ +public class TransactionId { + + protected String agentId; + protected long agentStartTime; + protected long transactionSequence; + + public TransactionId(String agentId, long agentStartTime, long transactionSequence) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + this.agentId = agentId; + this.agentStartTime = agentStartTime; + this.transactionSequence = transactionSequence; + } + + public TransactionId(long agentStartTime, long transactionSequence) { + this.agentStartTime = agentStartTime; + this.transactionSequence = transactionSequence; + } + + public String getAgentId() { + return agentId; + } + + public long getAgentStartTime() { + return agentStartTime; + } + + public long getTransactionSequence() { + return transactionSequence; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TransactionId that = (TransactionId) o; + + if (agentStartTime != that.agentStartTime) return false; + if (transactionSequence != that.transactionSequence) return false; + if (!agentId.equals(that.agentId)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = agentId.hashCode(); + result = 31 * result + (int) (agentStartTime ^ (agentStartTime >>> 32)); + result = 31 * result + (int) (transactionSequence ^ (transactionSequence >>> 32)); + return result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("TransactionId{"); + sb.append("agentId='").append(agentId).append('\''); + sb.append(", agentStartTime=").append(agentStartTime); + sb.append(", transactionSequence=").append(transactionSequence); + sb.append('}'); + return sb.toString(); + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionIdUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionIdUtils.java index 076a6bb99215..6c82ed15fca0 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionIdUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/TransactionIdUtils.java @@ -1,92 +1,92 @@ -package com.nhn.pinpoint.common.util; - -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.FixedBuffer; - -/** - * @author emeroad - */ -public final class TransactionIdUtils { - // html 에서 표시되는 값이라. html 상에서 해석이 다르게 되는 문자열은 사용하면 안됨. - public static final String TRANSACTION_ID_DELIMITER = "^"; - public static final byte VERSION = 0; - - public static String formatString(String agentId, long agentStartTime, long transactionSequence) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - StringBuilder sb = new StringBuilder(64); - sb.append(agentId); - sb.append(TRANSACTION_ID_DELIMITER); - sb.append(agentStartTime); - sb.append(TRANSACTION_ID_DELIMITER); - sb.append(transactionSequence); - return sb.toString(); - } - - public static byte[] formatBytes(String agentId, long agentStartTime, long transactionSequence) { - // agentId는 null이 될수 있음. - // vesion + prefixed size + string + long + long - final Buffer buffer = new AutomaticBuffer(1 + 5 + 24 + 10 + 10); - buffer.put(VERSION); - buffer.putPrefixedString(agentId); - buffer.putVar(agentStartTime); - buffer.putVar(transactionSequence); - return buffer.getBuffer(); - } - - public static TransactionId parseTransactionId(final byte[] transactionId) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - final Buffer buffer = new FixedBuffer(transactionId); - final byte version = buffer.readByte(); - if (version != VERSION) { - throw new IllegalArgumentException("invalid Version"); - } - - final String agentId = buffer.readPrefixedString(); - final long agentStartTime = buffer.readVarLong(); - final long transactionSequence = buffer.readVarLong(); - if (agentId == null) { - return new TransactionId(agentStartTime, transactionSequence); - } else { - return new TransactionId(agentId, agentStartTime,transactionSequence); - } - } - - public static TransactionId parseTransactionId(final String transactionId) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - - final int agentIdIndex = transactionId.indexOf(TRANSACTION_ID_DELIMITER); - if (agentIdIndex == -1) { - throw new IllegalArgumentException("agentIndex not found:" + transactionId); - } - final String agentId = transactionId.substring(0, agentIdIndex); - - final int agentStartTimeIndex = transactionId.indexOf(TRANSACTION_ID_DELIMITER, agentIdIndex + 1); - if (agentStartTimeIndex == -1) { - throw new IllegalArgumentException("agentStartTimeIndex not found:" + transactionId); - } - final long agentStartTime = parseLong(transactionId.substring(agentIdIndex + 1, agentStartTimeIndex)); - - int transactionSequenceIndex = transactionId.indexOf(TRANSACTION_ID_DELIMITER, agentStartTimeIndex + 1); - if (transactionSequenceIndex == -1) { - // 이거는 없을수 있음. transactionSequence 다음에 델리미터가 일단 없는게 기본값임. 향후 추가 아이디 스펙이 확장가능하므로 보완한다. - transactionSequenceIndex = transactionId.length(); - } - final long transactionSequence = parseLong(transactionId.substring(agentStartTimeIndex + 1, transactionSequenceIndex)); - return new TransactionId(agentId, agentStartTime, transactionSequence); - } - - private static long parseLong(String longString) { - try { - return Long.parseLong(longString); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("parseError. " + longString); - } - } -} +package com.nhn.pinpoint.common.util; + +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.FixedBuffer; + +/** + * @author emeroad + */ +public final class TransactionIdUtils { + // html 에서 표시되는 값이라. html 상에서 해석이 다르게 되는 문자열은 사용하면 안됨. + public static final String TRANSACTION_ID_DELIMITER = "^"; + public static final byte VERSION = 0; + + public static String formatString(String agentId, long agentStartTime, long transactionSequence) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + StringBuilder sb = new StringBuilder(64); + sb.append(agentId); + sb.append(TRANSACTION_ID_DELIMITER); + sb.append(agentStartTime); + sb.append(TRANSACTION_ID_DELIMITER); + sb.append(transactionSequence); + return sb.toString(); + } + + public static byte[] formatBytes(String agentId, long agentStartTime, long transactionSequence) { + // agentId는 null이 될수 있음. + // vesion + prefixed size + string + long + long + final Buffer buffer = new AutomaticBuffer(1 + 5 + 24 + 10 + 10); + buffer.put(VERSION); + buffer.putPrefixedString(agentId); + buffer.putVar(agentStartTime); + buffer.putVar(transactionSequence); + return buffer.getBuffer(); + } + + public static TransactionId parseTransactionId(final byte[] transactionId) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + final Buffer buffer = new FixedBuffer(transactionId); + final byte version = buffer.readByte(); + if (version != VERSION) { + throw new IllegalArgumentException("invalid Version"); + } + + final String agentId = buffer.readPrefixedString(); + final long agentStartTime = buffer.readVarLong(); + final long transactionSequence = buffer.readVarLong(); + if (agentId == null) { + return new TransactionId(agentStartTime, transactionSequence); + } else { + return new TransactionId(agentId, agentStartTime,transactionSequence); + } + } + + public static TransactionId parseTransactionId(final String transactionId) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + + final int agentIdIndex = transactionId.indexOf(TRANSACTION_ID_DELIMITER); + if (agentIdIndex == -1) { + throw new IllegalArgumentException("agentIndex not found:" + transactionId); + } + final String agentId = transactionId.substring(0, agentIdIndex); + + final int agentStartTimeIndex = transactionId.indexOf(TRANSACTION_ID_DELIMITER, agentIdIndex + 1); + if (agentStartTimeIndex == -1) { + throw new IllegalArgumentException("agentStartTimeIndex not found:" + transactionId); + } + final long agentStartTime = parseLong(transactionId.substring(agentIdIndex + 1, agentStartTimeIndex)); + + int transactionSequenceIndex = transactionId.indexOf(TRANSACTION_ID_DELIMITER, agentStartTimeIndex + 1); + if (transactionSequenceIndex == -1) { + // 이거는 없을수 있음. transactionSequence 다음에 델리미터가 일단 없는게 기본값임. 향후 추가 아이디 스펙이 확장가능하므로 보완한다. + transactionSequenceIndex = transactionId.length(); + } + final long transactionSequence = parseLong(transactionId.substring(agentStartTimeIndex + 1, transactionSequenceIndex)); + return new TransactionId(agentId, agentStartTime, transactionSequence); + } + + private static long parseLong(String longString) { + try { + return Long.parseLong(longString); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("parseError. " + longString); + } + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/IntHashMap.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/apache/IntHashMap.java similarity index 96% rename from commons/src/main/java/com/navercorp/pinpoint/common/IntHashMap.java rename to commons/src/main/java/com/navercorp/pinpoint/common/util/apache/IntHashMap.java index d16a12f2b1e8..2e13ac5c2e86 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/IntHashMap.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/apache/IntHashMap.java @@ -1,256 +1,256 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -/* - * Note: originally released under the GNU LGPL v2.1, - * but rereleased by the original author under the ASF license (above). - */ -package com.nhn.pinpoint.common; - -/** - *

A hash map that uses primitive ints for the key rather than objects.

- * - *

Note that this class is for internal optimization purposes only, and may - * not be supported in future releases of Apache Commons Lang. Utilities of - * this sort may be included in future releases of Apache Commons Collections.

- * - * @author Apache Software Foundation - * @author Justin Couch - * @author Alex Chaffee (alex@apache.org) - * @since 2.0 - * @version $Revision$ - * @see java.util.HashMap - */ -// 내부 튜닝용 가져다 사용하지 말것 -public class IntHashMap { - - /** - * The hash table data. - */ - private transient Entry table[]; - - /** - * The total number of entries in the hash table. - */ - private transient int count; - - /** - * The table is rehashed when its size exceeds this threshold. (The - * value of this field is (int)(capacity * loadFactor).) - * - * @serial - */ - private int threshold; - - /** - * The load factor for the hashtable. - * - * @serial - */ - private final float loadFactor; - - /** - *

Innerclass that acts as a datastructure to create a new entry in the - * table.

- */ - private static class Entry { - final int hash; - final int key; // TODO not read; seems to be always same as hash - T value; - Entry next; - - /** - *

Create a new entry with the given values.

- * - * @param hash The code used to hash the object with - * @param key The key used to enter this in the table - * @param value The value for this key - * @param next A reference to the next entry in the table - */ - protected Entry(int hash, int key, T value, Entry next) { - this.hash = hash; - this.key = key; - this.value = value; - this.next = next; - } - } - - /** - *

Constructs a new, empty hashtable with a default capacity and load - * factor, which is 20 and 0.75 respectively.

- */ - public IntHashMap() { - this(20, 0.75f); - } - - /** - *

Constructs a new, empty hashtable with the specified initial capacity - * and default load factor, which is 0.75.

- * - * @param initialCapacity the initial capacity of the hashtable. - * @throws IllegalArgumentException if the initial capacity is less - * than zero. - */ - public IntHashMap(int initialCapacity) { - this(initialCapacity, 0.75f); - } - - /** - *

Constructs a new, empty hashtable with the specified initial - * capacity and the specified load factor.

- * - * @param initialCapacity the initial capacity of the hashtable. - * @param loadFactor the load factor of the hashtable. - * @throws IllegalArgumentException if the initial capacity is less - * than zero, or if the load factor is nonpositive. - */ - public IntHashMap(int initialCapacity, float loadFactor) { - super(); - if (initialCapacity < 0) { - throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); - } - if (loadFactor <= 0) { - throw new IllegalArgumentException("Illegal Load: " + loadFactor); - } - if (initialCapacity == 0) { - initialCapacity = 1; - } - - this.loadFactor = loadFactor; - table = new Entry[initialCapacity]; - threshold = (int) (initialCapacity * loadFactor); - } - - /** - *

Returns the number of keys in this hashtable.

- * - * @return the number of keys in this hashtable. - */ - public int size() { - return count; - } - - /** - *

Tests if this hashtable maps no keys to values.

- * - * @return true if this hashtable maps no keys to values; - * false otherwise. - */ - public boolean isEmpty() { - return count == 0; - } - - - /** - *

Returns the value to which the specified key is mapped in this map.

- * - * @param key a key in the hashtable. - * @return the value to which the key is mapped in this hashtable; - * null if the key is not mapped to any value in - * this hashtable. - * @see #put(int, T) - */ - public T get(int key) { - Entry tab[] = table; - int hash = key; - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry e = tab[index]; e != null; e = e.next) { - if (e.hash == hash) { - return e.value; - } - } - return null; - } - - /** - *

Increases the capacity of and internally reorganizes this - * hashtable, in order to accommodate and access its entries more - * efficiently.

- * - *

This method is called automatically when the number of keys - * in the hashtable exceeds this hashtable's capacity and load - * factor.

- */ - protected void rehash() { - int oldCapacity = table.length; - Entry oldMap[] = table; - - int newCapacity = oldCapacity * 2 + 1; - Entry newMap[] = new Entry[newCapacity]; - - threshold = (int) (newCapacity * loadFactor); - table = newMap; - - for (int i = oldCapacity; i-- > 0;) { - for (Entry old = oldMap[i]; old != null;) { - Entry e = old; - old = old.next; - - int index = (e.hash & 0x7FFFFFFF) % newCapacity; - e.next = newMap[index]; - newMap[index] = e; - } - } - } - - /** - *

Maps the specified key to the specified - * value in this hashtable. The key cannot be - * null.

- * - *

The value can be retrieved by calling the get method - * with a key that is equal to the original key.

- * - * @param key the hashtable key. - * @param value the value. - * @return the previous value of the specified key in this hashtable, - * or null if it did not have one. - * @throws NullPointerException if the key is null. - * @see #get(int) - */ - public T put(int key, T value) { - // Makes sure the key is not already in the hashtable. - Entry tab[] = table; - int hash = key; - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry e = tab[index]; e != null; e = e.next) { - if (e.hash == hash) { - T old = e.value; - e.value = value; - return old; - } - } - - if (count >= threshold) { - // Rehash the table if the threshold is exceeded - rehash(); - - tab = table; - index = (hash & 0x7FFFFFFF) % tab.length; - } - - // Creates the new entry. - Entry e = new Entry(hash, key, value, tab[index]); - tab[index] = e; - count++; - return null; - } - - - -} - +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +/* + * Note: originally released under the GNU LGPL v2.1, + * but rereleased by the original author under the ASF license (above). + */ +package com.nhn.pinpoint.common.util.apache; + +/** + *

A hash map that uses primitive ints for the key rather than objects.

+ * + *

Note that this class is for internal optimization purposes only, and may + * not be supported in future releases of Apache Commons Lang. Utilities of + * this sort may be included in future releases of Apache Commons Collections.

+ * + * @author Apache Software Foundation + * @author Justin Couch + * @author Alex Chaffee (alex@apache.org) + * @since 2.0 + * @version $Revision$ + * @see java.util.HashMap + */ +// 내부 튜닝용 가져다 사용하지 말것 +public class IntHashMap { + + /** + * The hash table data. + */ + private transient Entry table[]; + + /** + * The total number of entries in the hash table. + */ + private transient int count; + + /** + * The table is rehashed when its size exceeds this threshold. (The + * value of this field is (int)(capacity * loadFactor).) + * + * @serial + */ + private int threshold; + + /** + * The load factor for the hashtable. + * + * @serial + */ + private final float loadFactor; + + /** + *

Innerclass that acts as a datastructure to create a new entry in the + * table.

+ */ + private static class Entry { + final int hash; + final int key; // TODO not read; seems to be always same as hash + T value; + Entry next; + + /** + *

Create a new entry with the given values.

+ * + * @param hash The code used to hash the object with + * @param key The key used to enter this in the table + * @param value The value for this key + * @param next A reference to the next entry in the table + */ + protected Entry(int hash, int key, T value, Entry next) { + this.hash = hash; + this.key = key; + this.value = value; + this.next = next; + } + } + + /** + *

Constructs a new, empty hashtable with a default capacity and load + * factor, which is 20 and 0.75 respectively.

+ */ + public IntHashMap() { + this(20, 0.75f); + } + + /** + *

Constructs a new, empty hashtable with the specified initial capacity + * and default load factor, which is 0.75.

+ * + * @param initialCapacity the initial capacity of the hashtable. + * @throws IllegalArgumentException if the initial capacity is less + * than zero. + */ + public IntHashMap(int initialCapacity) { + this(initialCapacity, 0.75f); + } + + /** + *

Constructs a new, empty hashtable with the specified initial + * capacity and the specified load factor.

+ * + * @param initialCapacity the initial capacity of the hashtable. + * @param loadFactor the load factor of the hashtable. + * @throws IllegalArgumentException if the initial capacity is less + * than zero, or if the load factor is nonpositive. + */ + public IntHashMap(int initialCapacity, float loadFactor) { + super(); + if (initialCapacity < 0) { + throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); + } + if (loadFactor <= 0) { + throw new IllegalArgumentException("Illegal Load: " + loadFactor); + } + if (initialCapacity == 0) { + initialCapacity = 1; + } + + this.loadFactor = loadFactor; + table = new Entry[initialCapacity]; + threshold = (int) (initialCapacity * loadFactor); + } + + /** + *

Returns the number of keys in this hashtable.

+ * + * @return the number of keys in this hashtable. + */ + public int size() { + return count; + } + + /** + *

Tests if this hashtable maps no keys to values.

+ * + * @return true if this hashtable maps no keys to values; + * false otherwise. + */ + public boolean isEmpty() { + return count == 0; + } + + + /** + *

Returns the value to which the specified key is mapped in this map.

+ * + * @param key a key in the hashtable. + * @return the value to which the key is mapped in this hashtable; + * null if the key is not mapped to any value in + * this hashtable. + * @see #put(int, T) + */ + public T get(int key) { + Entry tab[] = table; + int hash = key; + int index = (hash & 0x7FFFFFFF) % tab.length; + for (Entry e = tab[index]; e != null; e = e.next) { + if (e.hash == hash) { + return e.value; + } + } + return null; + } + + /** + *

Increases the capacity of and internally reorganizes this + * hashtable, in order to accommodate and access its entries more + * efficiently.

+ * + *

This method is called automatically when the number of keys + * in the hashtable exceeds this hashtable's capacity and load + * factor.

+ */ + protected void rehash() { + int oldCapacity = table.length; + Entry oldMap[] = table; + + int newCapacity = oldCapacity * 2 + 1; + Entry newMap[] = new Entry[newCapacity]; + + threshold = (int) (newCapacity * loadFactor); + table = newMap; + + for (int i = oldCapacity; i-- > 0;) { + for (Entry old = oldMap[i]; old != null;) { + Entry e = old; + old = old.next; + + int index = (e.hash & 0x7FFFFFFF) % newCapacity; + e.next = newMap[index]; + newMap[index] = e; + } + } + } + + /** + *

Maps the specified key to the specified + * value in this hashtable. The key cannot be + * null.

+ * + *

The value can be retrieved by calling the get method + * with a key that is equal to the original key.

+ * + * @param key the hashtable key. + * @param value the value. + * @return the previous value of the specified key in this hashtable, + * or null if it did not have one. + * @throws NullPointerException if the key is null. + * @see #get(int) + */ + public T put(int key, T value) { + // Makes sure the key is not already in the hashtable. + Entry tab[] = table; + int hash = key; + int index = (hash & 0x7FFFFFFF) % tab.length; + for (Entry e = tab[index]; e != null; e = e.next) { + if (e.hash == hash) { + T old = e.value; + e.value = value; + return old; + } + } + + if (count >= threshold) { + // Rehash the table if the threshold is exceeded + rehash(); + + tab = table; + index = (hash & 0x7FFFFFFF) % tab.length; + } + + // Creates the new entry. + Entry e = new Entry(hash, key, value, tab[index]); + tab[index] = e; + count++; + return null; + } + + + +} + diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/AnnotationKeyTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/AnnotationKeyTest.java index 73d6f3dcf2bf..f787675e2b22 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/AnnotationKeyTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/AnnotationKeyTest.java @@ -1,46 +1,50 @@ -package com.nhn.pinpoint.common; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class AnnotationKeyTest { - - @Test - public void getCode() { - - AnnotationKey annotationKey = AnnotationKey.findAnnotationKey(AnnotationKey.API.getCode()); - Assert.assertEquals(annotationKey, AnnotationKey.API); - } - -// @Test - public void intSize() { -// 2147483647 - System.out.println(Integer.MAX_VALUE); -// -2147483648 - System.out.println(Integer.MIN_VALUE); - } - - @Test - public void isArgsKey() { - Assert.assertTrue(AnnotationKey.isArgsKey(AnnotationKey.ARGS0.getCode())); - Assert.assertTrue(AnnotationKey.isArgsKey(AnnotationKey.ARGSN.getCode())); - Assert.assertTrue(AnnotationKey.isArgsKey(AnnotationKey.ARGS5.getCode())); - - Assert.assertFalse(AnnotationKey.isArgsKey(AnnotationKey.ARGS0.getCode() +1)); - Assert.assertFalse(AnnotationKey.isArgsKey(AnnotationKey.ARGSN.getCode() -1)); - Assert.assertFalse(AnnotationKey.isArgsKey(Integer.MAX_VALUE)); - Assert.assertFalse(AnnotationKey.isArgsKey(Integer.MIN_VALUE)); - - } - - @Test - public void isCachedArgsToArgs() { - int i = AnnotationKey.cachedArgsToArgs(AnnotationKey.CACHE_ARGS0.getCode()); - Assert.assertEquals(i, AnnotationKey.ARGS0.getCode()); - - - } -} +package com.nhn.pinpoint.common; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class AnnotationKeyTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void getCode() { + + AnnotationKey annotationKey = AnnotationKey.findAnnotationKey(AnnotationKey.API.getCode()); + Assert.assertEquals(annotationKey, AnnotationKey.API); + } + +// @Test + public void intSize() { +// 2147483647 + logger.debug("{}", Integer.MAX_VALUE); +// -2147483648 + logger.debug("{}", Integer.MIN_VALUE); + } + + @Test + public void isArgsKey() { + Assert.assertTrue(AnnotationKey.isArgsKey(AnnotationKey.ARGS0.getCode())); + Assert.assertTrue(AnnotationKey.isArgsKey(AnnotationKey.ARGSN.getCode())); + Assert.assertTrue(AnnotationKey.isArgsKey(AnnotationKey.ARGS5.getCode())); + + Assert.assertFalse(AnnotationKey.isArgsKey(AnnotationKey.ARGS0.getCode() +1)); + Assert.assertFalse(AnnotationKey.isArgsKey(AnnotationKey.ARGSN.getCode() -1)); + Assert.assertFalse(AnnotationKey.isArgsKey(Integer.MAX_VALUE)); + Assert.assertFalse(AnnotationKey.isArgsKey(Integer.MIN_VALUE)); + + } + + @Test + public void isCachedArgsToArgs() { + int i = AnnotationKey.cachedArgsToArgs(AnnotationKey.CACHE_ARGS0.getCode()); + Assert.assertEquals(i, AnnotationKey.ARGS0.getCode()); + + + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/HistogramSchemaTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/HistogramSchemaTest.java index a6b2ec1f318e..577f3748c2eb 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/HistogramSchemaTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/HistogramSchemaTest.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.common; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class HistogramSchemaTest { - @Test - public void testAddHistogramSlot() throws Exception { - - } - - @Test - public void testGetHistogramSlotList() throws Exception { - - } - - @Test - public void testCreateNode() throws Exception { - - } - - @Test - public void testFindHistogramSlot() throws Exception { - HistogramSchema histogramSchema = ServiceType.TOMCAT.getHistogramSchema(); - Assert.assertEquals(histogramSchema.findHistogramSlot(999).getSlotTime(), 1000); - Assert.assertEquals(histogramSchema.findHistogramSlot(1000).getSlotTime(), 1000); - Assert.assertEquals(histogramSchema.findHistogramSlot(1111).getSlotTime(), 3000); - } - - - - @Test - public void testGetHistogramSlotIndex() throws Exception { - - } -} +package com.nhn.pinpoint.common; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class HistogramSchemaTest { + @Test + public void testAddHistogramSlot() throws Exception { + + } + + @Test + public void testGetHistogramSlotList() throws Exception { + + } + + @Test + public void testCreateNode() throws Exception { + + } + + @Test + public void testFindHistogramSlot() throws Exception { + HistogramSchema histogramSchema = ServiceType.TOMCAT.getHistogramSchema(); + Assert.assertEquals(histogramSchema.findHistogramSlot(999).getSlotTime(), 1000); + Assert.assertEquals(histogramSchema.findHistogramSlot(1000).getSlotTime(), 1000); + Assert.assertEquals(histogramSchema.findHistogramSlot(1111).getSlotTime(), 3000); + } + + + + @Test + public void testGetHistogramSlotIndex() throws Exception { + + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/ServiceTypeTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/ServiceTypeTest.java index a09be2b72c4b..39a463b084a1 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/ServiceTypeTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/ServiceTypeTest.java @@ -13,9 +13,9 @@ public class ServiceTypeTest { @Test public void testIndexable() { - System.out.println(ServiceType.TOMCAT.isIndexable()); - System.out.println(ServiceType.BLOC.isIndexable()); - System.out.println(ServiceType.ARCUS.isIndexable()); + logger.debug("{}", ServiceType.TOMCAT.isIndexable()); + logger.debug("{}", ServiceType.BLOC.isIndexable()); + logger.debug("{}", ServiceType.ARCUS.isIndexable()); } @Test diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBoTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBoTest.java index ebf34eaf379e..709fee08535a 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBoTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatCpuLoadBoTest.java @@ -1,82 +1,82 @@ -package com.nhn.pinpoint.common.bo; - -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * @author hyungil.jeong - */ -public class AgentStatCpuLoadBoTest { - - // CPU 사용량 소수점 2자리 표시 - private static final double DELTA = 1e-4; - - @Test - public void testByteArrayConversion() { - // Given - final AgentStatCpuLoadBo testBo = createTestBo(0.22871734201908112D, 0.23790152370929718D); - // When - final byte[] serializedBo = testBo.writeValue(); - final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); - // Then - assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); - assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); - assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); - assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); - assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); - } - - @Test - public void testByteArrayConversionEdges() { - // Given - final AgentStatCpuLoadBo testBo = createTestBo(Double.MIN_VALUE, Double.MAX_VALUE); - // When - final byte[] serializedBo = testBo.writeValue(); - final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); - // Then - assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); - assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); - assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); - assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); - assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); - } - - @Test - public void testByteArrayConversionNanValues() { - // Given - final AgentStatCpuLoadBo testBo = createTestBo(Double.NaN, Double.NaN); - // When - final byte[] serializedBo = testBo.writeValue(); - final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); - // Then - assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); - assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); - assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); - assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); - assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); - } - - @Test - public void testByteArrayConversionInfiniteValues() { - // Given - final AgentStatCpuLoadBo testBo = createTestBo(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY); - // When - final byte[] serializedBo = testBo.writeValue(); - final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); - // Then - assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); - assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); - assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); - assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); - assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); - } - - private AgentStatCpuLoadBo createTestBo(double jvmCpuLoad, double systemCpuLoad) { - final AgentStatCpuLoadBo.Builder builder = new AgentStatCpuLoadBo.Builder("agentId", 0L, 0L); - builder.jvmCpuLoad(jvmCpuLoad); - builder.systemCpuLoad(systemCpuLoad); - return builder.build(); - } - -} +package com.nhn.pinpoint.common.bo; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * @author hyungil.jeong + */ +public class AgentStatCpuLoadBoTest { + + // CPU 사용량 소수점 2자리 표시 + private static final double DELTA = 1e-4; + + @Test + public void testByteArrayConversion() { + // Given + final AgentStatCpuLoadBo testBo = createTestBo(0.22871734201908112D, 0.23790152370929718D); + // When + final byte[] serializedBo = testBo.writeValue(); + final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); + // Then + assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); + assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); + assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); + assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); + assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); + } + + @Test + public void testByteArrayConversionEdges() { + // Given + final AgentStatCpuLoadBo testBo = createTestBo(Double.MIN_VALUE, Double.MAX_VALUE); + // When + final byte[] serializedBo = testBo.writeValue(); + final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); + // Then + assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); + assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); + assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); + assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); + assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); + } + + @Test + public void testByteArrayConversionNanValues() { + // Given + final AgentStatCpuLoadBo testBo = createTestBo(Double.NaN, Double.NaN); + // When + final byte[] serializedBo = testBo.writeValue(); + final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); + // Then + assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); + assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); + assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); + assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); + assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); + } + + @Test + public void testByteArrayConversionInfiniteValues() { + // Given + final AgentStatCpuLoadBo testBo = createTestBo(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY); + // When + final byte[] serializedBo = testBo.writeValue(); + final AgentStatCpuLoadBo deserializedBo = new AgentStatCpuLoadBo.Builder(serializedBo).build(); + // Then + assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); + assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); + assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); + assertEquals(testBo.getJvmCpuLoad(), deserializedBo.getJvmCpuLoad(), DELTA); + assertEquals(testBo.getSystemCpuLoad(), deserializedBo.getSystemCpuLoad(), DELTA); + } + + private AgentStatCpuLoadBo createTestBo(double jvmCpuLoad, double systemCpuLoad) { + final AgentStatCpuLoadBo.Builder builder = new AgentStatCpuLoadBo.Builder("agentId", 0L, 0L); + builder.jvmCpuLoad(jvmCpuLoad); + builder.systemCpuLoad(systemCpuLoad); + return builder.build(); + } + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBoTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBoTest.java index 3bff52451634..6ad0004ab31a 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBoTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/bo/AgentStatMemoryGcBoTest.java @@ -1,42 +1,42 @@ -package com.nhn.pinpoint.common.bo; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.nhn.pinpoint.thrift.dto.TJvmGcType; - -/** - * @author hyungil.jeong - */ -public class AgentStatMemoryGcBoTest { - - @Test - public void testByteArrayConversion() { - // Given - final AgentStatMemoryGcBo.Builder builder = new AgentStatMemoryGcBo.Builder("agentId", 0L, 1L); - builder.gcType(TJvmGcType.G1.name()); - builder.jvmMemoryHeapUsed(Long.MIN_VALUE); - builder.jvmMemoryHeapMax(Long.MAX_VALUE); - builder.jvmMemoryNonHeapUsed(Long.MIN_VALUE); - builder.jvmMemoryNonHeapMax(Long.MAX_VALUE); - builder.jvmGcOldCount(1L); - builder.jvmGcOldTime(2L); - final AgentStatMemoryGcBo testBo = builder.build(); - // When - final byte[] serializedBo = testBo.writeValue(); - final AgentStatMemoryGcBo deserializedBo = new AgentStatMemoryGcBo.Builder(serializedBo).build(); - // Then - assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); - assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); - assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); - assertEquals(testBo.getGcType(), deserializedBo.getGcType()); - assertEquals(testBo.getJvmMemoryHeapUsed(), deserializedBo.getJvmMemoryHeapUsed()); - assertEquals(testBo.getJvmMemoryHeapMax(), deserializedBo.getJvmMemoryHeapMax()); - assertEquals(testBo.getJvmMemoryNonHeapUsed(), deserializedBo.getJvmMemoryNonHeapUsed()); - assertEquals(testBo.getJvmMemoryNonHeapMax(), deserializedBo.getJvmMemoryNonHeapMax()); - assertEquals(testBo.getJvmGcOldCount(), deserializedBo.getJvmGcOldCount()); - assertEquals(testBo.getJvmGcOldTime(), deserializedBo.getJvmGcOldTime()); - } - -} +package com.nhn.pinpoint.common.bo; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.nhn.pinpoint.thrift.dto.TJvmGcType; + +/** + * @author hyungil.jeong + */ +public class AgentStatMemoryGcBoTest { + + @Test + public void testByteArrayConversion() { + // Given + final AgentStatMemoryGcBo.Builder builder = new AgentStatMemoryGcBo.Builder("agentId", 0L, 1L); + builder.gcType(TJvmGcType.G1.name()); + builder.jvmMemoryHeapUsed(Long.MIN_VALUE); + builder.jvmMemoryHeapMax(Long.MAX_VALUE); + builder.jvmMemoryNonHeapUsed(Long.MIN_VALUE); + builder.jvmMemoryNonHeapMax(Long.MAX_VALUE); + builder.jvmGcOldCount(1L); + builder.jvmGcOldTime(2L); + final AgentStatMemoryGcBo testBo = builder.build(); + // When + final byte[] serializedBo = testBo.writeValue(); + final AgentStatMemoryGcBo deserializedBo = new AgentStatMemoryGcBo.Builder(serializedBo).build(); + // Then + assertEquals(testBo.getAgentId(), deserializedBo.getAgentId()); + assertEquals(testBo.getStartTimestamp(), deserializedBo.getStartTimestamp()); + assertEquals(testBo.getTimestamp(), deserializedBo.getTimestamp()); + assertEquals(testBo.getGcType(), deserializedBo.getGcType()); + assertEquals(testBo.getJvmMemoryHeapUsed(), deserializedBo.getJvmMemoryHeapUsed()); + assertEquals(testBo.getJvmMemoryHeapMax(), deserializedBo.getJvmMemoryHeapMax()); + assertEquals(testBo.getJvmMemoryNonHeapUsed(), deserializedBo.getJvmMemoryNonHeapUsed()); + assertEquals(testBo.getJvmMemoryNonHeapMax(), deserializedBo.getJvmMemoryNonHeapMax()); + assertEquals(testBo.getJvmGcOldCount(), deserializedBo.getJvmGcOldCount()); + assertEquals(testBo.getJvmGcOldTime(), deserializedBo.getJvmGcOldTime()); + } + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/bo/AnnotationBoTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/bo/AnnotationBoTest.java index 14883995008e..419728e6f313 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/bo/AnnotationBoTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/bo/AnnotationBoTest.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import org.junit.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class AnnotationBoTest { - @Test - public void testGetVersion() throws Exception { - - } - - @Test - public void testSetVersion() throws Exception { - - } - - @Test - public void testWriteValue() throws Exception { - AnnotationBo bo = new AnnotationBo(); - bo.setKey(AnnotationKey.API.getCode()); - bo.setByteValue("value".getBytes("UTF-8")); -// int bufferSize = bo.getBufferSize(); - - Buffer buffer = new AutomaticBuffer(128); - bo.writeValue(buffer); - - AnnotationBo bo2 = new AnnotationBo(); - buffer.setOffset(0); - bo2.readValue(buffer); - Assert.assertEquals(bo.getKey(), bo2.getKey()); - Assert.assertEquals(bo.getValueType(), bo2.getValueType()); - Assert.assertArrayEquals(bo.getByteValue(), bo2.getByteValue()); - } - -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class AnnotationBoTest { + @Test + public void testGetVersion() throws Exception { + + } + + @Test + public void testSetVersion() throws Exception { + + } + + @Test + public void testWriteValue() throws Exception { + AnnotationBo bo = new AnnotationBo(); + bo.setKey(AnnotationKey.API.getCode()); + bo.setByteValue("value".getBytes("UTF-8")); +// int bufferSize = bo.getBufferSize(); + + Buffer buffer = new AutomaticBuffer(128); + bo.writeValue(buffer); + + AnnotationBo bo2 = new AnnotationBo(); + buffer.setOffset(0); + bo2.readValue(buffer); + Assert.assertEquals(bo.getKey(), bo2.getKey()); + Assert.assertEquals(bo.getValueType(), bo2.getValueType()); + Assert.assertArrayEquals(bo.getByteValue(), bo2.getByteValue()); + } + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanBoTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanBoTest.java index bed9f00939b4..399a6ae1832a 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanBoTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanBoTest.java @@ -1,111 +1,111 @@ -package com.nhn.pinpoint.common.bo; - - -import com.nhn.pinpoint.common.ServiceType; -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class SpanBoTest { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testVersion() { - SpanBo spanBo = new SpanBo(); - check(spanBo, 0); - check(spanBo, 254); - check(spanBo, 255); - try { - check(spanBo, 256); - Assert.fail(); - } catch (Exception e) { - } - - - } - - private void check(SpanBo spanBo, int v) { - spanBo.setVersion(v); - int version = spanBo.getVersion(); - - Assert.assertEquals(v, version); - } - - @Test - public void serialize() { - SpanBo spanBo = new SpanBo(); - spanBo.setAgentId("agentId"); - spanBo.setApplicationId("applicationId"); - spanBo.setEndPoint("end"); - spanBo.setRpc("rpc"); - - spanBo.setParentSpanId(5); - - spanBo.setAgentStartTime(1); - spanBo.setTraceAgentStartTime(2); - spanBo.setTraceTransactionSequence(3); - spanBo.setElapsed(4); - spanBo.setStartTime(5); - - - spanBo.setServiceType(ServiceType.BLOC); - byte[] bytes = spanBo.writeValue(); - logger.info("length:{}", bytes.length); - - SpanBo newSpanBo = new SpanBo(); - int i = newSpanBo.readValue(bytes, 0); - logger.info("length:{}", i); - Assert.assertEquals(bytes.length, i); - Assert.assertEquals(newSpanBo.getAgentId(), spanBo.getAgentId()); - Assert.assertEquals(newSpanBo.getApplicationId(), spanBo.getApplicationId()); - Assert.assertEquals(newSpanBo.getAgentStartTime(), spanBo.getAgentStartTime()); - Assert.assertEquals(newSpanBo.getElapsed(), spanBo.getElapsed()); - Assert.assertEquals(newSpanBo.getEndPoint(), spanBo.getEndPoint()); - Assert.assertEquals(newSpanBo.getErrCode(), spanBo.getErrCode()); - Assert.assertEquals(newSpanBo.getFlag(), spanBo.getFlag()); - -// 이건 serialize에서 안가져옴. -// Assert.assertEquals(newSpanBo.getTraceAgentStartTime(), spanBo.getTraceAgentStartTime()); -// Assert.assertEquals(newSpanBo.getTraceTransactionSequence(), spanBo.getTraceTransactionSequence()); - Assert.assertEquals(newSpanBo.getParentSpanId(), spanBo.getParentSpanId()); - - Assert.assertEquals(newSpanBo.getVersion(), spanBo.getVersion()); - - - } - - @Test - public void serialize2() { - SpanBo spanBo = new SpanBo(); - spanBo.setAgentId("agent"); - String service = createString(5); - spanBo.setApplicationId(service); - String endPoint = createString(127); - spanBo.setEndPoint(endPoint); - String rpc = createString(255); - spanBo.setRpc(rpc); - - spanBo.setServiceType(ServiceType.BLOC); - - byte[] bytes = spanBo.writeValue(); - logger.info("length:{}", bytes.length); - - SpanBo newSpanBo = new SpanBo(); - int i = newSpanBo.readValue(bytes, 0); - logger.info("length:{}", i); - Assert.assertEquals(bytes.length, i); - } - - private String createString(int size) { - StringBuilder sb = new StringBuilder(size); - for (int i = 0; i < size; i++) { - sb.append('a'); - } - return sb.toString(); - } - -} +package com.nhn.pinpoint.common.bo; + + +import com.nhn.pinpoint.common.ServiceType; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class SpanBoTest { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testVersion() { + SpanBo spanBo = new SpanBo(); + check(spanBo, 0); + check(spanBo, 254); + check(spanBo, 255); + try { + check(spanBo, 256); + Assert.fail(); + } catch (Exception e) { + } + + + } + + private void check(SpanBo spanBo, int v) { + spanBo.setVersion(v); + int version = spanBo.getVersion(); + + Assert.assertEquals(v, version); + } + + @Test + public void serialize() { + SpanBo spanBo = new SpanBo(); + spanBo.setAgentId("agentId"); + spanBo.setApplicationId("applicationId"); + spanBo.setEndPoint("end"); + spanBo.setRpc("rpc"); + + spanBo.setParentSpanId(5); + + spanBo.setAgentStartTime(1); + spanBo.setTraceAgentStartTime(2); + spanBo.setTraceTransactionSequence(3); + spanBo.setElapsed(4); + spanBo.setStartTime(5); + + + spanBo.setServiceType(ServiceType.BLOC); + byte[] bytes = spanBo.writeValue(); + logger.info("length:{}", bytes.length); + + SpanBo newSpanBo = new SpanBo(); + int i = newSpanBo.readValue(bytes, 0); + logger.info("length:{}", i); + Assert.assertEquals(bytes.length, i); + Assert.assertEquals(newSpanBo.getAgentId(), spanBo.getAgentId()); + Assert.assertEquals(newSpanBo.getApplicationId(), spanBo.getApplicationId()); + Assert.assertEquals(newSpanBo.getAgentStartTime(), spanBo.getAgentStartTime()); + Assert.assertEquals(newSpanBo.getElapsed(), spanBo.getElapsed()); + Assert.assertEquals(newSpanBo.getEndPoint(), spanBo.getEndPoint()); + Assert.assertEquals(newSpanBo.getErrCode(), spanBo.getErrCode()); + Assert.assertEquals(newSpanBo.getFlag(), spanBo.getFlag()); + +// 이건 serialize에서 안가져옴. +// Assert.assertEquals(newSpanBo.getTraceAgentStartTime(), spanBo.getTraceAgentStartTime()); +// Assert.assertEquals(newSpanBo.getTraceTransactionSequence(), spanBo.getTraceTransactionSequence()); + Assert.assertEquals(newSpanBo.getParentSpanId(), spanBo.getParentSpanId()); + + Assert.assertEquals(newSpanBo.getVersion(), spanBo.getVersion()); + + + } + + @Test + public void serialize2() { + SpanBo spanBo = new SpanBo(); + spanBo.setAgentId("agent"); + String service = createString(5); + spanBo.setApplicationId(service); + String endPoint = createString(127); + spanBo.setEndPoint(endPoint); + String rpc = createString(255); + spanBo.setRpc(rpc); + + spanBo.setServiceType(ServiceType.BLOC); + + byte[] bytes = spanBo.writeValue(); + logger.info("length:{}", bytes.length); + + SpanBo newSpanBo = new SpanBo(); + int i = newSpanBo.readValue(bytes, 0); + logger.info("length:{}", i); + Assert.assertEquals(bytes.length, i); + } + + private String createString(int size) { + StringBuilder sb = new StringBuilder(size); + for (int i = 0; i < size; i++) { + sb.append('a'); + } + return sb.toString(); + } + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanEventBoTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanEventBoTest.java index eaa72b4becd4..5961b45b7f73 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanEventBoTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/bo/SpanEventBoTest.java @@ -1,67 +1,67 @@ -package com.nhn.pinpoint.common.bo; - -import com.nhn.pinpoint.common.ServiceType; -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class SpanEventBoTest { - - @Test - public void testSerialize() throws Exception { - SpanEventBo spanEventBo = new SpanEventBo(); - spanEventBo.setAgentId("test"); - spanEventBo.setAgentStartTime(1); - spanEventBo.setDepth(3); - spanEventBo.setDestinationId("testdest"); - spanEventBo.setEndElapsed(2); - spanEventBo.setEndPoint("endpoint"); - - spanEventBo.setNextSpanId(4); - spanEventBo.setRpc("rpc"); - - spanEventBo.setServiceType(ServiceType.TOMCAT); - spanEventBo.setSpanId(12); - spanEventBo.setStartElapsed(100); - - byte[] bytes = spanEventBo.writeValue(); - - SpanEventBo newSpanEventBo = new SpanEventBo(); - int i = newSpanEventBo.readValue(bytes, 0); - Assert.assertEquals(bytes.length, i); - - - Assert.assertEquals(spanEventBo.getAgentId(), newSpanEventBo.getAgentId()); - Assert.assertEquals(spanEventBo.getAgentStartTime(), newSpanEventBo.getAgentStartTime()); - Assert.assertEquals(spanEventBo.getDepth(), newSpanEventBo.getDepth()); - Assert.assertEquals(spanEventBo.getDestinationId(), newSpanEventBo.getDestinationId()); - Assert.assertEquals(spanEventBo.getEndElapsed(), newSpanEventBo.getEndElapsed()); - Assert.assertEquals(spanEventBo.getEndPoint(), newSpanEventBo.getEndPoint()); - - - Assert.assertEquals(spanEventBo.getNextSpanId(), newSpanEventBo.getNextSpanId()); - Assert.assertEquals(spanEventBo.getRpc(), newSpanEventBo.getRpc()); - Assert.assertEquals(spanEventBo.getServiceType(), newSpanEventBo.getServiceType()); - Assert.assertEquals(spanEventBo.getStartElapsed(), newSpanEventBo.getStartElapsed()); - - - // 아래는 rowKeye에서 가져 오는값. - spanEventBo.setSpanId(1); - newSpanEventBo.setSpanId(1); - Assert.assertEquals(spanEventBo.getSpanId(), newSpanEventBo.getSpanId()); - - spanEventBo.setTraceTransactionSequence(1); - newSpanEventBo.setTraceTransactionSequence(1); - Assert.assertEquals(spanEventBo.getTraceTransactionSequence(), newSpanEventBo.getTraceTransactionSequence()); - - spanEventBo.setTraceAgentStartTime(3); - newSpanEventBo.setTraceAgentStartTime(3); - Assert.assertEquals(spanEventBo.getTraceAgentStartTime(), newSpanEventBo.getTraceAgentStartTime()); - - spanEventBo.setSequence((short) 3); - newSpanEventBo.setSequence((short) 3); - Assert.assertEquals(spanEventBo.getSequence(), newSpanEventBo.getSequence()); - } -} +package com.nhn.pinpoint.common.bo; + +import com.nhn.pinpoint.common.ServiceType; +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class SpanEventBoTest { + + @Test + public void testSerialize() throws Exception { + SpanEventBo spanEventBo = new SpanEventBo(); + spanEventBo.setAgentId("test"); + spanEventBo.setAgentStartTime(1); + spanEventBo.setDepth(3); + spanEventBo.setDestinationId("testdest"); + spanEventBo.setEndElapsed(2); + spanEventBo.setEndPoint("endpoint"); + + spanEventBo.setNextSpanId(4); + spanEventBo.setRpc("rpc"); + + spanEventBo.setServiceType(ServiceType.TOMCAT); + spanEventBo.setSpanId(12); + spanEventBo.setStartElapsed(100); + + byte[] bytes = spanEventBo.writeValue(); + + SpanEventBo newSpanEventBo = new SpanEventBo(); + int i = newSpanEventBo.readValue(bytes, 0); + Assert.assertEquals(bytes.length, i); + + + Assert.assertEquals(spanEventBo.getAgentId(), newSpanEventBo.getAgentId()); + Assert.assertEquals(spanEventBo.getAgentStartTime(), newSpanEventBo.getAgentStartTime()); + Assert.assertEquals(spanEventBo.getDepth(), newSpanEventBo.getDepth()); + Assert.assertEquals(spanEventBo.getDestinationId(), newSpanEventBo.getDestinationId()); + Assert.assertEquals(spanEventBo.getEndElapsed(), newSpanEventBo.getEndElapsed()); + Assert.assertEquals(spanEventBo.getEndPoint(), newSpanEventBo.getEndPoint()); + + + Assert.assertEquals(spanEventBo.getNextSpanId(), newSpanEventBo.getNextSpanId()); + Assert.assertEquals(spanEventBo.getRpc(), newSpanEventBo.getRpc()); + Assert.assertEquals(spanEventBo.getServiceType(), newSpanEventBo.getServiceType()); + Assert.assertEquals(spanEventBo.getStartElapsed(), newSpanEventBo.getStartElapsed()); + + + // 아래는 rowKeye에서 가져 오는값. + spanEventBo.setSpanId(1); + newSpanEventBo.setSpanId(1); + Assert.assertEquals(spanEventBo.getSpanId(), newSpanEventBo.getSpanId()); + + spanEventBo.setTraceTransactionSequence(1); + newSpanEventBo.setTraceTransactionSequence(1); + Assert.assertEquals(spanEventBo.getTraceTransactionSequence(), newSpanEventBo.getTraceTransactionSequence()); + + spanEventBo.setTraceAgentStartTime(3); + newSpanEventBo.setTraceAgentStartTime(3); + Assert.assertEquals(spanEventBo.getTraceAgentStartTime(), newSpanEventBo.getTraceAgentStartTime()); + + spanEventBo.setSequence((short) 3); + newSpanEventBo.setSequence((short) 3); + Assert.assertEquals(spanEventBo.getSequence(), newSpanEventBo.getSequence()); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/AutomaticBufferTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/AutomaticBufferTest.java index 516a96bd124c..7dc0d9108dac 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/AutomaticBufferTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/AutomaticBufferTest.java @@ -1,294 +1,294 @@ -package com.nhn.pinpoint.common.buffer; - -import com.nhn.pinpoint.common.util.BytesUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.hadoop.hbase.util.Bytes; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.charset.Charset; -import java.util.Random; - -/** - * @author emeroad - */ -public class AutomaticBufferTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private Random random = new Random(); - - @Test - public void testPutPrefixedBytes() throws Exception { - Buffer buffer = new AutomaticBuffer(0); - buffer.put(1); - byte[] buf = buffer.getBuffer(); - Assert.assertEquals(buf.length, 4); - Assert.assertEquals(1, BytesUtils.bytesToInt(buf, 0)); - } - - - @Test - public void testPadBytes() throws Exception { - int TOTAL_LENGTH = 20; - int TEST_SIZE = 10; - int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; - Buffer buffer = new AutomaticBuffer(10); - byte[] test = new byte[10]; - - random.nextBytes(test); - - buffer.putPadBytes(test, TOTAL_LENGTH); - - byte[] result = buffer.getBuffer(); - junit.framework.Assert.assertEquals(result.length, TOTAL_LENGTH); - junit.framework.Assert.assertTrue("check data", Bytes.equals(test, 0, TEST_SIZE, result, 0, TEST_SIZE)); - byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; - junit.framework.Assert.assertTrue("check pad", Bytes.equals(padBytes, 0, TEST_SIZE, result, TEST_SIZE, PAD_SIZE)); - - } - - @Test - public void testPadBytes_Error() throws Exception { - - Buffer buffer1_1 = new AutomaticBuffer(32); - try { - buffer1_1.putPadBytes(new byte[11], 10); - } catch (Exception e) { - } - - Buffer buffer1_2 = new AutomaticBuffer(32); - try { - buffer1_2.putPadBytes(new byte[20], 10); - junit.framework.Assert.fail("error"); - } catch (Exception e) { - } - - Buffer buffer2 = new AutomaticBuffer(32); - buffer2.putPadBytes(new byte[10], 10); - - - Buffer buffer3 = new AutomaticBuffer(5); - buffer3.putPadBytes(new byte[10], 10); - } - - - @Test - public void testPadString() throws Exception { - int TOTAL_LENGTH = 20; - int TEST_SIZE = 10; - int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; - Buffer buffer = new AutomaticBuffer(32); - String test = StringUtils.repeat('a', TEST_SIZE); - - buffer.putPadString(test, TOTAL_LENGTH); - - byte[] result = buffer.getBuffer(); - String decodedString = new String(result); - String trimString = decodedString.trim(); - junit.framework.Assert.assertEquals(result.length, TOTAL_LENGTH); - - junit.framework.Assert.assertEquals("check data", test, trimString); - - String padString = new String(result, TOTAL_LENGTH - TEST_SIZE, PAD_SIZE, "UTF-8"); - byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; - junit.framework.Assert.assertEquals("check pad", padString, new String(padBytes, Charset.forName("UTF-8"))); - - } - - @Test - public void testPadString_Error() throws Exception { - - Buffer buffer1_1 = new AutomaticBuffer(32); - try { - buffer1_1.putPadString(StringUtils.repeat('a', 11), 10); - } catch (Exception e) { - } - - Buffer buffer1_2 = new AutomaticBuffer(32); - try { - buffer1_2.putPadString(StringUtils.repeat('a', 20), 10); - junit.framework.Assert.fail("error"); - } catch (Exception e) { - } - - Buffer buffer2 = new AutomaticBuffer(32); - buffer2.putPadString(StringUtils.repeat('a', 10), 10); - - Buffer buffer3 = new AutomaticBuffer(5); - buffer3.putPadString(StringUtils.repeat('a', 10), 10); - } - - @Test - public void testPut2PrefixedBytes() throws Exception { - byte[] bytes1 = new byte[2]; - checkPut2PrefixedBytes(bytes1); - - byte[] bytes2 = new byte[0]; - checkPut2PrefixedBytes(bytes2); - - byte[] bytes3 = new byte[Short.MAX_VALUE]; - checkPut2PrefixedBytes(bytes3); - - checkPut2PrefixedBytes(null); - - try { - byte[] bytes4 = new byte[Short.MAX_VALUE+1]; - checkPut2PrefixedBytes(bytes4); - Assert.fail("too large bytes"); - } catch (Exception e) { - } - } - - private void checkPut2PrefixedBytes(byte[] bytes) { - Buffer buffer = new AutomaticBuffer(0); - buffer.put2PrefixedBytes(bytes); - - Buffer copy = new FixedBuffer(buffer.getBuffer()); - Assert.assertArrayEquals(bytes, copy.read2PrefixedBytes()); - } - - @Test - public void testPut4PrefixedBytes() throws Exception { - byte[] bytes1 = new byte[2]; - checkPut4PrefixedBytes(bytes1); - - byte[] bytes2 = new byte[0]; - checkPut4PrefixedBytes(bytes2); - - checkPut4PrefixedBytes(null); - - } - - private void checkPut4PrefixedBytes(byte[] bytes) { - Buffer buffer = new AutomaticBuffer(0); - buffer.put4PrefixedBytes(bytes); - - Buffer copy = new FixedBuffer(buffer.getBuffer()); - Assert.assertArrayEquals(bytes, copy.read4PrefixedBytes()); - } - - @Test - public void testPutPrefixedBytesCheckRange() throws Exception { - Buffer buffer = new AutomaticBuffer(1); - buffer.putPrefixedString(null); - byte[] internalBuffer = buffer.getInternalBuffer(); - // 상속 관계에 의해서 강제로 버퍼 사이즈를 늘어나지 않아도 되는데 사이즈가 늘어남. - Assert.assertEquals(1, internalBuffer.length); - } - - - - @Test - public void testCurrentTime() throws InterruptedException { - Buffer buffer = new AutomaticBuffer(32); - - long l = System.currentTimeMillis(); - buffer.putSVar(l); - logger.trace("currentTime size:{}", buffer.getOffset()); - buffer.setOffset(0); - Assert.assertEquals(buffer.readSVarLong(), l); - - - } - - @Test - public void testPutVarInt() throws Exception { - Buffer buffer = new AutomaticBuffer(0); - buffer.putVar(Integer.MAX_VALUE); - buffer.putVar(Integer.MIN_VALUE); - buffer.putVar(0); - buffer.putVar(1); - buffer.putVar(12345); - - buffer.setOffset(0); - Assert.assertEquals(buffer.readVarInt(), Integer.MAX_VALUE); - Assert.assertEquals(buffer.readVarInt(), Integer.MIN_VALUE); - Assert.assertEquals(buffer.readVarInt(), 0); - Assert.assertEquals(buffer.readVarInt(), 1); - Assert.assertEquals(buffer.readVarInt(), 12345); - } - - @Test - public void testPutVarLong() throws Exception { - Buffer buffer = new AutomaticBuffer(0); - buffer.putVar(Long.MAX_VALUE); - buffer.putVar(Long.MIN_VALUE); - buffer.putVar(0L); - buffer.putVar(1L); - buffer.putVar(12345L); - - buffer.setOffset(0); - Assert.assertEquals(buffer.readVarLong(), Long.MAX_VALUE); - Assert.assertEquals(buffer.readVarLong(), Long.MIN_VALUE); - Assert.assertEquals(buffer.readVarLong(), 0L); - Assert.assertEquals(buffer.readVarLong(), 1L); - Assert.assertEquals(buffer.readVarLong(), 12345L); - } - - @Test - public void testPutSVarLong() throws Exception { - Buffer buffer = new AutomaticBuffer(32); - buffer.putSVar(Long.MAX_VALUE); - buffer.putSVar(Long.MIN_VALUE); - buffer.putSVar(0L); - buffer.putSVar(1L); - buffer.putSVar(12345L); - - buffer.setOffset(0); - Assert.assertEquals(buffer.readSVarLong(), Long.MAX_VALUE); - Assert.assertEquals(buffer.readSVarLong(), Long.MIN_VALUE); - Assert.assertEquals(buffer.readSVarLong(), 0L); - Assert.assertEquals(buffer.readSVarLong(), 1L); - Assert.assertEquals(buffer.readSVarLong(), 12345L); - } - - @Test - public void testPutSVarInt() throws Exception { - Buffer buffer = new AutomaticBuffer(32); - buffer.putSVar(Integer.MAX_VALUE); - buffer.putSVar(Integer.MIN_VALUE); - buffer.putSVar(0); - buffer.putSVar(1); - buffer.putSVar(12345); - - buffer.setOffset(0); - Assert.assertEquals(buffer.readSVarInt(), Integer.MAX_VALUE); - Assert.assertEquals(buffer.readSVarInt(), Integer.MIN_VALUE); - Assert.assertEquals(buffer.readSVarInt(), 0); - Assert.assertEquals(buffer.readSVarInt(), 1); - Assert.assertEquals(buffer.readSVarInt(), 12345); - } - - @Test - public void testPut() throws Exception { - Buffer buffer = new AutomaticBuffer(0); - buffer.put(1); - buffer.put(1L); - buffer.putPrefixedBytes(new byte[10]); - buffer.put((byte)1); - - - } - - @Ignore - @Test - public void testUdp() throws Exception { - // Signature:Header{signature=85, version=100, type=28704} - Buffer buffer = new AutomaticBuffer(10); - buffer.put((byte)85); - buffer.put((byte) 100); - buffer.put((short)28704); - - Buffer read = new FixedBuffer(buffer.getBuffer()); - logger.info("{}", (char)read.readByte()); - logger.info("{}", (char)read.readByte()); - logger.info("{}", (char)read.readByte()); - logger.info("{}", (char)read.readByte()); - - } - -} +package com.nhn.pinpoint.common.buffer; + +import com.nhn.pinpoint.common.util.BytesUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.Charset; +import java.util.Random; + +/** + * @author emeroad + */ +public class AutomaticBufferTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Random random = new Random(); + + @Test + public void testPutPrefixedBytes() throws Exception { + Buffer buffer = new AutomaticBuffer(0); + buffer.put(1); + byte[] buf = buffer.getBuffer(); + Assert.assertEquals(buf.length, 4); + Assert.assertEquals(1, BytesUtils.bytesToInt(buf, 0)); + } + + + @Test + public void testPadBytes() throws Exception { + int TOTAL_LENGTH = 20; + int TEST_SIZE = 10; + int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; + Buffer buffer = new AutomaticBuffer(10); + byte[] test = new byte[10]; + + random.nextBytes(test); + + buffer.putPadBytes(test, TOTAL_LENGTH); + + byte[] result = buffer.getBuffer(); + junit.framework.Assert.assertEquals(result.length, TOTAL_LENGTH); + junit.framework.Assert.assertTrue("check data", Bytes.equals(test, 0, TEST_SIZE, result, 0, TEST_SIZE)); + byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; + junit.framework.Assert.assertTrue("check pad", Bytes.equals(padBytes, 0, TEST_SIZE, result, TEST_SIZE, PAD_SIZE)); + + } + + @Test + public void testPadBytes_Error() throws Exception { + + Buffer buffer1_1 = new AutomaticBuffer(32); + try { + buffer1_1.putPadBytes(new byte[11], 10); + } catch (Exception e) { + } + + Buffer buffer1_2 = new AutomaticBuffer(32); + try { + buffer1_2.putPadBytes(new byte[20], 10); + junit.framework.Assert.fail("error"); + } catch (Exception e) { + } + + Buffer buffer2 = new AutomaticBuffer(32); + buffer2.putPadBytes(new byte[10], 10); + + + Buffer buffer3 = new AutomaticBuffer(5); + buffer3.putPadBytes(new byte[10], 10); + } + + + @Test + public void testPadString() throws Exception { + int TOTAL_LENGTH = 20; + int TEST_SIZE = 10; + int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; + Buffer buffer = new AutomaticBuffer(32); + String test = StringUtils.repeat('a', TEST_SIZE); + + buffer.putPadString(test, TOTAL_LENGTH); + + byte[] result = buffer.getBuffer(); + String decodedString = new String(result); + String trimString = decodedString.trim(); + junit.framework.Assert.assertEquals(result.length, TOTAL_LENGTH); + + junit.framework.Assert.assertEquals("check data", test, trimString); + + String padString = new String(result, TOTAL_LENGTH - TEST_SIZE, PAD_SIZE, "UTF-8"); + byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; + junit.framework.Assert.assertEquals("check pad", padString, new String(padBytes, Charset.forName("UTF-8"))); + + } + + @Test + public void testPadString_Error() throws Exception { + + Buffer buffer1_1 = new AutomaticBuffer(32); + try { + buffer1_1.putPadString(StringUtils.repeat('a', 11), 10); + } catch (Exception e) { + } + + Buffer buffer1_2 = new AutomaticBuffer(32); + try { + buffer1_2.putPadString(StringUtils.repeat('a', 20), 10); + junit.framework.Assert.fail("error"); + } catch (Exception e) { + } + + Buffer buffer2 = new AutomaticBuffer(32); + buffer2.putPadString(StringUtils.repeat('a', 10), 10); + + Buffer buffer3 = new AutomaticBuffer(5); + buffer3.putPadString(StringUtils.repeat('a', 10), 10); + } + + @Test + public void testPut2PrefixedBytes() throws Exception { + byte[] bytes1 = new byte[2]; + checkPut2PrefixedBytes(bytes1); + + byte[] bytes2 = new byte[0]; + checkPut2PrefixedBytes(bytes2); + + byte[] bytes3 = new byte[Short.MAX_VALUE]; + checkPut2PrefixedBytes(bytes3); + + checkPut2PrefixedBytes(null); + + try { + byte[] bytes4 = new byte[Short.MAX_VALUE+1]; + checkPut2PrefixedBytes(bytes4); + Assert.fail("too large bytes"); + } catch (Exception e) { + } + } + + private void checkPut2PrefixedBytes(byte[] bytes) { + Buffer buffer = new AutomaticBuffer(0); + buffer.put2PrefixedBytes(bytes); + + Buffer copy = new FixedBuffer(buffer.getBuffer()); + Assert.assertArrayEquals(bytes, copy.read2PrefixedBytes()); + } + + @Test + public void testPut4PrefixedBytes() throws Exception { + byte[] bytes1 = new byte[2]; + checkPut4PrefixedBytes(bytes1); + + byte[] bytes2 = new byte[0]; + checkPut4PrefixedBytes(bytes2); + + checkPut4PrefixedBytes(null); + + } + + private void checkPut4PrefixedBytes(byte[] bytes) { + Buffer buffer = new AutomaticBuffer(0); + buffer.put4PrefixedBytes(bytes); + + Buffer copy = new FixedBuffer(buffer.getBuffer()); + Assert.assertArrayEquals(bytes, copy.read4PrefixedBytes()); + } + + @Test + public void testPutPrefixedBytesCheckRange() throws Exception { + Buffer buffer = new AutomaticBuffer(1); + buffer.putPrefixedString(null); + byte[] internalBuffer = buffer.getInternalBuffer(); + // 상속 관계에 의해서 강제로 버퍼 사이즈를 늘어나지 않아도 되는데 사이즈가 늘어남. + Assert.assertEquals(1, internalBuffer.length); + } + + + + @Test + public void testCurrentTime() throws InterruptedException { + Buffer buffer = new AutomaticBuffer(32); + + long l = System.currentTimeMillis(); + buffer.putSVar(l); + logger.trace("currentTime size:{}", buffer.getOffset()); + buffer.setOffset(0); + Assert.assertEquals(buffer.readSVarLong(), l); + + + } + + @Test + public void testPutVarInt() throws Exception { + Buffer buffer = new AutomaticBuffer(0); + buffer.putVar(Integer.MAX_VALUE); + buffer.putVar(Integer.MIN_VALUE); + buffer.putVar(0); + buffer.putVar(1); + buffer.putVar(12345); + + buffer.setOffset(0); + Assert.assertEquals(buffer.readVarInt(), Integer.MAX_VALUE); + Assert.assertEquals(buffer.readVarInt(), Integer.MIN_VALUE); + Assert.assertEquals(buffer.readVarInt(), 0); + Assert.assertEquals(buffer.readVarInt(), 1); + Assert.assertEquals(buffer.readVarInt(), 12345); + } + + @Test + public void testPutVarLong() throws Exception { + Buffer buffer = new AutomaticBuffer(0); + buffer.putVar(Long.MAX_VALUE); + buffer.putVar(Long.MIN_VALUE); + buffer.putVar(0L); + buffer.putVar(1L); + buffer.putVar(12345L); + + buffer.setOffset(0); + Assert.assertEquals(buffer.readVarLong(), Long.MAX_VALUE); + Assert.assertEquals(buffer.readVarLong(), Long.MIN_VALUE); + Assert.assertEquals(buffer.readVarLong(), 0L); + Assert.assertEquals(buffer.readVarLong(), 1L); + Assert.assertEquals(buffer.readVarLong(), 12345L); + } + + @Test + public void testPutSVarLong() throws Exception { + Buffer buffer = new AutomaticBuffer(32); + buffer.putSVar(Long.MAX_VALUE); + buffer.putSVar(Long.MIN_VALUE); + buffer.putSVar(0L); + buffer.putSVar(1L); + buffer.putSVar(12345L); + + buffer.setOffset(0); + Assert.assertEquals(buffer.readSVarLong(), Long.MAX_VALUE); + Assert.assertEquals(buffer.readSVarLong(), Long.MIN_VALUE); + Assert.assertEquals(buffer.readSVarLong(), 0L); + Assert.assertEquals(buffer.readSVarLong(), 1L); + Assert.assertEquals(buffer.readSVarLong(), 12345L); + } + + @Test + public void testPutSVarInt() throws Exception { + Buffer buffer = new AutomaticBuffer(32); + buffer.putSVar(Integer.MAX_VALUE); + buffer.putSVar(Integer.MIN_VALUE); + buffer.putSVar(0); + buffer.putSVar(1); + buffer.putSVar(12345); + + buffer.setOffset(0); + Assert.assertEquals(buffer.readSVarInt(), Integer.MAX_VALUE); + Assert.assertEquals(buffer.readSVarInt(), Integer.MIN_VALUE); + Assert.assertEquals(buffer.readSVarInt(), 0); + Assert.assertEquals(buffer.readSVarInt(), 1); + Assert.assertEquals(buffer.readSVarInt(), 12345); + } + + @Test + public void testPut() throws Exception { + Buffer buffer = new AutomaticBuffer(0); + buffer.put(1); + buffer.put(1L); + buffer.putPrefixedBytes(new byte[10]); + buffer.put((byte)1); + + + } + + @Ignore + @Test + public void testUdp() throws Exception { + // Signature:Header{signature=85, version=100, type=28704} + Buffer buffer = new AutomaticBuffer(10); + buffer.put((byte)85); + buffer.put((byte) 100); + buffer.put((short)28704); + + Buffer read = new FixedBuffer(buffer.getBuffer()); + logger.info("{}", (char)read.readByte()); + logger.info("{}", (char)read.readByte()); + logger.info("{}", (char)read.readByte()); + logger.info("{}", (char)read.readByte()); + + } + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/FixedBufferTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/FixedBufferTest.java index f5b1ba7f9078..d50ba2b9a337 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/FixedBufferTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/FixedBufferTest.java @@ -1,444 +1,444 @@ -package com.nhn.pinpoint.common.buffer; - -import com.nhn.pinpoint.common.util.BytesUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.hadoop.hbase.util.Bytes; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.Random; - -/** - * @author emeroad - */ -public class FixedBufferTest { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - private Random random = new Random(); - - @Test - public void testPutPrefixedBytes() throws Exception { - String test = "test"; - int endExpected = 3333; - testPutPrefixedBytes(test, endExpected); - testPutPrefixedBytes(null, endExpected); - testPutPrefixedBytes("", endExpected); - } - - private void testPutPrefixedBytes(String test, int expected) throws UnsupportedEncodingException { - Buffer buffer = new FixedBuffer(1024); - if (test != null) { - buffer.putPrefixedBytes(test.getBytes("UTF-8")); - } else { - buffer.putPrefixedString(null); - } - - buffer.put(expected); - byte[] buffer1 = buffer.getBuffer(); - - Buffer actual = new FixedBuffer(buffer1); - String s = actual.readPrefixedString(); - Assert.assertEquals(test, s); - - int i = actual.readInt(); - Assert.assertEquals(expected, i); - } - - @Test - public void testPadBytes() throws Exception { - int TOTAL_LENGTH = 20; - int TEST_SIZE = 10; - int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; - Buffer buffer = new FixedBuffer(32); - byte[] test = new byte[10]; - - random.nextBytes(test); - - buffer.putPadBytes(test, TOTAL_LENGTH); - - byte[] result = buffer.getBuffer(); - Assert.assertEquals(result.length, TOTAL_LENGTH); - Assert.assertTrue("check data", Bytes.equals(test, 0, TEST_SIZE, result, 0, TEST_SIZE)); - byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; - Assert.assertTrue("check pad", Bytes.equals(padBytes, 0, TEST_SIZE, result, TEST_SIZE, PAD_SIZE)); - - } - - @Test - public void readPadBytes() { - byte[] bytes = new byte[10]; - random.nextBytes(bytes); - Buffer writeBuffer = new FixedBuffer(32); - writeBuffer.putPadBytes(bytes, 20); - writeBuffer.put(255); - - Buffer readBuffer = new FixedBuffer(writeBuffer.getBuffer()); - byte[] readPadBytes = readBuffer.readPadBytes(20); - Assert.assertArrayEquals(bytes, Arrays.copyOf(readPadBytes, 10)); - int readInt = readBuffer.readInt(); - Assert.assertEquals(255, readInt); - } - - - @Test - public void testPadBytes_Error() throws Exception { - - Buffer buffer1_1 = new FixedBuffer(32); - try { - buffer1_1.putPadBytes(new byte[11], 10); - } catch (Exception e) { - } - - Buffer buffer1_2 = new FixedBuffer(32); - try { - buffer1_2.putPadBytes(new byte[20], 10); - Assert.fail("error"); - } catch (Exception e) { - } - - Buffer buffer2 = new FixedBuffer(32); - buffer2.putPadBytes(new byte[10], 10); - - } - - @Test - public void testPadString() throws Exception { - int TOTAL_LENGTH = 20; - int TEST_SIZE = 10; - int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; - Buffer buffer= new FixedBuffer(32); - String test = StringUtils.repeat('a', TEST_SIZE); - - buffer.putPadString(test, TOTAL_LENGTH); - - byte[] result = buffer.getBuffer(); - String decodedString = new String(result); - String trimString = decodedString.trim(); - Assert.assertEquals(result.length, TOTAL_LENGTH); - - Assert.assertEquals("check data", test, trimString); - - String padString = new String(result, TOTAL_LENGTH - TEST_SIZE, PAD_SIZE, "UTF-8"); - byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; - Assert.assertEquals("check pad", padString, new String(padBytes, Charset.forName("UTF-8"))); - - } - - @Test - public void readPadString() { - String testString = StringUtils.repeat('a', 10); - Buffer writeBuffer = new FixedBuffer(32); - writeBuffer.putPadString(testString, 20); - writeBuffer.put(255); - - Buffer readBuffer = new FixedBuffer(writeBuffer.getBuffer()); - String readPadString = readBuffer.readPadString(20); - Assert.assertEquals(testString, readPadString.substring(0, 10)); - int readInt = readBuffer.readInt(); - Assert.assertEquals(255, readInt); - } - - @Test - public void readPadStringAndRightTrim() { - String testString = StringUtils.repeat('a', 10); - Buffer writeBuffer = new FixedBuffer(32); - writeBuffer.putPadString(testString, 20); - writeBuffer.put(255); - - Buffer readBuffer = new FixedBuffer(writeBuffer.getBuffer()); - String readPadString = readBuffer.readPadStringAndRightTrim(20); - Assert.assertEquals(testString, readPadString); - int readInt = readBuffer.readInt(); - Assert.assertEquals(255, readInt); - } - - @Test - public void testPadString_Error() throws Exception { - - Buffer buffer1_1 = new FixedBuffer(32); - try { - buffer1_1.putPadString(StringUtils.repeat('a', 11), 10); - } catch (Exception e) { - } - - Buffer buffer1_2 = new FixedBuffer(32); - try { - buffer1_2.putPadString(StringUtils.repeat('a', 20), 10); - Assert.fail("error"); - } catch (Exception e) { - } - - Buffer buffer2 = new FixedBuffer(32); - buffer2.putPadString(StringUtils.repeat('a', 10), 10); - } - - @Test - public void testPut2PrefixedBytes() throws Exception { - String test = "test"; - int endExpected = 3333; - - checkPut2PrefixedBytes(test, endExpected); - checkPut2PrefixedBytes(null, endExpected); - checkPut2PrefixedBytes("", endExpected); - - byte[] bytes = new byte[Short.MAX_VALUE]; - checkPut2PrefixedBytes(BytesUtils.toString(bytes), endExpected, Short.MAX_VALUE * 2); - - try { - byte[] bytes2 = new byte[Short.MAX_VALUE + 1]; - checkPut2PrefixedBytes(BytesUtils.toString(bytes2), endExpected, Short.MAX_VALUE * 2); - Assert.fail("too large bytes"); - } catch (Exception e) { - } - - } - - private void checkPut2PrefixedBytes(String test, int expected) throws UnsupportedEncodingException { - checkPut2PrefixedBytes(test, expected, 1024); - } - - private void checkPut2PrefixedBytes(String test, int expected, int bufferSize) throws UnsupportedEncodingException { - Buffer buffer = new FixedBuffer(bufferSize); - if (test != null) { - buffer.put2PrefixedBytes(test.getBytes("UTF-8")); - } else { - buffer.put2PrefixedBytes(null); - } - - buffer.put(expected); - byte[] buffer1 = buffer.getBuffer(); - - Buffer actual = new FixedBuffer(buffer1); - String s = actual.read2PrefixedString(); - Assert.assertEquals(test, s); - - int i = actual.readInt(); - Assert.assertEquals(expected, i); - } - - @Test - public void testPut4PrefixedBytes() throws Exception { - String test = "test"; - int endExpected = 3333; - - checkPut4PrefixedBytes(test, endExpected); - checkPut4PrefixedBytes(null, endExpected); - checkPut4PrefixedBytes("", endExpected); - - } - - private void checkPut4PrefixedBytes(String test, int expected) throws UnsupportedEncodingException { - Buffer buffer = new FixedBuffer(1024); - if (test != null) { - buffer.put4PrefixedBytes(test.getBytes("UTF-8")); - } else { - buffer.put4PrefixedBytes(null); - } - - buffer.put(expected); - byte[] buffer1 = buffer.getBuffer(); - - Buffer actual = new FixedBuffer(buffer1); - String s = actual.read4PrefixedString(); - Assert.assertEquals(test, s); - - int i = actual.readInt(); - Assert.assertEquals(expected, i); - } - - @Test - public void testReadByte() throws Exception { - - } - - @Test - public void testReadBoolean() throws Exception { - - } - - @Test - public void testReadInt() throws Exception { - - } - - @Test - public void testReadLong() throws Exception { - - } - - - - - @Test - public void testReadPrefixedString() throws Exception { - - } - - @Test - public void testRead4PrefixedString() throws Exception { - String value = "test"; - byte[] length = Bytes.toBytes(value.length()); - byte[] string = Bytes.toBytes(value); - byte[] result = Bytes.add(length, string); - - - Buffer buffer = new FixedBuffer(result); - String prefixedString = buffer.read4PrefixedString(); - Assert.assertEquals(prefixedString, value); - - } - - @Test - public void testRead4PrefixedString_Null() throws Exception { - byte[] length = Bytes.toBytes(-1); - - - Buffer buffer = new FixedBuffer(length); - String prefixedString = buffer.read4PrefixedString(); - Assert.assertEquals(prefixedString, null); - - } - - @Test - public void testPut() throws Exception { - checkUnsignedByte(255); - - checkUnsignedByte(0); - } - - @Test - public void testPutVar32() throws Exception { - checkVarInt(Integer.MAX_VALUE, 5); - checkVarInt(25, 1); - checkVarInt(100, 1); - - checkVarInt(Integer.MIN_VALUE, 10); - - checkVarInt(0, -1); - checkVarInt(Integer.MAX_VALUE / 2, -1); - checkVarInt(Integer.MAX_VALUE / 10, -1); - checkVarInt(Integer.MAX_VALUE / 10000, -1); - - checkVarInt(Integer.MIN_VALUE / 2, -1); - checkVarInt(Integer.MIN_VALUE / 10, -1); - checkVarInt(Integer.MIN_VALUE / 10000, -1); - - } - - private void checkVarInt(int v, int offset) { - Buffer buffer = new FixedBuffer(32); - buffer.putVar(v); - if (offset != -1) { - Assert.assertEquals(buffer.getOffset(), offset); - } else { - logger.info("{} offsetSize:{}", v, buffer.getOffset()); - } - buffer.setOffset(0); - int readV = buffer.readVarInt(); - Assert.assertEquals(readV, v); - } - - @Test - public void testPutSVar32() throws Exception { - // 63이 1바이트 경계. - checkSVarInt(63, -1); - // 8191이 2바이트 경계 - checkSVarInt((1024*8)-1, -1); - - checkSVarInt(3, -1); - - checkSVarInt(Integer.MAX_VALUE, 5); - - checkSVarInt(Integer.MIN_VALUE, 5); - - checkSVarInt(0, -1); - checkSVarInt(Integer.MAX_VALUE / 2, -1); - checkSVarInt(Integer.MAX_VALUE / 10, -1); - checkSVarInt(Integer.MAX_VALUE / 10000, -1); - - checkSVarInt(Integer.MIN_VALUE / 2, -1); - checkSVarInt(Integer.MIN_VALUE / 10, -1); - checkSVarInt(Integer.MIN_VALUE / 10000, -1); - - - } - - private void checkSVarInt(int v, int offset) { - Buffer buffer = new FixedBuffer(32); - buffer.putSVar(v); - if (offset != -1) { - Assert.assertEquals(buffer.getOffset(), offset); - } else { - logger.info("{} offsetSize:{}", v, buffer.getOffset()); - } - buffer.setOffset(0); - int readV = buffer.readSVarInt(); - Assert.assertEquals(readV, v); - } - - @Test - public void testPutVar64() throws Exception { - - } - - private void checkUnsignedByte(int value) { - Buffer buffer = new FixedBuffer(1024); - buffer.put((byte) value); - byte[] buffer1 = buffer.getBuffer(); - - Buffer reader = new FixedBuffer(buffer1); - int i = reader.readUnsignedByte(); - Assert.assertEquals(value, i); - } - - - @Test - public void testGetBuffer() throws Exception { - Buffer buffer = new FixedBuffer(4); - buffer.put(1); - Assert.assertEquals(buffer.getOffset(), 4); - Assert.assertEquals(buffer.getBuffer().length, 4); - } - - @Test - public void testSliceGetBuffer() throws Exception { - Buffer buffer = new FixedBuffer(5); - buffer.put(1); - Assert.assertEquals(buffer.getOffset(), 4); - Assert.assertEquals(buffer.getBuffer().length, 4); - - byte[] buffer1 = buffer.getBuffer(); - byte[] buffer2 = buffer.getBuffer(); - Assert.assertTrue(buffer1 != buffer2); - - } - - @Test - public void testBoolean() { - Buffer buffer = new FixedBuffer(16); - buffer.put(true); - buffer.put(false); - - Buffer read = new FixedBuffer(buffer.getBuffer()); - boolean b = read.readBoolean(); - Assert.assertEquals(true, b); - - boolean c = read.readBoolean(); - Assert.assertEquals(false, c); - } - - @Test - public void testGetOffset() throws Exception { - Buffer buffer = new FixedBuffer(); - Assert.assertEquals(buffer.getOffset(), 0); - - buffer.put(4); - Assert.assertEquals(buffer.getOffset(), 4); - - } -} +package com.nhn.pinpoint.common.buffer; + +import com.nhn.pinpoint.common.util.BytesUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Random; + +/** + * @author emeroad + */ +public class FixedBufferTest { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Random random = new Random(); + + @Test + public void testPutPrefixedBytes() throws Exception { + String test = "test"; + int endExpected = 3333; + testPutPrefixedBytes(test, endExpected); + testPutPrefixedBytes(null, endExpected); + testPutPrefixedBytes("", endExpected); + } + + private void testPutPrefixedBytes(String test, int expected) throws UnsupportedEncodingException { + Buffer buffer = new FixedBuffer(1024); + if (test != null) { + buffer.putPrefixedBytes(test.getBytes("UTF-8")); + } else { + buffer.putPrefixedString(null); + } + + buffer.put(expected); + byte[] buffer1 = buffer.getBuffer(); + + Buffer actual = new FixedBuffer(buffer1); + String s = actual.readPrefixedString(); + Assert.assertEquals(test, s); + + int i = actual.readInt(); + Assert.assertEquals(expected, i); + } + + @Test + public void testPadBytes() throws Exception { + int TOTAL_LENGTH = 20; + int TEST_SIZE = 10; + int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; + Buffer buffer = new FixedBuffer(32); + byte[] test = new byte[10]; + + random.nextBytes(test); + + buffer.putPadBytes(test, TOTAL_LENGTH); + + byte[] result = buffer.getBuffer(); + Assert.assertEquals(result.length, TOTAL_LENGTH); + Assert.assertTrue("check data", Bytes.equals(test, 0, TEST_SIZE, result, 0, TEST_SIZE)); + byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; + Assert.assertTrue("check pad", Bytes.equals(padBytes, 0, TEST_SIZE, result, TEST_SIZE, PAD_SIZE)); + + } + + @Test + public void readPadBytes() { + byte[] bytes = new byte[10]; + random.nextBytes(bytes); + Buffer writeBuffer = new FixedBuffer(32); + writeBuffer.putPadBytes(bytes, 20); + writeBuffer.put(255); + + Buffer readBuffer = new FixedBuffer(writeBuffer.getBuffer()); + byte[] readPadBytes = readBuffer.readPadBytes(20); + Assert.assertArrayEquals(bytes, Arrays.copyOf(readPadBytes, 10)); + int readInt = readBuffer.readInt(); + Assert.assertEquals(255, readInt); + } + + + @Test + public void testPadBytes_Error() throws Exception { + + Buffer buffer1_1 = new FixedBuffer(32); + try { + buffer1_1.putPadBytes(new byte[11], 10); + } catch (Exception e) { + } + + Buffer buffer1_2 = new FixedBuffer(32); + try { + buffer1_2.putPadBytes(new byte[20], 10); + Assert.fail("error"); + } catch (Exception e) { + } + + Buffer buffer2 = new FixedBuffer(32); + buffer2.putPadBytes(new byte[10], 10); + + } + + @Test + public void testPadString() throws Exception { + int TOTAL_LENGTH = 20; + int TEST_SIZE = 10; + int PAD_SIZE = TOTAL_LENGTH - TEST_SIZE; + Buffer buffer= new FixedBuffer(32); + String test = StringUtils.repeat('a', TEST_SIZE); + + buffer.putPadString(test, TOTAL_LENGTH); + + byte[] result = buffer.getBuffer(); + String decodedString = new String(result); + String trimString = decodedString.trim(); + Assert.assertEquals(result.length, TOTAL_LENGTH); + + Assert.assertEquals("check data", test, trimString); + + String padString = new String(result, TOTAL_LENGTH - TEST_SIZE, PAD_SIZE, "UTF-8"); + byte[] padBytes = new byte[TOTAL_LENGTH - TEST_SIZE]; + Assert.assertEquals("check pad", padString, new String(padBytes, Charset.forName("UTF-8"))); + + } + + @Test + public void readPadString() { + String testString = StringUtils.repeat('a', 10); + Buffer writeBuffer = new FixedBuffer(32); + writeBuffer.putPadString(testString, 20); + writeBuffer.put(255); + + Buffer readBuffer = new FixedBuffer(writeBuffer.getBuffer()); + String readPadString = readBuffer.readPadString(20); + Assert.assertEquals(testString, readPadString.substring(0, 10)); + int readInt = readBuffer.readInt(); + Assert.assertEquals(255, readInt); + } + + @Test + public void readPadStringAndRightTrim() { + String testString = StringUtils.repeat('a', 10); + Buffer writeBuffer = new FixedBuffer(32); + writeBuffer.putPadString(testString, 20); + writeBuffer.put(255); + + Buffer readBuffer = new FixedBuffer(writeBuffer.getBuffer()); + String readPadString = readBuffer.readPadStringAndRightTrim(20); + Assert.assertEquals(testString, readPadString); + int readInt = readBuffer.readInt(); + Assert.assertEquals(255, readInt); + } + + @Test + public void testPadString_Error() throws Exception { + + Buffer buffer1_1 = new FixedBuffer(32); + try { + buffer1_1.putPadString(StringUtils.repeat('a', 11), 10); + } catch (Exception e) { + } + + Buffer buffer1_2 = new FixedBuffer(32); + try { + buffer1_2.putPadString(StringUtils.repeat('a', 20), 10); + Assert.fail("error"); + } catch (Exception e) { + } + + Buffer buffer2 = new FixedBuffer(32); + buffer2.putPadString(StringUtils.repeat('a', 10), 10); + } + + @Test + public void testPut2PrefixedBytes() throws Exception { + String test = "test"; + int endExpected = 3333; + + checkPut2PrefixedBytes(test, endExpected); + checkPut2PrefixedBytes(null, endExpected); + checkPut2PrefixedBytes("", endExpected); + + byte[] bytes = new byte[Short.MAX_VALUE]; + checkPut2PrefixedBytes(BytesUtils.toString(bytes), endExpected, Short.MAX_VALUE * 2); + + try { + byte[] bytes2 = new byte[Short.MAX_VALUE + 1]; + checkPut2PrefixedBytes(BytesUtils.toString(bytes2), endExpected, Short.MAX_VALUE * 2); + Assert.fail("too large bytes"); + } catch (Exception e) { + } + + } + + private void checkPut2PrefixedBytes(String test, int expected) throws UnsupportedEncodingException { + checkPut2PrefixedBytes(test, expected, 1024); + } + + private void checkPut2PrefixedBytes(String test, int expected, int bufferSize) throws UnsupportedEncodingException { + Buffer buffer = new FixedBuffer(bufferSize); + if (test != null) { + buffer.put2PrefixedBytes(test.getBytes("UTF-8")); + } else { + buffer.put2PrefixedBytes(null); + } + + buffer.put(expected); + byte[] buffer1 = buffer.getBuffer(); + + Buffer actual = new FixedBuffer(buffer1); + String s = actual.read2PrefixedString(); + Assert.assertEquals(test, s); + + int i = actual.readInt(); + Assert.assertEquals(expected, i); + } + + @Test + public void testPut4PrefixedBytes() throws Exception { + String test = "test"; + int endExpected = 3333; + + checkPut4PrefixedBytes(test, endExpected); + checkPut4PrefixedBytes(null, endExpected); + checkPut4PrefixedBytes("", endExpected); + + } + + private void checkPut4PrefixedBytes(String test, int expected) throws UnsupportedEncodingException { + Buffer buffer = new FixedBuffer(1024); + if (test != null) { + buffer.put4PrefixedBytes(test.getBytes("UTF-8")); + } else { + buffer.put4PrefixedBytes(null); + } + + buffer.put(expected); + byte[] buffer1 = buffer.getBuffer(); + + Buffer actual = new FixedBuffer(buffer1); + String s = actual.read4PrefixedString(); + Assert.assertEquals(test, s); + + int i = actual.readInt(); + Assert.assertEquals(expected, i); + } + + @Test + public void testReadByte() throws Exception { + + } + + @Test + public void testReadBoolean() throws Exception { + + } + + @Test + public void testReadInt() throws Exception { + + } + + @Test + public void testReadLong() throws Exception { + + } + + + + + @Test + public void testReadPrefixedString() throws Exception { + + } + + @Test + public void testRead4PrefixedString() throws Exception { + String value = "test"; + byte[] length = Bytes.toBytes(value.length()); + byte[] string = Bytes.toBytes(value); + byte[] result = Bytes.add(length, string); + + + Buffer buffer = new FixedBuffer(result); + String prefixedString = buffer.read4PrefixedString(); + Assert.assertEquals(prefixedString, value); + + } + + @Test + public void testRead4PrefixedString_Null() throws Exception { + byte[] length = Bytes.toBytes(-1); + + + Buffer buffer = new FixedBuffer(length); + String prefixedString = buffer.read4PrefixedString(); + Assert.assertEquals(prefixedString, null); + + } + + @Test + public void testPut() throws Exception { + checkUnsignedByte(255); + + checkUnsignedByte(0); + } + + @Test + public void testPutVar32() throws Exception { + checkVarInt(Integer.MAX_VALUE, 5); + checkVarInt(25, 1); + checkVarInt(100, 1); + + checkVarInt(Integer.MIN_VALUE, 10); + + checkVarInt(0, -1); + checkVarInt(Integer.MAX_VALUE / 2, -1); + checkVarInt(Integer.MAX_VALUE / 10, -1); + checkVarInt(Integer.MAX_VALUE / 10000, -1); + + checkVarInt(Integer.MIN_VALUE / 2, -1); + checkVarInt(Integer.MIN_VALUE / 10, -1); + checkVarInt(Integer.MIN_VALUE / 10000, -1); + + } + + private void checkVarInt(int v, int offset) { + Buffer buffer = new FixedBuffer(32); + buffer.putVar(v); + if (offset != -1) { + Assert.assertEquals(buffer.getOffset(), offset); + } else { + logger.info("{} offsetSize:{}", v, buffer.getOffset()); + } + buffer.setOffset(0); + int readV = buffer.readVarInt(); + Assert.assertEquals(readV, v); + } + + @Test + public void testPutSVar32() throws Exception { + // 63이 1바이트 경계. + checkSVarInt(63, -1); + // 8191이 2바이트 경계 + checkSVarInt((1024*8)-1, -1); + + checkSVarInt(3, -1); + + checkSVarInt(Integer.MAX_VALUE, 5); + + checkSVarInt(Integer.MIN_VALUE, 5); + + checkSVarInt(0, -1); + checkSVarInt(Integer.MAX_VALUE / 2, -1); + checkSVarInt(Integer.MAX_VALUE / 10, -1); + checkSVarInt(Integer.MAX_VALUE / 10000, -1); + + checkSVarInt(Integer.MIN_VALUE / 2, -1); + checkSVarInt(Integer.MIN_VALUE / 10, -1); + checkSVarInt(Integer.MIN_VALUE / 10000, -1); + + + } + + private void checkSVarInt(int v, int offset) { + Buffer buffer = new FixedBuffer(32); + buffer.putSVar(v); + if (offset != -1) { + Assert.assertEquals(buffer.getOffset(), offset); + } else { + logger.info("{} offsetSize:{}", v, buffer.getOffset()); + } + buffer.setOffset(0); + int readV = buffer.readSVarInt(); + Assert.assertEquals(readV, v); + } + + @Test + public void testPutVar64() throws Exception { + + } + + private void checkUnsignedByte(int value) { + Buffer buffer = new FixedBuffer(1024); + buffer.put((byte) value); + byte[] buffer1 = buffer.getBuffer(); + + Buffer reader = new FixedBuffer(buffer1); + int i = reader.readUnsignedByte(); + Assert.assertEquals(value, i); + } + + + @Test + public void testGetBuffer() throws Exception { + Buffer buffer = new FixedBuffer(4); + buffer.put(1); + Assert.assertEquals(buffer.getOffset(), 4); + Assert.assertEquals(buffer.getBuffer().length, 4); + } + + @Test + public void testSliceGetBuffer() throws Exception { + Buffer buffer = new FixedBuffer(5); + buffer.put(1); + Assert.assertEquals(buffer.getOffset(), 4); + Assert.assertEquals(buffer.getBuffer().length, 4); + + byte[] buffer1 = buffer.getBuffer(); + byte[] buffer2 = buffer.getBuffer(); + Assert.assertTrue(buffer1 != buffer2); + + } + + @Test + public void testBoolean() { + Buffer buffer = new FixedBuffer(16); + buffer.put(true); + buffer.put(false); + + Buffer read = new FixedBuffer(buffer.getBuffer()); + boolean b = read.readBoolean(); + Assert.assertEquals(true, b); + + boolean c = read.readBoolean(); + Assert.assertEquals(false, c); + } + + @Test + public void testGetOffset() throws Exception { + Buffer buffer = new FixedBuffer(); + Assert.assertEquals(buffer.getOffset(), 0); + + buffer.put(4); + Assert.assertEquals(buffer.getOffset(), 4); + + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBufferTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBufferTest.java index ff7eebde469d..bc37e50fe14c 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBufferTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetAutomaticBufferTest.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.common.buffer; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class OffsetAutomaticBufferTest { - @Test - public void testGetBuffer() throws Exception { - final int putValue = 10; - Buffer buffer = new OffsetAutomaticBuffer(new byte[10], 2); - buffer.put(putValue); - byte[] intBuffer = buffer.getBuffer(); - Assert.assertEquals(intBuffer.length, 4); - - Buffer read = new FixedBuffer(intBuffer); - int value = read.readInt(); - Assert.assertEquals(putValue, value); - } -} +package com.nhn.pinpoint.common.buffer; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class OffsetAutomaticBufferTest { + @Test + public void testGetBuffer() throws Exception { + final int putValue = 10; + Buffer buffer = new OffsetAutomaticBuffer(new byte[10], 2); + buffer.put(putValue); + byte[] intBuffer = buffer.getBuffer(); + Assert.assertEquals(intBuffer.length, 4); + + Buffer read = new FixedBuffer(intBuffer); + int value = read.readInt(); + Assert.assertEquals(putValue, value); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBufferTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBufferTest.java index b4e21e8b7eac..9d6119dd8462 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBufferTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/buffer/OffsetFixedBufferTest.java @@ -1,38 +1,38 @@ -package com.nhn.pinpoint.common.buffer; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class OffsetFixedBufferTest { - - @Test - public void testFixedBuffer() throws Exception { - new OffsetFixedBuffer(new byte[10], 10); - try { - new OffsetFixedBuffer(new byte[10], 11); - Assert.fail(); - } catch (Exception e) { - } - try { - new OffsetFixedBuffer(new byte[10], -1); - Assert.fail(); - } catch (Exception e) { - } - } - - @Test - public void testGetBuffer() throws Exception { - final int putValue = 10; - Buffer buffer = new OffsetFixedBuffer(new byte[10], 2); - buffer.put(putValue); - byte[] intBuffer = buffer.getBuffer(); - Assert.assertEquals(intBuffer.length, 4); - - Buffer read = new FixedBuffer(intBuffer); - int value = read.readInt(); - Assert.assertEquals(putValue, value); - } -} +package com.nhn.pinpoint.common.buffer; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class OffsetFixedBufferTest { + + @Test + public void testFixedBuffer() throws Exception { + new OffsetFixedBuffer(new byte[10], 10); + try { + new OffsetFixedBuffer(new byte[10], 11); + Assert.fail(); + } catch (Exception e) { + } + try { + new OffsetFixedBuffer(new byte[10], -1); + Assert.fail(); + } catch (Exception e) { + } + } + + @Test + public void testGetBuffer() throws Exception { + final int putValue = 10; + Buffer buffer = new OffsetFixedBuffer(new byte[10], 2); + buffer.put(putValue); + byte[] intBuffer = buffer.getBuffer(); + Assert.assertEquals(intBuffer.length, 4); + + Buffer read = new FixedBuffer(intBuffer); + int value = read.readInt(); + Assert.assertEquals(putValue, value); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2Test.java b/commons/src/test/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2Test.java index 6658d093bc81..8a324fa74383 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2Test.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/hbase/HbaseTemplate2Test.java @@ -1,70 +1,69 @@ -package com.nhn.pinpoint.common.hbase; - -import com.nhn.pinpoint.common.util.PropertyUtils; -import junit.framework.Assert; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.HBaseConfiguration; -import org.apache.hadoop.hbase.TableNotFoundException; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.hadoop.hbase.HbaseConfigurationFactoryBean; -import org.springframework.data.hadoop.hbase.HbaseSystemException; - -import java.io.IOException; -import java.util.Properties; - - -/** - * @author emeroad - */ -public class HbaseTemplate2Test { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private static HbaseConfigurationFactoryBean hbaseConfigurationFactoryBean; - - @BeforeClass - public static void beforeClass() throws IOException { - String path = HbaseTemplate2Test.class.getClassLoader().getResource("test-hbase.properties").getPath(); - Properties properties = PropertyUtils.readProperties(path); - - Configuration cfg = HBaseConfiguration.create(); - cfg.set("hbase.zookeeper.quorum", properties.getProperty("hbase.client.host")); - cfg.set("hbase.zookeeper.property.clientPort", properties.getProperty("hbase.client.port")); - hbaseConfigurationFactoryBean = new HbaseConfigurationFactoryBean(); - hbaseConfigurationFactoryBean.setConfiguration(cfg); - hbaseConfigurationFactoryBean.afterPropertiesSet(); - } - - @AfterClass - public static void afterClass() { - if (hbaseConfigurationFactoryBean != null) { - hbaseConfigurationFactoryBean.destroy(); - } - - } - - - @Test - public void notExist() throws Exception { - - HbaseTemplate2 hbaseTemplate2 = new HbaseTemplate2(); - hbaseTemplate2.setConfiguration(hbaseConfigurationFactoryBean.getObject()); - hbaseTemplate2.afterPropertiesSet(); - - try { - hbaseTemplate2.put("NOT_EXIST", new byte[0], "familyName".getBytes(), "columnName".getBytes(), new byte[0]); - Assert.fail("exceptions"); - } catch (HbaseSystemException e) { - if (!(e.getCause().getCause() instanceof TableNotFoundException)) { - Assert.fail("unexpected exception :" + e.getCause()); - } - } finally { - hbaseTemplate2.destroy(); - } - - - } -} +package com.nhn.pinpoint.common.hbase; + +import com.nhn.pinpoint.common.util.PropertyUtils; +import junit.framework.Assert; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.TableNotFoundException; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.hadoop.hbase.HbaseConfigurationFactoryBean; +import org.springframework.data.hadoop.hbase.HbaseSystemException; + +import java.io.IOException; +import java.util.Properties; + + +/** + * @author emeroad + */ +public class HbaseTemplate2Test { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static HbaseConfigurationFactoryBean hbaseConfigurationFactoryBean; + + @BeforeClass + public static void beforeClass() throws IOException { + Properties properties = PropertyUtils.loadPropertyFromClassPath("test-hbase.properties"); + + Configuration cfg = HBaseConfiguration.create(); + cfg.set("hbase.zookeeper.quorum", properties.getProperty("hbase.client.host")); + cfg.set("hbase.zookeeper.property.clientPort", properties.getProperty("hbase.client.port")); + hbaseConfigurationFactoryBean = new HbaseConfigurationFactoryBean(); + hbaseConfigurationFactoryBean.setConfiguration(cfg); + hbaseConfigurationFactoryBean.afterPropertiesSet(); + } + + @AfterClass + public static void afterClass() { + if (hbaseConfigurationFactoryBean != null) { + hbaseConfigurationFactoryBean.destroy(); + } + + } + + + @Test + public void notExist() throws Exception { + + HbaseTemplate2 hbaseTemplate2 = new HbaseTemplate2(); + hbaseTemplate2.setConfiguration(hbaseConfigurationFactoryBean.getObject()); + hbaseTemplate2.afterPropertiesSet(); + + try { + hbaseTemplate2.put("NOT_EXIST", new byte[0], "familyName".getBytes(), "columnName".getBytes(), new byte[0]); + Assert.fail("exceptions"); + } catch (HbaseSystemException e) { + if (!(e.getCause().getCause() instanceof TableNotFoundException)) { + Assert.fail("unexpected exception :" + e.getCause()); + } + } finally { + hbaseTemplate2.destroy(); + } + + + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/AnnotationTranscoderTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/AnnotationTranscoderTest.java index 355a2df55d3e..9b32677a60d8 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/AnnotationTranscoderTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/AnnotationTranscoderTest.java @@ -1,146 +1,146 @@ -package com.nhn.pinpoint.common.util; - - -import com.nhn.pinpoint.common.bo.IntStringValue; -import com.nhn.pinpoint.thrift.dto.TIntStringValue; -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.protocol.TProtocol; -import org.apache.thrift.transport.TIOStreamTransport; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayOutputStream; -import java.util.Arrays; -import java.util.Date; - -/** - * @author emeroad - */ -public class AnnotationTranscoderTest { - - private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - @Test - public void testDecode() throws Exception { - typeCode("test"); - typeCode(""); - typeCode("adfesdfsesdfsdfserfsdfsdfe"); - - typeCode(1); - typeCode(0); - typeCode(-1212); - - typeCode((short) 4); - typeCode((short) -124); - - typeCode(2L); - typeCode(-22342342L); - - typeCode(3f); - typeCode(123.3f); - - typeCode(4D); - typeCode(-124D); - - typeCode((byte) 4); - typeCode((byte) -14); - - typeCode(true); - typeCode(false); - - typeCode(null); - - typeUnsupportCode(new Date()); - - typeBinaryCode(new byte[]{12, 3, 4, 1, 23, 4, 1, 2, 3, 4, 4}); - - } - - private void typeCode(Object value) { - AnnotationTranscoder transcoder = new AnnotationTranscoder(); - - byte typeCode = transcoder.getTypeCode(value); - byte[] bytes = transcoder.encode(value, typeCode); - Object decode = transcoder.decode(typeCode, bytes); - - Assert.assertEquals(value, decode); - } - - private void typeUnsupportCode(Object value) { - AnnotationTranscoder transcoder = new AnnotationTranscoder(); - - byte typeCode = transcoder.getTypeCode(value); - byte[] bytes = transcoder.encode(value, typeCode); - Object decode = transcoder.decode(typeCode, bytes); - - Assert.assertEquals(value.toString(), decode.toString()); - } - - private void typeBinaryCode(byte[] value) { - AnnotationTranscoder transcoder = new AnnotationTranscoder(); - - byte typeCode = transcoder.getTypeCode(value); - byte[] bytes = transcoder.encode(value, typeCode); - Object decode = transcoder.decode(typeCode, bytes); - - Assert.assertArrayEquals(value, (byte[]) decode); - } - - @Test - public void testGetTypeCode() throws Exception { - int i = 2 << 8; - System.out.println(i); - write(i); - int j = 3 << 8; - System.out.println(j); - write(j); - write(10); - write(512); - write(256); - - - } - - @Test - public void testIntString() { - - testIntString(-1, ""); - testIntString(0, ""); - testIntString(1, ""); - testIntString(Integer.MAX_VALUE, "test"); - testIntString(Integer.MIN_VALUE, "test"); - - // null일때 0인자열로 생각하는 문제점이 있음. - testIntString(2, null); - } - - private void testIntString(int intValue, String stringValue) { - AnnotationTranscoder transcoder = new AnnotationTranscoder(); - TIntStringValue tIntStringValue = new TIntStringValue(intValue); - tIntStringValue.setStringValue(stringValue); - byte[] encode = transcoder.encode(tIntStringValue, AnnotationTranscoder.CODE_INT_STRING); - IntStringValue decode = (IntStringValue) transcoder.decode(AnnotationTranscoder.CODE_INT_STRING, encode); - Assert.assertEquals(tIntStringValue.getIntValue(), decode.getIntValue()); - Assert.assertEquals(tIntStringValue.getStringValue(), decode.getStringValue()); - } - - private void write(int value) throws TException { - TCompactProtocol.Factory factory = new TCompactProtocol.Factory(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(16); - TIOStreamTransport transport = new TIOStreamTransport(baos); - TProtocol protocol = factory.getProtocol(transport); - - protocol.writeI32(value); - byte[] buffer = baos.toByteArray(); - logger.info(Arrays.toString(buffer)); - } - - @Test - public void testEncode() throws Exception { - - } -} +package com.nhn.pinpoint.common.util; + + +import com.nhn.pinpoint.common.bo.IntStringValue; +import com.nhn.pinpoint.thrift.dto.TIntStringValue; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.transport.TIOStreamTransport; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.util.Arrays; +import java.util.Date; + +/** + * @author emeroad + */ +public class AnnotationTranscoderTest { + + private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Test + public void testDecode() throws Exception { + typeCode("test"); + typeCode(""); + typeCode("adfesdfsesdfsdfserfsdfsdfe"); + + typeCode(1); + typeCode(0); + typeCode(-1212); + + typeCode((short) 4); + typeCode((short) -124); + + typeCode(2L); + typeCode(-22342342L); + + typeCode(3f); + typeCode(123.3f); + + typeCode(4D); + typeCode(-124D); + + typeCode((byte) 4); + typeCode((byte) -14); + + typeCode(true); + typeCode(false); + + typeCode(null); + + typeUnsupportCode(new Date()); + + typeBinaryCode(new byte[]{12, 3, 4, 1, 23, 4, 1, 2, 3, 4, 4}); + + } + + private void typeCode(Object value) { + AnnotationTranscoder transcoder = new AnnotationTranscoder(); + + byte typeCode = transcoder.getTypeCode(value); + byte[] bytes = transcoder.encode(value, typeCode); + Object decode = transcoder.decode(typeCode, bytes); + + Assert.assertEquals(value, decode); + } + + private void typeUnsupportCode(Object value) { + AnnotationTranscoder transcoder = new AnnotationTranscoder(); + + byte typeCode = transcoder.getTypeCode(value); + byte[] bytes = transcoder.encode(value, typeCode); + Object decode = transcoder.decode(typeCode, bytes); + + Assert.assertEquals(value.toString(), decode.toString()); + } + + private void typeBinaryCode(byte[] value) { + AnnotationTranscoder transcoder = new AnnotationTranscoder(); + + byte typeCode = transcoder.getTypeCode(value); + byte[] bytes = transcoder.encode(value, typeCode); + Object decode = transcoder.decode(typeCode, bytes); + + Assert.assertArrayEquals(value, (byte[]) decode); + } + + @Test + public void testGetTypeCode() throws Exception { + int i = 2 << 8; + logger.debug("{}", i); + write(i); + int j = 3 << 8; + logger.debug("{}", j); + write(j); + write(10); + write(512); + write(256); + + + } + + @Test + public void testIntString() { + + testIntString(-1, ""); + testIntString(0, ""); + testIntString(1, ""); + testIntString(Integer.MAX_VALUE, "test"); + testIntString(Integer.MIN_VALUE, "test"); + + // null일때 0인자열로 생각하는 문제점이 있음. + testIntString(2, null); + } + + private void testIntString(int intValue, String stringValue) { + AnnotationTranscoder transcoder = new AnnotationTranscoder(); + TIntStringValue tIntStringValue = new TIntStringValue(intValue); + tIntStringValue.setStringValue(stringValue); + byte[] encode = transcoder.encode(tIntStringValue, AnnotationTranscoder.CODE_INT_STRING); + IntStringValue decode = (IntStringValue) transcoder.decode(AnnotationTranscoder.CODE_INT_STRING, encode); + Assert.assertEquals(tIntStringValue.getIntValue(), decode.getIntValue()); + Assert.assertEquals(tIntStringValue.getStringValue(), decode.getStringValue()); + } + + private void write(int value) throws TException { + TCompactProtocol.Factory factory = new TCompactProtocol.Factory(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(16); + TIOStreamTransport transport = new TIOStreamTransport(baos); + TProtocol protocol = factory.getProtocol(transport); + + protocol.writeI32(value); + byte[] buffer = baos.toByteArray(); + logger.info(Arrays.toString(buffer)); + } + + @Test + public void testEncode() throws Exception { + + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/ApiDescriptionParserTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/ApiDescriptionParserTest.java index 4a7184247cd8..62732af8d1a5 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/ApiDescriptionParserTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/ApiDescriptionParserTest.java @@ -1,75 +1,75 @@ -package com.nhn.pinpoint.common.util; - - -import org.junit.Assert; -import org.junit.Test; - - -/** - * @author emeroad - */ -public class ApiDescriptionParserTest { - private ApiDescriptionParser apiParser = new ApiDescriptionParser(); - - @Test - public void parse() { -// org.springframework.web.servlet.FrameworkServlet.doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) -// com.mysql.jdbc.ConnectionImpl.setAutoCommit(boolean autoCommitFlag) -// com.mysql.jdbc.ConnectionImpl.commit() -// org.apache.catalina.core.StandardHostValve.invoke(org.apache.catalina.connector.Request request, org.apache.catalina.connector.Response response):110 - String api = "a.StandardHostValve.invoke(b.Request request, b.Response response)"; - ApiDescription result = apiParser.parse(api); - - Assert.assertEquals("a.StandardHostValve", result.getClassName()); - Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); - Assert.assertEquals("a", result.getPackageNameName()); - - Assert.assertEquals("invoke", result.getMethodName()); - - Assert.assertEquals("invoke(Request request, Response response)", result.getSimpleMethodDescription()); - Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); - - Assert.assertArrayEquals(new String[]{"Request request", "Response response"}, result.getSimpleParameter()); - } - - - @Test - public void parseNoArgs() { - String api = "a.StandardHostValve.invoke()"; - ApiDescription result = apiParser.parse(api); - - Assert.assertEquals("a.StandardHostValve", result.getClassName()); - Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); - Assert.assertEquals("a", result.getPackageNameName()); - - Assert.assertEquals("invoke", result.getMethodName()); - - Assert.assertEquals("invoke()", result.getSimpleMethodDescription()); - Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); - - Assert.assertArrayEquals(new String[]{}, result.getSimpleParameter()); - } - - - @Test - public void parseNoPackage() { - - String api = "StandardHostValve.invoke(Request request, Response response)"; - ApiDescription result = apiParser.parse(api); - - Assert.assertEquals("StandardHostValve", result.getClassName()); - Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); - Assert.assertEquals("", result.getPackageNameName()); - - Assert.assertEquals("invoke", result.getMethodName()); - - Assert.assertEquals("invoke(Request request, Response response)", result.getSimpleMethodDescription()); - Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); - - Assert.assertArrayEquals(new String[]{"Request request", "Response response"}, result.getSimpleParameter()); - - } - - - -} +package com.nhn.pinpoint.common.util; + + +import org.junit.Assert; +import org.junit.Test; + + +/** + * @author emeroad + */ +public class ApiDescriptionParserTest { + private ApiDescriptionParser apiParser = new ApiDescriptionParser(); + + @Test + public void parse() { +// org.springframework.web.servlet.FrameworkServlet.doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) +// com.mysql.jdbc.ConnectionImpl.setAutoCommit(boolean autoCommitFlag) +// com.mysql.jdbc.ConnectionImpl.commit() +// org.apache.catalina.core.StandardHostValve.invoke(org.apache.catalina.connector.Request request, org.apache.catalina.connector.Response response):110 + String api = "a.StandardHostValve.invoke(b.Request request, b.Response response)"; + ApiDescription result = apiParser.parse(api); + + Assert.assertEquals("a.StandardHostValve", result.getClassName()); + Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); + Assert.assertEquals("a", result.getPackageNameName()); + + Assert.assertEquals("invoke", result.getMethodName()); + + Assert.assertEquals("invoke(Request request, Response response)", result.getSimpleMethodDescription()); + Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); + + Assert.assertArrayEquals(new String[]{"Request request", "Response response"}, result.getSimpleParameter()); + } + + + @Test + public void parseNoArgs() { + String api = "a.StandardHostValve.invoke()"; + ApiDescription result = apiParser.parse(api); + + Assert.assertEquals("a.StandardHostValve", result.getClassName()); + Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); + Assert.assertEquals("a", result.getPackageNameName()); + + Assert.assertEquals("invoke", result.getMethodName()); + + Assert.assertEquals("invoke()", result.getSimpleMethodDescription()); + Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); + + Assert.assertArrayEquals(new String[]{}, result.getSimpleParameter()); + } + + + @Test + public void parseNoPackage() { + + String api = "StandardHostValve.invoke(Request request, Response response)"; + ApiDescription result = apiParser.parse(api); + + Assert.assertEquals("StandardHostValve", result.getClassName()); + Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); + Assert.assertEquals("", result.getPackageNameName()); + + Assert.assertEquals("invoke", result.getMethodName()); + + Assert.assertEquals("invoke(Request request, Response response)", result.getSimpleMethodDescription()); + Assert.assertEquals("StandardHostValve", result.getSimpleClassName()); + + Assert.assertArrayEquals(new String[]{"Request request", "Response response"}, result.getSimpleParameter()); + + } + + + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/ByteSizeTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/ByteSizeTest.java index 1abe69d06c07..ab81d56f26f3 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/ByteSizeTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/ByteSizeTest.java @@ -1,36 +1,40 @@ -package com.nhn.pinpoint.common.util; - -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.protocol.TProtocol; -import org.apache.thrift.transport.TIOStreamTransport; -import org.junit.Test; - -import java.io.ByteArrayOutputStream; -import java.util.Arrays; -import java.util.concurrent.TimeUnit; - -/** - * - */ -public class ByteSizeTest { - @Test - public void test() throws TException { - TCompactProtocol.Factory factory = new TCompactProtocol.Factory(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(16); - TIOStreamTransport transport = new TIOStreamTransport(baos); - TProtocol protocol = factory.getProtocol(transport); - - long l = TimeUnit.DAYS.toMillis(1); - System.out.println("day:" + l); - long currentTime = System.currentTimeMillis(); - System.out.println("currentTime:" + currentTime); - protocol.writeI64(l); - byte[] buffer = baos.toByteArray(); - System.out.println(buffer.length); - - } - - -} +package com.nhn.pinpoint.common.util; + +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.transport.TIOStreamTransport; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.util.concurrent.TimeUnit; + +/** + * + */ +public class ByteSizeTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void test() throws TException { + TCompactProtocol.Factory factory = new TCompactProtocol.Factory(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(16); + TIOStreamTransport transport = new TIOStreamTransport(baos); + TProtocol protocol = factory.getProtocol(transport); + + long l = TimeUnit.DAYS.toMillis(1); + logger.debug("day:{}", l); + long currentTime = System.currentTimeMillis(); + logger.debug("currentTime:{}" + currentTime); + protocol.writeI64(l); + byte[] buffer = baos.toByteArray(); + logger.debug("{}", buffer.length); + + } + + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/BytesUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/BytesUtilsTest.java index c09d78f28921..086fe4afbf12 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/BytesUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/BytesUtilsTest.java @@ -1,187 +1,154 @@ -package com.nhn.pinpoint.common.util; - -import java.util.Arrays; -import java.util.UUID; - -import org.apache.hadoop.hbase.util.Bytes; -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.transport.TMemoryBuffer; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class BytesUtilsTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testLongLongToBytes() throws Exception { - long most = Long.MAX_VALUE; - long least = Long.MAX_VALUE - 1; - - test(most, least); - - UUID uuid = UUID.randomUUID(); - test(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits()); - } - - @Test - public void testStringLongLongToBytes() throws Exception { - BytesUtils.stringLongLongToBytes("123", 3, 1, 2); - try { - BytesUtils.stringLongLongToBytes("123", 2, 1, 2); - Assert.fail(); - } catch (Exception e) { - } - } - - @Test - public void testStringLongLongToBytes2() throws Exception { - byte[] bytes = BytesUtils.stringLongLongToBytes("123", 10, 1, 2); - String s = BytesUtils.toStringAndRightTrim(bytes, 0, 10); - Assert.assertEquals("123", s); - long l = BytesUtils.bytesToLong(bytes, 10); - Assert.assertEquals(l, 1); - long l2 = BytesUtils.bytesToLong(bytes, 10 + BytesUtils.LONG_BYTE_LENGTH); - Assert.assertEquals(l2, 2); - } - - @Test - public void testRightTrim() throws Exception { - String trim = BytesUtils.trimRight("test "); - Assert.assertEquals("test", trim); - - String trim1 = BytesUtils.trimRight("test"); - Assert.assertEquals("test", trim1); - - String trim2 = BytesUtils.trimRight(" test"); - Assert.assertEquals(" test", trim2); - - } - - - @Test - public void testInt() { - int i = Integer.MAX_VALUE - 5; - checkInt(i); - checkInt(23464); - } - - private void checkInt(int i) { - byte[] bytes = Bytes.toBytes(i); - int i2 = BytesUtils.bytesToInt(bytes, 0); - Assert.assertEquals(i, i2); - int i3 = Bytes.toInt(bytes); - Assert.assertEquals(i, i3); - } - - private void test(long most, long least) { - byte[] bytes1 = Bytes.toBytes(most); - byte[] bytes2 = Bytes.toBytes(least); - byte[] add = Bytes.add(bytes1, bytes2); - byte[] bytes = BytesUtils.longLongToBytes(most, least); - Assert.assertArrayEquals(add, bytes); - - - long[] longLong = BytesUtils.bytesToLongLong(bytes); - Assert.assertEquals(most, longLong[0]); - Assert.assertEquals(least, longLong[1]); - - - long bMost = BytesUtils.bytesToLong(bytes, 0); - long bLeast = BytesUtils.bytesToLong(bytes, 8); - Assert.assertEquals(most, bMost); - Assert.assertEquals(least, bLeast); - - byte bBytes[] = new byte[16]; - BytesUtils.writeLong(most, bBytes, 0); - BytesUtils.writeLong(least, bBytes, 8); - Assert.assertArrayEquals(add, bBytes); - } - - @Test - public void testAddStringLong() throws Exception { - byte[] testAgents = BytesUtils.add("testAgent", 11L); - byte[] buf = Bytes.add(Bytes.toBytes("testAgent"), Bytes.toBytes(11L)); - Assert.assertArrayEquals(testAgents, buf); - } - - @Test - public void testAddStringLong_NullError() throws Exception { - try { - BytesUtils.add((String)null, 11L); - Assert.fail(); - } catch (Exception e) { - } - } - - @Test - public void testToFixedLengthBytes() { - byte[] testValue = BytesUtils.toFixedLengthBytes("test", 10); - Assert.assertEquals(testValue.length, 10); - Assert.assertEquals(testValue[5], 0); - - try { - BytesUtils.toFixedLengthBytes("test", 2); - Assert.fail(); - } catch (Exception e) { - } - - try { - BytesUtils.toFixedLengthBytes("test", -1); - Assert.fail(); - } catch (Exception e) { - } - - byte[] testValue2 = BytesUtils.toFixedLengthBytes(null, 10); - Assert.assertEquals(testValue2.length, 10); - - } - - @Test - public void testMerge() { - byte[] b1 = new byte[] { 1, 2 }; - byte[] b2 = new byte[] { 3, 4 }; - - byte[] b3 = BytesUtils.merge(b1, b2); - - Assert.assertTrue(Arrays.equals(new byte[] { 1, 2, 3, 4 }, b3)); - } - - @Test - public void testZigZag() throws Exception { - testEncodingDecodingZigZag(0); - testEncodingDecodingZigZag(1); - testEncodingDecodingZigZag(2); - testEncodingDecodingZigZag(3); - } - - - private void testEncodingDecodingZigZag(int value) { - int encode = BytesUtils.intToZigZag(value); - int decode = BytesUtils.zigzagToInt(encode); - Assert.assertEquals(value, decode); - } - - - @Test - public void compactProtocolVint() throws TException { - TMemoryBuffer tMemoryBuffer = writeVInt32(BytesUtils.zigzagToInt(64)); - logger.debug("length:{}", tMemoryBuffer.length()); - - TMemoryBuffer tMemoryBuffer2 = writeVInt32(64); - logger.debug("length:{}", tMemoryBuffer2.length()); - - } - - private TMemoryBuffer writeVInt32(int i) throws TException { - TMemoryBuffer tMemoryBuffer = new TMemoryBuffer(10); - TCompactProtocol tCompactProtocol = new TCompactProtocol(tMemoryBuffer); - tCompactProtocol.writeI32(i); - return tMemoryBuffer; - } - - -} +package com.nhn.pinpoint.common.util; + +import java.util.Arrays; +import java.util.UUID; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.transport.TMemoryBuffer; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class BytesUtilsTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void testStringLongLongToBytes() throws Exception { + BytesUtils.stringLongLongToBytes("123", 3, 1, 2); + try { + BytesUtils.stringLongLongToBytes("123", 2, 1, 2); + Assert.fail(); + } catch (Exception e) { + } + } + + @Test + public void testStringLongLongToBytes2() throws Exception { + byte[] bytes = BytesUtils.stringLongLongToBytes("123", 10, 1, 2); + String s = BytesUtils.toStringAndRightTrim(bytes, 0, 10); + Assert.assertEquals("123", s); + long l = BytesUtils.bytesToLong(bytes, 10); + Assert.assertEquals(l, 1); + long l2 = BytesUtils.bytesToLong(bytes, 10 + BytesUtils.LONG_BYTE_LENGTH); + Assert.assertEquals(l2, 2); + } + + @Test + public void testRightTrim() throws Exception { + String trim = BytesUtils.trimRight("test "); + Assert.assertEquals("test", trim); + + String trim1 = BytesUtils.trimRight("test"); + Assert.assertEquals("test", trim1); + + String trim2 = BytesUtils.trimRight(" test"); + Assert.assertEquals(" test", trim2); + + } + + + @Test + public void testInt() { + int i = Integer.MAX_VALUE - 5; + checkInt(i); + checkInt(23464); + } + + private void checkInt(int i) { + byte[] bytes = Bytes.toBytes(i); + int i2 = BytesUtils.bytesToInt(bytes, 0); + Assert.assertEquals(i, i2); + int i3 = Bytes.toInt(bytes); + Assert.assertEquals(i, i3); + } + + + @Test + public void testAddStringLong() throws Exception { + byte[] testAgents = BytesUtils.add("testAgent", 11L); + byte[] buf = Bytes.add(Bytes.toBytes("testAgent"), Bytes.toBytes(11L)); + Assert.assertArrayEquals(testAgents, buf); + } + + @Test + public void testAddStringLong_NullError() throws Exception { + try { + BytesUtils.add((String)null, 11L); + Assert.fail(); + } catch (Exception e) { + } + } + + @Test + public void testToFixedLengthBytes() { + byte[] testValue = BytesUtils.toFixedLengthBytes("test", 10); + Assert.assertEquals(testValue.length, 10); + Assert.assertEquals(testValue[5], 0); + + try { + BytesUtils.toFixedLengthBytes("test", 2); + Assert.fail(); + } catch (Exception e) { + } + + try { + BytesUtils.toFixedLengthBytes("test", -1); + Assert.fail(); + } catch (Exception e) { + } + + byte[] testValue2 = BytesUtils.toFixedLengthBytes(null, 10); + Assert.assertEquals(testValue2.length, 10); + + } + + @Test + public void testMerge() { + byte[] b1 = new byte[] { 1, 2 }; + byte[] b2 = new byte[] { 3, 4 }; + + byte[] b3 = BytesUtils.merge(b1, b2); + + Assert.assertTrue(Arrays.equals(new byte[] { 1, 2, 3, 4 }, b3)); + } + + @Test + public void testZigZag() throws Exception { + testEncodingDecodingZigZag(0); + testEncodingDecodingZigZag(1); + testEncodingDecodingZigZag(2); + testEncodingDecodingZigZag(3); + } + + + private void testEncodingDecodingZigZag(int value) { + int encode = BytesUtils.intToZigZag(value); + int decode = BytesUtils.zigzagToInt(encode); + Assert.assertEquals(value, decode); + } + + + @Test + public void compactProtocolVint() throws TException { + TMemoryBuffer tMemoryBuffer = writeVInt32(BytesUtils.zigzagToInt(64)); + logger.debug("length:{}", tMemoryBuffer.length()); + + TMemoryBuffer tMemoryBuffer2 = writeVInt32(64); + logger.debug("length:{}", tMemoryBuffer2.length()); + + } + + private TMemoryBuffer writeVInt32(int i) throws TException { + TMemoryBuffer tMemoryBuffer = new TMemoryBuffer(10); + TCompactProtocol tCompactProtocol = new TCompactProtocol(tMemoryBuffer); + tCompactProtocol.writeI32(i); + return tMemoryBuffer; + } + + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/ClassLoaderUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/ClassLoaderUtilsTest.java new file mode 100644 index 000000000000..cc62a98e7d08 --- /dev/null +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/ClassLoaderUtilsTest.java @@ -0,0 +1,51 @@ +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; + +import java.net.URL; +import java.net.URLClassLoader; + +public class ClassLoaderUtilsTest { + + private static final URLClassLoader FAKE_CLASS_LOADER = new URLClassLoader(new URL[0]); + + @Test + public void testGetClassLoader1() throws Exception { + final Thread thread = Thread.currentThread(); + final ClassLoader contextClassLoader = thread.getContextClassLoader(); + + ClassLoader classLoader = ClassLoaderUtils.getClassLoader(); + + Assert.assertSame(contextClassLoader, classLoader); + } + + @Test + public void testGetClassLoader2() throws Exception { + final Thread thread = Thread.currentThread(); + final ClassLoader old = Thread.currentThread().getContextClassLoader(); + + thread.setContextClassLoader(FAKE_CLASS_LOADER); + ClassLoader classLoader = ClassLoaderUtils.getClassLoader(); + try { + Assert.assertSame(classLoader, FAKE_CLASS_LOADER); + } finally { + thread.setContextClassLoader(old); + } + } + + @Test + public void testGetClassLoader3() throws Exception { + final Thread thread = Thread.currentThread(); + final ClassLoader old = thread.getContextClassLoader(); + + thread.setContextClassLoader(null); + + ClassLoader classLoader = ClassLoaderUtils.getDefaultClassLoader(FAKE_CLASS_LOADER); + try { + Assert.assertSame(classLoader, FAKE_CLASS_LOADER); + } finally { + thread.setContextClassLoader(old); + } + } +} \ No newline at end of file diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/HashCodeTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/HashCodeTest.java deleted file mode 100644 index 900e844ded9f..000000000000 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/HashCodeTest.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.nhn.pinpoint.common.util; - -import org.junit.Test; - -import java.util.Random; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -/** - * test를 위해 hashcode를 찾을때 돌려볼수 있는 코드 - */ -public class HashCodeTest { - // @Test - public void test2() throws InterruptedException { -// "test" -// "tetU" -// "uGTt" -// System.out.println((int)'A'); -// System.out.println((int)'Z'); - System.out.println("test".hashCode()); - System.out.println("tfUU".hashCode()); - String a = "23 123"; - System.out.println(a.hashCode()); - System.out.println("test:" + a.hashCode()); - final int hashCode = a.hashCode(); - final ExecutorService es = Executors.newFixedThreadPool(4); - Runnable runnable = new Runnable() { - @Override - public void run() { - execute(hashCode); - } - }; - es.execute(runnable); - es.execute(runnable); - es.execute(runnable); - es.execute(runnable); - es.awaitTermination(1, TimeUnit.HOURS); -// execute(hashCode, random); -// test -// -1757224452 - - - } - - private void execute(int hashCode) { - Random random = new Random(); - while (true) { - int i = random.nextInt(30); -// System.out.println(i); - StringBuilder sb = new StringBuilder(); -// sb.append("12 "); - for (int j = 0; j < i; j++) { - char c = get(random); - sb.append(c); - } - sb.append(" 7"); - String s = sb.toString(); -// System.out.println(s.hashCode()); -// System.out.println(s); - if (hashCode == s.hashCode()) { -// if(a.equals(s)) { -// continue; -// } - System.out.println("find!!! equals:" + s); - break; - } - } - } - - // @Test - public void test() { -// "test" -// "tetU" -// "uGTt" -// System.out.println((int)'A'); -// System.out.println((int)'Z'); - String a = "test"; - System.out.println("test:" + a.hashCode()); - int hashCode = a.hashCode(); - Random random = new Random(); - while (true) { - int i = random.nextInt(50); -// System.out.println(i); - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < i; j++) { - char c = get(random); - sb.append(c); - } - String s = sb.toString(); -// System.out.println(s); - if (hashCode == s.hashCode()) { - if ("test".equals(s)) { - continue; - } - System.out.println("equals:" + s); - break; - } - } -// test -// -1757224452 - } - - char get(Random rand) { -// 65->90 : 25 -// 97->122; 25 - int choice = (char) rand.nextInt(2); - char ch; - if (choice == 0) { - ch = (char) ((rand.nextInt(25)) + 97); - } else { - ch = (char) ((rand.nextInt(25)) + 65); - } - - while (true) { - if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') { - return ch; - } - } - } -} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/HttpUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/HttpUtilsTest.java index 93a04330c4fe..b6bea67241c2 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/HttpUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/HttpUtilsTest.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import org.junit.Test; - -public class HttpUtilsTest { - @Test - public void contentTypeCharset1() { - String test = "text/plain; charset=UTF-8"; - - String charset = HttpUtils.parseContentTypeCharset(test); - Assert.assertEquals("UTF-8", charset); - } - - @Test - public void contentTypeCharset2() { - String test = "text/plain; charset=UTF-8;"; - - String charset = HttpUtils.parseContentTypeCharset(test); - Assert.assertEquals("UTF-8", charset); - } - - @Test - public void contentTypeCharset3() { - String test = "text/plain; charset=UTF-8; test=a"; - - String charset = HttpUtils.parseContentTypeCharset(test); - Assert.assertEquals("UTF-8", charset); - } - - @Test - public void contentTypeCharset4() { - String test = "text/plain; charset= UTF-8 ; test=a"; - - String charset = HttpUtils.parseContentTypeCharset(test); - Assert.assertEquals("UTF-8", charset); - } - +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; + +public class HttpUtilsTest { + @Test + public void contentTypeCharset1() { + String test = "text/plain; charset=UTF-8"; + + String charset = HttpUtils.parseContentTypeCharset(test); + Assert.assertEquals("UTF-8", charset); + } + + @Test + public void contentTypeCharset2() { + String test = "text/plain; charset=UTF-8;"; + + String charset = HttpUtils.parseContentTypeCharset(test); + Assert.assertEquals("UTF-8", charset); + } + + @Test + public void contentTypeCharset3() { + String test = "text/plain; charset=UTF-8; test=a"; + + String charset = HttpUtils.parseContentTypeCharset(test); + Assert.assertEquals("UTF-8", charset); + } + + @Test + public void contentTypeCharset4() { + String test = "text/plain; charset= UTF-8 ; test=a"; + + String charset = HttpUtils.parseContentTypeCharset(test); + Assert.assertEquals("UTF-8", charset); + } + } \ No newline at end of file diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/InetAddressUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/InetAddressUtilsTest.java index 42da6f2709a1..4abc1f11102f 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/InetAddressUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/InetAddressUtilsTest.java @@ -1,22 +1,26 @@ -package com.nhn.pinpoint.common.util; - -import org.junit.Test; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * - */ -public class InetAddressUtilsTest { - @Test - public void test() throws UnknownHostException { - InetAddress byName = InetAddress.getByName("0:0:0:0:0:0:0:1"); - - System.out.println(byName); - System.out.println(byName.getAddress().length); - - InetAddress ipv4= InetAddress.getByName("127.0.0.1"); - System.out.println(ipv4); - } -} +package com.nhn.pinpoint.common.util; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * + */ +public class InetAddressUtilsTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void test() throws UnknownHostException { + InetAddress byName = InetAddress.getByName("0:0:0:0:0:0:0:1"); + + logger.debug("{}", byName); + logger.debug("{}", byName.getAddress().length); + + InetAddress ipv4= InetAddress.getByName("127.0.0.1"); + logger.debug("{}", ipv4); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/JvmVersionTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/JvmVersionTest.java similarity index 94% rename from commons/src/test/java/com/navercorp/pinpoint/common/JvmVersionTest.java rename to commons/src/test/java/com/navercorp/pinpoint/common/util/JvmVersionTest.java index 0ebb0b312c37..69d371999e8b 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/JvmVersionTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/JvmVersionTest.java @@ -1,103 +1,103 @@ -package com.nhn.pinpoint.common; - -import static org.junit.Assert.*; -import static com.nhn.pinpoint.common.JvmVersion.*; - -import org.junit.Test; - -/** - * @author hyungil.jeong - */ -public class JvmVersionTest { - - @Test - public void testOnOrAfter() { - // JDK 5 - assertTrue(JAVA_5.onOrAfter(JAVA_5)); - assertFalse(JAVA_5.onOrAfter(JAVA_6)); - assertFalse(JAVA_5.onOrAfter(JAVA_7)); - assertFalse(JAVA_5.onOrAfter(JAVA_8)); - assertFalse(JAVA_5.onOrAfter(UNSUPPORTED)); - // JDK 6 - assertTrue(JAVA_6.onOrAfter(JAVA_5)); - assertTrue(JAVA_6.onOrAfter(JAVA_6)); - assertFalse(JAVA_6.onOrAfter(JAVA_7)); - assertFalse(JAVA_6.onOrAfter(JAVA_8)); - assertFalse(JAVA_6.onOrAfter(UNSUPPORTED)); - // JDK 7 - assertTrue(JAVA_7.onOrAfter(JAVA_5)); - assertTrue(JAVA_7.onOrAfter(JAVA_6)); - assertTrue(JAVA_7.onOrAfter(JAVA_7)); - assertFalse(JAVA_7.onOrAfter(JAVA_8)); - assertFalse(JAVA_7.onOrAfter(UNSUPPORTED)); - // JDK 8 - assertTrue(JAVA_8.onOrAfter(JAVA_5)); - assertTrue(JAVA_8.onOrAfter(JAVA_6)); - assertTrue(JAVA_8.onOrAfter(JAVA_7)); - assertTrue(JAVA_8.onOrAfter(JAVA_8)); - assertFalse(JAVA_8.onOrAfter(UNSUPPORTED)); - // Unsupported - assertFalse(UNSUPPORTED.onOrAfter(JAVA_5)); - assertFalse(UNSUPPORTED.onOrAfter(JAVA_6)); - assertFalse(UNSUPPORTED.onOrAfter(JAVA_7)); - assertFalse(UNSUPPORTED.onOrAfter(JAVA_8)); - assertFalse(UNSUPPORTED.onOrAfter(UNSUPPORTED)); - } - - @Test - public void testGetFromDoubleVersion() { - // JDK 5 - final JvmVersion java_5 = JvmVersion.getFromVersion(1.5); - assertSame(java_5, JAVA_5); - // JDK 6 - final JvmVersion java_6 = JvmVersion.getFromVersion(1.6); - assertSame(java_6, JAVA_6); - // JDK 7 - final JvmVersion java_7 = JvmVersion.getFromVersion(1.7); - assertSame(java_7, JAVA_7); - // JDK 8 - final JvmVersion java_8 = JvmVersion.getFromVersion(1.8); - assertSame(java_8, JAVA_8); - // Unsupported - final JvmVersion java_unsupported = JvmVersion.getFromVersion(0.9); - assertSame(java_unsupported, UNSUPPORTED); - } - - @Test - public void testGetFromStringVersion() { - // JDK 5 - final JvmVersion java_5 = JvmVersion.getFromVersion("1.5"); - assertSame(java_5, JAVA_5); - // JDK 6 - final JvmVersion java_6 = JvmVersion.getFromVersion("1.6"); - assertSame(java_6, JAVA_6); - // JDK 7 - final JvmVersion java_7 = JvmVersion.getFromVersion("1.7"); - assertSame(java_7, JAVA_7); - // JDK 8 - final JvmVersion java_8 = JvmVersion.getFromVersion("1.8"); - assertSame(java_8, JAVA_8); - // Unsupported - final JvmVersion java_unsupported = JvmVersion.getFromVersion("abc"); - assertSame(java_unsupported, UNSUPPORTED); - } - - @Test - public void testGetFromClassVersion() { - // JDK 5 - final JvmVersion java_5 = JvmVersion.getFromClassVersion(49); - assertSame(java_5, JAVA_5); - // JDK 6 - final JvmVersion java_6 = JvmVersion.getFromClassVersion(50); - assertSame(java_6, JAVA_6); - // JDK 7 - final JvmVersion java_7 = JvmVersion.getFromClassVersion(51); - assertSame(java_7, JAVA_7); - // JDK 8 - final JvmVersion java_8 = JvmVersion.getFromClassVersion(52); - assertSame(java_8, JAVA_8); - // Unsupported - final JvmVersion java_unsupported = JvmVersion.getFromClassVersion(-1); - assertSame(java_unsupported, UNSUPPORTED); - } -} +package com.nhn.pinpoint.common.util; + +import static org.junit.Assert.*; +import static com.nhn.pinpoint.common.util.JvmVersion.*; + +import org.junit.Test; + +/** + * @author hyungil.jeong + */ +public class JvmVersionTest { + + @Test + public void testOnOrAfter() { + // JDK 5 + assertTrue(JAVA_5.onOrAfter(JAVA_5)); + assertFalse(JAVA_5.onOrAfter(JAVA_6)); + assertFalse(JAVA_5.onOrAfter(JAVA_7)); + assertFalse(JAVA_5.onOrAfter(JAVA_8)); + assertFalse(JAVA_5.onOrAfter(UNSUPPORTED)); + // JDK 6 + assertTrue(JAVA_6.onOrAfter(JAVA_5)); + assertTrue(JAVA_6.onOrAfter(JAVA_6)); + assertFalse(JAVA_6.onOrAfter(JAVA_7)); + assertFalse(JAVA_6.onOrAfter(JAVA_8)); + assertFalse(JAVA_6.onOrAfter(UNSUPPORTED)); + // JDK 7 + assertTrue(JAVA_7.onOrAfter(JAVA_5)); + assertTrue(JAVA_7.onOrAfter(JAVA_6)); + assertTrue(JAVA_7.onOrAfter(JAVA_7)); + assertFalse(JAVA_7.onOrAfter(JAVA_8)); + assertFalse(JAVA_7.onOrAfter(UNSUPPORTED)); + // JDK 8 + assertTrue(JAVA_8.onOrAfter(JAVA_5)); + assertTrue(JAVA_8.onOrAfter(JAVA_6)); + assertTrue(JAVA_8.onOrAfter(JAVA_7)); + assertTrue(JAVA_8.onOrAfter(JAVA_8)); + assertFalse(JAVA_8.onOrAfter(UNSUPPORTED)); + // Unsupported + assertFalse(UNSUPPORTED.onOrAfter(JAVA_5)); + assertFalse(UNSUPPORTED.onOrAfter(JAVA_6)); + assertFalse(UNSUPPORTED.onOrAfter(JAVA_7)); + assertFalse(UNSUPPORTED.onOrAfter(JAVA_8)); + assertFalse(UNSUPPORTED.onOrAfter(UNSUPPORTED)); + } + + @Test + public void testGetFromDoubleVersion() { + // JDK 5 + final JvmVersion java_5 = JvmVersion.getFromVersion(1.5); + assertSame(java_5, JAVA_5); + // JDK 6 + final JvmVersion java_6 = JvmVersion.getFromVersion(1.6); + assertSame(java_6, JAVA_6); + // JDK 7 + final JvmVersion java_7 = JvmVersion.getFromVersion(1.7); + assertSame(java_7, JAVA_7); + // JDK 8 + final JvmVersion java_8 = JvmVersion.getFromVersion(1.8); + assertSame(java_8, JAVA_8); + // Unsupported + final JvmVersion java_unsupported = JvmVersion.getFromVersion(0.9); + assertSame(java_unsupported, UNSUPPORTED); + } + + @Test + public void testGetFromStringVersion() { + // JDK 5 + final JvmVersion java_5 = JvmVersion.getFromVersion("1.5"); + assertSame(java_5, JAVA_5); + // JDK 6 + final JvmVersion java_6 = JvmVersion.getFromVersion("1.6"); + assertSame(java_6, JAVA_6); + // JDK 7 + final JvmVersion java_7 = JvmVersion.getFromVersion("1.7"); + assertSame(java_7, JAVA_7); + // JDK 8 + final JvmVersion java_8 = JvmVersion.getFromVersion("1.8"); + assertSame(java_8, JAVA_8); + // Unsupported + final JvmVersion java_unsupported = JvmVersion.getFromVersion("abc"); + assertSame(java_unsupported, UNSUPPORTED); + } + + @Test + public void testGetFromClassVersion() { + // JDK 5 + final JvmVersion java_5 = JvmVersion.getFromClassVersion(49); + assertSame(java_5, JAVA_5); + // JDK 6 + final JvmVersion java_6 = JvmVersion.getFromClassVersion(50); + assertSame(java_6, JAVA_6); + // JDK 7 + final JvmVersion java_7 = JvmVersion.getFromClassVersion(51); + assertSame(java_7, JAVA_7); + // JDK 8 + final JvmVersion java_8 = JvmVersion.getFromClassVersion(52); + assertSame(java_8, JAVA_8); + // Unsupported + final JvmVersion java_unsupported = JvmVersion.getFromClassVersion(-1); + assertSame(java_unsupported, UNSUPPORTED); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/MathUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/MathUtilsTest.java index d66113d9f0ca..ed42f60baa32 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/MathUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/MathUtilsTest.java @@ -1,47 +1,47 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class MathUtilsTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void fastAbs() { - Assert.assertTrue(MathUtils.fastAbs(-1) > 0); - Assert.assertTrue(MathUtils.fastAbs(0) == 0); - Assert.assertTrue(MathUtils.fastAbs(1) > 0); - } - - - @Test - public void overflow() { - - - logger.debug("abs:{}", Math.abs(Integer.MIN_VALUE)); - logger.debug("fastabs:{}", MathUtils.fastAbs(Integer.MIN_VALUE)); - - int index = Integer.MIN_VALUE -2; - for(int i =0; i<5; i++) { - logger.debug("{}------------", i); - logger.debug("{}", index); - logger.debug("mod:{}", index % 3); - logger.debug("abs:{}", Math.abs(index)); - logger.debug("fastabs:{}", MathUtils.fastAbs(index)); - - index++; - } - - - - } - - -} +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class MathUtilsTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void fastAbs() { + Assert.assertTrue(MathUtils.fastAbs(-1) > 0); + Assert.assertTrue(MathUtils.fastAbs(0) == 0); + Assert.assertTrue(MathUtils.fastAbs(1) > 0); + } + + + @Test + public void overflow() { + + + logger.debug("abs:{}", Math.abs(Integer.MIN_VALUE)); + logger.debug("fastabs:{}", MathUtils.fastAbs(Integer.MIN_VALUE)); + + int index = Integer.MIN_VALUE -2; + for(int i =0; i<5; i++) { + logger.debug("{}------------", i); + logger.debug("{}", index); + logger.debug("mod:{}", index % 3); + logger.debug("abs:{}", Math.abs(index)); + logger.debug("fastabs:{}", MathUtils.fastAbs(index)); + + index++; + } + + + + } + + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/OutputParameterParserTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/OutputParameterParserTest.java index c3fbe06740e8..2c1bf3a46b54 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/OutputParameterParserTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/OutputParameterParserTest.java @@ -1,45 +1,45 @@ -package com.nhn.pinpoint.common.util; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -/** - * @author emeroad - */ -public class OutputParameterParserTest { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final OutputParameterParser parser = new OutputParameterParser(); - - @Test - public void testParseOutputParameter() throws Exception { - assertOutputParameter("12,34", "12", "34"); - assertOutputParameter("12,,34", "12,34"); - - assertOutputParameter("12,,", "12,"); - - assertOutputParameter("12,,34,123", "12,34", "123"); - - assertOutputParameter("12,", "12", ""); - - assertOutputParameter(""); - - } - - private void assertOutputParameter(String outputParam, String... params) { - List result = parser.parseOutputParameter(outputParam); - logger.info("parseResult:{}", result); - try { - Assert.assertArrayEquals(result.toArray(new String[result.size()]), params); - } catch (AssertionError e) { - logger.warn("parseResult:{}", result); - logger.warn("params:{}", params); - throw e; - } - } -} +package com.nhn.pinpoint.common.util; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * @author emeroad + */ +public class OutputParameterParserTest { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final OutputParameterParser parser = new OutputParameterParser(); + + @Test + public void testParseOutputParameter() throws Exception { + assertOutputParameter("12,34", "12", "34"); + assertOutputParameter("12,,34", "12,34"); + + assertOutputParameter("12,,", "12,"); + + assertOutputParameter("12,,34,123", "12,34", "123"); + + assertOutputParameter("12,", "12", ""); + + assertOutputParameter(""); + + } + + private void assertOutputParameter(String outputParam, String... params) { + List result = parser.parseOutputParameter(outputParam); + logger.info("parseResult:{}", result); + try { + Assert.assertArrayEquals(result.toArray(new String[result.size()]), params); + } catch (AssertionError e) { + logger.warn("parseResult:{}", result); + logger.warn("params:{}", params); + throw e; + } + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/PinpointThreadFactoryTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/PinpointThreadFactoryTest.java index 2b8cd34aa0d7..8809c56af42e 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/PinpointThreadFactoryTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/PinpointThreadFactoryTest.java @@ -1,43 +1,45 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class PinpointThreadFactoryTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testCreateThreadFactory() throws Exception { - final AtomicInteger test = new AtomicInteger(0); - - PinpointThreadFactory pinpoint = new PinpointThreadFactory("pinpoint"); - Thread thread = pinpoint.newThread(new Runnable() { - @Override - public void run() { - test.getAndIncrement(); - } - }); - thread.start(); - thread.join(); - Assert.assertEquals(test.get(), 1); - String threadName = thread.getName(); - logger.info(threadName); - Assert.assertTrue(threadName.startsWith("pinpoint(")); - Assert.assertTrue(threadName.endsWith(")")); - - Thread thread2 = pinpoint.newThread(new Runnable() { - @Override - public void run() { - } - }); - logger.info(thread2.getName()); - - } -} +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class PinpointThreadFactoryTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testCreateThreadFactory() throws Exception { + final AtomicInteger counter = new AtomicInteger(0); + + PinpointThreadFactory pinpoint = new PinpointThreadFactory("pinpoint"); + Thread thread = pinpoint.newThread(new Runnable() { + @Override + public void run() { + counter.getAndIncrement(); + } + }); + thread.start(); + thread.join(); + + Assert.assertEquals(counter.get(), 1); + + String threadName = thread.getName(); + logger.debug(threadName); + Assert.assertTrue(threadName.startsWith("pinpoint(")); + Assert.assertTrue(threadName.endsWith(")")); + + Thread thread2 = pinpoint.newThread(new Runnable() { + @Override + public void run() { + } + }); + logger.debug(thread2.getName()); + + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/PropertyUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/PropertyUtilsTest.java new file mode 100644 index 000000000000..08642ef6ecfc --- /dev/null +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/PropertyUtilsTest.java @@ -0,0 +1,30 @@ +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; + +import java.net.URL; +import java.util.Properties; + +public class PropertyUtilsTest { + + @Test + public void testLoadProperty() throws Exception { + URL resource = PropertyUtils.class.getClassLoader().getResource("test.properties"); + String path = resource.getPath(); + + Properties properties = PropertyUtils.loadProperty(path); + assertProperty(properties); + } + + @Test + public void testLoadPropertyFromClassPath() throws Exception { + Properties properties = PropertyUtils.loadPropertyFromClassPath("test.properties"); + assertProperty(properties); + } + + private void assertProperty(Properties properties) { + String test = properties.getProperty("test"); + Assert.assertEquals("pinpoint", test); + } +} \ No newline at end of file diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/RowKeyUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/RowKeyUtilsTest.java index 94227c761612..8f1fe1193e87 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/RowKeyUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/RowKeyUtilsTest.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.common.util; - -import com.nhn.pinpoint.common.bo.SqlMetaDataBo; -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class RowKeyUtilsTest { - @Test - public void testGetSqlId() throws Exception { - long startTime = System.currentTimeMillis(); - SqlMetaDataBo sqlMetaDataBo = new SqlMetaDataBo("agent", startTime, 1); - byte[] agents = sqlMetaDataBo.toRowKey(); - - - SqlMetaDataBo sqlId = new SqlMetaDataBo(); - sqlId.readRowKey(agents); - - Assert.assertEquals(sqlId.getAgentId(), "agent"); - Assert.assertEquals(sqlId.getHashCode(), 1); - Assert.assertEquals(sqlId.getStartTime(), startTime); - } -} +package com.nhn.pinpoint.common.util; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class RowKeyUtilsTest { + @Test + public void testGetSqlId() throws Exception { + long startTime = System.currentTimeMillis(); + SqlMetaDataBo sqlMetaDataBo = new SqlMetaDataBo("agent", startTime, 1); + byte[] agents = sqlMetaDataBo.toRowKey(); + + + SqlMetaDataBo sqlId = new SqlMetaDataBo(); + sqlId.readRowKey(agents); + + Assert.assertEquals(sqlId.getAgentId(), "agent"); + Assert.assertEquals(sqlId.getHashCode(), 1); + Assert.assertEquals(sqlId.getStartTime(), startTime); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/RpcCodeRangeTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/RpcCodeRangeTest.java index 354e46921142..a45916f5e837 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/RpcCodeRangeTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/RpcCodeRangeTest.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import org.junit.Test; - -import static org.junit.Assert.*; - -public class RpcCodeRangeTest { - - @Test - public void testIsRpcRange() throws Exception { - Assert.assertTrue(RpcCodeRange.isRpcRange(RpcCodeRange.RPC_START)); - Assert.assertTrue(RpcCodeRange.isRpcRange((short) (RpcCodeRange.RPC_END - 1))); - Assert.assertFalse(RpcCodeRange.isRpcRange((short) 1)); - } - +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class RpcCodeRangeTest { + + @Test + public void testIsRpcRange() throws Exception { + Assert.assertTrue(RpcCodeRange.isRpcRange(RpcCodeRange.RPC_START)); + Assert.assertTrue(RpcCodeRange.isRpcRange((short) (RpcCodeRange.RPC_END - 1))); + Assert.assertFalse(RpcCodeRange.isRpcRange((short) 1)); + } + } \ No newline at end of file diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/SpanUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/SpanUtilsTest.java index 47d6b5b333b2..9be68a10aa76 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/SpanUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/SpanUtilsTest.java @@ -1,67 +1,67 @@ -package com.nhn.pinpoint.common.util; - -import com.nhn.pinpoint.common.PinpointConstants; -import com.nhn.pinpoint.thrift.dto.TSpan; - -import junit.framework.Assert; -import org.apache.hadoop.hbase.util.Bytes; -import org.junit.Test; - -/** - * @author emeroad - */ -public class SpanUtilsTest { - @Test - public void testGetTraceIndexRowKeyWhiteSpace() throws Exception { - String agentId = "test test"; - long time = System.currentTimeMillis(); - check(agentId, time); - } - - @Test - public void testGetTraceIndexRowKey1() throws Exception { - String agentId = "test"; - long time = System.currentTimeMillis(); - check(agentId, time); - } - - @Test - public void testGetTraceIndexRowKey2() throws Exception { - String agentId = ""; - for (int i = 0; i < PinpointConstants.AGENT_NAME_MAX_LEN; i++) { - agentId += "1"; - } - - long time = System.currentTimeMillis(); - check(agentId, time); - } - - @Test - public void testGetTraceIndexRowKey3() throws Exception { - String agentId = ""; - for (int i = 0; i < PinpointConstants.AGENT_NAME_MAX_LEN + 1; i++) { - agentId += "1"; - } - - long time = System.currentTimeMillis(); - try { - check(agentId, time); - Assert.fail(); - } catch (Exception e) { - } - } - - private void check(String agentId0, long l1) { - TSpan span = new TSpan(); - span.setAgentId(agentId0); - span.setStartTime(l1); - - byte[] traceIndexRowKey = SpanUtils.getAgentIdTraceIndexRowKey(span.getAgentId(), span.getStartTime()); - - String agentId = Bytes.toString(traceIndexRowKey, 0, PinpointConstants.AGENT_NAME_MAX_LEN).trim(); - Assert.assertEquals(agentId0, agentId); - - long time = TimeUtils.recoveryTimeMillis(Bytes.toLong(traceIndexRowKey, PinpointConstants.AGENT_NAME_MAX_LEN)); - Assert.assertEquals(time, l1); - } -} +package com.nhn.pinpoint.common.util; + +import com.nhn.pinpoint.common.PinpointConstants; +import com.nhn.pinpoint.thrift.dto.TSpan; + +import junit.framework.Assert; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.Test; + +/** + * @author emeroad + */ +public class SpanUtilsTest { + @Test + public void testGetTraceIndexRowKeyWhiteSpace() throws Exception { + String agentId = "test test"; + long time = System.currentTimeMillis(); + check(agentId, time); + } + + @Test + public void testGetTraceIndexRowKey1() throws Exception { + String agentId = "test"; + long time = System.currentTimeMillis(); + check(agentId, time); + } + + @Test + public void testGetTraceIndexRowKey2() throws Exception { + String agentId = ""; + for (int i = 0; i < PinpointConstants.AGENT_NAME_MAX_LEN; i++) { + agentId += "1"; + } + + long time = System.currentTimeMillis(); + check(agentId, time); + } + + @Test + public void testGetTraceIndexRowKey3() throws Exception { + String agentId = ""; + for (int i = 0; i < PinpointConstants.AGENT_NAME_MAX_LEN + 1; i++) { + agentId += "1"; + } + + long time = System.currentTimeMillis(); + try { + check(agentId, time); + Assert.fail(); + } catch (Exception e) { + } + } + + private void check(String agentId0, long l1) { + TSpan span = new TSpan(); + span.setAgentId(agentId0); + span.setStartTime(l1); + + byte[] traceIndexRowKey = SpanUtils.getAgentIdTraceIndexRowKey(span.getAgentId(), span.getStartTime()); + + String agentId = Bytes.toString(traceIndexRowKey, 0, PinpointConstants.AGENT_NAME_MAX_LEN).trim(); + Assert.assertEquals(agentId0, agentId); + + long time = TimeUtils.recoveryTimeMillis(Bytes.toLong(traceIndexRowKey, PinpointConstants.AGENT_NAME_MAX_LEN)); + Assert.assertEquals(time, l1); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/SqlParserTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/SqlParserTest.java index c75bb9e1609c..25b4cab69572 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/SqlParserTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/SqlParserTest.java @@ -1,305 +1,309 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import junit.framework.AssertionFailedError; -import org.junit.Test; - -import java.util.List; - -/** - * @author emeroad - */ -public class SqlParserTest { - private SqlParser sqlParser = new SqlParser(); - private OutputParameterParser outputParameterParser = new OutputParameterParser(); - - @Test - public void normalizedSql() { - - ParsingResult parsingResult = sqlParser.normalizedSql("select * from table a = 1 and b=50 and c=? and d='11'"); - String s = parsingResult.getSql(); - - System.out.println(s); - System.out.println(parsingResult.getOutput()); - - ParsingResult parsingResult2 = sqlParser.normalizedSql(" "); - String s2 = parsingResult2.getSql(); - System.out.println(s2); - - System.out.println((char) -1); - String str = "s"; - System.out.println(str.codePointAt(0)); - System.out.println((int) str.charAt(0)); - System.out.println("high" + (char) Character.MAX_HIGH_SURROGATE); - System.out.println("low" + (char) Character.MIN_LOW_SURROGATE); - - System.out.println((int) Character.MIN_LOW_SURROGATE); - System.out.println((int) Character.MAX_HIGH_SURROGATE); - - ParsingResult parsingResult3 = sqlParser.normalizedSql("''"); - String s3 = parsingResult3.getSql(); - System.out.println("s3:" + s3); - System.out.println("sb3:" + parsingResult3.getOutput()); - } - - @Test - public void nullCheck() { - sqlParser.normalizedSql(null); - } - - @Test - public void complex() { - - assertEqual("select * from table a = 1 and b=50 and c=? and d='11'", - "select * from table a = 0# and b=1# and c=? and d='2$'", "1,50,11"); - - assertEqual("select * from table a = -1 and b=-50 and c=? and d='-11'", - "select * from table a = -0# and b=-1# and c=? and d='2$'", "1,50,-11"); - - assertEqual("select * from table a = +1 and b=+50 and c=? and d='+11'", - "select * from table a = +0# and b=+1# and c=? and d='2$'", "1,50,+11"); - - assertEqual("select * from table a = 1/*test*/ and b=50/*test*/ and c=? and d='11'", - "select * from table a = 0#/*test*/ and b=1#/*test*/ and c=? and d='2$'", "1,50,11"); - - assertEqual("select ZIPCODE,CITY from ZIPCODE"); - assertEqual("select a.ZIPCODE,a.CITY from ZIPCODE as a"); - assertEqual("select ZIPCODE,123 from ZIPCODE", - "select ZIPCODE,0# from ZIPCODE", "123"); - - assertEqual("SELECT * from table a=123 and b='abc' and c=1-3", - "SELECT * from table a=0# and b='1$' and c=2#-3#", "123,abc,1,3"); - - assertEqual("SYSTEM_RANGE(1, 10)", - "SYSTEM_RANGE(0#, 1#)", "1,10"); - - } - - @Test - public void etcState() { - - assertEqual("test.abc", "test.abc", ""); - assertEqual("test.abc123", "test.abc123", ""); - assertEqual("test.123", "test.123", ""); - - } - - @Test - public void objectEquals() { - - assertEqualObject("test.abc"); - assertEqualObject("test.abc123"); - assertEqualObject("test.123"); - - } - - - @Test - public void numberState() { - assertEqual("123", "0#", "123"); - // -가 진짜 숫자의 -인지 알려면 구문분석이 필요하므로 그냥 숫자만 치환한다. - assertEqual("-123", "-0#", "123"); - assertEqual("+123", "+0#", "123"); - assertEqual("1.23", "0#", "1.23"); - assertEqual("1.23.34", "0#", "1.23.34"); - assertEqual("123 456", "0# 1#", "123,456"); - assertEqual("1.23 4.56", "0# 1#", "1.23,4.56"); - assertEqual("1.23-4.56", "0#-1#", "1.23,4.56"); - - assertEqual("1<2", "0#<1#", "1,2"); - assertEqual("1< 2", "0#< 1#", "1,2"); - assertEqual("(1< 2)", "(0#< 1#)", "1,2"); - - assertEqual("-- 1.23", "-- 1.23", ""); - assertEqual("- -1.23", "- -0#", "1.23"); - assertEqual("--1.23", "--1.23", ""); - assertEqual("/* 1.23 */", "/* 1.23 */", ""); - assertEqual("/*1.23*/", "/*1.23*/", ""); - assertEqual("/* 1.23 \n*/", "/* 1.23 \n*/", ""); - - assertEqual("test123", "test123", ""); - assertEqual("test_123", "test_123", ""); - assertEqual("test_ 123", "test_ 0#", "123"); - - // 사실 이건 불가능한 토큰임. - assertEqual("123tst", "0#tst", "123"); - } - - @Test - public void numberState2() { - assertEqual("1.23e", "0#", "1.23e"); - assertEqual("1.23E", "0#", "1.23E"); - // -가 진짜 숫자의 -인지 알려면 구문분석이 필요하므로 그냥 숫자만 치환한다. - assertEqual("1.4e-10", "0#-1#", "1.4e,10"); - - } - - - @Test - public void singleLineCommentState() { - assertEqual("--", "--", ""); - assertEqual("//", "//", ""); - assertEqual("--123", "--123", ""); - assertEqual("//123", "//123", ""); - assertEqual("--test", "--test"); - assertEqual("//test", "//test"); - assertEqual("--test\ntest", "--test\ntest", ""); - assertEqual("--test\t\n", "--test\t\n", ""); - assertEqual("--test\n123 test", "--test\n0# test", "123"); - } - - - @Test - public void multiLineCommentState() { - assertEqual("/**/", "/**/", ""); - assertEqual("/* */", "/* */", ""); - assertEqual("/* */abc", "/* */abc", ""); - assertEqual("/* * */", "/* * */", ""); - assertEqual("/* * */", "/* * */", ""); - - assertEqual("/* abc", "/* abc", ""); - - assertEqual("select * from table", "select * from table", ""); - } - - @Test - public void symbolState() { - assertEqual("''", "''", ""); - assertEqual("'abc'", "'0$'", "abc"); - assertEqual("'a''bc'", "'0$'", "a''bc"); - assertEqual("'a' 'bc'", "'0$' '1$'", "a,bc"); - - assertEqual("'a''bc' 'a''bc'", "'0$' '1$'", "a''bc,a''bc"); - - - assertEqual("select * from table where a='a'", "select * from table where a='0$'", "a"); - } - - // @Test - public void charout() { - for (int i = 11; i < 67; i++) { - System.out.println((char) i); - } - } - - @Test - public void commentAndSymbolCombine() { - assertEqual("/* 'test' */", "/* 'test' */", ""); - assertEqual("/* 'test'' */", "/* 'test'' */", ""); - assertEqual("/* '' */", "/* '' */"); - - assertEqual("/* */ 123 */", "/* */ 0# */", "123"); - - assertEqual("' /* */'", "'0$'", " /* */"); - - } - - @Test - public void sepratorTest() { - - assertEqual("1234 456,7", "0# 1#,2#", "1234,456,7"); - - assertEqual("'1234 456,7'", "'0$'", "1234 456,,7"); - - assertEqual("'1234''456,7'", "'0$'", "1234''456,,7"); - ParsingResult parsingResult2 = this.sqlParser.normalizedSql("'1234''456,7'"); - System.out.println(parsingResult2); - // 문자열 토큰 - - - assertEqual("'1234' '456,7'", "'0$' '1$'", "1234,456,,7"); - } - - - @Test - public void combineTest() { - assertCombine("123 345", "0# 1#", "123,345"); - assertCombine("123 345 'test'", "0# 1# '2$'", "123,345,test"); - assertCombine("1 2 3 4 5 6 7 8 9 10 11", "0# 1# 2# 3# 4# 5# 6# 7# 8# 9# 10#", "1,2,3,4,5,6,7,8,9,10,11"); - } - - @Test - public void combineErrorTest() { - assertCombineErrorCase("123 10#", "0# 10#", "123,345"); - - assertCombineErrorCase("1 3 10#", "0# 2# 10#", "1,2,3"); - - assertCombineErrorCase("1 2 3", "0# 2 3", "1,2,3"); - assertCombineErrorCase("1 2 10", "0# 2 10", "1,2,3"); - assertCombineErrorCase("1 2 201", "0# 2 201", "1,2,3"); - - assertCombineErrorCase("1 2 11", "0# 2 10#", "1,2,3,4,5,6,7,8,9,10,11"); - - } - - private void assertCombine(String result, String sql, String outputParams) { - List output = this.outputParameterParser.parseOutputParameter(outputParams); - - ParsingResult parsingResult = this.sqlParser.normalizedSql(result); - Assert.assertEquals("sql", parsingResult.getSql(), sql); - String combine = this.sqlParser.combineOutputParams(sql, output); - Assert.assertEquals("combine", result, combine); - } - - private void assertCombineErrorCase(String expectedError, String sql, String outputParams) { - List output = this.outputParameterParser.parseOutputParameter(outputParams); -// ParsingResult parsingResult = this.sqlParser.normalizedSql(result); - String combine = this.sqlParser.combineOutputParams(sql, output); - Assert.assertEquals("combine", expectedError, combine); - } - - - private void assertEqual(String expected) { - ParsingResult parsingResult = sqlParser.normalizedSql(expected); - String normalizedSql = parsingResult.getSql(); - try { - Assert.assertEquals(expected, normalizedSql); - } catch (AssertionFailedError e) { - System.err.println("Original :" + expected); - throw e; - } - } - - private void assertEqual(String expected, String actual) { - ParsingResult parsingResult = sqlParser.normalizedSql(expected); - String normalizedSql = parsingResult.getSql(); - try { - Assert.assertEquals(actual, normalizedSql); - } catch (AssertionFailedError e) { - System.err.println("Original :" + expected); - throw e; - } - } - - private void assertEqual(String expected, String actual, String ouputExpected) { - ParsingResult parsingResult = sqlParser.normalizedSql(expected); - String normalizedSql = parsingResult.getSql(); - String output = parsingResult.getOutput(); - List outputParams = outputParameterParser.parseOutputParameter(output); - String s = sqlParser.combineOutputParams(normalizedSql, outputParams); - System.out.println("combine:" + s); - try { - Assert.assertEquals("normalizedSql check", actual, normalizedSql); - } catch (AssertionFailedError e) { - System.err.println("Original :" + expected); - throw e; - } - - Assert.assertEquals("outputParam check", ouputExpected, parsingResult.getOutput()); - } - - private void assertEqualObject(String expected) { - ParsingResult parsingResult = sqlParser.normalizedSql(expected); - String normalizedSql = parsingResult.getSql(); - try { - Assert.assertEquals("normalizedSql check", expected, normalizedSql); - Assert.assertSame(expected, normalizedSql); - } catch (AssertionFailedError e) { - System.err.println("Original :" + expected); - throw e; - } - - } - - -} +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import junit.framework.AssertionFailedError; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * @author emeroad + */ +public class SqlParserTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private SqlParser sqlParser = new SqlParser(); + private OutputParameterParser outputParameterParser = new OutputParameterParser(); + + @Test + public void normalizedSql() { + + ParsingResult parsingResult = sqlParser.normalizedSql("select * from table a = 1 and b=50 and c=? and d='11'"); + String s = parsingResult.getSql(); + + logger.debug(s); + logger.debug(parsingResult.getOutput()); + + ParsingResult parsingResult2 = sqlParser.normalizedSql(" "); + String s2 = parsingResult2.getSql(); + logger.debug(s2); + + logger.debug("{}", (char) -1); + String str = "s"; + logger.debug("{}", str.codePointAt(0)); + logger.debug("{}", (int) str.charAt(0)); + logger.debug("high:{}", Character.MAX_HIGH_SURROGATE); + logger.debug("low:{}", Character.MIN_LOW_SURROGATE); + logger.debug("{}", (int) Character.MIN_LOW_SURROGATE); + logger.debug("{}", (int) Character.MAX_HIGH_SURROGATE); + + ParsingResult parsingResult3 = sqlParser.normalizedSql("''"); + String s3 = parsingResult3.getSql(); + logger.debug("s3:{}", s3); + logger.debug("sb3:{}", parsingResult3.getOutput()); + } + + @Test + public void nullCheck() { + sqlParser.normalizedSql(null); + } + + @Test + public void complex() { + + assertEqual("select * from table a = 1 and b=50 and c=? and d='11'", + "select * from table a = 0# and b=1# and c=? and d='2$'", "1,50,11"); + + assertEqual("select * from table a = -1 and b=-50 and c=? and d='-11'", + "select * from table a = -0# and b=-1# and c=? and d='2$'", "1,50,-11"); + + assertEqual("select * from table a = +1 and b=+50 and c=? and d='+11'", + "select * from table a = +0# and b=+1# and c=? and d='2$'", "1,50,+11"); + + assertEqual("select * from table a = 1/*test*/ and b=50/*test*/ and c=? and d='11'", + "select * from table a = 0#/*test*/ and b=1#/*test*/ and c=? and d='2$'", "1,50,11"); + + assertEqual("select ZIPCODE,CITY from ZIPCODE"); + assertEqual("select a.ZIPCODE,a.CITY from ZIPCODE as a"); + assertEqual("select ZIPCODE,123 from ZIPCODE", + "select ZIPCODE,0# from ZIPCODE", "123"); + + assertEqual("SELECT * from table a=123 and b='abc' and c=1-3", + "SELECT * from table a=0# and b='1$' and c=2#-3#", "123,abc,1,3"); + + assertEqual("SYSTEM_RANGE(1, 10)", + "SYSTEM_RANGE(0#, 1#)", "1,10"); + + } + + @Test + public void etcState() { + + assertEqual("test.abc", "test.abc", ""); + assertEqual("test.abc123", "test.abc123", ""); + assertEqual("test.123", "test.123", ""); + + } + + @Test + public void objectEquals() { + + assertEqualObject("test.abc"); + assertEqualObject("test.abc123"); + assertEqualObject("test.123"); + + } + + + @Test + public void numberState() { + assertEqual("123", "0#", "123"); + // -가 진짜 숫자의 -인지 알려면 구문분석이 필요하므로 그냥 숫자만 치환한다. + assertEqual("-123", "-0#", "123"); + assertEqual("+123", "+0#", "123"); + assertEqual("1.23", "0#", "1.23"); + assertEqual("1.23.34", "0#", "1.23.34"); + assertEqual("123 456", "0# 1#", "123,456"); + assertEqual("1.23 4.56", "0# 1#", "1.23,4.56"); + assertEqual("1.23-4.56", "0#-1#", "1.23,4.56"); + + assertEqual("1<2", "0#<1#", "1,2"); + assertEqual("1< 2", "0#< 1#", "1,2"); + assertEqual("(1< 2)", "(0#< 1#)", "1,2"); + + assertEqual("-- 1.23", "-- 1.23", ""); + assertEqual("- -1.23", "- -0#", "1.23"); + assertEqual("--1.23", "--1.23", ""); + assertEqual("/* 1.23 */", "/* 1.23 */", ""); + assertEqual("/*1.23*/", "/*1.23*/", ""); + assertEqual("/* 1.23 \n*/", "/* 1.23 \n*/", ""); + + assertEqual("test123", "test123", ""); + assertEqual("test_123", "test_123", ""); + assertEqual("test_ 123", "test_ 0#", "123"); + + // 사실 이건 불가능한 토큰임. + assertEqual("123tst", "0#tst", "123"); + } + + @Test + public void numberState2() { + assertEqual("1.23e", "0#", "1.23e"); + assertEqual("1.23E", "0#", "1.23E"); + // -가 진짜 숫자의 -인지 알려면 구문분석이 필요하므로 그냥 숫자만 치환한다. + assertEqual("1.4e-10", "0#-1#", "1.4e,10"); + + } + + + @Test + public void singleLineCommentState() { + assertEqual("--", "--", ""); + assertEqual("//", "//", ""); + assertEqual("--123", "--123", ""); + assertEqual("//123", "//123", ""); + assertEqual("--test", "--test"); + assertEqual("//test", "//test"); + assertEqual("--test\ntest", "--test\ntest", ""); + assertEqual("--test\t\n", "--test\t\n", ""); + assertEqual("--test\n123 test", "--test\n0# test", "123"); + } + + + @Test + public void multiLineCommentState() { + assertEqual("/**/", "/**/", ""); + assertEqual("/* */", "/* */", ""); + assertEqual("/* */abc", "/* */abc", ""); + assertEqual("/* * */", "/* * */", ""); + assertEqual("/* * */", "/* * */", ""); + + assertEqual("/* abc", "/* abc", ""); + + assertEqual("select * from table", "select * from table", ""); + } + + @Test + public void symbolState() { + assertEqual("''", "''", ""); + assertEqual("'abc'", "'0$'", "abc"); + assertEqual("'a''bc'", "'0$'", "a''bc"); + assertEqual("'a' 'bc'", "'0$' '1$'", "a,bc"); + + assertEqual("'a''bc' 'a''bc'", "'0$' '1$'", "a''bc,a''bc"); + + + assertEqual("select * from table where a='a'", "select * from table where a='0$'", "a"); + } + + // @Test + public void charout() { + for (int i = 11; i < 67; i++) { + logger.debug("{}", (char) i); + } + } + + @Test + public void commentAndSymbolCombine() { + assertEqual("/* 'test' */", "/* 'test' */", ""); + assertEqual("/* 'test'' */", "/* 'test'' */", ""); + assertEqual("/* '' */", "/* '' */"); + + assertEqual("/* */ 123 */", "/* */ 0# */", "123"); + + assertEqual("' /* */'", "'0$'", " /* */"); + + } + + @Test + public void sepratorTest() { + + assertEqual("1234 456,7", "0# 1#,2#", "1234,456,7"); + + assertEqual("'1234 456,7'", "'0$'", "1234 456,,7"); + + assertEqual("'1234''456,7'", "'0$'", "1234''456,,7"); + ParsingResult parsingResult2 = this.sqlParser.normalizedSql("'1234''456,7'"); + logger.debug("{}", parsingResult2); + // 문자열 토큰 + + + assertEqual("'1234' '456,7'", "'0$' '1$'", "1234,456,,7"); + } + + + @Test + public void combineTest() { + assertCombine("123 345", "0# 1#", "123,345"); + assertCombine("123 345 'test'", "0# 1# '2$'", "123,345,test"); + assertCombine("1 2 3 4 5 6 7 8 9 10 11", "0# 1# 2# 3# 4# 5# 6# 7# 8# 9# 10#", "1,2,3,4,5,6,7,8,9,10,11"); + } + + @Test + public void combineErrorTest() { + assertCombineErrorCase("123 10#", "0# 10#", "123,345"); + + assertCombineErrorCase("1 3 10#", "0# 2# 10#", "1,2,3"); + + assertCombineErrorCase("1 2 3", "0# 2 3", "1,2,3"); + assertCombineErrorCase("1 2 10", "0# 2 10", "1,2,3"); + assertCombineErrorCase("1 2 201", "0# 2 201", "1,2,3"); + + assertCombineErrorCase("1 2 11", "0# 2 10#", "1,2,3,4,5,6,7,8,9,10,11"); + + } + + private void assertCombine(String result, String sql, String outputParams) { + List output = this.outputParameterParser.parseOutputParameter(outputParams); + + ParsingResult parsingResult = this.sqlParser.normalizedSql(result); + Assert.assertEquals("sql", parsingResult.getSql(), sql); + String combine = this.sqlParser.combineOutputParams(sql, output); + Assert.assertEquals("combine", result, combine); + } + + private void assertCombineErrorCase(String expectedError, String sql, String outputParams) { + List output = this.outputParameterParser.parseOutputParameter(outputParams); +// ParsingResult parsingResult = this.sqlParser.normalizedSql(result); + String combine = this.sqlParser.combineOutputParams(sql, output); + Assert.assertEquals("combine", expectedError, combine); + } + + + private void assertEqual(String expected) { + ParsingResult parsingResult = sqlParser.normalizedSql(expected); + String normalizedSql = parsingResult.getSql(); + try { + Assert.assertEquals(expected, normalizedSql); + } catch (AssertionFailedError e) { + logger.warn("Original :{}", expected); + throw e; + } + } + + private void assertEqual(String expected, String actual) { + ParsingResult parsingResult = sqlParser.normalizedSql(expected); + String normalizedSql = parsingResult.getSql(); + try { + Assert.assertEquals(actual, normalizedSql); + } catch (AssertionFailedError e) { + logger.warn("Original :{}", expected); + throw e; + } + } + + private void assertEqual(String expected, String actual, String ouputExpected) { + ParsingResult parsingResult = sqlParser.normalizedSql(expected); + String normalizedSql = parsingResult.getSql(); + String output = parsingResult.getOutput(); + List outputParams = outputParameterParser.parseOutputParameter(output); + String s = sqlParser.combineOutputParams(normalizedSql, outputParams); + logger.debug("combine:" + s); + try { + Assert.assertEquals("normalizedSql check", actual, normalizedSql); + } catch (AssertionFailedError e) { + logger.warn("Original :{}", expected); + throw e; + } + + Assert.assertEquals("outputParam check", ouputExpected, parsingResult.getOutput()); + } + + private void assertEqualObject(String expected) { + ParsingResult parsingResult = sqlParser.normalizedSql(expected); + String normalizedSql = parsingResult.getSql(); + try { + Assert.assertEquals("normalizedSql check", expected, normalizedSql); + Assert.assertSame(expected, normalizedSql); + } catch (AssertionFailedError e) { + logger.warn("Original :{}", expected); + throw e; + } + + } + + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParserTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParserTest.java index acd12b145134..c47a9d26b790 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParserTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/StringTraceHeaderParserTest.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.common.util; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.UUID; - -/** - * @author emeroad - */ -public class StringTraceHeaderParserTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private StringTraceHeaderParser parser= new StringTraceHeaderParser(); - - @Test - public void getIdSize() { - String test = "3ccb94f3-a8fe-4464-bfbd-d35490afab3d"; - logger.info("idSize={}", test.length()); - } - - - @Test - public void createStringBaseTraceHeader() { - createAndParser(UUID.randomUUID().toString(), 123, 345, 23423, (short) 22); - createAndParser(UUID.randomUUID().toString(), -1, 2, 0, (short) 0); - createAndParser(UUID.randomUUID().toString(), 234, 2, 0, (short) 0); - } - - - - private void createAndParser(String uuid, int spanId, int pSpanId, int sampling, short flag) { - String traceHeader = parser.createHeader(uuid, spanId, pSpanId, sampling, (short) flag); - - TraceHeader header = parser.parseHeader(traceHeader); - Assert.assertEquals("id", uuid, header.getId()); - Assert.assertEquals("spanId", String.valueOf(spanId), header.getSpanId()); - Assert.assertEquals("pSpanId", String.valueOf(pSpanId), header.getParentSpanId()); - Assert.assertEquals("sampling", String.valueOf(sampling), header.getSampling()); - Assert.assertEquals("flag", String.valueOf(flag), header.getFlag()); - logger.info("{}, parse:" + header); - } -} +package com.nhn.pinpoint.common.util; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.UUID; + +/** + * @author emeroad + */ +public class StringTraceHeaderParserTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private StringTraceHeaderParser parser= new StringTraceHeaderParser(); + + @Test + public void getIdSize() { + String test = "3ccb94f3-a8fe-4464-bfbd-d35490afab3d"; + logger.info("idSize={}", test.length()); + } + + + @Test + public void createStringBaseTraceHeader() { + createAndParser(UUID.randomUUID().toString(), 123, 345, 23423, (short) 22); + createAndParser(UUID.randomUUID().toString(), -1, 2, 0, (short) 0); + createAndParser(UUID.randomUUID().toString(), 234, 2, 0, (short) 0); + } + + + + private void createAndParser(String uuid, int spanId, int pSpanId, int sampling, short flag) { + String traceHeader = parser.createHeader(uuid, spanId, pSpanId, sampling, (short) flag); + + TraceHeader header = parser.parseHeader(traceHeader); + Assert.assertEquals("id", uuid, header.getId()); + Assert.assertEquals("spanId", String.valueOf(spanId), header.getSpanId()); + Assert.assertEquals("pSpanId", String.valueOf(pSpanId), header.getParentSpanId()); + Assert.assertEquals("sampling", String.valueOf(sampling), header.getSampling()); + Assert.assertEquals("flag", String.valueOf(flag), header.getFlag()); + logger.info("{}, parse:" + header); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeSlotTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeSlotTest.java index 6a21aa378005..6922fa5a825b 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeSlotTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeSlotTest.java @@ -1,53 +1,53 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - */ -public class TimeSlotTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final TimeSlot timeSlot = new DefaultTimeSlot(); - - @Test - public void testGetTimeSlot() throws Exception { - long currentTime = System.currentTimeMillis(); - // 슬롯 넘버를 알아온다. - long timeSlot = this.timeSlot.getTimeSlot(currentTime); - - logger.info("{} currentTime ", currentTime); - logger.info("{} timeSlot", timeSlot); - Assert.assertTrue(currentTime >= timeSlot); - } - - @Test - public void testSlotTime1() throws Exception { - int slotTest = 60 * 1000; - - // 슬롯 넘버를 알아온다. - long timeSlot = this.timeSlot.getTimeSlot(slotTest); - - logger.info("{} slotTest ", slotTest); - logger.info("{} timeSlot", timeSlot); - Assert.assertEquals(slotTest, timeSlot); - } - - @Test - public void testSlotTime2() throws Exception { - int sourceTest = 60 * 1000; - int slotTest = sourceTest + 1; - - - // 슬롯 넘버를 알아온다. - long timeSlot = this.timeSlot.getTimeSlot(slotTest); - - logger.info("{} slotTest ", slotTest); - logger.info("{} timeSlot", timeSlot); - Assert.assertEquals(sourceTest, timeSlot); - } -} +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + */ +public class TimeSlotTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final TimeSlot timeSlot = new DefaultTimeSlot(); + + @Test + public void testGetTimeSlot() throws Exception { + long currentTime = System.currentTimeMillis(); + // 슬롯 넘버를 알아온다. + long timeSlot = this.timeSlot.getTimeSlot(currentTime); + + logger.info("{} currentTime ", currentTime); + logger.info("{} timeSlot", timeSlot); + Assert.assertTrue(currentTime >= timeSlot); + } + + @Test + public void testSlotTime1() throws Exception { + int slotTest = 60 * 1000; + + // 슬롯 넘버를 알아온다. + long timeSlot = this.timeSlot.getTimeSlot(slotTest); + + logger.info("{} slotTest ", slotTest); + logger.info("{} timeSlot", timeSlot); + Assert.assertEquals(slotTest, timeSlot); + } + + @Test + public void testSlotTime2() throws Exception { + int sourceTest = 60 * 1000; + int slotTest = sourceTest + 1; + + + // 슬롯 넘버를 알아온다. + long timeSlot = this.timeSlot.getTimeSlot(slotTest); + + logger.info("{} slotTest ", slotTest); + logger.info("{} timeSlot", timeSlot); + Assert.assertEquals(sourceTest, timeSlot); + } +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeUtilsTest.java index af0ff83d2e4f..aeb2c0f83878 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/TimeUtilsTest.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class TimeUtilsTest { - @Test - public void testReverseCurrentTimeMillis() throws Exception { - long currentTime = System.currentTimeMillis(); - long reverseTime = TimeUtils.reverseTimeMillis(currentTime); - long recoveryTime = TimeUtils.recoveryTimeMillis(reverseTime); - - Assert.assertEquals(currentTime, recoveryTime); - } - - @Test - public void testTimeOrder() throws InterruptedException { - long l1 = TimeUtils.reverseCurrentTimeMillis(); - Thread.sleep(5); - long l2 = TimeUtils.reverseCurrentTimeMillis(); - - Assert.assertTrue(l1 > l2); - } - -} +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class TimeUtilsTest { + @Test + public void testReverseCurrentTimeMillis() throws Exception { + long currentTime = System.currentTimeMillis(); + long reverseTime = TimeUtils.reverseTimeMillis(currentTime); + long recoveryTime = TimeUtils.recoveryTimeMillis(reverseTime); + + Assert.assertEquals(currentTime, recoveryTime); + } + + @Test + public void testTimeOrder() throws InterruptedException { + long l1 = TimeUtils.reverseCurrentTimeMillis(); + Thread.sleep(5); + long l2 = TimeUtils.reverseCurrentTimeMillis(); + + Assert.assertTrue(l1 > l2); + } + +} diff --git a/commons/src/test/java/com/navercorp/pinpoint/common/util/TransactionIdUtilsTest.java b/commons/src/test/java/com/navercorp/pinpoint/common/util/TransactionIdUtilsTest.java index f62de88a10a9..dff3b93429a5 100644 --- a/commons/src/test/java/com/navercorp/pinpoint/common/util/TransactionIdUtilsTest.java +++ b/commons/src/test/java/com/navercorp/pinpoint/common/util/TransactionIdUtilsTest.java @@ -1,47 +1,47 @@ -package com.nhn.pinpoint.common.util; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class TransactionIdUtilsTest { - @Test - public void testParseTransactionId() { - TransactionId transactionId = TransactionIdUtils.parseTransactionId("test" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "1" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "2"); - Assert.assertEquals(transactionId.getAgentId(), "test"); - Assert.assertEquals(transactionId.getAgentStartTime(), 1L); - Assert.assertEquals(transactionId.getTransactionSequence(), 2L); - } - - @Test - public void testParseTransactionId2() { - TransactionId transactionId = TransactionIdUtils.parseTransactionId("test" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "1" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "2" + TransactionIdUtils.TRANSACTION_ID_DELIMITER); - Assert.assertEquals(transactionId.getAgentId(), "test"); - Assert.assertEquals(transactionId.getAgentStartTime(), 1L); - Assert.assertEquals(transactionId.getTransactionSequence(), 2L); - } - - - @Test - public void testParseTransactionIdByte() { - long time = System.currentTimeMillis(); - byte[] bytes = TransactionIdUtils.formatBytes("test", time, 2); - TransactionId transactionId = TransactionIdUtils.parseTransactionId(bytes); - Assert.assertEquals(transactionId.getAgentId(), "test"); - Assert.assertEquals(transactionId.getAgentStartTime(), time); - Assert.assertEquals(transactionId.getTransactionSequence(), 2L); - } - - @Test - public void testParseTransactionIdByte_AgentIdisNull() { - long time = System.currentTimeMillis(); - byte[] bytes = TransactionIdUtils.formatBytes(null, time, 1); - TransactionId transactionId = TransactionIdUtils.parseTransactionId(bytes); - Assert.assertEquals(transactionId.getAgentId(), null); - Assert.assertEquals(transactionId.getAgentStartTime(), time); - Assert.assertEquals(transactionId.getTransactionSequence(), 1L); - } - -} +package com.nhn.pinpoint.common.util; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class TransactionIdUtilsTest { + @Test + public void testParseTransactionId() { + TransactionId transactionId = TransactionIdUtils.parseTransactionId("test" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "1" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "2"); + Assert.assertEquals(transactionId.getAgentId(), "test"); + Assert.assertEquals(transactionId.getAgentStartTime(), 1L); + Assert.assertEquals(transactionId.getTransactionSequence(), 2L); + } + + @Test + public void testParseTransactionId2() { + TransactionId transactionId = TransactionIdUtils.parseTransactionId("test" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "1" + TransactionIdUtils.TRANSACTION_ID_DELIMITER + "2" + TransactionIdUtils.TRANSACTION_ID_DELIMITER); + Assert.assertEquals(transactionId.getAgentId(), "test"); + Assert.assertEquals(transactionId.getAgentStartTime(), 1L); + Assert.assertEquals(transactionId.getTransactionSequence(), 2L); + } + + + @Test + public void testParseTransactionIdByte() { + long time = System.currentTimeMillis(); + byte[] bytes = TransactionIdUtils.formatBytes("test", time, 2); + TransactionId transactionId = TransactionIdUtils.parseTransactionId(bytes); + Assert.assertEquals(transactionId.getAgentId(), "test"); + Assert.assertEquals(transactionId.getAgentStartTime(), time); + Assert.assertEquals(transactionId.getTransactionSequence(), 2L); + } + + @Test + public void testParseTransactionIdByte_AgentIdisNull() { + long time = System.currentTimeMillis(); + byte[] bytes = TransactionIdUtils.formatBytes(null, time, 1); + TransactionId transactionId = TransactionIdUtils.parseTransactionId(bytes); + Assert.assertEquals(transactionId.getAgentId(), null); + Assert.assertEquals(transactionId.getAgentStartTime(), time); + Assert.assertEquals(transactionId.getTransactionSequence(), 1L); + } + +} diff --git a/commons/src/test/resources/log4j.xml b/commons/src/test/resources/log4j.xml index 7067a1bb8a5f..e8645d9b610e 100644 --- a/commons/src/test/resources/log4j.xml +++ b/commons/src/test/resources/log4j.xml @@ -1,49 +1,49 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/commons/src/test/resources/test-hbase.properties b/commons/src/test/resources/test-hbase.properties index 121a25f03526..4ff60a94fc15 100644 --- a/commons/src/test/resources/test-hbase.properties +++ b/commons/src/test/resources/test-hbase.properties @@ -1,8 +1,8 @@ -#hbase.client.host=localhost -#hbase.client.host=10.64.84.188 -#dev-hippo002.ncl -hbase.client.host=10.101.17.108 - -hbase.client.port=2181 - +#hbase.client.host=localhost +#hbase.client.host=10.64.84.188 +#dev-hippo002.ncl +hbase.client.host=10.101.17.108 + +hbase.client.port=2181 + hbase.htable.threads.max=32 \ No newline at end of file diff --git a/commons/src/test/resources/test.properties b/commons/src/test/resources/test.properties new file mode 100644 index 000000000000..1757282f7f02 --- /dev/null +++ b/commons/src/test/resources/test.properties @@ -0,0 +1 @@ +test=pinpoint \ No newline at end of file diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml index 8f4939f76d63..43bc3321deb5 100644 --- a/findbugs-exclude.xml +++ b/findbugs-exclude.xml @@ -1,2 +1,2 @@ - - + + diff --git a/pom.xml b/pom.xml index 6e685ddc9286..d43f19213aed 100644 --- a/pom.xml +++ b/pom.xml @@ -389,6 +389,11 @@ ojdbc6 11.1.0.7.0 + + net.sourceforge.jtds + jtds + 1.2.5 + com.ning @@ -411,6 +416,11 @@ catalina 6.0.35 + + org.apache.tomcat + coyote + 6.0.35 + arcus @@ -486,11 +496,6 @@ commons-lang3 3.3.2 - - net.sourceforge.jtds - jtds - 1.2.4 - commons-fileupload commons-fileupload diff --git a/profiler-optional/README.md b/profiler-optional/README.md index 3e7e769d3906..b237b1917eee 100644 --- a/profiler-optional/README.md +++ b/profiler-optional/README.md @@ -1,42 +1,42 @@ -Pinpoint-profiler-optional -========= - -아래와 같이 maven compile을 하기 위해서는 JDK 1.7+이 필요합니다. -```xml - - org.apache.maven.plugins - maven-compiler-plugin - 2.5.1 - true - - 1.7 - 1.7 - ${compiler-debug} - true - true - true - 1.7 - ${JAVA_7_HOME}/bin/javac - UTF-8 - - -``` - -환경변수에 JAVA_7_HOME을 잡아주시고, maven의 settings.xml에 JAVA_7_HOME property를 아래와 같이 설정해주세요. - -(m2e 플러그인을 사용한 maven 빌드를 하시려면 settings.xml을 수정하셔야 합니다.) -```xml - - - - JAVA_7_HOME - - JDK 1.7+ 패스 - - - - - JAVA_7_HOME - - +Pinpoint-profiler-optional +========= + +아래와 같이 maven compile을 하기 위해서는 JDK 1.7+이 필요합니다. +```xml + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + true + + 1.7 + 1.7 + ${compiler-debug} + true + true + true + 1.7 + ${JAVA_7_HOME}/bin/javac + UTF-8 + + +``` + +환경변수에 JAVA_7_HOME을 잡아주시고, maven의 settings.xml에 JAVA_7_HOME property를 아래와 같이 설정해주세요. + +(m2e 플러그인을 사용한 maven 빌드를 하시려면 settings.xml을 수정하셔야 합니다.) +```xml + + + + JAVA_7_HOME + + JDK 1.7+ 패스 + + + + + JAVA_7_HOME + + ``` \ No newline at end of file diff --git a/profiler-optional/build.xml b/profiler-optional/build.xml index cde37bc5053d..125d6626acfe 100644 --- a/profiler-optional/build.xml +++ b/profiler-optional/build.xml @@ -1,42 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/profiler-optional/pom.xml b/profiler-optional/pom.xml index 2caf07dacece..541c21558f97 100644 --- a/profiler-optional/pom.xml +++ b/profiler-optional/pom.xml @@ -1,176 +1,176 @@ - - 4.0.0 - - com.nhn.pinpoint - pom - 1.0.3-SNAPSHOT - - - pinpoint-profiler-optional - pinpoint profiler optional - pinpoint profiler optional package - - - 1.7 - - - - - com.nhn.pinpoint - pinpoint-profiler - provided - - - com.nhn.pinpoint - pinpoint-commons - - - com.nhn.pinpoint - pinpoint-bootstrap - - - com.nhn.pinpoint - pinpoint-rpc - - - com.nhn.pinpoint - pinpoint-thrift - - - - - - - - - ${basedir}/src/main/java - - **/*.java - - - - true - ${basedir}/src/main/resources - - - - - ${basedir}/src/test/java - - **/*.java - - - - true - ${basedir}/src/test/resources - - - - - - maven-resources-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - - ${compiler-debug} - true - true - ${jdk.version} - ${env.JAVA_7_HOME}/bin/javac - - - - org.apache.maven.plugins - maven-jar-plugin - - - org.apache.maven.plugins - maven-antrun-plugin - - - package - - - - - - - - run - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - ${env.JAVA_7_HOME}/bin/java - once - - - - org.codehaus.mojo - findbugs-maven-plugin - - - com.atlassian.maven.plugins - maven-clover2-plugin - - - - - - - - - local - - true - - - true - - - - - - test - - true - - - - - - dev - - true - - - - - - release - - false - - - - - klocwork - - - - com.klocwork.ps - kwmaven - - - - - - + + 4.0.0 + + com.nhn.pinpoint + pom + 1.0.3-SNAPSHOT + + + pinpoint-profiler-optional + pinpoint profiler optional + pinpoint profiler optional package + + + 1.7 + + + + + com.nhn.pinpoint + pinpoint-profiler + provided + + + com.nhn.pinpoint + pinpoint-commons + + + com.nhn.pinpoint + pinpoint-bootstrap + + + com.nhn.pinpoint + pinpoint-rpc + + + com.nhn.pinpoint + pinpoint-thrift + + + + + + + + + ${basedir}/src/main/java + + **/*.java + + + + true + ${basedir}/src/main/resources + + + + + ${basedir}/src/test/java + + **/*.java + + + + true + ${basedir}/src/test/resources + + + + + + maven-resources-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + ${compiler-debug} + true + true + ${jdk.version} + ${env.JAVA_7_HOME}/bin/javac + + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-antrun-plugin + + + package + + + + + + + + run + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + ${env.JAVA_7_HOME}/bin/java + once + + + + org.codehaus.mojo + findbugs-maven-plugin + + + com.atlassian.maven.plugins + maven-clover2-plugin + + + + + + + + + local + + true + + + true + + + + + + test + + true + + + + + + dev + + true + + + + + + release + + false + + + + + klocwork + + + + com.klocwork.ps + kwmaven + + + + + + \ No newline at end of file diff --git a/profiler-optional/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EnhancedCpuLoadMetricSet.java b/profiler-optional/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EnhancedCpuLoadMetricSet.java index d80cbb1a4d61..329dd07d4ffc 100644 --- a/profiler-optional/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EnhancedCpuLoadMetricSet.java +++ b/profiler-optional/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EnhancedCpuLoadMetricSet.java @@ -1,36 +1,36 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; - -import com.codahale.metrics.Gauge; -import com.sun.management.OperatingSystemMXBean; - -/** - * @author hyungil.jeong - */ -public class EnhancedCpuLoadMetricSet extends AbstractCpuLoadMetricSet { - - @Override - protected Gauge getJvmCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { - return new Gauge() { - @Override - public Double getValue() { - return operatingSystemMXBean.getProcessCpuLoad(); - } - }; - } - - @Override - protected Gauge getSystemCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { - return new Gauge() { - @Override - public Double getValue() { - return operatingSystemMXBean.getSystemCpuLoad(); - } - }; - } - - @Override - public String toString() { - return "CpuLoadMetricSet for Java 1.7+"; - } - -} +package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; + +import com.codahale.metrics.Gauge; +import com.sun.management.OperatingSystemMXBean; + +/** + * @author hyungil.jeong + */ +public class EnhancedCpuLoadMetricSet extends AbstractCpuLoadMetricSet { + + @Override + protected Gauge getJvmCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { + return new Gauge() { + @Override + public Double getValue() { + return operatingSystemMXBean.getProcessCpuLoad(); + } + }; + } + + @Override + protected Gauge getSystemCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { + return new Gauge() { + @Override + public Double getValue() { + return operatingSystemMXBean.getSystemCpuLoad(); + } + }; + } + + @Override + public String toString() { + return "CpuLoadMetricSet for Java 1.7+"; + } + +} diff --git a/profiler/build.xml b/profiler/build.xml index b5bdb0d06146..d54b0293f1a6 100644 --- a/profiler/build.xml +++ b/profiler/build.xml @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/profiler/findbugs-exclude.xml b/profiler/findbugs-exclude.xml index a4b4e8251d57..0193409a64e7 100644 --- a/profiler/findbugs-exclude.xml +++ b/profiler/findbugs-exclude.xml @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/profiler/pom.xml b/profiler/pom.xml index 9b430ce5580c..b1d880d913af 100644 --- a/profiler/pom.xml +++ b/profiler/pom.xml @@ -162,6 +162,11 @@ ojdbc6 provided + + net.sourceforge.jtds + jtds + provided + com.nhncorp.lucy @@ -273,6 +278,11 @@ catalina provided + + org.apache.tomcat + coyote + test + arcus diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformation.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformation.java index 7b8351dea6d9..ffe5f71a9d1a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformation.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformation.java @@ -1,98 +1,98 @@ -package com.nhn.pinpoint.profiler; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author emeroad - * @author koo.taejin - */ -public class AgentInformation { - private final String agentId; - private final String applicationName; - private final long startTime; - private final int pid; - private final String machineName; - private final short serverType; - private final String version; - - public AgentInformation(String agentId, String applicationName, long startTime, int pid, String machineName, short serverType, String version) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (machineName == null) { - throw new NullPointerException("machineName must not be null"); - } - if (version == null) { - throw new NullPointerException("version must not be null"); - } - this.agentId = agentId; - this.applicationName = applicationName; - this.startTime = startTime; - this.pid = pid; - this.machineName = machineName; - this.serverType = serverType; - this.version = version; - } - - - - public String getAgentId() { - return agentId; - } - - public String getApplicationName() { - return applicationName; - } - - public long getStartTime() { - return startTime; - } - - public int getPid() { - return pid; - } - - public String getMachineName() { - return machineName; - } - - public short getServerType() { - return serverType; - } - - public String getVersion() { - return version; - } - - public Map toMap() { - Map map = new HashMap(); - - map.put(AgentPropertiesType.AGENT_ID.getName(), this.agentId); - map.put(AgentPropertiesType.APPLICATION_NAME.getName(), this.applicationName); - map.put(AgentPropertiesType.HOSTNAME.getName(), this.machineName); - map.put(AgentPropertiesType.PID.getName(), this.pid); - map.put(AgentPropertiesType.SERVICE_TYPE.getName(), this.serverType); - map.put(AgentPropertiesType.START_TIMESTAMP.getName(), this.startTime); - map.put(AgentPropertiesType.VERSION.getName(), this.version); - - return map; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("AgentInformation{"); - sb.append("agentId='").append(agentId).append('\''); - sb.append(", applicationName='").append(applicationName).append('\''); - sb.append(", startTime=").append(startTime); - sb.append(", pid=").append(pid); - sb.append(", machineName='").append(machineName).append('\''); - sb.append(", serverType=").append(serverType); - sb.append(", version='").append(version).append('\''); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.profiler; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author emeroad + * @author koo.taejin + */ +public class AgentInformation { + private final String agentId; + private final String applicationName; + private final long startTime; + private final int pid; + private final String machineName; + private final short serverType; + private final String version; + + public AgentInformation(String agentId, String applicationName, long startTime, int pid, String machineName, short serverType, String version) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (machineName == null) { + throw new NullPointerException("machineName must not be null"); + } + if (version == null) { + throw new NullPointerException("version must not be null"); + } + this.agentId = agentId; + this.applicationName = applicationName; + this.startTime = startTime; + this.pid = pid; + this.machineName = machineName; + this.serverType = serverType; + this.version = version; + } + + + + public String getAgentId() { + return agentId; + } + + public String getApplicationName() { + return applicationName; + } + + public long getStartTime() { + return startTime; + } + + public int getPid() { + return pid; + } + + public String getMachineName() { + return machineName; + } + + public short getServerType() { + return serverType; + } + + public String getVersion() { + return version; + } + + public Map toMap() { + Map map = new HashMap(); + + map.put(AgentPropertiesType.AGENT_ID.getName(), this.agentId); + map.put(AgentPropertiesType.APPLICATION_NAME.getName(), this.applicationName); + map.put(AgentPropertiesType.HOSTNAME.getName(), this.machineName); + map.put(AgentPropertiesType.PID.getName(), this.pid); + map.put(AgentPropertiesType.SERVICE_TYPE.getName(), this.serverType); + map.put(AgentPropertiesType.START_TIMESTAMP.getName(), this.startTime); + map.put(AgentPropertiesType.VERSION.getName(), this.version); + + return map; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("AgentInformation{"); + sb.append("agentId='").append(agentId).append('\''); + sb.append(", applicationName='").append(applicationName).append('\''); + sb.append(", startTime=").append(startTime); + sb.append(", pid=").append(pid); + sb.append(", machineName='").append(machineName).append('\''); + sb.append(", serverType=").append(serverType); + sb.append(", version='").append(version).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformationFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformationFactory.java index a15d5d72dac6..fb636d2b36fa 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformationFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInformationFactory.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.profiler; - -import com.nhn.pinpoint.bootstrap.util.NetworkUtils; -import com.nhn.pinpoint.common.PinpointConstants; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.Version; -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.profiler.util.RuntimeMXBeanUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * @author emeroad - */ -public class AgentInformationFactory { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public AgentInformationFactory() { - } - - public AgentInformation createAgentInformation(ServiceType serverType) { - if (serverType == null) { - throw new NullPointerException("serverType must not be null"); - } - // TODO 일단 임시로 호환성을 위해 agentid에 machinename을 넣도록 하자 - // TODO 박스 하나에 서버 인스턴스를 여러개 실행할 때에 문제가 될 수 있음. - final String machineName = NetworkUtils.getHostName(); - final String agentId = getId("pinpoint.agentId", machineName, PinpointConstants.AGENT_NAME_MAX_LEN); - final String applicationName = getId("pinpoint.applicationName", "UnknownApplicationName", PinpointConstants.APPLICATION_NAME_MAX_LEN); - final long startTime = RuntimeMXBeanUtils.getVmStartTime(); - final int pid = RuntimeMXBeanUtils.getPid(); - return new AgentInformation(agentId, applicationName, startTime, pid, machineName, serverType.getCode(), Version.VERSION); - } - - private String getId(String key, String defaultValue, int maxlen) { - String value = System.getProperty(key, defaultValue); - validateId(value, key, maxlen); - return value; - } - - private void validateId(String id, String idName, int maxlen) { - // 에러 체크 로직을 bootclass 앞단으로 이동시켜야 함. - // 아니면 여기서 체크해서 실패시 agent동작을 하지 않도록 하던가 하는 추가 동작을 해야함. - byte[] bytes = BytesUtils.toBytes(id); - if (bytes.length > maxlen) { - logger.warn("{} is too long(1~24). value={}", idName, id); - } - } -} +package com.nhn.pinpoint.profiler; + +import com.nhn.pinpoint.bootstrap.util.NetworkUtils; +import com.nhn.pinpoint.common.PinpointConstants; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.Version; +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.profiler.util.RuntimeMXBeanUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * @author emeroad + */ +public class AgentInformationFactory { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public AgentInformationFactory() { + } + + public AgentInformation createAgentInformation(ServiceType serverType) { + if (serverType == null) { + throw new NullPointerException("serverType must not be null"); + } + // TODO 일단 임시로 호환성을 위해 agentid에 machinename을 넣도록 하자 + // TODO 박스 하나에 서버 인스턴스를 여러개 실행할 때에 문제가 될 수 있음. + final String machineName = NetworkUtils.getHostName(); + final String agentId = getId("pinpoint.agentId", machineName, PinpointConstants.AGENT_NAME_MAX_LEN); + final String applicationName = getId("pinpoint.applicationName", "UnknownApplicationName", PinpointConstants.APPLICATION_NAME_MAX_LEN); + final long startTime = RuntimeMXBeanUtils.getVmStartTime(); + final int pid = RuntimeMXBeanUtils.getPid(); + return new AgentInformation(agentId, applicationName, startTime, pid, machineName, serverType.getCode(), Version.VERSION); + } + + private String getId(String key, String defaultValue, int maxlen) { + String value = System.getProperty(key, defaultValue); + validateId(value, key, maxlen); + return value; + } + + private void validateId(String id, String idName, int maxlen) { + // 에러 체크 로직을 bootclass 앞단으로 이동시켜야 함. + // 아니면 여기서 체크해서 실패시 agent동작을 하지 않도록 하던가 하는 추가 동작을 해야함. + byte[] bytes = BytesUtils.toBytes(id); + if (bytes.length > maxlen) { + logger.warn("{} is too long(1~24). value={}", idName, id); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentProperties.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentProperties.java index 5d1dbc10dacf..5164993b56d3 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentProperties.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentProperties.java @@ -1,45 +1,45 @@ -package com.nhn.pinpoint.profiler; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.util.ClassUtils; - -/** - * @author koo.taejin - */ -public class AgentProperties { - - // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 - // 변경시 함께 변경 필요 - // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 - - public static final String KEY_HOSTNAME = "hostName"; - public static final String KEY_IP = "ip"; - public static final String KEY_AGENTID = "agentId"; - public static final String KEY_APPLICATION_NAME = "applicationName"; - public static final String KEY_SERVICE_TYPE = "serviceType"; - public static final String KEY_PID = "pid"; - public static final String KEY_VERSION = "version"; - public static final String KEY_START_TIME_MILLIS = "startTimestamp"; - - private final Map properties; - - public AgentProperties(Map properties) { - this.properties = properties; - } - - public T getProperties(String key, Class returnClazz) { - Object value = properties.get(key); - - if (value == null) { - return null; - } - - if (ClassUtils.isAssignable(value.getClass(), returnClazz)) { - return (T) value; - } - - return null; - } - -} +package com.nhn.pinpoint.profiler; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.util.ClassUtils; + +/** + * @author koo.taejin + */ +public class AgentProperties { + + // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 + // 변경시 함께 변경 필요 + // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 + + public static final String KEY_HOSTNAME = "hostName"; + public static final String KEY_IP = "ip"; + public static final String KEY_AGENTID = "agentId"; + public static final String KEY_APPLICATION_NAME = "applicationName"; + public static final String KEY_SERVICE_TYPE = "serviceType"; + public static final String KEY_PID = "pid"; + public static final String KEY_VERSION = "version"; + public static final String KEY_START_TIME_MILLIS = "startTimestamp"; + + private final Map properties; + + public AgentProperties(Map properties) { + this.properties = properties; + } + + public T getProperties(String key, Class returnClazz) { + Object value = properties.get(key); + + if (value == null) { + return null; + } + + if (ClassUtils.isAssignable(value.getClass(), returnClazz)) { + return (T) value; + } + + return null; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentPropertiesType.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentPropertiesType.java index 37f6e6d81f39..c158ca019c14 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentPropertiesType.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentPropertiesType.java @@ -1,58 +1,58 @@ -package com.nhn.pinpoint.profiler; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.util.ClassUtils; - -/** - * @author koo.taejin - */ -public enum AgentPropertiesType { - - // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 - // 변경시 함께 변경 필요 - // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 - - HOSTNAME("hostName", String.class), - IP("ip", String.class), - AGENT_ID("agentId", String.class), - APPLICATION_NAME("applicationName", String.class), - SERVICE_TYPE("serviceType", Integer.class), - PID("pid", Integer.class), - VERSION("version", String.class), - START_TIMESTAMP("startTimestamp", Long.class); - - - private final String name; - private final Class clazzType; - - private AgentPropertiesType(String name, Class clazzType) { - this.name = name; - this.clazzType = clazzType; - } - - public String getName() { - return name; - } - - public Class getClazzType() { - return clazzType; - } - - public static boolean hasAllType(Map properties) { - for (AgentPropertiesType type : AgentPropertiesType.values()) { - Object value = properties.get(type.getName()); - - if (value == null) { - return false; - } - - if (!ClassUtils.isAssignable(value.getClass(), type.getClazzType())) { - return false; - } - } - - return true; - } - -} +package com.nhn.pinpoint.profiler; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.util.ClassUtils; + +/** + * @author koo.taejin + */ +public enum AgentPropertiesType { + + // 해당 객체는 profiler, collector 양쪽에 함꼐 있음 + // 변경시 함께 변경 필요 + // map으로 처리하기 때문에 이전 파라미터 제거 대신 추가할 경우 확장성에는 문제가 없음 + + HOSTNAME("hostName", String.class), + IP("ip", String.class), + AGENT_ID("agentId", String.class), + APPLICATION_NAME("applicationName", String.class), + SERVICE_TYPE("serviceType", Integer.class), + PID("pid", Integer.class), + VERSION("version", String.class), + START_TIMESTAMP("startTimestamp", Long.class); + + + private final String name; + private final Class clazzType; + + private AgentPropertiesType(String name, Class clazzType) { + this.name = name; + this.clazzType = clazzType; + } + + public String getName() { + return name; + } + + public Class getClazzType() { + return clazzType; + } + + public static boolean hasAllType(Map properties) { + for (AgentPropertiesType type : AgentPropertiesType.values()) { + Object value = properties.get(type.getName()); + + if (value == null) { + return false; + } + + if (!ClassUtils.isAssignable(value.getClass(), type.getClazzType())) { + return false; + } + } + + return true; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentStatus.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentStatus.java index 094315d8ec62..44e5152137bd 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentStatus.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentStatus.java @@ -3,6 +3,5 @@ public enum AgentStatus { INITIALIZING, RUNNING, - STOPPING, STOPPED } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java index 79e488a9acc5..b08303c761e0 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java @@ -47,6 +47,7 @@ /** * @author emeroad * @author koo.taejin + * @author hyungil.jeong */ public class DefaultAgent implements Agent { @@ -66,7 +67,7 @@ public class DefaultAgent implements Agent { private final PinpointSocketFactory factory; private final PinpointSocket socket; - + private final EnhancedDataSender tcpDataSender; private final DataSender statDataSender; private final DataSender spanDataSender; @@ -87,7 +88,6 @@ public class DefaultAgent implements Agent { ClassPreLoader.preload(); } - public DefaultAgent(String agentArgs, Instrumentation instrumentation, ProfilerConfig profilerConfig) { if (instrumentation == null) { throw new NullPointerException("instrumentation must not be null"); @@ -123,17 +123,19 @@ public DefaultAgent(String agentArgs, Instrumentation instrumentation, ProfilerC logger.info("agentInformation:{}", agentInformation); this.tAgentInfo = createTAgentInfo(); - + this.factory = createPinpointSocketFactory(); - this.socket = createPinpointSocket(this.profilerConfig.getCollectorServerIp(), this.profilerConfig.getCollectorTcpServerPort(), factory, this.profilerConfig.isTcpDataSenderCommandAcceptEnable()); - + this.socket = createPinpointSocket(this.profilerConfig.getCollectorServerIp(), this.profilerConfig.getCollectorTcpServerPort(), factory, + this.profilerConfig.isTcpDataSenderCommandAcceptEnable()); + this.tcpDataSender = createTcpDataSender(socket); - + this.spanDataSender = createUdpDataSender(this.profilerConfig.getCollectorUdpSpanServerPort(), "Pinpoint-UdpSpanDataExecutor", - this.profilerConfig.getSpanDataSenderWriteQueueSize(), this.profilerConfig.getSpanDataSenderSocketTimeout(), this.profilerConfig.getSpanDataSenderSocketSendBufferSize()); + this.profilerConfig.getSpanDataSenderWriteQueueSize(), this.profilerConfig.getSpanDataSenderSocketTimeout(), + this.profilerConfig.getSpanDataSenderSocketSendBufferSize()); this.statDataSender = createUdpDataSender(this.profilerConfig.getCollectorUdpServerPort(), "Pinpoint-UdpStatDataExecutor", - this.profilerConfig.getStatDataSenderWriteQueueSize(), this.profilerConfig.getStatDataSenderSocketTimeout(), this.profilerConfig.getStatDataSenderSocketSendBufferSize()); - + this.profilerConfig.getStatDataSenderWriteQueueSize(), this.profilerConfig.getStatDataSenderSocketTimeout(), + this.profilerConfig.getStatDataSenderSocketSendBufferSize()); this.traceContext = createTraceContext(agentInformation.getServerType()); @@ -143,15 +145,13 @@ public DefaultAgent(String agentArgs, Instrumentation instrumentation, ProfilerC this.agentStatMonitor = new AgentStatMonitor(this.statDataSender, this.agentInformation.getAgentId(), this.agentInformation.getStartTime()); preLoadClass(); - + /** - * FIXME - * tomcat의 경우에는 com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.CatalinaAwaitInterceptor가 - * org/apache/catalina/startup/Catalina/await함수가 실행되기 전에 실행해주나. - * stand alone application은 그렇지 않으므로.. + * FIXME tomcat의 경우에는 com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.CatalinaAwaitInterceptor가 org/apache/catalina/startup/Catalina/await함수가 실행되기 + * 전에 실행해주나. stand alone application은 그렇지 않으므로.. */ if (typeResolver.isManuallyStartupRequired()) { - started(); + start(); } } @@ -168,8 +168,6 @@ public ClassFileTransformer getClassFileTransformer() { return classFileTransformer; } - - private void dumpSystemProperties() { if (logger.isInfoEnabled()) { Properties properties = System.getProperties(); @@ -191,7 +189,6 @@ public ProfilerConfig getProfilerConfig() { return profilerConfig; } - private TAgentInfo createTAgentInfo() { final ServerInfo serverInfo = this.serverInfo; String ip = serverInfo.getHostip(); @@ -209,16 +206,14 @@ private TAgentInfo createTAgentInfo() { agentInfo.setApplicationName(agentInformation.getApplicationName()); agentInfo.setPid(agentInformation.getPid()); agentInfo.setStartTimestamp(agentInformation.getStartTime()); - agentInfo.setServiceType(agentInformation.getServerType()); + agentInfo.setServiceType(agentInformation.getServerType()); agentInfo.setVersion(Version.VERSION); -// agentInfo.setIsAlive(true); + // agentInfo.setIsAlive(true); return agentInfo; } - - private void changeStatus(AgentStatus status) { this.agentStatus = status; if (logger.isDebugEnabled()) { @@ -235,7 +230,6 @@ private void bindPLoggerFactory(PLoggerBinder binder) { // shutdown hook이나 stop에 LoggerBinder의 연결을 풀어야 되는가? } - private TraceContext createTraceContext(short serverType) { final StorageFactory storageFactory = createStorageFactory(); logger.info("StorageFactoryType:{}", storageFactory); @@ -248,10 +242,8 @@ private TraceContext createTraceContext(short serverType) { traceContext.setAgentInformation(this.agentInformation); traceContext.setPriorityDataSender(this.tcpDataSender); - traceContext.setProfilerConfig(profilerConfig); - return traceContext; } @@ -274,33 +266,33 @@ private Sampler createSampler() { } protected PinpointSocketFactory createPinpointSocketFactory() { - Map properties = this.agentInformation.toMap(); - properties.put(AgentPropertiesType.IP.getName(), serverInfo.getHostip()); + Map properties = this.agentInformation.toMap(); + properties.put(AgentPropertiesType.IP.getName(), serverInfo.getHostip()); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); pinpointSocketFactory.setTimeoutMillis(1000 * 5); pinpointSocketFactory.setProperties(properties); return pinpointSocketFactory; - } - + } + protected PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { - return createPinpointSocket(host, port, factory, false); + return createPinpointSocket(host, port, factory, false); } - + protected PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory, boolean useMessageListener) { - // 1.2 버전이 Tcp Data Command 허용하는 버전이 아니기 떄문에 true이던 false이던 무조건 SimpleLoggingMessageListener를 이용하게 함 - // SimpleLoggingMessageListener.LISTENER 는 서로 통신을 하지 않게 설정되어 있음 (테스트코드는 pinpoint-rpc에 존재) - // 1.3 버전으로 할 경우 아래 분기에서 MessageListener 변경 필요 - MessageListener messageListener = null; - if (useMessageListener) { - messageListener = SimpleLoggingMessageListener.LISTENER; - } else { - messageListener = SimpleLoggingMessageListener.LISTENER; - } - - PinpointSocket socket = null; - for (int i = 0; i < 3; i++) { + // 1.2 버전이 Tcp Data Command 허용하는 버전이 아니기 떄문에 true이던 false이던 무조건 SimpleLoggingMessageListener를 이용하게 함 + // SimpleLoggingMessageListener.LISTENER 는 서로 통신을 하지 않게 설정되어 있음 (테스트코드는 pinpoint-rpc에 존재) + // 1.3 버전으로 할 경우 아래 분기에서 MessageListener 변경 필요 + MessageListener messageListener = null; + if (useMessageListener) { + messageListener = SimpleLoggingMessageListener.LISTENER; + } else { + messageListener = SimpleLoggingMessageListener.LISTENER; + } + + PinpointSocket socket = null; + for (int i = 0; i < 3; i++) { try { socket = factory.connect(host, port, messageListener); logger.info("tcp connect success:{}/{}", host, port); @@ -311,34 +303,33 @@ protected PinpointSocket createPinpointSocket(String host, int port, PinpointSoc } logger.warn("change background tcp connect mode {}/{} ", host, port); socket = factory.scheduledConnect(host, port, messageListener); - + return socket; } protected EnhancedDataSender createTcpDataSender(PinpointSocket socket) { return new TcpDataSender(socket); } - + protected DataSender createUdpDataSender(int port, String threadName, int writeQueueSize, int timeout, int sendBufferSize) { return new UdpDataSender(this.profilerConfig.getCollectorServerIp(), port, threadName, writeQueueSize, timeout, sendBufferSize); } - - protected EnhancedDataSender getTcpDataSender() { - return tcpDataSender; - } - protected DataSender getStatDataSender() { - return statDataSender; - } + protected EnhancedDataSender getTcpDataSender() { + return tcpDataSender; + } - protected DataSender getSpanDataSender() { - return spanDataSender; - } + protected DataSender getStatDataSender() { + return statDataSender; + } - public void addConnector(String protocol, int port){ - this.serverInfo.addConnector(protocol, port); + protected DataSender getSpanDataSender() { + return spanDataSender; } + public void addConnector(String protocol, int port) { + this.serverInfo.addConnector(protocol, port); + } public ServerInfo getServerInfo() { return this.serverInfo; @@ -352,28 +343,31 @@ public AgentInformation getAgentInformation() { return agentInformation; } - public boolean isRunning() { - return agentStatus == AgentStatus.RUNNING; - } - - // TODO 필요없을것 같음 started를 start로 바꿔도 될 듯... @Override public void start() { + synchronized (this) { + if (this.agentStatus == AgentStatus.INITIALIZING) { + changeStatus(AgentStatus.RUNNING); + } else { + logger.warn("Agent already started."); + return; + } + } logger.info("Starting {} Agent.", ProductInfo.CAMEL_NAME); - } - - /** - * org/apache/catalina/startup/Catalina/await함수가 호출되기 전에 실행된다. - * Tomcat이 구동되고 context가 모두 로드 된 다음 사용자의 요청을 처리할 수 있게 되었을 때 실행됨. - */ - public void started() { - changeStatus(AgentStatus.RUNNING); this.heartBitChecker.start(); this.agentStatMonitor.start(); } @Override public void stop() { + synchronized (this) { + if (this.agentStatus == AgentStatus.RUNNING) { + changeStatus(AgentStatus.STOPPED); + } else { + logger.warn("Cannot stop agent. Current status = [{}]", this.agentStatus); + return; + } + } logger.info("Stopping {} Agent.", ProductInfo.CAMEL_NAME); this.heartBitChecker.stop(); @@ -383,8 +377,6 @@ public void stop() { this.tcpDataSender.send(tAgentInfo); // TODO send tAgentInfo alive false후 send 메시지의 처리가 정확하지 않음 - changeStatus(AgentStatus.STOPPING); - this.agentStatMonitor.stop(); // 종료 처리 필요. @@ -393,13 +385,11 @@ public void stop() { this.tcpDataSender.stop(); if (this.socket != null) { - this.socket.close(); + this.socket.close(); } if (this.factory != null) { - this.factory.release(); + this.factory.release(); } - - changeStatus(AgentStatus.STOPPED); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitChecker.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitChecker.java index 07bbcbe64fff..56079a71e3db 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitChecker.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitChecker.java @@ -1,126 +1,126 @@ -package com.nhn.pinpoint.profiler; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.common.util.PinpointThreadFactory; -import com.nhn.pinpoint.profiler.sender.EnhancedDataSender; -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; -import com.nhn.pinpoint.thrift.dto.TAgentInfo; - - -/** - * @author emeroad - * @author koo.taejin - */ -public class HeartBitChecker { - private static final Logger LOGGER = LoggerFactory.getLogger(HeartBitChecker.class); - - private static final ThreadFactory THREAD_FACTORY = new PinpointThreadFactory("Pinpoint-Agent-Heartbeat-Thread", true); - - private final HeartBitStateContext heartBitState = new HeartBitStateContext(); - - // FIXME 디폴트 타임아웃이 3000임 이게 Constants로 빠져있지 않아서 혹 타임아웃 시간 변경될 경우 수정 필요 - private static final long WAIT_LATCH_WAIT_MILLIS = 3000L + 1000L; - - private long heartBitInterVal; - private EnhancedDataSender dataSender; - private TAgentInfo agentInfo; - - private Thread ioThread; - - public HeartBitChecker(EnhancedDataSender dataSender, long heartBitInterVal, TAgentInfo agentInfo) { - if (dataSender == null) { - throw new NullPointerException("dataSender must not be null"); - } - if (agentInfo == null) { - throw new NullPointerException("agentInfo must not be null"); - } - this.dataSender = dataSender; - this.heartBitInterVal = heartBitInterVal; - this.agentInfo = agentInfo; - } - - public void start() { - if (LOGGER.isInfoEnabled()) { - LOGGER.info("Send startup information to Pinpoint server via {}. agentInfo={}", dataSender.getClass().getSimpleName(), agentInfo); - } - - // start 메소드에서는 둘간의 우선순위 신경쓸 필요없음. - this.heartBitState.changeStateToNeedRequest(System.currentTimeMillis()); - this.dataSender.addReconnectEventListener(new ReconnectEventListener(heartBitState)); - - this.ioThread = THREAD_FACTORY.newThread(heartBitCommand); - this.ioThread.start(); - } - - private Runnable heartBitCommand = new Runnable() { - @Override - public void run() { - - if (LOGGER.isInfoEnabled()) { - LOGGER.info("Starting agent heartbeat. heartbeatInterval:{}", heartBitInterVal); - } - while (true) { - if (heartBitState.needRequest()) { - CountDownLatch latch = new CountDownLatch(1); - // request timeout이 3000기 때문에 latch.await()를 그냥 걸어도됨 - dataSender.request(agentInfo, new HeartBitCheckerListener(heartBitState, latch)); - - try { - boolean awaitSuccess = latch.await(WAIT_LATCH_WAIT_MILLIS, TimeUnit.MILLISECONDS); - if (!awaitSuccess) { - heartBitState.changeStateToNeedRequest(System.currentTimeMillis()); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; - } - } - - // TODO 정밀한 시간계산 없이 일단 그냥 interval 단위로 보냄. - try { - Thread.sleep(heartBitInterVal); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; - } - } - LOGGER.info("HeartBitChecker ioThread stopped."); - } - }; - - - public void stop() { - LOGGER.info("HeartBitChecker stop"); - heartBitState.changeStateToFinish(); - - ioThread.interrupt(); - try { - ioThread.join(1000 * 5); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - private static class ReconnectEventListener implements PinpointSocketReconnectEventListener { - - private final HeartBitStateContext heartBitState; - - public ReconnectEventListener(HeartBitStateContext heartBitState) { - this.heartBitState = heartBitState; - } - - @Override - public void reconnectPerformed(PinpointSocket socket) { - LOGGER.info("Reconnect Performed (Socket = {})", socket); - this.heartBitState.changeStateToNeedRequest(System.currentTimeMillis()); - } - } - -} +package com.nhn.pinpoint.profiler; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.common.util.PinpointThreadFactory; +import com.nhn.pinpoint.profiler.sender.EnhancedDataSender; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; +import com.nhn.pinpoint.thrift.dto.TAgentInfo; + + +/** + * @author emeroad + * @author koo.taejin + */ +public class HeartBitChecker { + private static final Logger LOGGER = LoggerFactory.getLogger(HeartBitChecker.class); + + private static final ThreadFactory THREAD_FACTORY = new PinpointThreadFactory("Pinpoint-Agent-Heartbeat-Thread", true); + + private final HeartBitStateContext heartBitState = new HeartBitStateContext(); + + // FIXME 디폴트 타임아웃이 3000임 이게 Constants로 빠져있지 않아서 혹 타임아웃 시간 변경될 경우 수정 필요 + private static final long WAIT_LATCH_WAIT_MILLIS = 3000L + 1000L; + + private long heartBitInterVal; + private EnhancedDataSender dataSender; + private TAgentInfo agentInfo; + + private Thread ioThread; + + public HeartBitChecker(EnhancedDataSender dataSender, long heartBitInterVal, TAgentInfo agentInfo) { + if (dataSender == null) { + throw new NullPointerException("dataSender must not be null"); + } + if (agentInfo == null) { + throw new NullPointerException("agentInfo must not be null"); + } + this.dataSender = dataSender; + this.heartBitInterVal = heartBitInterVal; + this.agentInfo = agentInfo; + } + + public void start() { + if (LOGGER.isInfoEnabled()) { + LOGGER.info("Send startup information to Pinpoint server via {}. agentInfo={}", dataSender.getClass().getSimpleName(), agentInfo); + } + + // start 메소드에서는 둘간의 우선순위 신경쓸 필요없음. + this.heartBitState.changeStateToNeedRequest(System.currentTimeMillis()); + this.dataSender.addReconnectEventListener(new ReconnectEventListener(heartBitState)); + + this.ioThread = THREAD_FACTORY.newThread(heartBitCommand); + this.ioThread.start(); + } + + private Runnable heartBitCommand = new Runnable() { + @Override + public void run() { + + if (LOGGER.isInfoEnabled()) { + LOGGER.info("Starting agent heartbeat. heartbeatInterval:{}", heartBitInterVal); + } + while (true) { + if (heartBitState.needRequest()) { + CountDownLatch latch = new CountDownLatch(1); + // request timeout이 3000기 때문에 latch.await()를 그냥 걸어도됨 + dataSender.request(agentInfo, new HeartBitCheckerListener(heartBitState, latch)); + + try { + boolean awaitSuccess = latch.await(WAIT_LATCH_WAIT_MILLIS, TimeUnit.MILLISECONDS); + if (!awaitSuccess) { + heartBitState.changeStateToNeedRequest(System.currentTimeMillis()); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } + } + + // TODO 정밀한 시간계산 없이 일단 그냥 interval 단위로 보냄. + try { + Thread.sleep(heartBitInterVal); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } + } + LOGGER.info("HeartBitChecker ioThread stopped."); + } + }; + + + public void stop() { + LOGGER.info("HeartBitChecker stop"); + heartBitState.changeStateToFinish(); + + ioThread.interrupt(); + try { + ioThread.join(1000 * 5); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private static class ReconnectEventListener implements PinpointSocketReconnectEventListener { + + private final HeartBitStateContext heartBitState; + + public ReconnectEventListener(HeartBitStateContext heartBitState) { + this.heartBitState = heartBitState; + } + + @Override + public void reconnectPerformed(PinpointSocket socket) { + LOGGER.info("Reconnect Performed (Socket = {})", socket); + this.heartBitState.changeStateToNeedRequest(System.currentTimeMillis()); + } + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitCheckerListener.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitCheckerListener.java index 9f33cea53654..a7a252d85d7a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitCheckerListener.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitCheckerListener.java @@ -1,76 +1,76 @@ -package com.nhn.pinpoint.profiler; - -import java.util.concurrent.CountDownLatch; - -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.FutureListener; -import com.nhn.pinpoint.rpc.ResponseMessage; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; - -public class HeartBitCheckerListener implements FutureListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final HeartBitStateContext state; - private final CountDownLatch latch; - private final long createTimeMillis; - - public HeartBitCheckerListener(HeartBitStateContext state, CountDownLatch latch) { - this.state = state; - this.latch = latch; - this.createTimeMillis = System.currentTimeMillis(); - } - - // Latch 타이밍 중요함 잘못 걸면 문제한 대기할수 있음 - - @Override - public void onComplete(Future future) { - try { - if (future != null && future.isSuccess()) { - TBase tbase = deserialize(future); - if (tbase instanceof TResult) { - TResult result = (TResult) tbase; - if (result.isSuccess()) { - logger.debug("result success"); - state.changeStateToNeedNotRequest(createTimeMillis); - return; - } else { - logger.warn("request fail. Caused:{}", result.getMessage()); - } - } else { - logger.warn("Invalid Class. {}", tbase); - } - } - } catch(Exception e) { - logger.warn("request fail. caused:{}", e.getMessage()); - } finally { - latch.countDown(); - } - state.changeStateToNeedRequest(System.currentTimeMillis()); - } - - private TBase deserialize(Future future) { - final ResponseMessage responseMessage = future.getResult(); - - // TODO theradlocalcache로 변경해야 되는지 검토 자주 생성이 될수 있는 객체라서 life cycle이 상이함. - HeaderTBaseDeserializer deserializer = HeaderTBaseDeserializerFactory.DEFAULT_FACTORY.createDeserializer(); - byte[] message = responseMessage.getMessage(); - // caching해야 될려나? - try { - return deserializer.deserialize(message); - } catch (TException e) { - if (logger.isWarnEnabled()) { - logger.warn("Deserialize fail. Caused:{}", e.getMessage(), e); - } - return null; - } - } - -} +package com.nhn.pinpoint.profiler; + +import java.util.concurrent.CountDownLatch; + +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.FutureListener; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; + +public class HeartBitCheckerListener implements FutureListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final HeartBitStateContext state; + private final CountDownLatch latch; + private final long createTimeMillis; + + public HeartBitCheckerListener(HeartBitStateContext state, CountDownLatch latch) { + this.state = state; + this.latch = latch; + this.createTimeMillis = System.currentTimeMillis(); + } + + // Latch 타이밍 중요함 잘못 걸면 문제한 대기할수 있음 + + @Override + public void onComplete(Future future) { + try { + if (future != null && future.isSuccess()) { + TBase tbase = deserialize(future); + if (tbase instanceof TResult) { + TResult result = (TResult) tbase; + if (result.isSuccess()) { + logger.debug("result success"); + state.changeStateToNeedNotRequest(createTimeMillis); + return; + } else { + logger.warn("request fail. Caused:{}", result.getMessage()); + } + } else { + logger.warn("Invalid Class. {}", tbase); + } + } + } catch(Exception e) { + logger.warn("request fail. caused:{}", e.getMessage()); + } finally { + latch.countDown(); + } + state.changeStateToNeedRequest(System.currentTimeMillis()); + } + + private TBase deserialize(Future future) { + final ResponseMessage responseMessage = future.getResult(); + + // TODO theradlocalcache로 변경해야 되는지 검토 자주 생성이 될수 있는 객체라서 life cycle이 상이함. + HeaderTBaseDeserializer deserializer = HeaderTBaseDeserializerFactory.DEFAULT_FACTORY.createDeserializer(); + byte[] message = responseMessage.getMessage(); + // caching해야 될려나? + try { + return deserializer.deserialize(message); + } catch (TException e) { + if (logger.isWarnEnabled()) { + logger.warn("Deserialize fail. Caused:{}", e.getMessage(), e); + } + return null; + } + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitState.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitState.java index 35af12bd78e7..6d1aba5888c2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitState.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitState.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.profiler; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public enum HeartBitState { - - // 상태를 잘게 나누는게 의미가 없음 (reconnect등 필요없음) - // NONE, NEED_REQUEST, NEED_NOT_REQUEST로 나눔 - // 성능이나 메모리적으로 문제가 되면 Constant나 static으로 빼는게 좋을듯 - NONE { - - @Override - public List getChangeAvailableStateList() { - List avaiableStateList = new ArrayList(); - avaiableStateList.add(NEED_REQUEST); - avaiableStateList.add(NEED_NOT_REQUEST); - return avaiableStateList; - } - - }, - - NEED_REQUEST { - - @Override - public List getChangeAvailableStateList() { - List avaiableStateList = new ArrayList(); - avaiableStateList.add(NEED_REQUEST); - avaiableStateList.add(NEED_NOT_REQUEST); - avaiableStateList.add(FINISH); - return avaiableStateList; - } - - }, - - NEED_NOT_REQUEST { - - @Override - public List getChangeAvailableStateList() { - List avaiableStateList = new ArrayList(); - avaiableStateList.add(NEED_REQUEST); - avaiableStateList.add(NEED_NOT_REQUEST); - avaiableStateList.add(FINISH); - return avaiableStateList; - } - - }, - - FINISH { - - @Override - public List getChangeAvailableStateList() { - return Collections.EMPTY_LIST; - } - - }; - - public abstract List getChangeAvailableStateList(); -} +package com.nhn.pinpoint.profiler; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public enum HeartBitState { + + // 상태를 잘게 나누는게 의미가 없음 (reconnect등 필요없음) + // NONE, NEED_REQUEST, NEED_NOT_REQUEST로 나눔 + // 성능이나 메모리적으로 문제가 되면 Constant나 static으로 빼는게 좋을듯 + NONE { + + @Override + public List getChangeAvailableStateList() { + List avaiableStateList = new ArrayList(); + avaiableStateList.add(NEED_REQUEST); + avaiableStateList.add(NEED_NOT_REQUEST); + return avaiableStateList; + } + + }, + + NEED_REQUEST { + + @Override + public List getChangeAvailableStateList() { + List avaiableStateList = new ArrayList(); + avaiableStateList.add(NEED_REQUEST); + avaiableStateList.add(NEED_NOT_REQUEST); + avaiableStateList.add(FINISH); + return avaiableStateList; + } + + }, + + NEED_NOT_REQUEST { + + @Override + public List getChangeAvailableStateList() { + List avaiableStateList = new ArrayList(); + avaiableStateList.add(NEED_REQUEST); + avaiableStateList.add(NEED_NOT_REQUEST); + avaiableStateList.add(FINISH); + return avaiableStateList; + } + + }, + + FINISH { + + @Override + public List getChangeAvailableStateList() { + return Collections.EMPTY_LIST; + } + + }; + + public abstract List getChangeAvailableStateList(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitStateContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitStateContext.java index ec2cb01d8752..c8523f784ef0 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitStateContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/HeartBitStateContext.java @@ -1,104 +1,104 @@ -package com.nhn.pinpoint.profiler; - -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author koo.taejin - */ -public class HeartBitStateContext { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - // 클래스로 감싸 두지 않음 - private HeartBitState state = HeartBitState.NONE; - private long prevEventTimeMillis; - - public HeartBitStateContext() { - this.prevEventTimeMillis = System.currentTimeMillis(); - } - - boolean needRequest() { - synchronized (this) { - if (state == HeartBitState.NEED_REQUEST || state == HeartBitState.NONE) { - return true; - } else { - return false; - } - } - } - - // 메시지 성공시를 제외하고는 이걸로 변경하면 안됨 - boolean changeStateToNeedRequest(long eventTimeMillis) { - logger.info("{} will change to NEED_REQUEST state.", this.getClass().getSimpleName()); - - if (prevEventTimeMillis <= eventTimeMillis) { - synchronized (this) { - boolean isChange = changeState(this.state, HeartBitState.NEED_REQUEST); - if (isChange) { - prevEventTimeMillis = eventTimeMillis; - } - logger.info("{} change to NEED_REQUEST state ({}) .",this.getClass().getSimpleName(), isChange); - return isChange; - } - } - return false; - } - - boolean changeStateToNeedNotRequest(long eventTimeMillis) { - logger.info("{} will change to NEED_NOT_REQUEST state.", this.getClass().getSimpleName()); - - if (prevEventTimeMillis < eventTimeMillis) { - synchronized (this) { - boolean isChange = changeState(this.state, HeartBitState.NEED_NOT_REQUEST); - if (isChange) { - prevEventTimeMillis = eventTimeMillis; - } - logger.info("{} change to NEED_NOT_REQUEST state ({}) .", this.getClass().getSimpleName(), isChange); - return isChange; - } - } - return false; - } - - boolean changeStateToFinish() { - logger.info("{} will change to FINISH state.", this.getClass().getSimpleName()); - - synchronized (this) { - boolean isChange = changeState(this.state, HeartBitState.FINISH); - logger.info("{} change to FINISH state ({}) .",this.getClass().getSimpleName(), isChange); - return isChange; - } - } - - private boolean changeState(HeartBitState current, HeartBitState next) { - synchronized (this) { - List changeAvaialableStateList = current.getChangeAvailableStateList(); - - if (changeAvaialableStateList.contains(next)) { - return compareAndSet(current, next); - } else { - return false; - } - } - } - - private boolean compareAndSet(HeartBitState current, HeartBitState next) { - synchronized (this) { - if (this.state == current) { - this.state = next; - return true; - } else { - return false; - } - } - } - - public HeartBitState getState() { - return state; - } - -} +package com.nhn.pinpoint.profiler; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author koo.taejin + */ +public class HeartBitStateContext { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + // 클래스로 감싸 두지 않음 + private HeartBitState state = HeartBitState.NONE; + private long prevEventTimeMillis; + + public HeartBitStateContext() { + this.prevEventTimeMillis = System.currentTimeMillis(); + } + + boolean needRequest() { + synchronized (this) { + if (state == HeartBitState.NEED_REQUEST || state == HeartBitState.NONE) { + return true; + } else { + return false; + } + } + } + + // 메시지 성공시를 제외하고는 이걸로 변경하면 안됨 + boolean changeStateToNeedRequest(long eventTimeMillis) { + logger.info("{} will change to NEED_REQUEST state.", this.getClass().getSimpleName()); + + if (prevEventTimeMillis <= eventTimeMillis) { + synchronized (this) { + boolean isChange = changeState(this.state, HeartBitState.NEED_REQUEST); + if (isChange) { + prevEventTimeMillis = eventTimeMillis; + } + logger.info("{} change to NEED_REQUEST state ({}) .",this.getClass().getSimpleName(), isChange); + return isChange; + } + } + return false; + } + + boolean changeStateToNeedNotRequest(long eventTimeMillis) { + logger.info("{} will change to NEED_NOT_REQUEST state.", this.getClass().getSimpleName()); + + if (prevEventTimeMillis < eventTimeMillis) { + synchronized (this) { + boolean isChange = changeState(this.state, HeartBitState.NEED_NOT_REQUEST); + if (isChange) { + prevEventTimeMillis = eventTimeMillis; + } + logger.info("{} change to NEED_NOT_REQUEST state ({}) .", this.getClass().getSimpleName(), isChange); + return isChange; + } + } + return false; + } + + boolean changeStateToFinish() { + logger.info("{} will change to FINISH state.", this.getClass().getSimpleName()); + + synchronized (this) { + boolean isChange = changeState(this.state, HeartBitState.FINISH); + logger.info("{} change to FINISH state ({}) .",this.getClass().getSimpleName(), isChange); + return isChange; + } + } + + private boolean changeState(HeartBitState current, HeartBitState next) { + synchronized (this) { + List changeAvaialableStateList = current.getChangeAvailableStateList(); + + if (changeAvaialableStateList.contains(next)) { + return compareAndSet(current, next); + } else { + return false; + } + } + } + + private boolean compareAndSet(HeartBitState current, HeartBitState next) { + synchronized (this) { + if (this.state == current) { + this.state = next; + return true; + } else { + return false; + } + } + } + + public HeartBitState getState() { + return state; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/LifeCycleEventListener.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/LifeCycleEventListener.java index 633005632bdb..623204607734 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/LifeCycleEventListener.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/LifeCycleEventListener.java @@ -1,47 +1,34 @@ -package com.nhn.pinpoint.profiler; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - - -/** - * @author emeroad - */ -public class LifeCycleEventListener { - - private final static PLogger logger = PLoggerFactory.getLogger(LifeCycleEventListener.class.getName()); - - private Agent agent; - private boolean started = false; - - public LifeCycleEventListener(Agent agent) { - if (agent == null) { - throw new IllegalArgumentException("agent must not be null"); - } - this.agent = agent; - } - - public synchronized void start() { - logger.info("LifeCycleEventListener start"); - - if (started) { - logger.info("already started"); - return; - } - - agent.start(); - started = true; - } - - public synchronized void stop() { - logger.info("LifeCycleEventListener stop"); - - if (!started) { - logger.info("already stopped"); - return; - } - started = false; - agent.stop(); - } -} +package com.nhn.pinpoint.profiler; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; + + +/** + * @author emeroad + * @author hyungil.jeong + */ +public class LifeCycleEventListener { + + private final static PLogger logger = PLoggerFactory.getLogger(LifeCycleEventListener.class.getName()); + + private final Agent agent; + + public LifeCycleEventListener(Agent agent) { + if (agent == null) { + throw new IllegalArgumentException("agent must not be null"); + } + this.agent = agent; + } + + public void start() { + logger.info("LifeCycleEventListener start"); + agent.start(); + } + + public void stop() { + logger.info("LifeCycleEventListener stop"); + agent.stop(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ActiveThreadCounter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ActiveThreadCounter.java index 88b0b420aa13..eac2acce5030 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ActiveThreadCounter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ActiveThreadCounter.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.profiler.context; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class ActiveThreadCounter { - private AtomicInteger counter = new AtomicInteger(0); - - public void start() { - counter.incrementAndGet(); - } - - public void end() { - counter.decrementAndGet(); - } - - public int getActiveThread() { - return counter.get(); - } - - public void reset() { - counter.set(0); - } -} +package com.nhn.pinpoint.profiler.context; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class ActiveThreadCounter { + private AtomicInteger counter = new AtomicInteger(0); + + public void start() { + counter.incrementAndGet(); + } + + public void end() { + counter.decrementAndGet(); + } + + public int getActiveThread() { + return counter.get(); + } + + public void reset() { + counter.set(0); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTrace.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTrace.java index a31668c7a429..ffbcacb8656e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTrace.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultAsyncTrace.java @@ -1,205 +1,205 @@ -package com.nhn.pinpoint.profiler.context; - -import java.util.TimerTask; -import java.util.concurrent.atomic.AtomicInteger; - -import com.nhn.pinpoint.bootstrap.context.AsyncTrace; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.util.StringUtils; -import com.nhn.pinpoint.profiler.context.storage.Storage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -@Deprecated -public class DefaultAsyncTrace implements AsyncTrace { - private static final Logger logger = LoggerFactory.getLogger(DefaultAsyncTrace.class); - private static final boolean isDebug = logger.isDebugEnabled(); - private static final boolean isTrace = logger.isTraceEnabled(); - - - public static final int NON_REGIST = -1; - // private int id; - // 비동기일 경우 traceenable의 경우 애매함. span을 보내는것으로 데이터를 생성하므로 약간 이상. - // private boolean tracingEnabled; - - - - private final AtomicInteger state = new AtomicInteger(STATE_INIT); - - private int asyncId = NON_REGIST; - private SpanEvent spanEvent; - - private Storage storage; - private TimerTask timeoutTask; - - public DefaultAsyncTrace(SpanEvent spanEvent) { - this.spanEvent = spanEvent; - } - - public void setStorage(Storage storage) { - this.storage = storage; - } - - @Override - public void setTimeoutTask(TimerTask timeoutTask) { - this.timeoutTask = timeoutTask; - } - - @Override - public void setAsyncId(int asyncId) { - this.asyncId = asyncId; - } - - @Override - public int getAsyncId() { - return asyncId; - } - - - private Object attachObject; - - @Override - public Object getAttachObject() { - return attachObject; - } - - @Override - public void setAttachObject(Object attachObject) { - this.attachObject = attachObject; - } - - @Override - public void traceBlockBegin() { - } - - @Override - public void markBeforeTime() { - spanEvent.markStartTime(); - } - - @Override - public long getBeforeTime() { - return spanEvent.getStartTime(); - } - - @Override - public void traceBlockEnd() { - logSpan(this.spanEvent); - } - - @Override - public void markAfterTime() { - spanEvent.markAfterTime(); - } - - - @Override - public void recordApi(MethodDescriptor methodDescriptor) { - if (methodDescriptor == null) { - return; - } - if (methodDescriptor.getApiId() == 0) { - recordAttribute(AnnotationKey.API, methodDescriptor.getFullName()); - } else { - spanEvent.setApiId(methodDescriptor.getApiId()); - } - } - - - - @Override - public void recordException(Object result) { - if (result instanceof Throwable) { - Throwable th = (Throwable) result; - String drop = StringUtils.drop(th.getMessage()); - - recordAttribute(AnnotationKey.EXCEPTION, drop); - -// TODO 비동기 api일 경우, span에 exception을 마크하기가 까다로움 -// AnnotationKey span = getCallStack().getSpan(); -// if (span.getErrCode() == 0) { -// span.setErrCode(1); -// } - } - } - - @Override - public void recordAttribute(final AnnotationKey key, final String value) { - spanEvent.addAnnotation(new Annotation(key.getCode(), value)); - } - - @Override - public void recordAttribute(final AnnotationKey key, final int value) { - spanEvent.addAnnotation(new Annotation(key.getCode(), value)); - } - - - @Override - public void recordAttribute(final AnnotationKey key, final Object value) { - spanEvent.addAnnotation(new Annotation(key.getCode(), value)); - } - - @Override - public void recordServiceType(final ServiceType serviceType) { - this.spanEvent.setServiceType(serviceType.getCode()); - } - - @Override - public void recordRpcName(final String rpcName) { - this.spanEvent.setRpc(rpcName); - - } - - - @Override - public void recordDestinationId(String destinationId) { - this.spanEvent.setDestinationId(destinationId); - } - - // TODO: final String... endPoint로 받으면 합치는데 비용이 들어가 그냥 한번에 받는게 나을것 같음. - @Override - public void recordEndPoint(final String endPoint) { - this.spanEvent.setEndPoint(endPoint); - } - - private void logSpan(SpanEvent spanEvent) { - try { - if (isTrace) { - Thread thread = Thread.currentThread(); - logger.trace("[WRITE SpanEvent]{} CurrentThreadID={} CurrentThreadName={}", spanEvent, thread.getId(), thread.getName()); - } - this.storage.store(spanEvent); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - } - - public int getState() { - return state.get(); - } - - public void timeout() { - if (state.compareAndSet(STATE_INIT, STATE_TIMEOUT)) { - // TODO timeout spanEvent log 던지기. - // 뭘 어떤 내용을 던져야 되는지 아직 모르겠음???? - } - } - - public boolean fire() { - if (state.compareAndSet(STATE_INIT, STATE_FIRE)) { - if (timeoutTask != null) { - // timeout이 걸려 있는 asynctrace일 경우 호출해 준다. - this.timeoutTask.cancel(); - } - return true; - } - return false; - } - - -} +package com.nhn.pinpoint.profiler.context; + +import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicInteger; + +import com.nhn.pinpoint.bootstrap.context.AsyncTrace; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.util.StringUtils; +import com.nhn.pinpoint.profiler.context.storage.Storage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +@Deprecated +public class DefaultAsyncTrace implements AsyncTrace { + private static final Logger logger = LoggerFactory.getLogger(DefaultAsyncTrace.class); + private static final boolean isDebug = logger.isDebugEnabled(); + private static final boolean isTrace = logger.isTraceEnabled(); + + + public static final int NON_REGIST = -1; + // private int id; + // 비동기일 경우 traceenable의 경우 애매함. span을 보내는것으로 데이터를 생성하므로 약간 이상. + // private boolean tracingEnabled; + + + + private final AtomicInteger state = new AtomicInteger(STATE_INIT); + + private int asyncId = NON_REGIST; + private SpanEvent spanEvent; + + private Storage storage; + private TimerTask timeoutTask; + + public DefaultAsyncTrace(SpanEvent spanEvent) { + this.spanEvent = spanEvent; + } + + public void setStorage(Storage storage) { + this.storage = storage; + } + + @Override + public void setTimeoutTask(TimerTask timeoutTask) { + this.timeoutTask = timeoutTask; + } + + @Override + public void setAsyncId(int asyncId) { + this.asyncId = asyncId; + } + + @Override + public int getAsyncId() { + return asyncId; + } + + + private Object attachObject; + + @Override + public Object getAttachObject() { + return attachObject; + } + + @Override + public void setAttachObject(Object attachObject) { + this.attachObject = attachObject; + } + + @Override + public void traceBlockBegin() { + } + + @Override + public void markBeforeTime() { + spanEvent.markStartTime(); + } + + @Override + public long getBeforeTime() { + return spanEvent.getStartTime(); + } + + @Override + public void traceBlockEnd() { + logSpan(this.spanEvent); + } + + @Override + public void markAfterTime() { + spanEvent.markAfterTime(); + } + + + @Override + public void recordApi(MethodDescriptor methodDescriptor) { + if (methodDescriptor == null) { + return; + } + if (methodDescriptor.getApiId() == 0) { + recordAttribute(AnnotationKey.API, methodDescriptor.getFullName()); + } else { + spanEvent.setApiId(methodDescriptor.getApiId()); + } + } + + + + @Override + public void recordException(Object result) { + if (result instanceof Throwable) { + Throwable th = (Throwable) result; + String drop = StringUtils.drop(th.getMessage()); + + recordAttribute(AnnotationKey.EXCEPTION, drop); + +// TODO 비동기 api일 경우, span에 exception을 마크하기가 까다로움 +// AnnotationKey span = getCallStack().getSpan(); +// if (span.getErrCode() == 0) { +// span.setErrCode(1); +// } + } + } + + @Override + public void recordAttribute(final AnnotationKey key, final String value) { + spanEvent.addAnnotation(new Annotation(key.getCode(), value)); + } + + @Override + public void recordAttribute(final AnnotationKey key, final int value) { + spanEvent.addAnnotation(new Annotation(key.getCode(), value)); + } + + + @Override + public void recordAttribute(final AnnotationKey key, final Object value) { + spanEvent.addAnnotation(new Annotation(key.getCode(), value)); + } + + @Override + public void recordServiceType(final ServiceType serviceType) { + this.spanEvent.setServiceType(serviceType.getCode()); + } + + @Override + public void recordRpcName(final String rpcName) { + this.spanEvent.setRpc(rpcName); + + } + + + @Override + public void recordDestinationId(String destinationId) { + this.spanEvent.setDestinationId(destinationId); + } + + // TODO: final String... endPoint로 받으면 합치는데 비용이 들어가 그냥 한번에 받는게 나을것 같음. + @Override + public void recordEndPoint(final String endPoint) { + this.spanEvent.setEndPoint(endPoint); + } + + private void logSpan(SpanEvent spanEvent) { + try { + if (isTrace) { + Thread thread = Thread.currentThread(); + logger.trace("[WRITE SpanEvent]{} CurrentThreadID={} CurrentThreadName={}", spanEvent, thread.getId(), thread.getName()); + } + this.storage.store(spanEvent); + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } + } + + public int getState() { + return state.get(); + } + + public void timeout() { + if (state.compareAndSet(STATE_INIT, STATE_TIMEOUT)) { + // TODO timeout spanEvent log 던지기. + // 뭘 어떤 내용을 던져야 되는지 아직 모르겠음???? + } + } + + public boolean fire() { + if (state.compareAndSet(STATE_INIT, STATE_FIRE)) { + if (timeoutTask != null) { + // timeout이 걸려 있는 asynctrace일 경우 호출해 준다. + this.timeoutTask.cancel(); + } + return true; + } + return false; + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java index da344875dfd0..e449ff3a2650 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java @@ -1,308 +1,308 @@ -package com.nhn.pinpoint.profiler.context; - - -import com.nhn.pinpoint.bootstrap.context.*; -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.util.DefaultParsingResult; -import com.nhn.pinpoint.profiler.AgentInformation; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.profiler.context.storage.LogStorageFactory; -import com.nhn.pinpoint.profiler.context.storage.StorageFactory; -import com.nhn.pinpoint.profiler.metadata.SimpleCache; -import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; -import com.nhn.pinpoint.profiler.monitor.metric.ContextMetric; -import com.nhn.pinpoint.profiler.monitor.metric.MetricRegistry; -import com.nhn.pinpoint.profiler.sampler.TrueSampler; -import com.nhn.pinpoint.profiler.sender.EnhancedDataSender; -import com.nhn.pinpoint.thrift.dto.TApiMetaData; -import com.nhn.pinpoint.thrift.dto.TSqlMetaData; -import com.nhn.pinpoint.common.util.ParsingResult; -import com.nhn.pinpoint.common.util.SqlParser; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.profiler.metadata.LRUCache; -import com.nhn.pinpoint.profiler.metadata.Result; -import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; -import com.nhn.pinpoint.bootstrap.sampler.Sampler; -import com.nhn.pinpoint.thrift.dto.TStringMetaData; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public class DefaultTraceContext implements TraceContext { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private final TraceFactory traceFactory; - - private final ActiveThreadCounter activeThreadCounter = new ActiveThreadCounter(); - - -// private GlobalCallTrace globalCallTrace = new GlobalCallTrace(); - - private AgentInformation agentInformation; - - private EnhancedDataSender priorityDataSender; - - private final ServiceType contextServiceType; - - private final MetricRegistry metricRegistry; - - private final SimpleCache sqlCache; - private final SqlParser sqlParser = new SqlParser(); - - private final SimpleCache apiCache = new SimpleCache(); - private final SimpleCache stringCache = new SimpleCache(); - - private final JDBCUrlParser jdbcUrlParser = new JDBCUrlParser(); - - private ProfilerConfig profilerConfig; - - // for test - public DefaultTraceContext() { - this(LRUCache.DEFAULT_CACHE_SIZE, ServiceType.STAND_ALONE.getCode(), new LogStorageFactory(), new TrueSampler()); - } - - public DefaultTraceContext(final int sqlCacheSize, final short contextServiceType, StorageFactory storageFactory, Sampler sampler) { - if (storageFactory == null) { - throw new NullPointerException("storageFactory must not be null"); - } - if (sampler == null) { - throw new NullPointerException("sampler must not be null"); - } - this.sqlCache = new SimpleCache(sqlCacheSize); - this.contextServiceType = ServiceType.findServiceType(contextServiceType); - this.metricRegistry = new MetricRegistry(this.contextServiceType); - - this.traceFactory = new ThreadLocalTraceFactory(this, metricRegistry, storageFactory, sampler); - } - - /** - * sampling 여부까지 체크하여 유효성을 검증한 후 Trace를 리턴한다. - * @return - */ - public Trace currentTraceObject() { - return traceFactory.currentTraceObject(); - } - - public Trace currentRpcTraceObject() { - return traceFactory.currentTraceObject(); - } - - /** - * 유효성을 검증하지 않고 Trace를 리턴한다. - * @return - */ - @Override - public Trace currentRawTraceObject() { - return traceFactory.currentRawTraceObject(); - } - - @Override - public Trace disableSampling() { - return null; -// TODO STATDISABLE 통계 코드 일단 제거 -// return traceFactory.disableSampling(); - } - - public void setProfilerConfig(final ProfilerConfig profilerConfig) { - this.profilerConfig = profilerConfig; - } - - @Override - public ProfilerConfig getProfilerConfig() { - return profilerConfig; - } - - // remote 에서 샘플링 대상으로 선정된 경우. - public Trace continueTraceObject(final TraceId traceID) { - return traceFactory.continueTraceObject(traceID); - } - - public Trace newTraceObject() { - return traceFactory.newTraceObject(); - } - - - @Override - public void detachTraceObject() { - this.traceFactory.detachTraceObject(); - } - - - //@Override - public ActiveThreadCounter getActiveThreadCounter() { - return activeThreadCounter; - } - - public AgentInformation getAgentInformation() { - return agentInformation; - } - - @Override - public String getAgentId() { - return this.agentInformation.getAgentId(); - } - - @Override - public String getApplicationName() { - return this.agentInformation.getApplicationName(); - } - - @Override - public long getAgentStartTime() { - return this.agentInformation.getStartTime(); - } - - @Override - public short getServerTypeCode() { - return this.agentInformation.getServerType(); - } - - @Override - public String getServerType() { - return ServiceType.findServiceType(this.agentInformation.getServerType()).getDesc(); - } - - - @Override - public int cacheApi(final MethodDescriptor methodDescriptor) { - final String fullName = methodDescriptor.getFullName(); - final Result result = this.apiCache.put(fullName); - if (result.isNewValue()) { - methodDescriptor.setApiId(result.getId()); - - final TApiMetaData apiMetadata = new TApiMetaData(); - apiMetadata.setAgentId(getAgentId()); - apiMetadata.setAgentStartTime(getAgentStartTime()); - - apiMetadata.setApiId(result.getId()); - apiMetadata.setApiInfo(methodDescriptor.getApiDescriptor()); - apiMetadata.setLine(methodDescriptor.getLineNumber()); - - this.priorityDataSender.request(apiMetadata); - } - return result.getId(); - } - - @Override - public int cacheString(final String value) { - if (value == null) { - return 0; - } - final Result result = this.stringCache.put(value); - if (result.isNewValue()) { - final TStringMetaData stringMetaData = new TStringMetaData(); - stringMetaData.setAgentId(getAgentId()); - stringMetaData.setAgentStartTime(getAgentStartTime()); - - stringMetaData.setStringId(result.getId()); - stringMetaData.setStringValue(value); - this.priorityDataSender.request(stringMetaData); - } - return result.getId(); - } - - @Override - public TraceId createTraceId(final String transactionId, final long parentSpanID, final long spanID, final short flags) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - // TODO parse error 때 예외 처리 필요. - return DefaultTraceId.parse(transactionId, parentSpanID, spanID, flags); - } - - - @Override - public ParsingResult parseSql(final String sql) { - - final DefaultParsingResult parsingResult = this.sqlParser.normalizedSql(sql); - final String normalizedSql = parsingResult.getSql(); - // 파싱시 변경되지 않았다면 동일 객체를 리턴하므로 그냥 ==비교를 하면 됨 - - final Result cachingResult = this.sqlCache.put(normalizedSql); - if (cachingResult.isNewValue()) { - if (isDebug) { - // TODO hit% 로그를 남겨야 문제 발생시 도움이 될듯 하다. - logger.debug("NewSQLParsingResult:{}", parsingResult); - } - // newValue란 의미는 cache에 인입됬다는 의미이고 이는 신규 sql문일 가능성이 있다는 의미임. - // 그러므로 메타데이터를 서버로 전송해야 한다. - - - final TSqlMetaData sqlMetaData = new TSqlMetaData(); - sqlMetaData.setAgentId(getAgentId()); - sqlMetaData.setAgentStartTime(getAgentStartTime()); - - sqlMetaData.setSqlId(cachingResult.getId()); - sqlMetaData.setSql(normalizedSql); - - // 좀더 신뢰성이 있는 tcp connection이 필요함. - this.priorityDataSender.request(sqlMetaData); - } - parsingResult.setId(cachingResult.getId()); - return parsingResult; - } - - @Override - public DatabaseInfo parseJdbcUrl(final String url) { - return this.jdbcUrlParser.parse(url); - } - - @Override - public DatabaseInfo createDatabaseInfo(ServiceType type, ServiceType executeQueryType, String url, int port, String databaseId) { - List host = new ArrayList(); - host.add(url + ":" + port); - DatabaseInfo databaseInfo = new DefaultDatabaseInfo(type, executeQueryType, url, url, host, databaseId); - return databaseInfo; - } - - - - public void setPriorityDataSender(final EnhancedDataSender priorityDataSender) { - this.priorityDataSender = priorityDataSender; - } - - - public void setAgentInformation(final AgentInformation agentInformation) { - if (agentInformation == null) { - throw new NullPointerException("agentInformation must not be null"); - } - this.agentInformation = agentInformation; - } - - @Override - public Metric getRpcMetric(ServiceType serviceType) { - if (serviceType == null) { - throw new NullPointerException("serviceType must not be null"); - } - - return this.metricRegistry.getRpcMetric(serviceType); - } - - - public void recordContextMetricIsError() { - recordContextMetric(HistogramSchema.ERROR_SLOT_TIME); - } - - public void recordContextMetric(int elapsedTime) { - final ContextMetric contextMetric = this.metricRegistry.getResponseMetric(); - contextMetric.addResponseTime(elapsedTime); - } - - public void recordAcceptResponseTime(String parentApplicationName, short parentApplicationType, int elapsedTime) { - final ContextMetric contextMetric = this.metricRegistry.getResponseMetric(); - contextMetric.addAcceptHistogram(parentApplicationName, parentApplicationType, elapsedTime); - } - - public void recordUserAcceptResponseTime(int elapsedTime) { - final ContextMetric contextMetric = this.metricRegistry.getResponseMetric(); - contextMetric.addUserAcceptHistogram(elapsedTime); - } -} +package com.nhn.pinpoint.profiler.context; + + +import com.nhn.pinpoint.bootstrap.context.*; +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.util.DefaultParsingResult; +import com.nhn.pinpoint.profiler.AgentInformation; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.profiler.context.storage.LogStorageFactory; +import com.nhn.pinpoint.profiler.context.storage.StorageFactory; +import com.nhn.pinpoint.profiler.metadata.SimpleCache; +import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; +import com.nhn.pinpoint.profiler.monitor.metric.ContextMetric; +import com.nhn.pinpoint.profiler.monitor.metric.MetricRegistry; +import com.nhn.pinpoint.profiler.sampler.TrueSampler; +import com.nhn.pinpoint.profiler.sender.EnhancedDataSender; +import com.nhn.pinpoint.thrift.dto.TApiMetaData; +import com.nhn.pinpoint.thrift.dto.TSqlMetaData; +import com.nhn.pinpoint.common.util.ParsingResult; +import com.nhn.pinpoint.common.util.SqlParser; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.profiler.metadata.LRUCache; +import com.nhn.pinpoint.profiler.metadata.Result; +import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; +import com.nhn.pinpoint.bootstrap.sampler.Sampler; +import com.nhn.pinpoint.thrift.dto.TStringMetaData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class DefaultTraceContext implements TraceContext { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private final TraceFactory traceFactory; + + private final ActiveThreadCounter activeThreadCounter = new ActiveThreadCounter(); + + +// private GlobalCallTrace globalCallTrace = new GlobalCallTrace(); + + private AgentInformation agentInformation; + + private EnhancedDataSender priorityDataSender; + + private final ServiceType contextServiceType; + + private final MetricRegistry metricRegistry; + + private final SimpleCache sqlCache; + private final SqlParser sqlParser = new SqlParser(); + + private final SimpleCache apiCache = new SimpleCache(); + private final SimpleCache stringCache = new SimpleCache(); + + private final JDBCUrlParser jdbcUrlParser = new JDBCUrlParser(); + + private ProfilerConfig profilerConfig; + + // for test + public DefaultTraceContext() { + this(LRUCache.DEFAULT_CACHE_SIZE, ServiceType.STAND_ALONE.getCode(), new LogStorageFactory(), new TrueSampler()); + } + + public DefaultTraceContext(final int sqlCacheSize, final short contextServiceType, StorageFactory storageFactory, Sampler sampler) { + if (storageFactory == null) { + throw new NullPointerException("storageFactory must not be null"); + } + if (sampler == null) { + throw new NullPointerException("sampler must not be null"); + } + this.sqlCache = new SimpleCache(sqlCacheSize); + this.contextServiceType = ServiceType.findServiceType(contextServiceType); + this.metricRegistry = new MetricRegistry(this.contextServiceType); + + this.traceFactory = new ThreadLocalTraceFactory(this, metricRegistry, storageFactory, sampler); + } + + /** + * sampling 여부까지 체크하여 유효성을 검증한 후 Trace를 리턴한다. + * @return + */ + public Trace currentTraceObject() { + return traceFactory.currentTraceObject(); + } + + public Trace currentRpcTraceObject() { + return traceFactory.currentTraceObject(); + } + + /** + * 유효성을 검증하지 않고 Trace를 리턴한다. + * @return + */ + @Override + public Trace currentRawTraceObject() { + return traceFactory.currentRawTraceObject(); + } + + @Override + public Trace disableSampling() { + return null; +// TODO STATDISABLE 통계 코드 일단 제거 +// return traceFactory.disableSampling(); + } + + public void setProfilerConfig(final ProfilerConfig profilerConfig) { + this.profilerConfig = profilerConfig; + } + + @Override + public ProfilerConfig getProfilerConfig() { + return profilerConfig; + } + + // remote 에서 샘플링 대상으로 선정된 경우. + public Trace continueTraceObject(final TraceId traceID) { + return traceFactory.continueTraceObject(traceID); + } + + public Trace newTraceObject() { + return traceFactory.newTraceObject(); + } + + + @Override + public void detachTraceObject() { + this.traceFactory.detachTraceObject(); + } + + + //@Override + public ActiveThreadCounter getActiveThreadCounter() { + return activeThreadCounter; + } + + public AgentInformation getAgentInformation() { + return agentInformation; + } + + @Override + public String getAgentId() { + return this.agentInformation.getAgentId(); + } + + @Override + public String getApplicationName() { + return this.agentInformation.getApplicationName(); + } + + @Override + public long getAgentStartTime() { + return this.agentInformation.getStartTime(); + } + + @Override + public short getServerTypeCode() { + return this.agentInformation.getServerType(); + } + + @Override + public String getServerType() { + return ServiceType.findServiceType(this.agentInformation.getServerType()).getDesc(); + } + + + @Override + public int cacheApi(final MethodDescriptor methodDescriptor) { + final String fullName = methodDescriptor.getFullName(); + final Result result = this.apiCache.put(fullName); + if (result.isNewValue()) { + methodDescriptor.setApiId(result.getId()); + + final TApiMetaData apiMetadata = new TApiMetaData(); + apiMetadata.setAgentId(getAgentId()); + apiMetadata.setAgentStartTime(getAgentStartTime()); + + apiMetadata.setApiId(result.getId()); + apiMetadata.setApiInfo(methodDescriptor.getApiDescriptor()); + apiMetadata.setLine(methodDescriptor.getLineNumber()); + + this.priorityDataSender.request(apiMetadata); + } + return result.getId(); + } + + @Override + public int cacheString(final String value) { + if (value == null) { + return 0; + } + final Result result = this.stringCache.put(value); + if (result.isNewValue()) { + final TStringMetaData stringMetaData = new TStringMetaData(); + stringMetaData.setAgentId(getAgentId()); + stringMetaData.setAgentStartTime(getAgentStartTime()); + + stringMetaData.setStringId(result.getId()); + stringMetaData.setStringValue(value); + this.priorityDataSender.request(stringMetaData); + } + return result.getId(); + } + + @Override + public TraceId createTraceId(final String transactionId, final long parentSpanID, final long spanID, final short flags) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + // TODO parse error 때 예외 처리 필요. + return DefaultTraceId.parse(transactionId, parentSpanID, spanID, flags); + } + + + @Override + public ParsingResult parseSql(final String sql) { + + final DefaultParsingResult parsingResult = this.sqlParser.normalizedSql(sql); + final String normalizedSql = parsingResult.getSql(); + // 파싱시 변경되지 않았다면 동일 객체를 리턴하므로 그냥 ==비교를 하면 됨 + + final Result cachingResult = this.sqlCache.put(normalizedSql); + if (cachingResult.isNewValue()) { + if (isDebug) { + // TODO hit% 로그를 남겨야 문제 발생시 도움이 될듯 하다. + logger.debug("NewSQLParsingResult:{}", parsingResult); + } + // newValue란 의미는 cache에 인입됬다는 의미이고 이는 신규 sql문일 가능성이 있다는 의미임. + // 그러므로 메타데이터를 서버로 전송해야 한다. + + + final TSqlMetaData sqlMetaData = new TSqlMetaData(); + sqlMetaData.setAgentId(getAgentId()); + sqlMetaData.setAgentStartTime(getAgentStartTime()); + + sqlMetaData.setSqlId(cachingResult.getId()); + sqlMetaData.setSql(normalizedSql); + + // 좀더 신뢰성이 있는 tcp connection이 필요함. + this.priorityDataSender.request(sqlMetaData); + } + parsingResult.setId(cachingResult.getId()); + return parsingResult; + } + + @Override + public DatabaseInfo parseJdbcUrl(final String url) { + return this.jdbcUrlParser.parse(url); + } + + @Override + public DatabaseInfo createDatabaseInfo(ServiceType type, ServiceType executeQueryType, String url, int port, String databaseId) { + List host = new ArrayList(); + host.add(url + ":" + port); + DatabaseInfo databaseInfo = new DefaultDatabaseInfo(type, executeQueryType, url, url, host, databaseId); + return databaseInfo; + } + + + + public void setPriorityDataSender(final EnhancedDataSender priorityDataSender) { + this.priorityDataSender = priorityDataSender; + } + + + public void setAgentInformation(final AgentInformation agentInformation) { + if (agentInformation == null) { + throw new NullPointerException("agentInformation must not be null"); + } + this.agentInformation = agentInformation; + } + + @Override + public Metric getRpcMetric(ServiceType serviceType) { + if (serviceType == null) { + throw new NullPointerException("serviceType must not be null"); + } + + return this.metricRegistry.getRpcMetric(serviceType); + } + + + public void recordContextMetricIsError() { + recordContextMetric(HistogramSchema.ERROR_SLOT_TIME); + } + + public void recordContextMetric(int elapsedTime) { + final ContextMetric contextMetric = this.metricRegistry.getResponseMetric(); + contextMetric.addResponseTime(elapsedTime); + } + + public void recordAcceptResponseTime(String parentApplicationName, short parentApplicationType, int elapsedTime) { + final ContextMetric contextMetric = this.metricRegistry.getResponseMetric(); + contextMetric.addAcceptHistogram(parentApplicationName, parentApplicationType, elapsedTime); + } + + public void recordUserAcceptResponseTime(int elapsedTime) { + final ContextMetric contextMetric = this.metricRegistry.getResponseMetric(); + contextMetric.addUserAcceptHistogram(elapsedTime); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java index c8a358ae8c1b..1b3233d7e3d1 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java @@ -1,187 +1,187 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.Metric; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.util.ParsingResult; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; - - -/** - * @author emeroad - */ -public class DisableTrace implements Trace { - - public static final DisableTrace INSTANCE = new DisableTrace(); - // 구지 객체를 생성하여 사용할 필요가 없을듯. - private DisableTrace() { - } - - @Override - public void traceBlockBegin() { - throw new UnsupportedOperationException(); - } - - @Override - public void markBeforeTime() { - throw new UnsupportedOperationException(); - } - - @Override - public long getBeforeTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void markAfterTime() { - throw new UnsupportedOperationException(); - } - - @Override - public long getAfterTime() { - throw new UnsupportedOperationException(); - } - - @Override - public void traceBlockBegin(int stackId) { - throw new UnsupportedOperationException(); - } - - @Override - public void traceRootBlockEnd() { - throw new UnsupportedOperationException(); - } - - @Override - public void traceBlockEnd() { - throw new UnsupportedOperationException(); - } - - @Override - public void traceBlockEnd(int stackId) { - throw new UnsupportedOperationException(); - } - - @Override - public TraceId getTraceId() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean canSampled() { - // sampling false를 항상 false를 리턴한다. - return false; - } - - @Override - public boolean isRoot() { - return false; - } - - @Override - public void recordException(Throwable throwable) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) { - throw new UnsupportedOperationException(); - } - - @Override - public ParsingResult recordSqlInfo(String sql) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordSqlParsingResult(ParsingResult parsingResult) { - throw new UnsupportedOperationException(); - } - - public void recordSqlParsingResult(ParsingResult parsingResult, String bindValue) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordAttribute(AnnotationKey key, String value) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordAttribute(AnnotationKey key, int value) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordAttribute(AnnotationKey key, Object value) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordServiceType(ServiceType serviceType) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordRpcName(String rpc) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordDestinationId(String destinationId) { - throw new UnsupportedOperationException(); - } - - - @Override - public void recordEndPoint(String endPoint) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordRemoteAddress(String remoteAddress) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordNextSpanId(long spanId) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordParentApplication(String parentApplicationName, short parentApplicationType) { - throw new UnsupportedOperationException(); - } - - @Override - public void recordAcceptorHost(String host) { - throw new UnsupportedOperationException(); - } - - @Override - public int getStackFrameId() { - throw new UnsupportedOperationException(); - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.Metric; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.util.ParsingResult; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; + + +/** + * @author emeroad + */ +public class DisableTrace implements Trace { + + public static final DisableTrace INSTANCE = new DisableTrace(); + // 구지 객체를 생성하여 사용할 필요가 없을듯. + private DisableTrace() { + } + + @Override + public void traceBlockBegin() { + throw new UnsupportedOperationException(); + } + + @Override + public void markBeforeTime() { + throw new UnsupportedOperationException(); + } + + @Override + public long getBeforeTime() { + throw new UnsupportedOperationException(); + } + + @Override + public void markAfterTime() { + throw new UnsupportedOperationException(); + } + + @Override + public long getAfterTime() { + throw new UnsupportedOperationException(); + } + + @Override + public void traceBlockBegin(int stackId) { + throw new UnsupportedOperationException(); + } + + @Override + public void traceRootBlockEnd() { + throw new UnsupportedOperationException(); + } + + @Override + public void traceBlockEnd() { + throw new UnsupportedOperationException(); + } + + @Override + public void traceBlockEnd(int stackId) { + throw new UnsupportedOperationException(); + } + + @Override + public TraceId getTraceId() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean canSampled() { + // sampling false를 항상 false를 리턴한다. + return false; + } + + @Override + public boolean isRoot() { + return false; + } + + @Override + public void recordException(Throwable throwable) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) { + throw new UnsupportedOperationException(); + } + + @Override + public ParsingResult recordSqlInfo(String sql) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordSqlParsingResult(ParsingResult parsingResult) { + throw new UnsupportedOperationException(); + } + + public void recordSqlParsingResult(ParsingResult parsingResult, String bindValue) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordAttribute(AnnotationKey key, String value) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordAttribute(AnnotationKey key, int value) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordAttribute(AnnotationKey key, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordServiceType(ServiceType serviceType) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordRpcName(String rpc) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordDestinationId(String destinationId) { + throw new UnsupportedOperationException(); + } + + + @Override + public void recordEndPoint(String endPoint) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordRemoteAddress(String remoteAddress) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordNextSpanId(long spanId) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordParentApplication(String parentApplicationName, short parentApplicationType) { + throw new UnsupportedOperationException(); + } + + @Override + public void recordAcceptorHost(String host) { + throw new UnsupportedOperationException(); + } + + @Override + public int getStackFrameId() { + throw new UnsupportedOperationException(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/GlobalCallTrace.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/GlobalCallTrace.java index 53be7095704b..489dcacd5208 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/GlobalCallTrace.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/GlobalCallTrace.java @@ -1,81 +1,81 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.AsyncTrace; - -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * 뭔가 복잡한 비동기 call trace시 객체 등록용으로 쓰자. - * 근데 손좀봐야 될듯.뭔가 좀 구림. - * @author emeroad - */ -@Deprecated -public class GlobalCallTrace { - - private static final long FLUSH_TIMEOUT = 120000L; // 2 minutes - - private static final AtomicInteger timerId = new AtomicInteger(0); - - private ConcurrentMap trace = new ConcurrentHashMap(32); - private AtomicInteger idGenerator = new AtomicInteger(0); - // stop을 해줘야 할듯. - private Timer timer = new Timer("Pinpoint-GlobalCallTrace-Timer-" + timerId.getAndIncrement(), true); - - public int registerTraceObject(AsyncTrace asyncTrace) { - // TODO 연관관계가 전달부분이 영 별로임. - - TimeoutTask timeoutTask = new TimeoutTask(trace, asyncTrace.getAsyncId()); - asyncTrace.setTimeoutTask(timeoutTask); - - int id = put(asyncTrace); - asyncTrace.setAsyncId(id); - timer.schedule(timeoutTask, FLUSH_TIMEOUT); - return id; - } - - private int put(AsyncTrace asyncTrace) { - int id = idGenerator.getAndIncrement(); - trace.put(id, (DefaultAsyncTrace)asyncTrace); - return id; - } - - public AsyncTrace getTraceObject(int asyncId) { - return trace.get(asyncId); - } - - public AsyncTrace removeTraceObject(int asyncId) { - AsyncTrace asyncTrace = trace.remove(asyncId); - if (asyncTrace != null) { - boolean result = ((DefaultAsyncTrace)asyncTrace).fire(); - if (!result) { - // 이미 timeout된 asyncTrace임. - return null; - } - } - return asyncTrace; - } - - - private static class TimeoutTask extends TimerTask { - private ConcurrentMap trace; - private int id; -// private final AsyncTrace asyncTrace; - - public TimeoutTask(ConcurrentMap trace, int id) { - this.trace = trace; - this.id = id; - } - - @Override - public void run() { - DefaultAsyncTrace asyncTrace = (DefaultAsyncTrace) trace.remove(id); - if (asyncTrace != null) { - asyncTrace.timeout(); - } - } - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.AsyncTrace; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 뭔가 복잡한 비동기 call trace시 객체 등록용으로 쓰자. + * 근데 손좀봐야 될듯.뭔가 좀 구림. + * @author emeroad + */ +@Deprecated +public class GlobalCallTrace { + + private static final long FLUSH_TIMEOUT = 120000L; // 2 minutes + + private static final AtomicInteger timerId = new AtomicInteger(0); + + private ConcurrentMap trace = new ConcurrentHashMap(32); + private AtomicInteger idGenerator = new AtomicInteger(0); + // stop을 해줘야 할듯. + private Timer timer = new Timer("Pinpoint-GlobalCallTrace-Timer-" + timerId.getAndIncrement(), true); + + public int registerTraceObject(AsyncTrace asyncTrace) { + // TODO 연관관계가 전달부분이 영 별로임. + + TimeoutTask timeoutTask = new TimeoutTask(trace, asyncTrace.getAsyncId()); + asyncTrace.setTimeoutTask(timeoutTask); + + int id = put(asyncTrace); + asyncTrace.setAsyncId(id); + timer.schedule(timeoutTask, FLUSH_TIMEOUT); + return id; + } + + private int put(AsyncTrace asyncTrace) { + int id = idGenerator.getAndIncrement(); + trace.put(id, (DefaultAsyncTrace)asyncTrace); + return id; + } + + public AsyncTrace getTraceObject(int asyncId) { + return trace.get(asyncId); + } + + public AsyncTrace removeTraceObject(int asyncId) { + AsyncTrace asyncTrace = trace.remove(asyncId); + if (asyncTrace != null) { + boolean result = ((DefaultAsyncTrace)asyncTrace).fire(); + if (!result) { + // 이미 timeout된 asyncTrace임. + return null; + } + } + return asyncTrace; + } + + + private static class TimeoutTask extends TimerTask { + private ConcurrentMap trace; + private int id; +// private final AsyncTrace asyncTrace; + + public TimeoutTask(ConcurrentMap trace, int id) { + this.trace = trace; + this.id = id; + } + + @Override + public void run() { + DefaultAsyncTrace asyncTrace = (DefaultAsyncTrace) trace.remove(id); + if (asyncTrace != null) { + asyncTrace.timeout(); + } + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/MetricTrace.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/MetricTrace.java index 5e2264b2d84e..eef155a33269 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/MetricTrace.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/MetricTrace.java @@ -1,351 +1,351 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.util.DefaultParsingResult; -import com.nhn.pinpoint.common.util.ParsingResult; -import com.nhn.pinpoint.exception.PinpointException; -import com.nhn.pinpoint.profiler.monitor.metric.Histogram; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class MetricTrace implements Trace { - - private static final Logger logger = LoggerFactory.getLogger(MetricTrace.class.getName()); - private static final boolean isDebug = logger.isDebugEnabled(); - private static final boolean isTrace = logger.isTraceEnabled(); - - private static final int EXCEPTION_MARK = -1; - - private static final ParsingResult PARSING_RESULT = new DefaultParsingResult("", new StringBuilder()); - - private final boolean sampling = false; - - private TraceId traceId; - - private final CallStack callStack; - - private final TraceContext traceContext; - - // use for calculating depth of each Span. - private int latestStackIndex = -1; - private StackFrame currentStackFrame; - - private long transactionId; - - public MetricTrace(final TraceContext traceContext, long transactionId) { - if (traceContext == null) { - throw new NullPointerException("traceContext must not be null"); - } - this.traceContext = traceContext; - this.transactionId = transactionId; - - final Span span = createSpan(); - this.callStack = new CallStack(span); - this.latestStackIndex = this.callStack.push(); - - final StackFrame stackFrame = createSpanStackFrame(ROOT_STACKID, callStack.getSpan()); - this.callStack.setStackFrame(stackFrame); - this.currentStackFrame = stackFrame; - - } - - private Span createSpan() { - return new Span(); - } - - public MetricTrace(TraceContext traceContext, TraceId continueTraceId) { - if (traceContext == null) { - throw new NullPointerException("traceContext must not be null"); - } - if (continueTraceId == null) { - throw new NullPointerException("continueTraceId must not be null"); - } - this.traceContext = traceContext; - this.traceId = continueTraceId; - final Span span = createSpan(); - this.callStack = new CallStack(span); - latestStackIndex = this.callStack.push(); - StackFrame stackFrame = createSpanStackFrame(ROOT_STACKID, callStack.getSpan()); - this.callStack.setStackFrame(stackFrame); - this.currentStackFrame = stackFrame; - } - - public CallStack getCallStack() { - return callStack; - } - - - - public int getCallStackDepth() { - return this.callStack.getIndex(); - } - - - private StackFrame createSpanEventStackFrame(int stackId) { - SpanEvent spanEvent = new SpanEvent(callStack.getSpan()); - // Span내부의 SpanEvent로 들어가지 않을 경우 사용하기 위해 set한다. - - SpanEventStackFrame stackFrame = new SpanEventStackFrame(spanEvent); - stackFrame.setStackFrameId(stackId); - - return stackFrame; - } - - private StackFrame createSpanStackFrame(int stackId, Span span) { - RootStackFrame stackFrame = new RootStackFrame(span); - stackFrame.setStackFrameId(stackId); - return stackFrame; - } - - @Override - public void traceBlockBegin() { - traceBlockBegin(DEFAULT_STACKID); - } - - @Override - public void markBeforeTime() { - this.currentStackFrame.markBeforeTime(); - } - - @Override - public long getBeforeTime() { - return this.currentStackFrame.getBeforeTime(); - } - - @Override - public void markAfterTime() { - this.currentStackFrame.markAfterTime(); - } - - @Override - public long getAfterTime() { - return this.currentStackFrame.getAfterTime(); - } - - - @Override - public void traceBlockBegin(final int stackId) { - final int currentStackIndex = callStack.push(); - final StackFrame stackFrame = createSpanEventStackFrame(stackId); - - if (latestStackIndex != currentStackIndex) { - latestStackIndex = currentStackIndex; - SpanEvent spanEvent = ((SpanEventStackFrame) stackFrame).getSpanEvent(); - spanEvent.setDepth(latestStackIndex); - } - - callStack.setStackFrame(stackFrame); - this.currentStackFrame = stackFrame; - } - - @Override - public void traceRootBlockEnd() { - metricResponseTime(); - checkStackId(ROOT_STACKID); - callStack.popRoot(); - // 잘못된 stack 조작시 다음부터 그냥 nullPointerException이 발생할건데 괜찮은가? - this.currentStackFrame = null; - } - - - - @Override - public void traceBlockEnd() { - traceBlockEnd(DEFAULT_STACKID); - } - - private void metricResponseTime() { - final int errCode = this.getCallStack().getSpan().getErrCode(); - if (errCode != 0) { - traceContext.recordContextMetricIsError(); - } else { - final int elapsedTime = this.currentStackFrame.getElapsedTime(); - traceContext.recordContextMetric(elapsedTime); - } - } - - - @Override - public void traceBlockEnd(int stackId) { - checkStackId(stackId); - StackFrame popStackFrame = callStack.pop(); - // pop 할때 frame위치를 원복해야 한다. - this.currentStackFrame = popStackFrame; - } - - private void checkStackId(int stackId) { - final StackFrame currentStackFrame = this.currentStackFrame; - int stackFrameId = currentStackFrame.getStackFrameId(); - if (stackFrameId != stackId) { - // 자체 stack dump를 하면 오류발견이 쉬울것으로 생각됨 - if (logger.isWarnEnabled()) { - PinpointException exception = new PinpointException("Corrupted CallStack found"); - logger.warn("Corrupted CallStack found. StackId not matched. expected:{} current:{}", stackId, stackFrameId, exception); - } - } - } - - public StackFrame getCurrentStackFrame() { - return callStack.getCurrentStackFrame(); - } - - /** - * Get current TraceID. If it was not set this will return null. - * - * @return - */ - @Override - public TraceId getTraceId() { - return this.traceId; - } - - @Override - public boolean canSampled() { - return this.sampling; - } - - @Override - public boolean isRoot() { - return false; - } - - - @Override - public void recordException(Throwable th) { - if (th == null) { - return; - } - // TODO 추가적인 객체를 생성하지 않도록 MARK Exception이 있으면 좋을것 같음. - this.currentStackFrame.setExceptionInfo(EXCEPTION_MARK, ""); - - final Span span = getCallStack().getSpan(); - if (!span.isSetErrCode()) { - span.setErrCode(1); - } - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor) { - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) { - } - - @Override - public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) { - } - - @Override - public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) { - } - - - @Override - public ParsingResult recordSqlInfo(String sql) { - return PARSING_RESULT; - } - - @Override - public void recordSqlParsingResult(ParsingResult parsingResult) { - } - - @Override - public void recordSqlParsingResult(ParsingResult parsingResult, String bindValue) { - - } - - - @Override - public void recordAttribute(final AnnotationKey key, final String value) { - } - - @Override - public void recordAttribute(final AnnotationKey key, final int value) { - } - - - @Override - public void recordAttribute(final AnnotationKey key, final Object value) { - } - - - @Override - public void recordServiceType(final ServiceType serviceType) { - final StackFrame currentStackFrame = this.currentStackFrame; - currentStackFrame.setServiceType(serviceType.getCode()); - } - - @Override - public void recordRpcName(final String rpc) { - } - - @Override - public void recordDestinationId(final String destinationId) { - StackFrame currentStackFrame = this.currentStackFrame; - if (currentStackFrame instanceof SpanEventStackFrame) { - ((SpanEventStackFrame) currentStackFrame).setDestinationId(destinationId); - } else { - throw new PinpointTraceException("not SpanEventStackFrame"); - } - } - - @Override - public void recordEndPoint(final String endPoint) { - } - - @Override - public void recordRemoteAddress(final String remoteAddress) { - } - - @Override - public void recordNextSpanId(long nextSpanId) { - } - - @Override - public void recordParentApplication(String parentApplicationName, short parentApplicationType) { - StackFrame currentStackFrame = this.currentStackFrame; - if (currentStackFrame instanceof RootStackFrame) { - final Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setParentApplicationName(parentApplicationName); - span.setParentApplicationType(parentApplicationType); - if (isDebug) { - logger.debug("ParentApplicationName marked. parentApplicationName={}", parentApplicationName); - } - } else { - throw new PinpointTraceException("not RootStackFrame"); - } - } - - @Override - public void recordAcceptorHost(String host) { - StackFrame currentStackFrame = this.currentStackFrame; - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setAcceptorHost(host); // me - if (isDebug) { - logger.debug("Acceptor host received. host={}", host); - } - } else { - throw new PinpointTraceException("not RootStackFrame"); - } - } - - @Override - public int getStackFrameId() { - return this.getCurrentStackFrame().getStackFrameId(); - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.util.DefaultParsingResult; +import com.nhn.pinpoint.common.util.ParsingResult; +import com.nhn.pinpoint.exception.PinpointException; +import com.nhn.pinpoint.profiler.monitor.metric.Histogram; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class MetricTrace implements Trace { + + private static final Logger logger = LoggerFactory.getLogger(MetricTrace.class.getName()); + private static final boolean isDebug = logger.isDebugEnabled(); + private static final boolean isTrace = logger.isTraceEnabled(); + + private static final int EXCEPTION_MARK = -1; + + private static final ParsingResult PARSING_RESULT = new DefaultParsingResult("", new StringBuilder()); + + private final boolean sampling = false; + + private TraceId traceId; + + private final CallStack callStack; + + private final TraceContext traceContext; + + // use for calculating depth of each Span. + private int latestStackIndex = -1; + private StackFrame currentStackFrame; + + private long transactionId; + + public MetricTrace(final TraceContext traceContext, long transactionId) { + if (traceContext == null) { + throw new NullPointerException("traceContext must not be null"); + } + this.traceContext = traceContext; + this.transactionId = transactionId; + + final Span span = createSpan(); + this.callStack = new CallStack(span); + this.latestStackIndex = this.callStack.push(); + + final StackFrame stackFrame = createSpanStackFrame(ROOT_STACKID, callStack.getSpan()); + this.callStack.setStackFrame(stackFrame); + this.currentStackFrame = stackFrame; + + } + + private Span createSpan() { + return new Span(); + } + + public MetricTrace(TraceContext traceContext, TraceId continueTraceId) { + if (traceContext == null) { + throw new NullPointerException("traceContext must not be null"); + } + if (continueTraceId == null) { + throw new NullPointerException("continueTraceId must not be null"); + } + this.traceContext = traceContext; + this.traceId = continueTraceId; + final Span span = createSpan(); + this.callStack = new CallStack(span); + latestStackIndex = this.callStack.push(); + StackFrame stackFrame = createSpanStackFrame(ROOT_STACKID, callStack.getSpan()); + this.callStack.setStackFrame(stackFrame); + this.currentStackFrame = stackFrame; + } + + public CallStack getCallStack() { + return callStack; + } + + + + public int getCallStackDepth() { + return this.callStack.getIndex(); + } + + + private StackFrame createSpanEventStackFrame(int stackId) { + SpanEvent spanEvent = new SpanEvent(callStack.getSpan()); + // Span내부의 SpanEvent로 들어가지 않을 경우 사용하기 위해 set한다. + + SpanEventStackFrame stackFrame = new SpanEventStackFrame(spanEvent); + stackFrame.setStackFrameId(stackId); + + return stackFrame; + } + + private StackFrame createSpanStackFrame(int stackId, Span span) { + RootStackFrame stackFrame = new RootStackFrame(span); + stackFrame.setStackFrameId(stackId); + return stackFrame; + } + + @Override + public void traceBlockBegin() { + traceBlockBegin(DEFAULT_STACKID); + } + + @Override + public void markBeforeTime() { + this.currentStackFrame.markBeforeTime(); + } + + @Override + public long getBeforeTime() { + return this.currentStackFrame.getBeforeTime(); + } + + @Override + public void markAfterTime() { + this.currentStackFrame.markAfterTime(); + } + + @Override + public long getAfterTime() { + return this.currentStackFrame.getAfterTime(); + } + + + @Override + public void traceBlockBegin(final int stackId) { + final int currentStackIndex = callStack.push(); + final StackFrame stackFrame = createSpanEventStackFrame(stackId); + + if (latestStackIndex != currentStackIndex) { + latestStackIndex = currentStackIndex; + SpanEvent spanEvent = ((SpanEventStackFrame) stackFrame).getSpanEvent(); + spanEvent.setDepth(latestStackIndex); + } + + callStack.setStackFrame(stackFrame); + this.currentStackFrame = stackFrame; + } + + @Override + public void traceRootBlockEnd() { + metricResponseTime(); + checkStackId(ROOT_STACKID); + callStack.popRoot(); + // 잘못된 stack 조작시 다음부터 그냥 nullPointerException이 발생할건데 괜찮은가? + this.currentStackFrame = null; + } + + + + @Override + public void traceBlockEnd() { + traceBlockEnd(DEFAULT_STACKID); + } + + private void metricResponseTime() { + final int errCode = this.getCallStack().getSpan().getErrCode(); + if (errCode != 0) { + traceContext.recordContextMetricIsError(); + } else { + final int elapsedTime = this.currentStackFrame.getElapsedTime(); + traceContext.recordContextMetric(elapsedTime); + } + } + + + @Override + public void traceBlockEnd(int stackId) { + checkStackId(stackId); + StackFrame popStackFrame = callStack.pop(); + // pop 할때 frame위치를 원복해야 한다. + this.currentStackFrame = popStackFrame; + } + + private void checkStackId(int stackId) { + final StackFrame currentStackFrame = this.currentStackFrame; + int stackFrameId = currentStackFrame.getStackFrameId(); + if (stackFrameId != stackId) { + // 자체 stack dump를 하면 오류발견이 쉬울것으로 생각됨 + if (logger.isWarnEnabled()) { + PinpointException exception = new PinpointException("Corrupted CallStack found"); + logger.warn("Corrupted CallStack found. StackId not matched. expected:{} current:{}", stackId, stackFrameId, exception); + } + } + } + + public StackFrame getCurrentStackFrame() { + return callStack.getCurrentStackFrame(); + } + + /** + * Get current TraceID. If it was not set this will return null. + * + * @return + */ + @Override + public TraceId getTraceId() { + return this.traceId; + } + + @Override + public boolean canSampled() { + return this.sampling; + } + + @Override + public boolean isRoot() { + return false; + } + + + @Override + public void recordException(Throwable th) { + if (th == null) { + return; + } + // TODO 추가적인 객체를 생성하지 않도록 MARK Exception이 있으면 좋을것 같음. + this.currentStackFrame.setExceptionInfo(EXCEPTION_MARK, ""); + + final Span span = getCallStack().getSpan(); + if (!span.isSetErrCode()) { + span.setErrCode(1); + } + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor) { + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) { + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) { + } + + @Override + public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) { + } + + + @Override + public ParsingResult recordSqlInfo(String sql) { + return PARSING_RESULT; + } + + @Override + public void recordSqlParsingResult(ParsingResult parsingResult) { + } + + @Override + public void recordSqlParsingResult(ParsingResult parsingResult, String bindValue) { + + } + + + @Override + public void recordAttribute(final AnnotationKey key, final String value) { + } + + @Override + public void recordAttribute(final AnnotationKey key, final int value) { + } + + + @Override + public void recordAttribute(final AnnotationKey key, final Object value) { + } + + + @Override + public void recordServiceType(final ServiceType serviceType) { + final StackFrame currentStackFrame = this.currentStackFrame; + currentStackFrame.setServiceType(serviceType.getCode()); + } + + @Override + public void recordRpcName(final String rpc) { + } + + @Override + public void recordDestinationId(final String destinationId) { + StackFrame currentStackFrame = this.currentStackFrame; + if (currentStackFrame instanceof SpanEventStackFrame) { + ((SpanEventStackFrame) currentStackFrame).setDestinationId(destinationId); + } else { + throw new PinpointTraceException("not SpanEventStackFrame"); + } + } + + @Override + public void recordEndPoint(final String endPoint) { + } + + @Override + public void recordRemoteAddress(final String remoteAddress) { + } + + @Override + public void recordNextSpanId(long nextSpanId) { + } + + @Override + public void recordParentApplication(String parentApplicationName, short parentApplicationType) { + StackFrame currentStackFrame = this.currentStackFrame; + if (currentStackFrame instanceof RootStackFrame) { + final Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setParentApplicationName(parentApplicationName); + span.setParentApplicationType(parentApplicationType); + if (isDebug) { + logger.debug("ParentApplicationName marked. parentApplicationName={}", parentApplicationName); + } + } else { + throw new PinpointTraceException("not RootStackFrame"); + } + } + + @Override + public void recordAcceptorHost(String host) { + StackFrame currentStackFrame = this.currentStackFrame; + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setAcceptorHost(host); // me + if (isDebug) { + logger.debug("Acceptor host received. host={}", host); + } + } else { + throw new PinpointTraceException("not RootStackFrame"); + } + } + + @Override + public int getStackFrameId() { + return this.getCurrentStackFrame().getStackFrameId(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/PinpointTraceException.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/PinpointTraceException.java index dd88a93e6ad3..51ba8007fd5f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/PinpointTraceException.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/PinpointTraceException.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.exception.PinpointException; - -/** - * @author emeroad - */ -public class PinpointTraceException extends PinpointException { - - public PinpointTraceException() { - } - - public PinpointTraceException(String message) { - super(message); - } - - public PinpointTraceException(String message, Throwable cause) { - super(message, cause); - } - - public PinpointTraceException(Throwable cause) { - super(cause); - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.exception.PinpointException; + +/** + * @author emeroad + */ +public class PinpointTraceException extends PinpointException { + + public PinpointTraceException() { + } + + public PinpointTraceException(String message) { + super(message); + } + + public PinpointTraceException(String message, Throwable cause) { + super(message, cause); + } + + public PinpointTraceException(Throwable cause) { + super(cause); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/RootStackFrame.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/RootStackFrame.java index f7e577aab906..ed117c0577fb 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/RootStackFrame.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/RootStackFrame.java @@ -1,111 +1,111 @@ -package com.nhn.pinpoint.profiler.context; - -/** - * @author emeroad - */ -public class RootStackFrame implements StackFrame { - - private final Span span; - private int stackId; - private Object frameObject; - - - public RootStackFrame(Span span) { - if (span == null) { - throw new NullPointerException("span must not be null"); - } - this.span = span; - } - - - @Override - public int getStackFrameId() { - return stackId; - } - - @Override - public void setStackFrameId(int stackId) { - this.stackId = stackId; - } - - @Override - public void markBeforeTime() { - this.span.markBeforeTime(); - } - - @Override - public long getBeforeTime() { - return this.span.getStartTime(); - } - - @Override - public void markAfterTime() { - this.span.markAfterTime(); - } - - @Override - public long getAfterTime() { - return span.getAfterTime(); - } - - @Override - public int getElapsedTime() { - return span.getElapsed(); - } - - - public Span getSpan() { - return span; - } - - @Override - public void setEndPoint(String endPoint) { - this.span.setEndPoint(endPoint); - } - - @Override - public void setRpc(String rpc) { - this.span.setRpc(rpc); - } - - @Override - public void setApiId(int apiId) { - this.span.setApiId(apiId); - } - - @Override - public void setExceptionInfo(int exceptionId, String exceptionMessage) { - this.span.setExceptionInfo(exceptionId, exceptionMessage); - } - - @Override - public void setServiceType(short serviceType) { - this.span.setServiceType(serviceType); - } - - @Override - public void addAnnotation(Annotation annotation) { - this.span.addAnnotation(annotation); - } - - public void setRemoteAddress(String remoteAddress) { - this.span.setRemoteAddr(remoteAddress); - } - - @Override - public void attachFrameObject(Object frameObject) { - this.frameObject = frameObject; - } - - @Override - public Object getFrameObject() { - return this.frameObject; - } - - @Override - public Object detachFrameObject() { - Object copy = this.frameObject; - this.frameObject = null; - return copy; - } -} +package com.nhn.pinpoint.profiler.context; + +/** + * @author emeroad + */ +public class RootStackFrame implements StackFrame { + + private final Span span; + private int stackId; + private Object frameObject; + + + public RootStackFrame(Span span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + this.span = span; + } + + + @Override + public int getStackFrameId() { + return stackId; + } + + @Override + public void setStackFrameId(int stackId) { + this.stackId = stackId; + } + + @Override + public void markBeforeTime() { + this.span.markBeforeTime(); + } + + @Override + public long getBeforeTime() { + return this.span.getStartTime(); + } + + @Override + public void markAfterTime() { + this.span.markAfterTime(); + } + + @Override + public long getAfterTime() { + return span.getAfterTime(); + } + + @Override + public int getElapsedTime() { + return span.getElapsed(); + } + + + public Span getSpan() { + return span; + } + + @Override + public void setEndPoint(String endPoint) { + this.span.setEndPoint(endPoint); + } + + @Override + public void setRpc(String rpc) { + this.span.setRpc(rpc); + } + + @Override + public void setApiId(int apiId) { + this.span.setApiId(apiId); + } + + @Override + public void setExceptionInfo(int exceptionId, String exceptionMessage) { + this.span.setExceptionInfo(exceptionId, exceptionMessage); + } + + @Override + public void setServiceType(short serviceType) { + this.span.setServiceType(serviceType); + } + + @Override + public void addAnnotation(Annotation annotation) { + this.span.addAnnotation(annotation); + } + + public void setRemoteAddress(String remoteAddress) { + this.span.setRemoteAddr(remoteAddress); + } + + @Override + public void attachFrameObject(Object frameObject) { + this.frameObject = frameObject; + } + + @Override + public Object getFrameObject() { + return this.frameObject; + } + + @Override + public Object detachFrameObject() { + Object copy = this.frameObject; + this.frameObject = null; + return copy; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunk.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunk.java index bc2deff698ef..07dd393f4a00 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunk.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunk.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.profiler.context; - -import java.util.ArrayList; -import java.util.List; - -import com.nhn.pinpoint.profiler.AgentInformation; -import com.nhn.pinpoint.thrift.dto.TAnnotation; -import com.nhn.pinpoint.thrift.dto.TSpanChunk; -import com.nhn.pinpoint.thrift.dto.TSpanEvent; -import org.apache.thrift.TBase; - -import com.nhn.pinpoint.profiler.DefaultAgent; - -/** - * @author emeroad - */ -public class SpanChunk extends TSpanChunk { - - public SpanChunk(List spanEventList) { - if (spanEventList == null) { - throw new NullPointerException("spanEventList must not be null"); - } - setSpanEventList((List) spanEventList); - } -} +package com.nhn.pinpoint.profiler.context; + +import java.util.ArrayList; +import java.util.List; + +import com.nhn.pinpoint.profiler.AgentInformation; +import com.nhn.pinpoint.thrift.dto.TAnnotation; +import com.nhn.pinpoint.thrift.dto.TSpanChunk; +import com.nhn.pinpoint.thrift.dto.TSpanEvent; +import org.apache.thrift.TBase; + +import com.nhn.pinpoint.profiler.DefaultAgent; + +/** + * @author emeroad + */ +public class SpanChunk extends TSpanChunk { + + public SpanChunk(List spanEventList) { + if (spanEventList == null) { + throw new NullPointerException("spanEventList must not be null"); + } + setSpanEventList((List) spanEventList); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java index 6051f8a4da21..e57a7305c05b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.profiler.AgentInformation; -import com.nhn.pinpoint.thrift.dto.TSpanEvent; - -import java.util.List; - -/** - * @author emeroad - */ -public class SpanChunkFactory { - - private final AgentInformation agentInformation; - - public SpanChunkFactory(AgentInformation agentInformation) { - if (agentInformation == null) { - throw new NullPointerException("agentInformation must not be null"); - } - this.agentInformation = agentInformation; - } - - public SpanChunk create(final List flushData) { - if (flushData == null) { - throw new NullPointerException("flushData must not be null"); - } - // TODO 반드시 1개 이상이라는 조건을 충족해야 된다. - final int size = flushData.size(); - if (size < 1) { - throw new IllegalArgumentException("flushData.size() < 1 size:" + size); - } - - - final SpanEvent first = flushData.get(0); - if (first == null) { - throw new IllegalStateException("first SpanEvent is null"); - } - final Span parentSpan = first.getSpan(); - final String agentId = this.agentInformation.getAgentId(); - - final SpanChunk spanChunk = new SpanChunk(flushData); - spanChunk.setAgentId(agentId); - spanChunk.setApplicationName(this.agentInformation.getApplicationName()); - spanChunk.setAgentStartTime(this.agentInformation.getStartTime()); - - spanChunk.setServiceType(parentSpan.getServiceType()); - - - final byte[] transactionId = parentSpan.getTransactionId(); - spanChunk.setTransactionId(transactionId); - - - spanChunk.setSpanId(parentSpan.getSpanId()); - - spanChunk.setEndPoint(parentSpan.getEndPoint()); - return spanChunk; - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.profiler.AgentInformation; +import com.nhn.pinpoint.thrift.dto.TSpanEvent; + +import java.util.List; + +/** + * @author emeroad + */ +public class SpanChunkFactory { + + private final AgentInformation agentInformation; + + public SpanChunkFactory(AgentInformation agentInformation) { + if (agentInformation == null) { + throw new NullPointerException("agentInformation must not be null"); + } + this.agentInformation = agentInformation; + } + + public SpanChunk create(final List flushData) { + if (flushData == null) { + throw new NullPointerException("flushData must not be null"); + } + // TODO 반드시 1개 이상이라는 조건을 충족해야 된다. + final int size = flushData.size(); + if (size < 1) { + throw new IllegalArgumentException("flushData.size() < 1 size:" + size); + } + + + final SpanEvent first = flushData.get(0); + if (first == null) { + throw new IllegalStateException("first SpanEvent is null"); + } + final Span parentSpan = first.getSpan(); + final String agentId = this.agentInformation.getAgentId(); + + final SpanChunk spanChunk = new SpanChunk(flushData); + spanChunk.setAgentId(agentId); + spanChunk.setApplicationName(this.agentInformation.getApplicationName()); + spanChunk.setAgentStartTime(this.agentInformation.getStartTime()); + + spanChunk.setServiceType(parentSpan.getServiceType()); + + + final byte[] transactionId = parentSpan.getTransactionId(); + spanChunk.setTransactionId(transactionId); + + + spanChunk.setSpanId(parentSpan.getSpanId()); + + spanChunk.setEndPoint(parentSpan.getEndPoint()); + return spanChunk; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEventStackFrame.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEventStackFrame.java index 3f38c13bb76c..ec3778c6698b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEventStackFrame.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEventStackFrame.java @@ -1,117 +1,117 @@ -package com.nhn.pinpoint.profiler.context; - -/** - * @author emeroad - */ -public class SpanEventStackFrame implements StackFrame { - private final SpanEvent spanEvent; - private int stackId; - private Object frameObject; - - public SpanEventStackFrame(SpanEvent spanEvent) { - if (spanEvent == null) { - throw new NullPointerException("spanEvent must not be null"); - } - this.spanEvent = spanEvent; - } - - @Override - public int getStackFrameId() { - return stackId; - } - - @Override - public void setStackFrameId(int stackId) { - this.stackId = stackId; - } - - @Override - public void markBeforeTime() { - spanEvent.markStartTime(); - } - - @Override - public long getBeforeTime() { - return spanEvent.getStartTime(); - } - - @Override - public void markAfterTime() { - spanEvent.markAfterTime(); - } - - @Override - public long getAfterTime() { - return spanEvent.getAfterTime(); - } - - @Override - public int getElapsedTime() { - return spanEvent.getEndElapsed(); - } - - public void setSequence(short sequence) { - spanEvent.setSequence(sequence); - } - - public SpanEvent getSpanEvent() { - return spanEvent; - } - - @Override - public void setEndPoint(String endPoint) { - this.spanEvent.setEndPoint(endPoint); - } - - @Override - public void setRpc(String rpc) { - this.spanEvent.setRpc(rpc); - } - - @Override - public void setApiId(int apiId) { - this.spanEvent.setApiId(apiId); - } - - @Override - public void setExceptionInfo(int exceptionId, String exceptionMessage) { - this.spanEvent.setExceptionInfo(exceptionId, exceptionMessage); - } - - @Override - public void setServiceType(short serviceType) { - spanEvent.setServiceType(serviceType); - } - - @Override - public void addAnnotation(Annotation annotation) { - this.spanEvent.addAnnotation(annotation); - } - - public void setDestinationId(String destinationId) { - this.spanEvent.setDestinationId(destinationId); - } - - public void setNextSpanId(long nextSpanId) { - this.spanEvent.setNextSpanId(nextSpanId); - } - - @Override - public void attachFrameObject(Object frameObject) { - this.frameObject = frameObject; - } - - @Override - public Object getFrameObject() { - return this.frameObject; - } - - @Override - public Object detachFrameObject() { - Object copy = this.frameObject; - this.frameObject = null; - return copy; - } - - -} +package com.nhn.pinpoint.profiler.context; + +/** + * @author emeroad + */ +public class SpanEventStackFrame implements StackFrame { + private final SpanEvent spanEvent; + private int stackId; + private Object frameObject; + + public SpanEventStackFrame(SpanEvent spanEvent) { + if (spanEvent == null) { + throw new NullPointerException("spanEvent must not be null"); + } + this.spanEvent = spanEvent; + } + + @Override + public int getStackFrameId() { + return stackId; + } + + @Override + public void setStackFrameId(int stackId) { + this.stackId = stackId; + } + + @Override + public void markBeforeTime() { + spanEvent.markStartTime(); + } + + @Override + public long getBeforeTime() { + return spanEvent.getStartTime(); + } + + @Override + public void markAfterTime() { + spanEvent.markAfterTime(); + } + + @Override + public long getAfterTime() { + return spanEvent.getAfterTime(); + } + + @Override + public int getElapsedTime() { + return spanEvent.getEndElapsed(); + } + + public void setSequence(short sequence) { + spanEvent.setSequence(sequence); + } + + public SpanEvent getSpanEvent() { + return spanEvent; + } + + @Override + public void setEndPoint(String endPoint) { + this.spanEvent.setEndPoint(endPoint); + } + + @Override + public void setRpc(String rpc) { + this.spanEvent.setRpc(rpc); + } + + @Override + public void setApiId(int apiId) { + this.spanEvent.setApiId(apiId); + } + + @Override + public void setExceptionInfo(int exceptionId, String exceptionMessage) { + this.spanEvent.setExceptionInfo(exceptionId, exceptionMessage); + } + + @Override + public void setServiceType(short serviceType) { + spanEvent.setServiceType(serviceType); + } + + @Override + public void addAnnotation(Annotation annotation) { + this.spanEvent.addAnnotation(annotation); + } + + public void setDestinationId(String destinationId) { + this.spanEvent.setDestinationId(destinationId); + } + + public void setNextSpanId(long nextSpanId) { + this.spanEvent.setNextSpanId(nextSpanId); + } + + @Override + public void attachFrameObject(Object frameObject) { + this.frameObject = frameObject; + } + + @Override + public Object getFrameObject() { + return this.frameObject; + } + + @Override + public Object detachFrameObject() { + Object copy = this.frameObject; + this.frameObject = null; + return copy; + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StackFrame.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StackFrame.java index 04d90482a682..28790ad47cf9 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StackFrame.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/StackFrame.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.profiler.context; - -/** - * @author emeroad - */ -public interface StackFrame { - - int getStackFrameId(); - - void setStackFrameId(int stackId); - - void markBeforeTime(); - - long getBeforeTime(); - - void markAfterTime(); - - long getAfterTime(); - - int getElapsedTime(); - - void setEndPoint(String endPoint); - - void setRpc(String rpc); - - void setApiId(int apiId); - - void setExceptionInfo(int exceptionId, String exceptionMessage); - - void setServiceType(short serviceType); - - void addAnnotation(Annotation annotation); - - void attachFrameObject(Object frameObject); - - Object getFrameObject(); - - Object detachFrameObject(); -} +package com.nhn.pinpoint.profiler.context; + +/** + * @author emeroad + */ +public interface StackFrame { + + int getStackFrameId(); + + void setStackFrameId(int stackId); + + void markBeforeTime(); + + long getBeforeTime(); + + void markAfterTime(); + + long getAfterTime(); + + int getElapsedTime(); + + void setEndPoint(String endPoint); + + void setRpc(String rpc); + + void setApiId(int apiId); + + void setExceptionInfo(int exceptionId, String exceptionMessage); + + void setServiceType(short serviceType); + + void addAnnotation(Annotation annotation); + + void attachFrameObject(Object frameObject); + + Object getFrameObject(); + + Object detachFrameObject(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactory.java index 7ea3632a9d14..a10a4e90c25f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactory.java @@ -1,162 +1,162 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.bootstrap.sampler.Sampler; -import com.nhn.pinpoint.exception.PinpointException; -import com.nhn.pinpoint.profiler.context.storage.Storage; -import com.nhn.pinpoint.profiler.context.storage.StorageFactory; -import com.nhn.pinpoint.profiler.monitor.metric.MetricRegistry; -import com.nhn.pinpoint.profiler.util.NamedThreadLocal; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.atomic.AtomicLong; - -/** - * @author emeroad - */ -public class ThreadLocalTraceFactory implements TraceFactory { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final ThreadLocal threadLocal = new NamedThreadLocal("Trace"); - - private final TraceContext traceContext; - private final MetricRegistry metricRegistry; - - private final StorageFactory storageFactory; - private final Sampler sampler; - - // internal stacktrace 추적때 필요한 unique 아이디, activethreadcount의 slow 타임 계산의 위해서도 필요할듯 함. - // 일단 소스를 좀더 단순화 하기 위해서 옮김. - private final AtomicLong transactionId = new AtomicLong(0); - - public ThreadLocalTraceFactory(TraceContext traceContext, MetricRegistry metricRegistry, StorageFactory storageFactory, Sampler sampler) { - if (traceContext == null) { - throw new NullPointerException("traceContext must not be null"); - } - if (metricRegistry == null) { - throw new NullPointerException("metricRegistry must not be null"); - } - if (storageFactory == null) { - throw new NullPointerException("storageFactory must not be null"); - } - if (sampler == null) { - throw new NullPointerException("sampler must not be null"); - } - this.traceContext = traceContext; - this.metricRegistry = metricRegistry; - this.storageFactory = storageFactory; - this.sampler = sampler; - } - - - /** - * sampling 여부까지 체크하여 유효성을 검증한 후 Trace를 리턴한다. - * @return - */ - @Override - public Trace currentTraceObject() { - final Trace trace = threadLocal.get(); - if (trace == null) { - return null; - } - if (trace.canSampled()) { - return trace; - } - return null; - } - - @Override - public Trace currentRpcTraceObject() { - final Trace trace = threadLocal.get(); - if (trace == null) { - return null; - } - return trace; - } - - /** - * 유효성을 검증하지 않고 Trace를 리턴한다. - * @return - */ - @Override - public Trace currentRawTraceObject() { - return threadLocal.get(); - } - - @Override - public Trace disableSampling() { - checkBeforeTraceObject(); - final Trace metricTrace = createMetricTrace(); - threadLocal.set(metricTrace); -// return metricTrace; - // TODO STATDISABLE 잠시 통계기능을 disable시키기 위해서 null리턴 - return null; - } - - // remote 에서 샘플링 대상으로 선정된 경우. - @Override - public Trace continueTraceObject(final TraceId traceID) { - checkBeforeTraceObject(); - - // datasender연결 부분 수정 필요. - final DefaultTrace trace = new DefaultTrace(traceContext, traceID); - final Storage storage = storageFactory.createStorage(); - trace.setStorage(storage); - // remote에 의해 trace가 continue될때는 sampling flag를 좀더 상위에서 하므로 무조껀 true여야함. - // TODO remote에서 sampling flag로 마크가되는 대상으로 왔을 경우도 추가로 샘플링 칠수 있어야 할것으로 보임. - trace.setSampling(true); - - threadLocal.set(trace); - return trace; - } - - private void checkBeforeTraceObject() { - final Trace old = this.threadLocal.get(); - if (old != null) { - final PinpointException exception = new PinpointException("already Trace Object exist."); - if (logger.isWarnEnabled()) { - logger.warn("beforeTrace:{}", old, exception); - } - throw exception; - } - } - - @Override - public Trace newTraceObject() { - checkBeforeTraceObject(); - // datasender연결 부분 수정 필요. - final boolean sampling = sampler.isSampling(); - if (sampling) { - final Storage storage = storageFactory.createStorage(); - final DefaultTrace trace = new DefaultTrace(traceContext, nextTransactionId()); - trace.setStorage(storage); - trace.setSampling(sampling); - threadLocal.set(trace); - return trace; - } else { - final Trace metricTrace = createMetricTrace(); - threadLocal.set(metricTrace); - return metricTrace; - } - } - - private Trace createMetricTrace() { - return DisableTrace.INSTANCE; -// TODO STATDISABLE 일단 통게 저장기능은 disable한다. -// return new MetricTrace(traceContext, nextTransactionId()); - } - - private long nextTransactionId() { - return this.transactionId.getAndIncrement(); - } - - - @Override - public void detachTraceObject() { - this.threadLocal.remove(); - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.bootstrap.sampler.Sampler; +import com.nhn.pinpoint.exception.PinpointException; +import com.nhn.pinpoint.profiler.context.storage.Storage; +import com.nhn.pinpoint.profiler.context.storage.StorageFactory; +import com.nhn.pinpoint.profiler.monitor.metric.MetricRegistry; +import com.nhn.pinpoint.profiler.util.NamedThreadLocal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.AtomicLong; + +/** + * @author emeroad + */ +public class ThreadLocalTraceFactory implements TraceFactory { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ThreadLocal threadLocal = new NamedThreadLocal("Trace"); + + private final TraceContext traceContext; + private final MetricRegistry metricRegistry; + + private final StorageFactory storageFactory; + private final Sampler sampler; + + // internal stacktrace 추적때 필요한 unique 아이디, activethreadcount의 slow 타임 계산의 위해서도 필요할듯 함. + // 일단 소스를 좀더 단순화 하기 위해서 옮김. + private final AtomicLong transactionId = new AtomicLong(0); + + public ThreadLocalTraceFactory(TraceContext traceContext, MetricRegistry metricRegistry, StorageFactory storageFactory, Sampler sampler) { + if (traceContext == null) { + throw new NullPointerException("traceContext must not be null"); + } + if (metricRegistry == null) { + throw new NullPointerException("metricRegistry must not be null"); + } + if (storageFactory == null) { + throw new NullPointerException("storageFactory must not be null"); + } + if (sampler == null) { + throw new NullPointerException("sampler must not be null"); + } + this.traceContext = traceContext; + this.metricRegistry = metricRegistry; + this.storageFactory = storageFactory; + this.sampler = sampler; + } + + + /** + * sampling 여부까지 체크하여 유효성을 검증한 후 Trace를 리턴한다. + * @return + */ + @Override + public Trace currentTraceObject() { + final Trace trace = threadLocal.get(); + if (trace == null) { + return null; + } + if (trace.canSampled()) { + return trace; + } + return null; + } + + @Override + public Trace currentRpcTraceObject() { + final Trace trace = threadLocal.get(); + if (trace == null) { + return null; + } + return trace; + } + + /** + * 유효성을 검증하지 않고 Trace를 리턴한다. + * @return + */ + @Override + public Trace currentRawTraceObject() { + return threadLocal.get(); + } + + @Override + public Trace disableSampling() { + checkBeforeTraceObject(); + final Trace metricTrace = createMetricTrace(); + threadLocal.set(metricTrace); +// return metricTrace; + // TODO STATDISABLE 잠시 통계기능을 disable시키기 위해서 null리턴 + return null; + } + + // remote 에서 샘플링 대상으로 선정된 경우. + @Override + public Trace continueTraceObject(final TraceId traceID) { + checkBeforeTraceObject(); + + // datasender연결 부분 수정 필요. + final DefaultTrace trace = new DefaultTrace(traceContext, traceID); + final Storage storage = storageFactory.createStorage(); + trace.setStorage(storage); + // remote에 의해 trace가 continue될때는 sampling flag를 좀더 상위에서 하므로 무조껀 true여야함. + // TODO remote에서 sampling flag로 마크가되는 대상으로 왔을 경우도 추가로 샘플링 칠수 있어야 할것으로 보임. + trace.setSampling(true); + + threadLocal.set(trace); + return trace; + } + + private void checkBeforeTraceObject() { + final Trace old = this.threadLocal.get(); + if (old != null) { + final PinpointException exception = new PinpointException("already Trace Object exist."); + if (logger.isWarnEnabled()) { + logger.warn("beforeTrace:{}", old, exception); + } + throw exception; + } + } + + @Override + public Trace newTraceObject() { + checkBeforeTraceObject(); + // datasender연결 부분 수정 필요. + final boolean sampling = sampler.isSampling(); + if (sampling) { + final Storage storage = storageFactory.createStorage(); + final DefaultTrace trace = new DefaultTrace(traceContext, nextTransactionId()); + trace.setStorage(storage); + trace.setSampling(sampling); + threadLocal.set(trace); + return trace; + } else { + final Trace metricTrace = createMetricTrace(); + threadLocal.set(metricTrace); + return metricTrace; + } + } + + private Trace createMetricTrace() { + return DisableTrace.INSTANCE; +// TODO STATDISABLE 일단 통게 저장기능은 disable한다. +// return new MetricTrace(traceContext, nextTransactionId()); + } + + private long nextTransactionId() { + return this.transactionId.getAndIncrement(); + } + + + @Override + public void detachTraceObject() { + this.threadLocal.remove(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceFactory.java index 2a9adbb14378..3e4fe910a48b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceFactory.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.bootstrap.sampler.Sampler; - -/** - * @author emeroad - */ -public interface TraceFactory { - Trace currentTraceObject(); - - Trace currentRpcTraceObject(); - - Trace currentRawTraceObject(); - - Trace disableSampling(); - - // remote 에서 샘플링 대상으로 선정된 경우. - Trace continueTraceObject(TraceId traceID); - - Trace newTraceObject(); - - void detachTraceObject(); -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.bootstrap.sampler.Sampler; + +/** + * @author emeroad + */ +public interface TraceFactory { + Trace currentTraceObject(); + + Trace currentRpcTraceObject(); + + Trace currentRawTraceObject(); + + Trace disableSampling(); + + // remote 에서 샘플링 대상으로 선정된 경우. + Trace continueTraceObject(TraceId traceID); + + Trace newTraceObject(); + + void detachTraceObject(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java index acf01b58ba14..323639d1b736 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java @@ -1,106 +1,106 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import com.nhn.pinpoint.profiler.context.*; -import com.nhn.pinpoint.profiler.sender.DataSender; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public class BufferedStorage implements Storage { - private static final Logger logger = LoggerFactory.getLogger(BufferedStorage.class); - private static final boolean isDebug = logger.isDebugEnabled(); - - private static final int DEFAULT_BUFFER_SIZE = 20; - - private final int bufferSize; - - private List storage ; - private final DataSender dataSender; - private final SpanChunkFactory spanChunkFactory; - - public BufferedStorage(DataSender dataSender, SpanChunkFactory spanChunkFactory) { - this(dataSender, spanChunkFactory, DEFAULT_BUFFER_SIZE); - } - - public BufferedStorage(DataSender dataSender, SpanChunkFactory spanChunkFactory, int bufferSize) { - if (dataSender == null) { - throw new NullPointerException("dataSender must not be null"); - } - if (spanChunkFactory == null) { - throw new NullPointerException("spanChunkFactory must not be null"); - } - this.dataSender = dataSender; - this.spanChunkFactory = spanChunkFactory; - this.bufferSize = bufferSize; - this.storage = new ArrayList(bufferSize); - } - - - @Override - public void store(SpanEvent spanEvent) { - - List flushData = null; - synchronized (this) { - addSpanEvent(spanEvent); - if (storage.size() >= bufferSize) { - // data copy - flushData = storage; - storage = new ArrayList(bufferSize); - } - } - if (flushData != null) { - final SpanChunk spanChunk = spanChunkFactory.create(flushData); - if (isDebug) { - logger.debug("flush SpanChunk {}", spanChunk); - } - dataSender.send(spanChunk); - } - } - - private void addSpanEvent(SpanEvent spanEvent) { - final List storage = this.storage; - if (storage == null) { - if (logger.isErrorEnabled()) { - logger.error("storage is null. discard spanEvent:{}", spanEvent); - } - // 이미 span이 와서 flush된 상황임. - // 비동기를 이쪽에 포함시키면 이렇게 될수 있으나. 현재 구조를 변경할 계획임. - return; - } - storage.add(spanEvent); - } - - - @Override - public void store(Span span) { - flushAll(span); - } - - private void flushAll(Span span) { - List spanEventList; - synchronized (this) { - spanEventList = storage; - this.storage = null; - } - if (spanEventList != null && !spanEventList.isEmpty()) { - span.setSpanEventList((List) spanEventList); - } - if (isDebug) { - logger.debug("flush span {}", span); - } - dataSender.send(span); - } - - @Override - public String toString() { - return "BufferedStorage{" + - "bufferSize=" + bufferSize + - ", dataSender=" + dataSender + - '}'; - } -} +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.profiler.context.*; +import com.nhn.pinpoint.profiler.sender.DataSender; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class BufferedStorage implements Storage { + private static final Logger logger = LoggerFactory.getLogger(BufferedStorage.class); + private static final boolean isDebug = logger.isDebugEnabled(); + + private static final int DEFAULT_BUFFER_SIZE = 20; + + private final int bufferSize; + + private List storage ; + private final DataSender dataSender; + private final SpanChunkFactory spanChunkFactory; + + public BufferedStorage(DataSender dataSender, SpanChunkFactory spanChunkFactory) { + this(dataSender, spanChunkFactory, DEFAULT_BUFFER_SIZE); + } + + public BufferedStorage(DataSender dataSender, SpanChunkFactory spanChunkFactory, int bufferSize) { + if (dataSender == null) { + throw new NullPointerException("dataSender must not be null"); + } + if (spanChunkFactory == null) { + throw new NullPointerException("spanChunkFactory must not be null"); + } + this.dataSender = dataSender; + this.spanChunkFactory = spanChunkFactory; + this.bufferSize = bufferSize; + this.storage = new ArrayList(bufferSize); + } + + + @Override + public void store(SpanEvent spanEvent) { + + List flushData = null; + synchronized (this) { + addSpanEvent(spanEvent); + if (storage.size() >= bufferSize) { + // data copy + flushData = storage; + storage = new ArrayList(bufferSize); + } + } + if (flushData != null) { + final SpanChunk spanChunk = spanChunkFactory.create(flushData); + if (isDebug) { + logger.debug("flush SpanChunk {}", spanChunk); + } + dataSender.send(spanChunk); + } + } + + private void addSpanEvent(SpanEvent spanEvent) { + final List storage = this.storage; + if (storage == null) { + if (logger.isErrorEnabled()) { + logger.error("storage is null. discard spanEvent:{}", spanEvent); + } + // 이미 span이 와서 flush된 상황임. + // 비동기를 이쪽에 포함시키면 이렇게 될수 있으나. 현재 구조를 변경할 계획임. + return; + } + storage.add(spanEvent); + } + + + @Override + public void store(Span span) { + flushAll(span); + } + + private void flushAll(Span span) { + List spanEventList; + synchronized (this) { + spanEventList = storage; + this.storage = null; + } + if (spanEventList != null && !spanEventList.isEmpty()) { + span.setSpanEventList((List) spanEventList); + } + if (isDebug) { + logger.debug("flush span {}", span); + } + dataSender.send(span); + } + + @Override + public String toString() { + return "BufferedStorage{" + + "bufferSize=" + bufferSize + + ", dataSender=" + dataSender + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java index 92b0a22d1ad2..6530ce6d232b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java @@ -1,45 +1,45 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import com.nhn.pinpoint.profiler.AgentInformation; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.profiler.context.SpanChunkFactory; -import com.nhn.pinpoint.profiler.sender.DataSender; - -/** - * @author emeroad - */ -public class BufferedStorageFactory implements StorageFactory { - - private final DataSender dataSender; - private final int bufferSize; - private final SpanChunkFactory spanChunkFactory; - - public BufferedStorageFactory(DataSender dataSender, ProfilerConfig config, AgentInformation agentInformation) { - if (dataSender == null) { - throw new NullPointerException("dataSender must not be null"); - } - if (config == null) { - throw new NullPointerException("config must not be null"); - } - this.dataSender = dataSender; - - this.bufferSize = config.getIoBufferingBufferBufferSize(); - - this.spanChunkFactory = new SpanChunkFactory(agentInformation); - } - - - @Override - public Storage createStorage() { - BufferedStorage bufferedStorage = new BufferedStorage(this.dataSender, spanChunkFactory, this.bufferSize); - return bufferedStorage; - } - - @Override - public String toString() { - return "BufferedStorageFactory{" + - "bufferSize=" + bufferSize + - ", dataSender=" + dataSender + - '}'; - } -} +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.profiler.AgentInformation; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.profiler.context.SpanChunkFactory; +import com.nhn.pinpoint.profiler.sender.DataSender; + +/** + * @author emeroad + */ +public class BufferedStorageFactory implements StorageFactory { + + private final DataSender dataSender; + private final int bufferSize; + private final SpanChunkFactory spanChunkFactory; + + public BufferedStorageFactory(DataSender dataSender, ProfilerConfig config, AgentInformation agentInformation) { + if (dataSender == null) { + throw new NullPointerException("dataSender must not be null"); + } + if (config == null) { + throw new NullPointerException("config must not be null"); + } + this.dataSender = dataSender; + + this.bufferSize = config.getIoBufferingBufferSize(); + + this.spanChunkFactory = new SpanChunkFactory(agentInformation); + } + + + @Override + public Storage createStorage() { + BufferedStorage bufferedStorage = new BufferedStorage(this.dataSender, spanChunkFactory, this.bufferSize); + return bufferedStorage; + } + + @Override + public String toString() { + return "BufferedStorageFactory{" + + "bufferSize=" + bufferSize + + ", dataSender=" + dataSender + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java index b481d1d9a2fc..19886353c73c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java @@ -1,33 +1,33 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import com.nhn.pinpoint.profiler.context.Span; -import com.nhn.pinpoint.profiler.context.SpanEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class LogStorageFactory implements StorageFactory { - - private final static Storage DEFAULT_STORAGE = new LogStorage(); - - @Override - public Storage createStorage() { - // 상태 없음 그냥 재활용하면 됨. - return DEFAULT_STORAGE; - } - - public static class LogStorage implements Storage { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - @Override - public void store(SpanEvent spanEvent) { - logger.debug("log spanEvent:{}", spanEvent); - } - - @Override - public void store(Span span) { - logger.debug("log span:{}", span); - } - } -} +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.profiler.context.Span; +import com.nhn.pinpoint.profiler.context.SpanEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class LogStorageFactory implements StorageFactory { + + private final static Storage DEFAULT_STORAGE = new LogStorage(); + + @Override + public Storage createStorage() { + // 상태 없음 그냥 재활용하면 됨. + return DEFAULT_STORAGE; + } + + public static class LogStorage implements Storage { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Override + public void store(SpanEvent spanEvent) { + logger.debug("log spanEvent:{}", spanEvent); + } + + @Override + public void store(Span span) { + logger.debug("log span:{}", span); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/ReadableSpanStorage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/ReadableSpanStorage.java deleted file mode 100644 index c0560ed43e6c..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/ReadableSpanStorage.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import java.util.ArrayList; -import java.util.List; - -import com.nhn.pinpoint.bootstrap.context.ReadableStorage; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.profiler.context.Span; -import com.nhn.pinpoint.profiler.context.SpanEvent; - -/** - * @author Hyun Jeong - */ -public final class ReadableSpanStorage implements Storage, ReadableStorage { - - private List spanEventList = new ArrayList(10); - - @Override - public void store(SpanEvent spanEvent) { - if (spanEvent == null) { - throw new NullPointerException("spanEvent must not be null"); - } - final List spanEventList = this.spanEventList; - if (spanEventList != null) { - final SpanEventBo spanEventBo = new SpanEventBo(spanEvent.getSpan(), spanEvent); - spanEventList.add(spanEventBo); - } else { - throw new IllegalStateException("spanEventList is null"); - } - } - - @Override - public void store(Span span) { - if (span == null) { - throw new NullPointerException("span must not be null"); - } - this.spanEventList = null; - } - - @Override - public List getSpanEventList() { - if (this.spanEventList == null) { - throw new IllegalStateException("Trace not initialized or already completed."); - } - return this.spanEventList; - } - -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/ReadableSpanStorageFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/ReadableSpanStorageFactory.java deleted file mode 100644 index 3133286c155d..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/ReadableSpanStorageFactory.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.nhn.pinpoint.profiler.context.storage; - -/** - * @author Hyun Jeong - */ -public class ReadableSpanStorageFactory implements StorageFactory { - - @Override - public Storage createStorage() { - return new ReadableSpanStorage(); - } - -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorage.java index 2d89bbe8ae43..8c5effdf1ec5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorage.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import com.nhn.pinpoint.profiler.context.Span; -import com.nhn.pinpoint.profiler.context.SpanEvent; -import com.nhn.pinpoint.profiler.sender.DataSender; -import com.nhn.pinpoint.thrift.dto.TSpanEvent; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public class SpanStorage implements Storage { - - protected List spanEventList = new ArrayList(10); - private final DataSender dataSender; - - public SpanStorage(DataSender dataSender) { - if (dataSender == null) { - throw new NullPointerException("dataSender must not be null"); - } - this.dataSender = dataSender; - } - - @Override - public void store(SpanEvent spanEvent) { - if (spanEvent == null) { - throw new NullPointerException("spanEvent must not be null"); - } - final List spanEventList = this.spanEventList; - if (spanEventList != null) { - spanEventList.add(spanEvent); - } else { - throw new IllegalStateException("spanEventList is null"); - } - } - - @Override - public void store(Span span) { - if (span == null) { - throw new NullPointerException("span must not be null"); - } - span.setSpanEventList(spanEventList); - spanEventList = null; - this.dataSender.send(span); - } -} +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.profiler.context.Span; +import com.nhn.pinpoint.profiler.context.SpanEvent; +import com.nhn.pinpoint.profiler.sender.DataSender; +import com.nhn.pinpoint.thrift.dto.TSpanEvent; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class SpanStorage implements Storage { + + protected List spanEventList = new ArrayList(10); + private final DataSender dataSender; + + public SpanStorage(DataSender dataSender) { + if (dataSender == null) { + throw new NullPointerException("dataSender must not be null"); + } + this.dataSender = dataSender; + } + + @Override + public void store(SpanEvent spanEvent) { + if (spanEvent == null) { + throw new NullPointerException("spanEvent must not be null"); + } + final List spanEventList = this.spanEventList; + if (spanEventList != null) { + spanEventList.add(spanEvent); + } else { + throw new IllegalStateException("spanEventList is null"); + } + } + + @Override + public void store(Span span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + span.setSpanEventList(spanEventList); + spanEventList = null; + this.dataSender.send(span); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorageFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorageFactory.java index b29bef3950da..aab3c4233d3b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorageFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/SpanStorageFactory.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import com.nhn.pinpoint.profiler.sender.DataSender; - -/** - * @author emeroad - */ -public class SpanStorageFactory implements StorageFactory { - - protected final DataSender dataSender; - - public SpanStorageFactory(DataSender dataSender) { - if (dataSender == null) { - throw new NullPointerException("dataSender must not be null"); - } - this.dataSender = dataSender; - } - - @Override - public Storage createStorage() { - return new SpanStorage(this.dataSender); - } -} +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.profiler.sender.DataSender; + +/** + * @author emeroad + */ +public class SpanStorageFactory implements StorageFactory { + + protected final DataSender dataSender; + + public SpanStorageFactory(DataSender dataSender) { + if (dataSender == null) { + throw new NullPointerException("dataSender must not be null"); + } + this.dataSender = dataSender; + } + + @Override + public Storage createStorage() { + return new SpanStorage(this.dataSender); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java index 3289b105f477..b35a47ce389f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java @@ -1,25 +1,23 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import com.nhn.pinpoint.profiler.context.Span; -import com.nhn.pinpoint.profiler.context.SpanEvent; -import com.nhn.pinpoint.profiler.sender.DataSender; - -/** - * @author emeroad - */ -public interface Storage { - - /** - * store(SpanEvent spanEvent)와 store(Span span)간 동기화가 구현되어 있어야 한다. - * - * @param spanEvent - */ - void store(SpanEvent spanEvent); - - /** - * store(SpanEvent spanEvent)와 store(Span span)간 동기화가 구현되어 있어야 한다. - * - * @param span - */ - void store(Span span); -} +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.profiler.context.Span; +import com.nhn.pinpoint.profiler.context.SpanEvent; +import com.nhn.pinpoint.profiler.sender.DataSender; + +/** + * @author emeroad + */ +public interface Storage { + + /** + * + * @param spanEvent + */ + void store(SpanEvent spanEvent); + + /** + * + * @param span + */ + void store(Span span); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/StorageFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/StorageFactory.java index 4ad5454092b6..1145c2aee5ec 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/StorageFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/StorageFactory.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.profiler.context.storage; - -/** - * @author emeroad - */ -public interface StorageFactory { - Storage createStorage(); -} +package com.nhn.pinpoint.profiler.context.storage; + +/** + * @author emeroad + */ +public interface StorageFactory { + Storage createStorage(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateSimpleInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateSimpleInterceptor.java index f6968ded2096..c623c3e3727c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateSimpleInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateSimpleInterceptor.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.profiler.util.DepthScope; -import com.nhn.pinpoint.profiler.util.Scope; - -/** - * @author emeroad - */ -public class DebugScopeDelegateSimpleInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - private final SimpleAroundInterceptor delegate; - private final Scope scope; - - - public DebugScopeDelegateSimpleInterceptor(SimpleAroundInterceptor delegate, Scope scope) { - if (delegate == null) { - throw new NullPointerException("delegate must not be null"); - } - if (scope == null) { - throw new NullPointerException("scope must not be null"); - } - this.delegate = delegate; - this.scope = scope; - } - - @Override - public void before(Object target, Object[] args) { - final int push = scope.push(); - if (push != DepthScope.ZERO) { - if (isDebug) { - logger.debug("push {}. skip trace. level:{} {}", new Object[]{scope.getName(), push, delegate.getClass()}); - } - return; - } - this.delegate.before(target, args); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - final int pop = scope.pop(); - if (pop != DepthScope.ZERO) { - if (isDebug) { - logger.debug("pop {}. skip trace. level:{} {}", new Object[]{scope.getName(), pop, delegate.getClass()}); - } - return; - } - this.delegate.after(target, args, result, throwable); - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - if (this.delegate instanceof ByteCodeMethodDescriptorSupport) { - ((ByteCodeMethodDescriptorSupport) this.delegate).setMethodDescriptor(descriptor); - } - } - - @Override - public void setTraceContext(TraceContext traceContext) { - if (this.delegate instanceof TraceContextSupport) { - ((TraceContextSupport) this.delegate).setTraceContext(traceContext); - } - } -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.profiler.util.DepthScope; +import com.nhn.pinpoint.profiler.util.Scope; + +/** + * @author emeroad + */ +public class DebugScopeDelegateSimpleInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + private final SimpleAroundInterceptor delegate; + private final Scope scope; + + + public DebugScopeDelegateSimpleInterceptor(SimpleAroundInterceptor delegate, Scope scope) { + if (delegate == null) { + throw new NullPointerException("delegate must not be null"); + } + if (scope == null) { + throw new NullPointerException("scope must not be null"); + } + this.delegate = delegate; + this.scope = scope; + } + + @Override + public void before(Object target, Object[] args) { + final int push = scope.push(); + if (push != DepthScope.ZERO) { + if (isDebug) { + logger.debug("push {}. skip trace. level:{} {}", new Object[]{scope.getName(), push, delegate.getClass()}); + } + return; + } + this.delegate.before(target, args); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + final int pop = scope.pop(); + if (pop != DepthScope.ZERO) { + if (isDebug) { + logger.debug("pop {}. skip trace. level:{} {}", new Object[]{scope.getName(), pop, delegate.getClass()}); + } + return; + } + this.delegate.after(target, args, result, throwable); + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + if (this.delegate instanceof ByteCodeMethodDescriptorSupport) { + ((ByteCodeMethodDescriptorSupport) this.delegate).setMethodDescriptor(descriptor); + } + } + + @Override + public void setTraceContext(TraceContext traceContext) { + if (this.delegate instanceof TraceContextSupport) { + ((TraceContextSupport) this.delegate).setTraceContext(traceContext); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateStaticInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateStaticInterceptor.java index 65c69e36ad5d..3ac006ea303f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateStaticInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DebugScopeDelegateStaticInterceptor.java @@ -1,66 +1,66 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.profiler.util.DepthScope; -import com.nhn.pinpoint.profiler.util.Scope; - -/** - * @author emeroad - */ -public class DebugScopeDelegateStaticInterceptor implements StaticAroundInterceptor, TraceContextSupport { - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - private final StaticAroundInterceptor delegate; - private final Scope scope; - - - public DebugScopeDelegateStaticInterceptor(StaticAroundInterceptor delegate, Scope scope) { - if (delegate == null) { - throw new NullPointerException("delegate must not be null"); - } - if (scope == null) { - throw new NullPointerException("scope must not be null"); - } - this.delegate = delegate; - this.scope = scope; - } - - @Override - public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { - final int push = scope.push(); - if (push != DepthScope.ZERO) { - if (isDebug) { - logger.debug("push {}. skip trace. level:{} {}", new Object[]{scope.getName(), push, delegate.getClass()}); - } - return; - } - this.delegate.before(target, className, methodName, parameterDescription, args); - } - - @Override - public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - final int pop = scope.pop(); - if (pop != DepthScope.ZERO) { - if (isDebug) { - logger.debug("pop {}. skip trace. level:{} {}", new Object[]{scope.getName(), pop, delegate.getClass()}); - } - return; - } - this.delegate.after(target, className, methodName, parameterDescription, args, result, throwable); - } - - - @Override - public void setTraceContext(TraceContext traceContext) { - if (this.delegate instanceof TraceContextSupport) { - ((TraceContextSupport) this.delegate).setTraceContext(traceContext); - } - } - - - -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.profiler.util.DepthScope; +import com.nhn.pinpoint.profiler.util.Scope; + +/** + * @author emeroad + */ +public class DebugScopeDelegateStaticInterceptor implements StaticAroundInterceptor, TraceContextSupport { + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + private final StaticAroundInterceptor delegate; + private final Scope scope; + + + public DebugScopeDelegateStaticInterceptor(StaticAroundInterceptor delegate, Scope scope) { + if (delegate == null) { + throw new NullPointerException("delegate must not be null"); + } + if (scope == null) { + throw new NullPointerException("scope must not be null"); + } + this.delegate = delegate; + this.scope = scope; + } + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + final int push = scope.push(); + if (push != DepthScope.ZERO) { + if (isDebug) { + logger.debug("push {}. skip trace. level:{} {}", new Object[]{scope.getName(), push, delegate.getClass()}); + } + return; + } + this.delegate.before(target, className, methodName, parameterDescription, args); + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + final int pop = scope.pop(); + if (pop != DepthScope.ZERO) { + if (isDebug) { + logger.debug("pop {}. skip trace. level:{} {}", new Object[]{scope.getName(), pop, delegate.getClass()}); + } + return; + } + this.delegate.after(target, className, methodName, parameterDescription, args, result, throwable); + } + + + @Override + public void setTraceContext(TraceContext traceContext) { + if (this.delegate instanceof TraceContextSupport) { + ((TraceContextSupport) this.delegate).setTraceContext(traceContext); + } + } + + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DefaultMethodDescriptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DefaultMethodDescriptor.java index 209c29cdc933..29c45eef8442 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DefaultMethodDescriptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/DefaultMethodDescriptor.java @@ -1,150 +1,150 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.profiler.util.ApiUtils; - -import java.util.Arrays; - -/** - * @author emeroad - */ -public class DefaultMethodDescriptor implements MethodDescriptor { - private String className; - - private String methodName; - - private String[] parameterTypes; - - private String[] parameterVariableName; - - - private String parameterDescriptor; - - private String apiDescriptor; - - private int lineNumber; - - private int apiId = 0; - - private String fullName; - - public DefaultMethodDescriptor() { - } - - public DefaultMethodDescriptor(String className, String methodName, String[] parameterTypes, String[] parameterVariableName) { - this.className = className; - this.methodName = methodName; - this.parameterTypes = parameterTypes; - this.parameterVariableName = parameterVariableName; - this.parameterDescriptor = ApiUtils.mergeParameterVariableNameDescription(parameterTypes, parameterVariableName); - this.apiDescriptor = ApiUtils.mergeApiDescriptor(className, methodName, parameterDescriptor); - } - - public String getParameterDescriptor() { - return parameterDescriptor; - } - - public void setParameterDescriptor(String parameterDescriptor) { - this.parameterDescriptor = parameterDescriptor; - } - - - public void setMethodName(String methodName) { - this.methodName = methodName; - } - - public void setParameterTypes(String[] parameterTypes) { - this.parameterTypes = parameterTypes; - } - - public void setParameterVariableName(String[] parameterVariableName) { - this.parameterVariableName = parameterVariableName; - } - - public void setLineNumber(int lineNumber) { - this.lineNumber = lineNumber; - } - - @Override - public String getMethodName() { - return methodName; - } - - @Override - public String getClassName() { - return className; - } - - - public void setClassName(String className) { - this.className = className; - } - - @Override - public String[] getParameterTypes() { - return parameterTypes; - } - - @Override - public String[] getParameterVariableName() { - return parameterVariableName; - } - - - public int getLineNumber() { - return lineNumber; - } - - @Override - public String getFullName() { - if (fullName != null) { - return fullName; - } - StringBuilder buffer = new StringBuilder(256); - buffer.append(className); - buffer.append("."); - buffer.append(methodName); - buffer.append(parameterDescriptor); - if (lineNumber != -1) { - buffer.append(":"); - buffer.append(lineNumber); - } - fullName = buffer.toString(); - return fullName; - } - - public void setApiDescriptor(String apiDescriptor) { - this.apiDescriptor = apiDescriptor; - } - - @Override - public String getApiDescriptor() { - return apiDescriptor; - } - - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } - - @Override - public int getApiId() { - return apiId; - } - - - @Override - public String toString() { - return "DefaultMethodDescriptor{" + - "className='" + className + '\'' + - ", methodName='" + methodName + '\'' + - ", parameterTypes=" + (parameterTypes == null ? null : Arrays.asList(parameterTypes)) + - ", parameterVariableName=" + (parameterVariableName == null ? null : Arrays.asList(parameterVariableName)) + - ", parameterDescriptor='" + parameterDescriptor + '\'' + - ", apiDescriptor='" + apiDescriptor + '\'' + - ", lineNumber=" + lineNumber + - ", apiId=" + apiId + - ", fullName='" + fullName + '\'' + - '}'; - } -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.profiler.util.ApiUtils; + +import java.util.Arrays; + +/** + * @author emeroad + */ +public class DefaultMethodDescriptor implements MethodDescriptor { + private String className; + + private String methodName; + + private String[] parameterTypes; + + private String[] parameterVariableName; + + + private String parameterDescriptor; + + private String apiDescriptor; + + private int lineNumber; + + private int apiId = 0; + + private String fullName; + + public DefaultMethodDescriptor() { + } + + public DefaultMethodDescriptor(String className, String methodName, String[] parameterTypes, String[] parameterVariableName) { + this.className = className; + this.methodName = methodName; + this.parameterTypes = parameterTypes; + this.parameterVariableName = parameterVariableName; + this.parameterDescriptor = ApiUtils.mergeParameterVariableNameDescription(parameterTypes, parameterVariableName); + this.apiDescriptor = ApiUtils.mergeApiDescriptor(className, methodName, parameterDescriptor); + } + + public String getParameterDescriptor() { + return parameterDescriptor; + } + + public void setParameterDescriptor(String parameterDescriptor) { + this.parameterDescriptor = parameterDescriptor; + } + + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public void setParameterTypes(String[] parameterTypes) { + this.parameterTypes = parameterTypes; + } + + public void setParameterVariableName(String[] parameterVariableName) { + this.parameterVariableName = parameterVariableName; + } + + public void setLineNumber(int lineNumber) { + this.lineNumber = lineNumber; + } + + @Override + public String getMethodName() { + return methodName; + } + + @Override + public String getClassName() { + return className; + } + + + public void setClassName(String className) { + this.className = className; + } + + @Override + public String[] getParameterTypes() { + return parameterTypes; + } + + @Override + public String[] getParameterVariableName() { + return parameterVariableName; + } + + + public int getLineNumber() { + return lineNumber; + } + + @Override + public String getFullName() { + if (fullName != null) { + return fullName; + } + StringBuilder buffer = new StringBuilder(256); + buffer.append(className); + buffer.append("."); + buffer.append(methodName); + buffer.append(parameterDescriptor); + if (lineNumber != -1) { + buffer.append(":"); + buffer.append(lineNumber); + } + fullName = buffer.toString(); + return fullName; + } + + public void setApiDescriptor(String apiDescriptor) { + this.apiDescriptor = apiDescriptor; + } + + @Override + public String getApiDescriptor() { + return apiDescriptor; + } + + @Override + public void setApiId(int apiId) { + this.apiId = apiId; + } + + @Override + public int getApiId() { + return apiId; + } + + + @Override + public String toString() { + return "DefaultMethodDescriptor{" + + "className='" + className + '\'' + + ", methodName='" + methodName + '\'' + + ", parameterTypes=" + (parameterTypes == null ? null : Arrays.asList(parameterTypes)) + + ", parameterVariableName=" + (parameterVariableName == null ? null : Arrays.asList(parameterVariableName)) + + ", parameterDescriptor='" + parameterDescriptor + '\'' + + ", apiDescriptor='" + apiDescriptor + '\'' + + ", lineNumber=" + lineNumber + + ", apiId=" + apiId + + ", fullName='" + fullName + '\'' + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateSimpleInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateSimpleInterceptor.java index fc707f5918e6..28464ca3961d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateSimpleInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateSimpleInterceptor.java @@ -1,62 +1,62 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.profiler.util.DepthScope; -import com.nhn.pinpoint.profiler.util.Scope; - -/** - * @author emeroad - */ -public class ScopeDelegateSimpleInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { - - private final SimpleAroundInterceptor delegate; - private final Scope scope; - - - public ScopeDelegateSimpleInterceptor(SimpleAroundInterceptor delegate, Scope scope) { - if (delegate == null) { - throw new NullPointerException("delegate must not be null"); - } - if (scope == null) { - throw new NullPointerException("scope must not be null"); - } - this.delegate = delegate; - this.scope = scope; - } - - @Override - public void before(Object target, Object[] args) { - final int push = scope.push(); - if (push != DepthScope.ZERO) { - return; - } - this.delegate.before(target, args); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - final int pop = scope.pop(); - if (pop != DepthScope.ZERO) { - return; - } - this.delegate.after(target, args, result, throwable); - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - if (this.delegate instanceof ByteCodeMethodDescriptorSupport) { - ((ByteCodeMethodDescriptorSupport) this.delegate).setMethodDescriptor(descriptor); - } - } - - @Override - public void setTraceContext(TraceContext traceContext) { - if (this.delegate instanceof TraceContextSupport) { - ((TraceContextSupport) this.delegate).setTraceContext(traceContext); - } - } -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.profiler.util.DepthScope; +import com.nhn.pinpoint.profiler.util.Scope; + +/** + * @author emeroad + */ +public class ScopeDelegateSimpleInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { + + private final SimpleAroundInterceptor delegate; + private final Scope scope; + + + public ScopeDelegateSimpleInterceptor(SimpleAroundInterceptor delegate, Scope scope) { + if (delegate == null) { + throw new NullPointerException("delegate must not be null"); + } + if (scope == null) { + throw new NullPointerException("scope must not be null"); + } + this.delegate = delegate; + this.scope = scope; + } + + @Override + public void before(Object target, Object[] args) { + final int push = scope.push(); + if (push != DepthScope.ZERO) { + return; + } + this.delegate.before(target, args); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + final int pop = scope.pop(); + if (pop != DepthScope.ZERO) { + return; + } + this.delegate.after(target, args, result, throwable); + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + if (this.delegate instanceof ByteCodeMethodDescriptorSupport) { + ((ByteCodeMethodDescriptorSupport) this.delegate).setMethodDescriptor(descriptor); + } + } + + @Override + public void setTraceContext(TraceContext traceContext) { + if (this.delegate instanceof TraceContextSupport) { + ((TraceContextSupport) this.delegate).setTraceContext(traceContext); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateStaticInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateStaticInterceptor.java index 71e965d42d9d..f0d074b3686b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateStaticInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/ScopeDelegateStaticInterceptor.java @@ -1,56 +1,56 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.profiler.util.DepthScope; -import com.nhn.pinpoint.profiler.util.Scope; - -/** - * @author emeroad - */ -public class ScopeDelegateStaticInterceptor implements StaticAroundInterceptor, TraceContextSupport { - private final StaticAroundInterceptor delegate; - private final Scope scope; - - - public ScopeDelegateStaticInterceptor(StaticAroundInterceptor delegate, Scope scope) { - if (delegate == null) { - throw new NullPointerException("delegate must not be null"); - } - if (scope == null) { - throw new NullPointerException("scope must not be null"); - } - this.delegate = delegate; - this.scope = scope; - } - - @Override - public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { - final int push = scope.push(); - if (push != DepthScope.ZERO) { - return; - } - this.delegate.before(target, className, methodName, parameterDescription, args); - } - - @Override - public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - final int pop = scope.pop(); - if (pop != DepthScope.ZERO) { - return; - } - this.delegate.after(target, className, methodName, parameterDescription, args, result, throwable); - } - - - @Override - public void setTraceContext(TraceContext traceContext) { - if (this.delegate instanceof TraceContextSupport) { - ((TraceContextSupport) this.delegate).setTraceContext(traceContext); - } - } - - - -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.profiler.util.DepthScope; +import com.nhn.pinpoint.profiler.util.Scope; + +/** + * @author emeroad + */ +public class ScopeDelegateStaticInterceptor implements StaticAroundInterceptor, TraceContextSupport { + private final StaticAroundInterceptor delegate; + private final Scope scope; + + + public ScopeDelegateStaticInterceptor(StaticAroundInterceptor delegate, Scope scope) { + if (delegate == null) { + throw new NullPointerException("delegate must not be null"); + } + if (scope == null) { + throw new NullPointerException("scope must not be null"); + } + this.delegate = delegate; + this.scope = scope; + } + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + final int push = scope.push(); + if (push != DepthScope.ZERO) { + return; + } + this.delegate.before(target, className, methodName, parameterDescription, args); + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + final int pop = scope.pop(); + if (pop != DepthScope.ZERO) { + return; + } + this.delegate.after(target, className, methodName, parameterDescription, args, result, throwable); + } + + + @Override + public void setTraceContext(TraceContext traceContext) { + if (this.delegate instanceof TraceContextSupport) { + ((TraceContextSupport) this.delegate).setTraceContext(traceContext); + } + } + + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ByteCodeInstrumentor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ByteCodeInstrumentor.java index d3598e795760..df847973cdb6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ByteCodeInstrumentor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ByteCodeInstrumentor.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import java.security.ProtectionDomain; - -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.profiler.util.Scope; - -/** - * @author emeroad - */ -public interface ByteCodeInstrumentor { - - - void checkLibrary(ClassLoader classLoader, String javassistClassName); - - InstrumentClass getClass(String javassistClassName) throws InstrumentException; - - Scope getScope(String scopeName); - - Class defineClass(ClassLoader classLoader, String defineClass, ProtectionDomain protectedDomain) throws InstrumentException; - - Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN) throws InstrumentException; - -// Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN, Object[] params) throws InstrumentException; - - Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN, Object[] params, Class[] paramClazz) throws InstrumentException; -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import java.security.ProtectionDomain; + +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.profiler.util.Scope; + +/** + * @author emeroad + */ +public interface ByteCodeInstrumentor { + + + void checkLibrary(ClassLoader classLoader, String javassistClassName); + + InstrumentClass getClass(String javassistClassName) throws InstrumentException; + + Scope getScope(String scopeName); + + Class defineClass(ClassLoader classLoader, String defineClass, ProtectionDomain protectedDomain) throws InstrumentException; + + Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN) throws InstrumentException; + +// Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN, Object[] params) throws InstrumentException; + + Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN, Object[] params, Class[] paramClazz) throws InstrumentException; +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ClassLoadChecker.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ClassLoadChecker.java index 4e009628e67d..d0936045a331 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ClassLoadChecker.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/ClassLoadChecker.java @@ -1,68 +1,68 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class ClassLoadChecker { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private static final Object EXIST = new Object(); - - private final ConcurrentMap load = new ConcurrentHashMap(); - - public boolean exist(ClassLoader cl, String className) { - LoadClass key = new LoadClass(cl, className); - Object old = load.putIfAbsent(key, EXIST); - if (old == null) { - if (isDebug) { - logger.debug("{} not exist from ", cl); - } - return false; - } - if (isDebug) { - logger.debug("{} already exist from ", cl); - } - return true; - } - - private static class LoadClass { - private final ClassLoader classLoader; - private final String className; - - private LoadClass(ClassLoader classLoader, String className) { - if (className == null) { - throw new NullPointerException("className must not be null"); - } - // classLoader는 null일수도 있을거 같음. 몇몇 java reference의 최상위 로더의 경우 null 이 나옴. - this.classLoader = classLoader; - this.className = className; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - LoadClass loadClass = (LoadClass) o; - - if (classLoader != null ? !classLoader.equals(loadClass.classLoader) : loadClass.classLoader != null) return false; - if (!className.equals(loadClass.className)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = classLoader != null ? classLoader.hashCode() : 0; - result = 31 * result + className.hashCode(); - return result; - } - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class ClassLoadChecker { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private static final Object EXIST = new Object(); + + private final ConcurrentMap load = new ConcurrentHashMap(); + + public boolean exist(ClassLoader cl, String className) { + LoadClass key = new LoadClass(cl, className); + Object old = load.putIfAbsent(key, EXIST); + if (old == null) { + if (isDebug) { + logger.debug("{} not exist from ", cl); + } + return false; + } + if (isDebug) { + logger.debug("{} already exist from ", cl); + } + return true; + } + + private static class LoadClass { + private final ClassLoader classLoader; + private final String className; + + private LoadClass(ClassLoader classLoader, String className) { + if (className == null) { + throw new NullPointerException("className must not be null"); + } + // classLoader는 null일수도 있을거 같음. 몇몇 java reference의 최상위 로더의 경우 null 이 나옴. + this.classLoader = classLoader; + this.className = className; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + LoadClass loadClass = (LoadClass) o; + + if (classLoader != null ? !classLoader.equals(loadClass.classLoader) : loadClass.classLoader != null) return false; + if (!className.equals(loadClass.className)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = classLoader != null ? classLoader.hashCode() : 0; + result = 31 * result + className.hashCode(); + return result; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilder.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilder.java index e4cfac833b72..544d7fb69e0f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilder.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilder.java @@ -1,42 +1,42 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import java.util.Formatter; - -/** - * @author emeroad - */ -public class CodeBuilder { - - private final StringBuilder codeBlock; - private final Formatter formatter; - - public CodeBuilder() { - this(1024); - } - - public CodeBuilder(int bufferSize) { - this.codeBlock = new StringBuilder(bufferSize); - this.formatter = new Formatter(codeBlock); - } - - public void begin() { - codeBlock.append('{'); - } - - public void end() { - codeBlock.append('}'); - } - - public void append(String code) { - codeBlock.append(code); - } - - public void format(String format, Object... args) { - formatter.format(format, args); - } - - public String toString() { - return codeBlock.toString(); - } - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import java.util.Formatter; + +/** + * @author emeroad + */ +public class CodeBuilder { + + private final StringBuilder codeBlock; + private final Formatter formatter; + + public CodeBuilder() { + this(1024); + } + + public CodeBuilder(int bufferSize) { + this.codeBlock = new StringBuilder(bufferSize); + this.formatter = new Formatter(codeBlock); + } + + public void begin() { + codeBlock.append('{'); + } + + public void end() { + codeBlock.append('}'); + } + + public void append(String code) { + codeBlock.append(code); + } + + public void format(String format, Object... args) { + formatter.format(format, args); + } + + public String toString() { + return codeBlock.toString(); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentClass.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentClass.java index bf2e1639cdab..a120e3187bb2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentClass.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentClass.java @@ -1,106 +1,106 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue; -import com.nhn.pinpoint.profiler.util.DepthScope; -import com.nhn.pinpoint.profiler.util.Scope; - -import java.util.List; - -/** - * @author emeroad - * @author netspider - */ -public interface InstrumentClass { - - boolean isInterface(); - - String getName(); - - boolean insertCodeBeforeMethod(String methodName, String[] args, String code); - - boolean insertCodeAfterMethod(String methodName, String[] args, String code); - - int addAllConstructorInterceptor(Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; - - int addAllConstructorInterceptor(Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; - - int addConstructorInterceptor(String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; - - int addConstructorInterceptor(String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; - - int reuseInterceptor(String methodName, String[] args, int interceptorId) throws InstrumentException, NotFoundInstrumentException; - - int reuseInterceptor(String methodName, String[] args, int interceptorId, Type type) throws InstrumentException, NotFoundInstrumentException; - - - int addInterceptor(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; - - int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException, NotFoundInstrumentException; - - int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException, NotFoundInstrumentException; - - int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException; - /** - * methodName, args가 일치하는 메소드가 클래스에 구현되어있는 경우에만 scope interceptor를 적용합니다. - * - * @param methodName - * @param args - * @param interceptor - * @param scope - * @return - * @throws InstrumentException - */ - int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException; - - int addInterceptor(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; - - int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; - - int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; - - boolean addDebugLogBeforeAfterMethod(); - - boolean addDebugLogBeforeAfterConstructor(); - - byte[] toBytecode() throws InstrumentException ; - - Class toClass() throws InstrumentException; - - /** - * 대신 addTraceValue 를 사용하라. - */ - @Deprecated - void addTraceVariable(String variableName, String setterName, String getterName, String variableType, String initValue) throws InstrumentException; - - /** - * 대신 addTraceValue 를 사용하라. - */ - @Deprecated - void addTraceVariable(String variableName, String setterName, String getterName, String variableType) throws InstrumentException; - - void addTraceValue(Class traceValue, String initValue) throws InstrumentException; - - void addTraceValue(Class traceValue) throws InstrumentException; - - boolean insertCodeAfterConstructor(String[] args, String code); - - boolean insertCodeBeforeConstructor(String[] args, String code); - - List getDeclaredMethods() throws NotFoundInstrumentException; - - List getDeclaredMethods(MethodFilter methodFilter) throws NotFoundInstrumentException; - - public boolean isInterceptable(); - - boolean hasDeclaredMethod(String methodName, String[] args); - - @Deprecated - boolean hasMethod(String methodName, String[] args); - - boolean hasMethod(String methodName, String desc); - - InstrumentClass getNestedClass(String className); - - void addGetter(String getterName, String fieldName, String fieldType) throws InstrumentException; -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue; +import com.nhn.pinpoint.profiler.util.DepthScope; +import com.nhn.pinpoint.profiler.util.Scope; + +import java.util.List; + +/** + * @author emeroad + * @author netspider + */ +public interface InstrumentClass { + + boolean isInterface(); + + String getName(); + + boolean insertCodeBeforeMethod(String methodName, String[] args, String code); + + boolean insertCodeAfterMethod(String methodName, String[] args, String code); + + int addAllConstructorInterceptor(Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; + + int addAllConstructorInterceptor(Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; + + int addConstructorInterceptor(String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; + + int addConstructorInterceptor(String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; + + int reuseInterceptor(String methodName, String[] args, int interceptorId) throws InstrumentException, NotFoundInstrumentException; + + int reuseInterceptor(String methodName, String[] args, int interceptorId, Type type) throws InstrumentException, NotFoundInstrumentException; + + + int addInterceptor(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; + + int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException, NotFoundInstrumentException; + + int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException, NotFoundInstrumentException; + + int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException; + /** + * methodName, args가 일치하는 메소드가 클래스에 구현되어있는 경우에만 scope interceptor를 적용합니다. + * + * @param methodName + * @param args + * @param interceptor + * @param scope + * @return + * @throws InstrumentException + */ + int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException; + + int addInterceptor(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; + + int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException; + + int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException; + + boolean addDebugLogBeforeAfterMethod(); + + boolean addDebugLogBeforeAfterConstructor(); + + byte[] toBytecode() throws InstrumentException ; + + Class toClass() throws InstrumentException; + + /** + * 대신 addTraceValue 를 사용하라. + */ + @Deprecated + void addTraceVariable(String variableName, String setterName, String getterName, String variableType, String initValue) throws InstrumentException; + + /** + * 대신 addTraceValue 를 사용하라. + */ + @Deprecated + void addTraceVariable(String variableName, String setterName, String getterName, String variableType) throws InstrumentException; + + void addTraceValue(Class traceValue, String initValue) throws InstrumentException; + + void addTraceValue(Class traceValue) throws InstrumentException; + + boolean insertCodeAfterConstructor(String[] args, String code); + + boolean insertCodeBeforeConstructor(String[] args, String code); + + List getDeclaredMethods() throws NotFoundInstrumentException; + + List getDeclaredMethods(MethodFilter methodFilter) throws NotFoundInstrumentException; + + public boolean isInterceptable(); + + boolean hasDeclaredMethod(String methodName, String[] args); + + @Deprecated + boolean hasMethod(String methodName, String[] args); + + boolean hasMethod(String methodName, String desc); + + InstrumentClass getNestedClass(String className); + + void addGetter(String getterName, String fieldName, String fieldType) throws InstrumentException; +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentException.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentException.java index e05e788d4536..cc165b64ca61 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentException.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/InstrumentException.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -// TODO 추후 별도 계층구조가 필요하면 분화 필요. -/** - * @author emeroad - */ -public class InstrumentException extends Exception { - - private static final long serialVersionUID = 7594176009977030312L; - - public InstrumentException() { - } - - public InstrumentException(String message) { - super(message); - } - - public InstrumentException(String message, Throwable cause) { - super(message, cause); - } - - public InstrumentException(Throwable cause) { - super(cause); - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +// TODO 추후 별도 계층구조가 필요하면 분화 필요. +/** + * @author emeroad + */ +public class InstrumentException extends Exception { + + private static final long serialVersionUID = 7594176009977030312L; + + public InstrumentException() { + } + + public InstrumentException(String message) { + super(message); + } + + public InstrumentException(String message, Throwable cause) { + super(message, cause); + } + + public InstrumentException(Throwable cause) { + super(cause); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistByteCodeInstrumentor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistByteCodeInstrumentor.java index 433f6aae8bc8..fb8a2705bfc2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistByteCodeInstrumentor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistByteCodeInstrumentor.java @@ -1,266 +1,266 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.net.URLClassLoader; -import java.security.ProtectionDomain; - - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.profiler.util.Scope; -import com.nhn.pinpoint.profiler.util.ScopePool; -import javassist.CannotCompileException; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.NotFoundException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class JavaAssistByteCodeInstrumentor implements ByteCodeInstrumentor { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final boolean isInfo = logger.isInfoEnabled(); - private final boolean isDebug = logger.isDebugEnabled(); - - private final NamedClassPool rootClassPool; - // classPool의 수평적 확장이 필요할수 있음. was에 여러개의 webapp가 있을 경우 충돌방지. - private final NamedClassPool childClassPool; - - private Agent agent; - - private final ScopePool scopePool = new ScopePool(); - - private final ClassLoadChecker classLoadChecker = new ClassLoadChecker(); - - public JavaAssistByteCodeInstrumentor() { - this.rootClassPool = createClassPool(null, "rootClassPool"); - this.childClassPool = new NamedClassPool(rootClassPool, "childClassPool"); - } - - public JavaAssistByteCodeInstrumentor(String[] pathNames, Agent agent) { - this.rootClassPool = createClassPool(pathNames, "rootClassPool"); - this.childClassPool = createChildClassPool(rootClassPool, "childClassPool"); - this.agent = agent; - // agent의 class는 rootClassPool에 넣는다. - checkLibrary(this.getClass().getClassLoader(), this.rootClassPool, this.getClass().getName()); - } - - public Agent getAgent() { - return agent; - } - - public ClassPool getClassPool() { - return this.childClassPool; - } - - @Override - public Scope getScope(String scopeName) { - return this.scopePool.getScope(scopeName); - } - - private NamedClassPool createClassPool(String[] pathNames, String classPoolName) { - NamedClassPool classPool = new NamedClassPool(null, classPoolName); - classPool.appendSystemPath(); - if (pathNames != null) { - for (String path : pathNames) { - appendClassPath(classPool, path); - } - } - return classPool; - } - - private NamedClassPool createChildClassPool(ClassPool rootClassPool, String classPoolName) { - NamedClassPool childClassPool = new NamedClassPool(rootClassPool, classPoolName); - childClassPool.appendSystemPath(); - childClassPool.childFirstLookup = true; - return childClassPool; - } - - - private void appendClassPath(ClassPool classPool, String pathName) { - try { - classPool.appendClassPath(pathName); - } catch (NotFoundException e) { - if (logger.isWarnEnabled()) { - logger.warn("appendClassPath fail. lib not found. {}", e.getMessage(), e); - } - } - } - - public void checkLibrary(ClassLoader classLoader, String javassistClassName) { - checkLibrary(classLoader, this.childClassPool, javassistClassName); - } - - public void checkLibrary(ClassLoader classLoader, NamedClassPool classPool, String javassistClassName) { - // 최상위 classLoader일 경우 null이라 찾을필요가 없음. - if (classLoader == null) { - return; - } - // TODO Util로 뽑을까? - boolean findClass = findClass(javassistClassName, classPool); - if (findClass) { - if (isDebug) { - logger.debug("checkLibrary cl:{} clPool:{}, class:{} found.", classLoader, classPool.getName(), javassistClassName); - } - return; - } - loadClassLoaderLibraries(classLoader, classPool); - } - - @Override - public InstrumentClass getClass(String javassistClassName) throws InstrumentException { - try { - CtClass cc = childClassPool.get(javassistClassName); - return new JavaAssistClass(this, cc); - } catch (NotFoundException e) { - throw new InstrumentException(javassistClassName + " class not found. Cause:" + e.getMessage(), e); - } - } - - @Override - public Class defineClass(ClassLoader classLoader, String defineClass, ProtectionDomain protectedDomain) throws InstrumentException { - if (isInfo) { - logger.info("defineClass class:{}, cl:{}", defineClass, classLoader); - } - try { - // classLoader로 락을 잡는게 안전함. - // 어차피 classLoader에서 락을 잡고 들어오는점도 있고. 예외 사항이 발생할수 있기 때문에. - // classLoader의 재진입 락을 잡고 들어오는게 무난함. - synchronized (classLoader) { - if (this.classLoadChecker.exist(classLoader, defineClass)) { - return classLoader.loadClass(defineClass); - } else { - final CtClass clazz = childClassPool.get(defineClass); - - // 로그 레벨을 debug로 하니 개발때 제대로 체크 안하는 사람이 있어서 수정함. - checkTargetClassInterface(clazz); - - defineAbstractSuperClass(clazz, classLoader, protectedDomain); - defineNestedClass(clazz, classLoader, protectedDomain); - return clazz.toClass(classLoader, protectedDomain); - } - } - } catch (NotFoundException e) { - throw new InstrumentException(defineClass + " class not found. Cause:" + e.getMessage(), e); - } catch (CannotCompileException e) { - throw new InstrumentException(defineClass + " class define fail. cl:" + classLoader + " Cause:" + e.getMessage(), e); - } catch (ClassNotFoundException e) { - throw new InstrumentException(defineClass + " class not found. Cause:" + e.getMessage(), e); - } - } - - private void checkTargetClassInterface(CtClass clazz) throws NotFoundException, InstrumentException { - final String name = TargetClassLoader.class.getName(); - final CtClass[] interfaces = clazz.getInterfaces(); - for (CtClass anInterface : interfaces) { - if (name.equals(anInterface.getName())) { - return; - } - } - throw new InstrumentException("newInterceptor() not support. " + clazz.getName()); - } - - private void defineAbstractSuperClass(CtClass clazz, ClassLoader classLoader, ProtectionDomain protectedDomain) throws NotFoundException, CannotCompileException { - final CtClass superClass = clazz.getSuperclass(); - if (superClass == null) { - // java.lang.Object가 아닌 경우 null은 안나올듯. - return; - } - final int modifiers = superClass.getModifiers(); - if (Modifier.isAbstract(modifiers)) { - if (this.classLoadChecker.exist(classLoader, superClass.getName())) { - // nestedClass는 자기 자신에게만 속해 있으므로 로드 여부 체크가 필요 없으나 abstractClass는 같이 사용할수 있으므로 체크해야 된다. - return; - } - if (isInfo) { - logger.info("defineAbstractSuperClass class:{} cl:{}", superClass.getName(), classLoader); - } - // 좀더 정확하게 java 스펙처럼 하려면 제귀를 돌면서 추가로 super를 확인해야 되나. 구지 그래야 되나 싶다. 패스. - // 스펙상 1차원 abstractClass만 지원하는 것으로.. - superClass.toClass(classLoader, protectedDomain); - } - } - - private void defineNestedClass(CtClass clazz, ClassLoader classLoader, ProtectionDomain protectedDomain) throws NotFoundException, CannotCompileException { - CtClass[] nestedClasses = clazz.getNestedClasses(); - if (nestedClasses.length == 0) { - return; - } - for (CtClass nested : nestedClasses) { - // 재귀하면서 최하위부터 로드 - defineNestedClass(nested, classLoader, protectedDomain); - if (isInfo) { - logger.info("defineNestedClass class:{} cl:{}", nested.getName(), classLoader); - } - nested.toClass(classLoader, protectedDomain); - } - } - - public boolean findClass(String javassistClassName, ClassPool classPool) { - URL url = classPool.find(javassistClassName); - if (url == null) { - return false; - } - return true; - } - - @Override - public Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN) throws InstrumentException { - Class aClass = this.defineClass(classLoader, interceptorFQCN, protectedDomain); - try { - return (Interceptor) aClass.newInstance(); - } catch (InstantiationException e) { - throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); - } - } - - @Override - public Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN, Object[] params, Class[] paramClazz) throws InstrumentException { - Class aClass = this.defineClass(classLoader, interceptorFQCN, protectedDomain); - try { - Constructor constructor = aClass.getConstructor(paramClazz); - return (Interceptor) constructor.newInstance(params); - } catch (InstantiationException e) { - throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); - } catch (NoSuchMethodException e) { - throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); - } catch (InvocationTargetException e) { - throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); - } - - } - - private void loadClassLoaderLibraries(ClassLoader classLoader, NamedClassPool classPool) { - if (classLoader instanceof URLClassLoader) { - URLClassLoader urlClassLoader = (URLClassLoader) classLoader; - // classLoader가 가지고 있는 전체 리소스를 가능한 패스로 다 걸어야 됨 - // 임의의 class가 없을 경우 class의 byte code를 classpool에 적재 할 수 없음. - URL[] urlList = urlClassLoader.getURLs(); - for (URL tempURL : urlList) { - String filePath = tempURL.getFile(); - try { - classPool.appendClassPath(filePath); - // 만약 한개만 로딩해도 된다면. return true 할것 - if (isInfo) { - logger.info("Loaded cl:{} classPool:{} {} ", classLoader.getClass().getName(), classPool.getName(), filePath); - } - } catch (NotFoundException e) { - if (logger.isWarnEnabled()) { - logger.warn("lib load fail. path:{} cl:{} clPool:{}, Cause:{}", filePath, classLoader, classPool.getName(), e.getMessage(), e); - } - } - } - } - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.ProtectionDomain; + + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.profiler.util.Scope; +import com.nhn.pinpoint.profiler.util.ScopePool; +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.NotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class JavaAssistByteCodeInstrumentor implements ByteCodeInstrumentor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final boolean isInfo = logger.isInfoEnabled(); + private final boolean isDebug = logger.isDebugEnabled(); + + private final NamedClassPool rootClassPool; + // classPool의 수평적 확장이 필요할수 있음. was에 여러개의 webapp가 있을 경우 충돌방지. + private final NamedClassPool childClassPool; + + private Agent agent; + + private final ScopePool scopePool = new ScopePool(); + + private final ClassLoadChecker classLoadChecker = new ClassLoadChecker(); + + public JavaAssistByteCodeInstrumentor() { + this.rootClassPool = createClassPool(null, "rootClassPool"); + this.childClassPool = new NamedClassPool(rootClassPool, "childClassPool"); + } + + public JavaAssistByteCodeInstrumentor(String[] pathNames, Agent agent) { + this.rootClassPool = createClassPool(pathNames, "rootClassPool"); + this.childClassPool = createChildClassPool(rootClassPool, "childClassPool"); + this.agent = agent; + // agent의 class는 rootClassPool에 넣는다. + checkLibrary(this.getClass().getClassLoader(), this.rootClassPool, this.getClass().getName()); + } + + public Agent getAgent() { + return agent; + } + + public ClassPool getClassPool() { + return this.childClassPool; + } + + @Override + public Scope getScope(String scopeName) { + return this.scopePool.getScope(scopeName); + } + + private NamedClassPool createClassPool(String[] pathNames, String classPoolName) { + NamedClassPool classPool = new NamedClassPool(null, classPoolName); + classPool.appendSystemPath(); + if (pathNames != null) { + for (String path : pathNames) { + appendClassPath(classPool, path); + } + } + return classPool; + } + + private NamedClassPool createChildClassPool(ClassPool rootClassPool, String classPoolName) { + NamedClassPool childClassPool = new NamedClassPool(rootClassPool, classPoolName); + childClassPool.appendSystemPath(); + childClassPool.childFirstLookup = true; + return childClassPool; + } + + + private void appendClassPath(ClassPool classPool, String pathName) { + try { + classPool.appendClassPath(pathName); + } catch (NotFoundException e) { + if (logger.isWarnEnabled()) { + logger.warn("appendClassPath fail. lib not found. {}", e.getMessage(), e); + } + } + } + + public void checkLibrary(ClassLoader classLoader, String javassistClassName) { + checkLibrary(classLoader, this.childClassPool, javassistClassName); + } + + public void checkLibrary(ClassLoader classLoader, NamedClassPool classPool, String javassistClassName) { + // 최상위 classLoader일 경우 null이라 찾을필요가 없음. + if (classLoader == null) { + return; + } + // TODO Util로 뽑을까? + boolean findClass = findClass(javassistClassName, classPool); + if (findClass) { + if (isDebug) { + logger.debug("checkLibrary cl:{} clPool:{}, class:{} found.", classLoader, classPool.getName(), javassistClassName); + } + return; + } + loadClassLoaderLibraries(classLoader, classPool); + } + + @Override + public InstrumentClass getClass(String javassistClassName) throws InstrumentException { + try { + CtClass cc = childClassPool.get(javassistClassName); + return new JavaAssistClass(this, cc); + } catch (NotFoundException e) { + throw new InstrumentException(javassistClassName + " class not found. Cause:" + e.getMessage(), e); + } + } + + @Override + public Class defineClass(ClassLoader classLoader, String defineClass, ProtectionDomain protectedDomain) throws InstrumentException { + if (isInfo) { + logger.info("defineClass class:{}, cl:{}", defineClass, classLoader); + } + try { + // classLoader로 락을 잡는게 안전함. + // 어차피 classLoader에서 락을 잡고 들어오는점도 있고. 예외 사항이 발생할수 있기 때문에. + // classLoader의 재진입 락을 잡고 들어오는게 무난함. + synchronized (classLoader) { + if (this.classLoadChecker.exist(classLoader, defineClass)) { + return classLoader.loadClass(defineClass); + } else { + final CtClass clazz = childClassPool.get(defineClass); + + // 로그 레벨을 debug로 하니 개발때 제대로 체크 안하는 사람이 있어서 수정함. + checkTargetClassInterface(clazz); + + defineAbstractSuperClass(clazz, classLoader, protectedDomain); + defineNestedClass(clazz, classLoader, protectedDomain); + return clazz.toClass(classLoader, protectedDomain); + } + } + } catch (NotFoundException e) { + throw new InstrumentException(defineClass + " class not found. Cause:" + e.getMessage(), e); + } catch (CannotCompileException e) { + throw new InstrumentException(defineClass + " class define fail. cl:" + classLoader + " Cause:" + e.getMessage(), e); + } catch (ClassNotFoundException e) { + throw new InstrumentException(defineClass + " class not found. Cause:" + e.getMessage(), e); + } + } + + private void checkTargetClassInterface(CtClass clazz) throws NotFoundException, InstrumentException { + final String name = TargetClassLoader.class.getName(); + final CtClass[] interfaces = clazz.getInterfaces(); + for (CtClass anInterface : interfaces) { + if (name.equals(anInterface.getName())) { + return; + } + } + throw new InstrumentException("newInterceptor() not support. " + clazz.getName()); + } + + private void defineAbstractSuperClass(CtClass clazz, ClassLoader classLoader, ProtectionDomain protectedDomain) throws NotFoundException, CannotCompileException { + final CtClass superClass = clazz.getSuperclass(); + if (superClass == null) { + // java.lang.Object가 아닌 경우 null은 안나올듯. + return; + } + final int modifiers = superClass.getModifiers(); + if (Modifier.isAbstract(modifiers)) { + if (this.classLoadChecker.exist(classLoader, superClass.getName())) { + // nestedClass는 자기 자신에게만 속해 있으므로 로드 여부 체크가 필요 없으나 abstractClass는 같이 사용할수 있으므로 체크해야 된다. + return; + } + if (isInfo) { + logger.info("defineAbstractSuperClass class:{} cl:{}", superClass.getName(), classLoader); + } + // 좀더 정확하게 java 스펙처럼 하려면 제귀를 돌면서 추가로 super를 확인해야 되나. 구지 그래야 되나 싶다. 패스. + // 스펙상 1차원 abstractClass만 지원하는 것으로.. + superClass.toClass(classLoader, protectedDomain); + } + } + + private void defineNestedClass(CtClass clazz, ClassLoader classLoader, ProtectionDomain protectedDomain) throws NotFoundException, CannotCompileException { + CtClass[] nestedClasses = clazz.getNestedClasses(); + if (nestedClasses.length == 0) { + return; + } + for (CtClass nested : nestedClasses) { + // 재귀하면서 최하위부터 로드 + defineNestedClass(nested, classLoader, protectedDomain); + if (isInfo) { + logger.info("defineNestedClass class:{} cl:{}", nested.getName(), classLoader); + } + nested.toClass(classLoader, protectedDomain); + } + } + + public boolean findClass(String javassistClassName, ClassPool classPool) { + URL url = classPool.find(javassistClassName); + if (url == null) { + return false; + } + return true; + } + + @Override + public Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN) throws InstrumentException { + Class aClass = this.defineClass(classLoader, interceptorFQCN, protectedDomain); + try { + return (Interceptor) aClass.newInstance(); + } catch (InstantiationException e) { + throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); + } + } + + @Override + public Interceptor newInterceptor(ClassLoader classLoader, ProtectionDomain protectedDomain, String interceptorFQCN, Object[] params, Class[] paramClazz) throws InstrumentException { + Class aClass = this.defineClass(classLoader, interceptorFQCN, protectedDomain); + try { + Constructor constructor = aClass.getConstructor(paramClazz); + return (Interceptor) constructor.newInstance(params); + } catch (InstantiationException e) { + throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); + } catch (NoSuchMethodException e) { + throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); + } catch (InvocationTargetException e) { + throw new InstrumentException(aClass + " instance create fail Cause:" + e.getMessage(), e); + } + + } + + private void loadClassLoaderLibraries(ClassLoader classLoader, NamedClassPool classPool) { + if (classLoader instanceof URLClassLoader) { + URLClassLoader urlClassLoader = (URLClassLoader) classLoader; + // classLoader가 가지고 있는 전체 리소스를 가능한 패스로 다 걸어야 됨 + // 임의의 class가 없을 경우 class의 byte code를 classpool에 적재 할 수 없음. + URL[] urlList = urlClassLoader.getURLs(); + for (URL tempURL : urlList) { + String filePath = tempURL.getFile(); + try { + classPool.appendClassPath(filePath); + // 만약 한개만 로딩해도 된다면. return true 할것 + if (isInfo) { + logger.info("Loaded cl:{} classPool:{} {} ", classLoader.getClass().getName(), classPool.getName(), filePath); + } + } catch (NotFoundException e) { + if (logger.isWarnEnabled()) { + logger.warn("lib load fail. path:{} cl:{} clPool:{}, Cause:{}", filePath, classLoader, classPool.getName(), e.getMessage(), e); + } + } + } + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java index 953dd717ecf1..4b04230418e7 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java @@ -1,978 +1,978 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue; -import com.nhn.pinpoint.profiler.util.ApiUtils; -import com.nhn.pinpoint.profiler.interceptor.*; -import com.nhn.pinpoint.profiler.util.JavaAssistUtils; - -import com.nhn.pinpoint.profiler.util.Scope; -import javassist.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - * @author netspider - */ -public class JavaAssistClass implements InstrumentClass { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private JavaAssistByteCodeInstrumentor instrumentor; - private CtClass ctClass; - private static final int STATIC_INTERCEPTOR = 0; - private static final int SIMPLE_INTERCEPTOR = 1; - - private static final int NOT_DEFINE_INTERCEPTOR_ID = -1; - - private static final String FIELD_PREFIX = "__p"; - private static final String SETTER_PREFIX = "__set"; - private static final String GETTER_PREFIX = "__get"; - private static final String MARKER_CLASS_NAME = "com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue"; - - - public JavaAssistClass(JavaAssistByteCodeInstrumentor instrumentor, CtClass ctClass) { - this.instrumentor = instrumentor; - this.ctClass = ctClass; - } - - public boolean isInterface() { - return this.ctClass.isInterface(); - } - - public String getName() { - return this.ctClass.getName(); - } - - @Override - public boolean insertCodeBeforeConstructor(String[] args, String code) { - try { - CtConstructor constructor = getConstructor(args); - constructor.insertBefore(code); - return true; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - return false; - } - } - - @Override - public boolean insertCodeAfterConstructor(String[] args, String code) { - try { - CtConstructor constructor = getConstructor(args); - constructor.insertAfter(code); - return true; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - return false; - } - } - - @Override - public boolean insertCodeBeforeMethod(String methodName, String[] args, String code) { - try { - CtMethod method = getMethod(methodName, args); - method.insertBefore(code); - return true; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - return false; - } - } - - @Override - public boolean insertCodeAfterMethod(String methodName, String[] args, String code) { - try { - CtMethod method = getMethod(methodName, args); - method.insertAfter(code); - return true; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - return false; - } - } - - @Deprecated - public void addTraceVariable(String variableName, String setterName, String getterName, String variableType, String initValue) throws InstrumentException { - addTraceVariable0(variableName, setterName, getterName, variableType, initValue); - } - - @Deprecated - public void addTraceVariable(String variableName, String setterName, String getterName, String variableType) throws InstrumentException { - addTraceVariable0(variableName, setterName, getterName, variableType, null); - } - - @Deprecated - private void addTraceVariable0(String variableName, String setterName, String getterName, String variableType, String initValue) throws InstrumentException { - try { - CtClass type = instrumentor.getClassPool().get(variableType); - CtField traceVariable = new CtField(type, variableName, ctClass); - if (initValue == null) { - ctClass.addField(traceVariable); - } else { - ctClass.addField(traceVariable, initValue); - } - if (setterName != null) { - CtMethod setterMethod = CtNewMethod.setter(setterName, traceVariable); - ctClass.addMethod(setterMethod); - } - if (getterName != null) { - CtMethod getterMethod = CtNewMethod.getter(getterName, traceVariable); - ctClass.addMethod(getterMethod); - } - } catch (NotFoundException e) { - throw new InstrumentException(variableName + " addTraceVariable fail. Cause:" + e.getMessage(), e); - } catch (CannotCompileException e) { - throw new InstrumentException(variableName + " addTraceVariable fail. Cause:" + e.getMessage(), e); - } - } - - public void addTraceValue(Class traceValue) throws InstrumentException { - addTraceValue0(traceValue, null); - } - - public void addTraceValue(Class traceValue, String initValue) throws InstrumentException { - addTraceValue0(traceValue, initValue); - } - - public void addTraceValue0(Class traceValue, String initValue) throws InstrumentException { - if (traceValue == null) { - throw new NullPointerException("traceValue must not be null"); - } - // testcase에서 classLoader가 다를수 있어서 isAssignableFrom으로 안함. - // 추가로 수정하긴해야 될듯함. - final boolean marker = checkTraceValueMarker(traceValue); - if (!marker) { - throw new InstrumentException(traceValue + " marker interface not implements" ); - } - - try { - final CtClass ctValueHandler = instrumentor.getClassPool().get(traceValue.getName()); - - final java.lang.reflect.Method[] declaredMethods = traceValue.getDeclaredMethods(); - final String variableName = FIELD_PREFIX + ctValueHandler.getSimpleName(); - - final CtField traceVariableType = determineTraceValueType(variableName, declaredMethods); - - boolean requiredField = false; - for (java.lang.reflect.Method method : declaredMethods) { - // 2개 이상의 중복일때를 체크하지 않았음. - if (isSetter(method)) { - // setter - CtMethod setterMethod = CtNewMethod.setter(method.getName(), traceVariableType); - ctClass.addMethod(setterMethod); - requiredField = true; - } else if(isGetter(method)) { - // getter - CtMethod getterMethod = CtNewMethod.getter(method.getName(), traceVariableType); - ctClass.addMethod(getterMethod); - requiredField = true; - } - } - if (requiredField) { - ctClass.addInterface(ctValueHandler); - if (initValue == null) { - ctClass.addField(traceVariableType); - } else { - ctClass.addField(traceVariableType, initValue); - } - } - - } catch (NotFoundException e) { - throw new InstrumentException(traceValue + " implements fail. Cause:" + e.getMessage(), e); - } catch (CannotCompileException e) { - throw new InstrumentException(traceValue + " implements fail. Cause:" + e.getMessage(), e); - } - } - - - - private boolean checkTraceValueMarker(Class traceValue) { - for (Class anInterface : traceValue.getInterfaces()) { - if (MARKER_CLASS_NAME.equals(anInterface.getName())) { - return true; - } - } - return false; - } - - private boolean isGetter(java.lang.reflect.Method method) { - return method.getName().startsWith(GETTER_PREFIX); - } - - private boolean isSetter(java.lang.reflect.Method method) { - return method.getName().startsWith(SETTER_PREFIX); - } - - private CtField determineTraceValueType(String variableName, java.lang.reflect.Method[] declaredMethods) throws NotFoundException, CannotCompileException, InstrumentException { - Class getterReturnType = null; - Class setterType = null; - for (java.lang.reflect.Method method : declaredMethods) { - if (isGetter(method)) { - getterReturnType = method.getReturnType(); - } else if (isSetter(method)) { - Class[] parameterTypes = method.getParameterTypes(); - if (parameterTypes.length != 1) { - throw new InstrumentException("invalid setterParameter. parameterTypes:" + Arrays.toString(parameterTypes)); - } - setterType = parameterTypes[0]; - } - } - if (getterReturnType == null && setterType == null) { - throw new InstrumentException("getter or setter not found"); - } - if (getterReturnType != null && setterType != null) { - if(!getterReturnType.equals(setterType)) { - throw new InstrumentException("invalid setter or getter parameter"); - } - } - Class resolveType; - if (getterReturnType != null) { - resolveType = getterReturnType; - } else { - resolveType = setterType; - } - CtClass type = instrumentor.getClassPool().get(resolveType.getName()); - return new CtField(type, variableName, ctClass); - } - - public int addConstructorInterceptor(String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException { - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - final CtBehavior behavior = getBehavior(null, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); - return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false); - } - - public int addConstructorInterceptor(String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - final CtBehavior behavior = getBehavior(null, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); - return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false); - } - - public int addAllConstructorInterceptor(Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException{ - return addAllConstructorInterceptor(interceptor, Type.around); - } - - public int addAllConstructorInterceptor(Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - final CtConstructor[] constructorList = ctClass.getConstructors(); - final int length = constructorList.length; - if (length == 0) { - throw new NotFoundInstrumentException("Constructor not found."); - } - int interceptorId = 0; - if (length > 0) { - interceptorId = addInterceptor0(constructorList[0], null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false); - } - if (length > 1) { - for (int i = 1; i< length; i++) { - addInterceptor0(constructorList[i], null, null, interceptorId, Type.around, false); - } - } - return interceptorId; - } - - - @Override - public int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException { - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); - return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, true); - } - - @Override - public int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); - return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, true); - } - - @Override - public int addInterceptor(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException { - if (methodName == null) { - throw new NullPointerException("methodName must not be null"); - } - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); - return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false); - } - - @Override - public int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException, NotFoundInstrumentException { - final Scope scope = this.instrumentor.getScope(scopeName); - return addScopeInterceptor(methodName, args, interceptor, scope); - } - - - @Override - public int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException, NotFoundInstrumentException { - if (methodName == null) { - throw new NullPointerException("methodName must not be null"); - } - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - if (scope == null) { - throw new NullPointerException("scope must not be null"); - } - interceptor = wrapScopeInterceptor(interceptor, scope); - return addInterceptor(methodName, args, interceptor); - } - - /* - * (non-Javadoc) - * @see com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass#addScopeInterceptorIfDeclared(java.lang.String, java.lang.String[], com.nhn.pinpoint.bootstrap.interceptor.Interceptor, com.nhn.pinpoint.profiler.util.DepthScope) - */ - @Override - public int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException { - if (methodName == null) { - throw new NullPointerException("methodName must not be null"); - } - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - if (scope == null) { - throw new NullPointerException("scope must not be null"); - } - if (hasDeclaredMethod(methodName, args)) { - interceptor = wrapScopeInterceptor(interceptor, scope); - return addInterceptor(methodName, args, interceptor); - } else { - if (logger.isWarnEnabled()) { - logger.warn("Method is not declared. class={}, methodName={}, args={}", ctClass.getName(), methodName, Arrays.toString(args)); - } - return -1; - } - } - - @Override - public int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException { - final Scope scope = this.instrumentor.getScope(scopeName); - return addScopeInterceptorIfDeclared(methodName, args, interceptor, scope); - } - - private Interceptor wrapScopeInterceptor(Interceptor interceptor, Scope scope) { - final Logger interceptorLogger = LoggerFactory.getLogger(interceptor.getClass()); - - if (interceptor instanceof SimpleAroundInterceptor) { - if (interceptorLogger.isDebugEnabled()) { - return new DebugScopeDelegateSimpleInterceptor((SimpleAroundInterceptor)interceptor, scope); - } else { - return new ScopeDelegateSimpleInterceptor((SimpleAroundInterceptor)interceptor, scope); - } - } - else if (interceptor instanceof StaticAroundInterceptor) { - if (interceptorLogger.isDebugEnabled()) { - return new DebugScopeDelegateStaticInterceptor((StaticAroundInterceptor)interceptor, scope); - } else { - return new ScopeDelegateStaticInterceptor((StaticAroundInterceptor)interceptor, scope); - } - } - throw new IllegalArgumentException("unknown Interceptor Type:" + interceptor.getClass()); - - } - - @Override - public int reuseInterceptor(String methodName, String[] args, int interceptorId) throws InstrumentException, NotFoundInstrumentException { - final CtBehavior behavior = getBehavior(methodName, args, null, interceptorId); - return addInterceptor0(behavior, methodName, null, interceptorId, Type.around, false); - } - - @Override - public int reuseInterceptor(String methodName, String[] args, int interceptorId, Type type) throws InstrumentException, NotFoundInstrumentException { - final CtBehavior behavior = getBehavior(methodName, args, null, interceptorId); - return addInterceptor0(behavior, methodName, null, interceptorId, type, false); - } - - @Override - public int addInterceptor(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { - if (interceptor == null) { - throw new IllegalArgumentException("interceptor is null"); - } - final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); - return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false); - } - - private CtBehavior getBehavior(String methodName, String[] args) throws NotFoundException { - if (methodName == null) { - return getConstructor(args); - } - return getMethod(methodName, args); - } - - private CtBehavior getBehavior(String methodName, String[] args, Interceptor interceptor, int interceptorId) throws NotFoundInstrumentException { - try { - return getBehavior(methodName, args); - } catch (NotFoundException e) { - // target method나 constructor를 차지 못했을 경우는 NotFoundInstrumentException을 던진다. - if (interceptor == null) { - throw new NotFoundInstrumentException(interceptorId + " add fail. Cause:" + e.getMessage(), e); - } else { - throw new NotFoundInstrumentException(interceptor.getClass().getSimpleName() + " add fail. Cause:" + e.getMessage(), e); - } - } - } - - private int addInterceptor0(CtBehavior behavior, String methodName, Interceptor interceptor, int interceptorId, Type type, boolean useContextClassLoader) throws InstrumentException, NotFoundInstrumentException { - try { - if (interceptor != null) { - if(interceptor instanceof StaticAroundInterceptor) { - StaticAroundInterceptor staticAroundInterceptor = (StaticAroundInterceptor) interceptor; - interceptorId = InterceptorRegistry.addInterceptor(staticAroundInterceptor); - } else if(interceptor instanceof SimpleAroundInterceptor) { - SimpleAroundInterceptor simpleAroundInterceptor = (SimpleAroundInterceptor) interceptor; - interceptorId = InterceptorRegistry.addSimpleInterceptor(simpleAroundInterceptor); - } else { - throw new InstrumentException("unsupported Interceptor Type:" + interceptor); - } - // traceContext는 가장먼제 inject되어야 한다. - if (interceptor instanceof TraceContextSupport) { - ((TraceContextSupport)interceptor).setTraceContext(instrumentor.getAgent().getTraceContext()); - } - if (interceptor instanceof ByteCodeMethodDescriptorSupport) { - setMethodDescriptor(behavior, (ByteCodeMethodDescriptorSupport) interceptor); - } - } else { - interceptor = InterceptorRegistry.findInterceptor(interceptorId); - } - // 이제는 aroundType 인터셉터만 받고 코드 인젝션을 별도 type으로 받아야 함. - if (interceptor instanceof StaticAroundInterceptor) { - switch (type) { - case around: - addStaticAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - break; - case before: - addStaticBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - break; - case after: - addStaticAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - break; - default: - throw new UnsupportedOperationException("unsupport type"); - } - } else if(interceptor instanceof SimpleAroundInterceptor) { - switch (type) { - case around: - addSimpleAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - break; - case before: - addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - break; - case after: - addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - break; - default: - throw new UnsupportedOperationException("unsupport type"); - } - } else { - throw new IllegalArgumentException("unsupported"); - } - return interceptorId; - } catch (NotFoundException e) { - throw new InstrumentException(interceptor.getClass().getSimpleName() + " add fail. Cause:" + e.getMessage(), e); - } catch (CannotCompileException e) { - throw new InstrumentException(interceptor.getClass().getSimpleName() + "add fail. Cause:" + e.getMessage(), e); - } - } - - private void setMethodDescriptor(CtBehavior behavior, ByteCodeMethodDescriptorSupport interceptor) throws NotFoundException { - DefaultMethodDescriptor methodDescriptor = new DefaultMethodDescriptor(); - - String methodName = behavior.getName(); - methodDescriptor.setMethodName(methodName); - - methodDescriptor.setClassName(ctClass.getName()); - - CtClass[] ctParameterTypes = behavior.getParameterTypes(); - String[] parameterTypes = JavaAssistUtils.getParameterType(ctParameterTypes); - methodDescriptor.setParameterTypes(parameterTypes); - - String[] parameterVariableName = JavaAssistUtils.getParameterVariableName(behavior); - methodDescriptor.setParameterVariableName(parameterVariableName); - - int lineNumber = JavaAssistUtils.getLineNumber(behavior); - methodDescriptor.setLineNumber(lineNumber); - - String parameterDescriptor = ApiUtils.mergeParameterVariableNameDescription(parameterTypes, parameterVariableName); - methodDescriptor.setParameterDescriptor(parameterDescriptor); - - String apiDescriptor = ApiUtils.mergeApiDescriptor(ctClass.getName(), methodName, parameterDescriptor); - methodDescriptor.setApiDescriptor(apiDescriptor); - - interceptor.setMethodDescriptor(methodDescriptor); - } - - private void addStaticAroundInterceptor(String methodName, int id, CtBehavior method, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { - addStaticBeforeInterceptor(methodName, id, method, useContextClassLoader); - addStaticAfterInterceptor(methodName, id, method, useContextClassLoader); - } - - private void addStaticBeforeInterceptor(String methodName, int id, CtBehavior behavior, boolean useContextClassLoader) throws CannotCompileException, NotFoundException { - addBeforeInterceptor(methodName, id, behavior, useContextClassLoader, STATIC_INTERCEPTOR); - } - - private void addStaticAfterInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { - addAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader, STATIC_INTERCEPTOR); - } - - private void addSimpleAroundInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { - addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader); - } - - private void addSimpleBeforeInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { - addBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader, SIMPLE_INTERCEPTOR); - } - - private void addSimpleAfterInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { - addAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader, SIMPLE_INTERCEPTOR); - } - - - - - private void addAfterInterceptor(String methodName, int id, CtBehavior behavior, boolean useContextClassLoader, int interceptorType) throws NotFoundException, CannotCompileException { - String returnType = getReturnType(behavior); - String target = getTarget(behavior); - - String parameterTypeString = null; - if (interceptorType == STATIC_INTERCEPTOR) { - parameterTypeString = JavaAssistUtils.getParameterDescription(behavior.getParameterTypes()); - } - final String parameter = getParameter(behavior); - - final CodeBuilder after = new CodeBuilder(); - if (useContextClassLoader) { - after.begin(); - beginAddFindInterceptorCode(id, after, interceptorType); - // TODO getMethod는 느림 캐쉬로 대체하던가 아니면 추가적인 방안이 필요함. - if (interceptorType == STATIC_INTERCEPTOR) { - after.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); - } else { - after.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); - } - after.format(" java.lang.reflect.Method method = interceptor.getClass().getMethod(\"%1$s\", methodArgsClassParams);", "after"); - if (interceptorType == STATIC_INTERCEPTOR) { - after.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, %6$s, null };", target, ctClass.getName(), methodName, parameterTypeString, parameter, returnType); - } else { - after.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, %2$s, %3$s, null };", target, parameter, returnType); - } - after.append(" method.invoke(interceptor, methodParams);"); - endAddFindInterceptorCode(after); - after.end(); - } else { - after.begin(); - - if (interceptorType == STATIC_INTERCEPTOR) { - after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id); - after.format(" interceptor.after(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, %6$s, null);", target, ctClass.getName(), methodName, parameterTypeString, parameter, returnType); - } else { - after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id); - after.format(" interceptor.after(%1$s, %2$s, %3$s, null);", target, parameter, returnType); - } - after.end(); - } - final String buildAfter = after.toString(); - if (isDebug) { - logger.debug("addAfterInterceptor after behavior:{} code:{}", behavior.getLongName(), buildAfter); - } - behavior.insertAfter(buildAfter); - - - CodeBuilder catchCode = new CodeBuilder(); - if (useContextClassLoader) { - catchCode.begin(); - beginAddFindInterceptorCode(id, catchCode, interceptorType); - if(interceptorType == STATIC_INTERCEPTOR) { - catchCode.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); - } else { - catchCode.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); - } - catchCode.format(" java.lang.reflect.Method method = interceptor.getClass().getMethod(\"%1$s\", methodArgsClassParams);", "after"); - if (interceptorType == STATIC_INTERCEPTOR) { - catchCode.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, null, $e };", target, ctClass.getName(), methodName, parameterTypeString, parameter); - } else { - catchCode.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, %2$s, null, $e };", target, parameter); - } - catchCode.append(" method.invoke(interceptor, methodParams);"); - endAddFindInterceptorCode(catchCode); - catchCode.append(" throw $e;"); - catchCode.end(); - } else { - catchCode.begin(); - if (interceptorType == STATIC_INTERCEPTOR) { - catchCode.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id); - catchCode.format(" interceptor.after(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, null, $e);", target, ctClass.getName(), methodName, parameterTypeString, parameter); - } else { - catchCode.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id); - catchCode.format(" interceptor.after(%1$s, %2$s, null, $e);", target, parameter); - } - catchCode.append(" throw $e;"); - catchCode.end(); - } - String buildCatch = catchCode.toString(); - if (isDebug) { - logger.debug("addAfterInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildCatch); - } - CtClass th = instrumentor.getClassPool().get("java.lang.Throwable"); - behavior.addCatch(buildCatch, th); - - } - - private void endAddFindInterceptorCode(CodeBuilder catchCode) { - catchCode.format("}"); - } - - private void beginAddFindInterceptorCode(int id, CodeBuilder after, int interceptorType) { - after.append("java.lang.ClassLoader contextClassLoader = java.lang.Thread.currentThread().getContextClassLoader();"); - after.append("if (contextClassLoader != null) {"); - after.append(" java.lang.Class interceptorRegistryClass = contextClassLoader.loadClass(\"com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry\");"); - if (interceptorType == STATIC_INTERCEPTOR) { - after.append(" java.lang.reflect.Method getInterceptorMethod = interceptorRegistryClass.getMethod(\"getInterceptor\", new java.lang.Class[]{ int.class });"); - } else { - after.append(" java.lang.reflect.Method getInterceptorMethod = interceptorRegistryClass.getMethod(\"getSimpleInterceptor\", new java.lang.Class[]{ int.class });"); - } - after.format(" java.lang.Object[] interceptorParams = new java.lang.Object[] { java.lang.Integer.valueOf(%1$d) };", id); - after.format(" java.lang.Object interceptor = getInterceptorMethod.invoke(interceptorRegistryClass, interceptorParams);"); - } - - private String getTarget(CtBehavior behavior) { - boolean staticMethod = JavaAssistUtils.isStaticBehavior(behavior); - if (staticMethod) { - return "null"; - } else { - return "this"; - } - } - - public String getReturnType(CtBehavior behavior) throws NotFoundException { - if (behavior instanceof CtMethod) { - CtClass returnType = ((CtMethod) behavior).getReturnType(); - if (CtClass.voidType == returnType) { - return "null"; - } - } - return "($w)$_"; - } - - - private void addBeforeInterceptor(String methodName, int id, CtBehavior behavior, boolean useContextClassLoader, int interceptorType) throws CannotCompileException, NotFoundException { - String target = getTarget(behavior); - // 인터셉터 호출시 최대한 연산량을 줄이기 위해서 정보는 가능한 정적 데이터로 생성한다. - String parameterDescription = null; - if (interceptorType == STATIC_INTERCEPTOR) { - parameterDescription = JavaAssistUtils.getParameterDescription(behavior.getParameterTypes()); - } - String parameter = getParameter(behavior); - - CodeBuilder code = new CodeBuilder(); - if (useContextClassLoader) { - code.begin(); -// java.lang.ClassLoader contextClassLoader = java.lang.Thread.currentThread().getContextClassLoader(); -// java.lang.Class interceptorRegistryClass = contextClassLoader.loadClass("com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry"); -// java.lang.reflect.Method getInterceptorMethod = interceptorRegistryClass.getMethod("getInterceptor", int.class); -// java.lang.Object interceptor = getInterceptorMethod.invoke(interceptorRegistryClass, 1); -// java.lang.reflect.Method beforeMethod = interceptor.getClass().getMethod("before", java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class); -// beforeMethod.invoke(interceptor, null, null, null, null, null); -// - beginAddFindInterceptorCode(id, code, interceptorType); - if(interceptorType == STATIC_INTERCEPTOR) { - code.append(" java.lang.Class[] beforeMethodParams = new Class[]{java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class};"); - } else { - code.append(" java.lang.Class[] beforeMethodParams = new Class[]{java.lang.Object.class, java.lang.Object[].class};"); - } - code.format(" java.lang.reflect.Method beforeMethod = interceptor.getClass().getMethod(\"%1$s\", beforeMethodParams);", "before"); - if(interceptorType == STATIC_INTERCEPTOR) { - code.format(" java.lang.Object[] beforeParams = new java.lang.Object[] { %1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s };", target, ctClass.getName(), methodName, parameterDescription, parameter); - } else { - code.format(" java.lang.Object[] beforeParams = new java.lang.Object[] { %1$s, %2$s };", target, parameter); - } - code.append(" beforeMethod.invoke(interceptor, beforeParams);"); - code.append("}"); - code.end(); - } else { - code.begin(); - if (interceptorType == STATIC_INTERCEPTOR) { - code.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id); - code.format(" interceptor.before(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s);", target, ctClass.getName(), methodName, parameterDescription, parameter); - } else { - // simpleInterceptor인덱스에서 검색하여 typecasting을 제거한다. - code.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id); - code.format(" interceptor.before(%1$s, %2$s);", target, parameter); - } - code.end(); - } - String buildBefore = code.toString(); - if (isDebug) { - logger.debug("addStaticBeforeInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildBefore); - } - - if (behavior instanceof CtConstructor) { - ((CtConstructor) behavior).insertBeforeBody(buildBefore); - } else { - behavior.insertBefore(buildBefore); - } - } - - private String getParameter(CtBehavior behavior) throws NotFoundException { - CtClass[] parameterTypes = behavior.getParameterTypes(); - if (parameterTypes.length == 0) { - return "null"; - } - return "$args"; - } - - public boolean addDebugLogBeforeAfterMethod() { - String className = this.ctClass.getName(); - LoggingInterceptor loggingInterceptor = new LoggingInterceptor(className); - int id = InterceptorRegistry.addInterceptor(loggingInterceptor); - try { - CtClass cc = this.instrumentor.getClassPool().get(className); - CtMethod[] methods = cc.getDeclaredMethods(); - - for (CtMethod method : methods) { - if (method.isEmpty()) { - if (isDebug) { - logger.debug("{} is empty.", method.getLongName()); - } - continue; - } - String methodName = method.getName(); - - // TODO method의 prameter type을 interceptor에 별도 추가해야 될것으로 보임. - String params = getParamsToString(method.getParameterTypes()); - addStaticAroundInterceptor(methodName, id, method, false); - } - return true; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - return false; - } - - /** - * 제대로 동작안함 다시 봐야 될것 같음. 생성자일경우의 bytecode 수정시 에러가 남. - * - * @return - */ - @Deprecated - public boolean addDebugLogBeforeAfterConstructor() { - String className = this.ctClass.getName(); - LoggingInterceptor loggingInterceptor = new LoggingInterceptor(className); - int id = InterceptorRegistry.addInterceptor(loggingInterceptor); - try { - CtClass cc = this.instrumentor.getClassPool().get(className); - CtConstructor[] constructors = cc.getConstructors(); - - for (CtConstructor constructor : constructors) { - if (constructor.isEmpty()) { - if (isDebug) { - logger.debug("{} is empty.", constructor.getLongName()); - } - continue; - } - String constructorName = constructor.getName(); - String params = getParamsToString(constructor.getParameterTypes()); - - // constructor.insertAfter("{System.out.println(\"*****" + - // constructorName + " Constructor:Param=(" + params + - // ") is finished. \" + $args);}"); - // constructor.addCatch("{System.out.println(\"*****" + - // constructorName + " Constructor:Param=(" + params + - // ") is finished.\"); throw $e; }" - // , instrumentor.getClassPool().get("java.lang.Throwable")); - addStaticAroundInterceptor(constructorName, id, constructor, false); - } - return true; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - return false; - } - - private String getParamsToString(CtClass[] params) throws NotFoundException { - StringBuilder sb = new StringBuilder(512); - if (params.length != 0) { - int paramsLength = params.length; - for (int loop = paramsLength - 1; loop > 0; loop--) { - sb.append(params[loop].getName()).append(","); - } - } - String paramsStr = sb.toString(); - if (isDebug) { - logger.debug("params type:{}", paramsStr); - } - return paramsStr; - } - - private CtMethod getMethod(String methodName, String[] args) throws NotFoundException { - CtClass[] params = JavaAssistUtils.getCtParameter(args, instrumentor.getClassPool()); - // cttime에는 직접 구현클래스를 조작해야 되므로 상속관계의 method를 찾으면 안됨. - return ctClass.getDeclaredMethod(methodName, params); - } - - private CtConstructor getConstructor(String[] args) throws NotFoundException { - CtClass[] params = JavaAssistUtils.getCtParameter(args, instrumentor.getClassPool()); - return ctClass.getDeclaredConstructor(params); - } - - - @Override - public byte[] toBytecode() { - try { - byte[] bytes = ctClass.toBytecode(); - ctClass.detach(); - return bytes; - } catch (IOException e) { - logger.info("IoException class:{} Caused:{}", ctClass.getName(), e.getMessage(), e); - } catch (CannotCompileException e) { - logger.info("CannotCompileException class:{} Caused:{}", ctClass.getName(), e.getMessage(), e); - } - return null; - } - - public Class toClass() throws InstrumentException { - try { - return ctClass.toClass(); - } catch (CannotCompileException e) { - throw new InstrumentException( "CannotCompileException class:" + ctClass.getName() + " " + e.getMessage(), e); - } - } - - public List getDeclaredMethods() throws NotFoundInstrumentException { - return getDeclaredMethods(SkipMethodFilter.FILTER); - } - - - public List getDeclaredMethods(MethodFilter methodFilter) throws NotFoundInstrumentException { - if (methodFilter == null) { - throw new NullPointerException("methodFilter must not be null"); - } - try { - final CtMethod[] declaredMethod = ctClass.getDeclaredMethods(); - final List candidateList = new ArrayList(declaredMethod.length); - for (CtMethod ctMethod : declaredMethod) { - if (methodFilter.filter(ctMethod)) { - continue; - } - String methodName = ctMethod.getName(); - CtClass[] paramTypes = ctMethod.getParameterTypes(); - String[] parameterType = JavaAssistUtils.getParameterType(paramTypes); - Method method = new Method(methodName, parameterType); - candidateList.add(method); - } - return candidateList; - } catch (NotFoundException e) { - throw new NotFoundInstrumentException("getDeclaredMethods(), Caused:" + e.getMessage(), e); - } - } - - public boolean isInterceptable() { - return !ctClass.isInterface() && !ctClass.isAnnotation() && !ctClass.isModified(); - } - - @Override - public boolean hasDeclaredMethod(String methodName, String[] args) { - try { - CtClass[] params = JavaAssistUtils.getCtParameter(args, instrumentor.getClassPool()); - CtMethod m = ctClass.getDeclaredMethod(methodName, params); - return m != null; - } catch (NotFoundException e) { - return false; - } - } - - /** - * 가능한 String methodName, String desc을 사용하자. 편한대신에 속도가 상대적으로 좀 느리다. - * @param methodName - * @param args - * @return - */ - @Override - public boolean hasMethod(String methodName, String[] args) { - final String parameterDescription = JavaAssistUtils.getParameterDescription(args); - final CtMethod[] methods = ctClass.getMethods(); - for (CtMethod method : methods) { - if (methodName.equals(method.getName()) && method.getMethodInfo2().getDescriptor().startsWith(parameterDescription)) { - return true; - } - - } - return false; - } - - @Override - public boolean hasMethod(String methodName, String desc) { - try { - CtMethod m = ctClass.getMethod(methodName, desc); - return m != null; - } catch (NotFoundException e) { - return false; - } - } - - @Override - public InstrumentClass getNestedClass(String className) { - try { - CtClass[] nestedClasses = ctClass.getNestedClasses(); - - if (nestedClasses == null || nestedClasses.length == 0) { - return null; - } - - for (CtClass nested : nestedClasses) { - if (nested.getName().equals(className)) { - return new JavaAssistClass(this.instrumentor, nested); - } - } - } catch (NotFoundException e) { - return null; - } - return null; - } - - @Override - public void addGetter(String getterName, String variableName, String variableType) throws InstrumentException { - try { - // FIXME getField, getDeclaredField둘 중 뭐가 나을지. 자식 클래스에 getter를 만들려면 getField가 나을 것 같기도 하고. - CtField traceVariable = ctClass.getField(variableName); - CtMethod getterMethod = CtNewMethod.getter(getterName, traceVariable); - ctClass.addMethod(getterMethod); - } catch (NotFoundException ex) { - throw new InstrumentException(variableName + " addVariableAccessor fail. Cause:" + ex.getMessage(), ex); - } catch (CannotCompileException ex) { - throw new InstrumentException(variableName + " addVariableAccessor fail. Cause:" + ex.getMessage(), ex); - } - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue; +import com.nhn.pinpoint.profiler.util.ApiUtils; +import com.nhn.pinpoint.profiler.interceptor.*; +import com.nhn.pinpoint.profiler.util.JavaAssistUtils; + +import com.nhn.pinpoint.profiler.util.Scope; +import javassist.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + * @author netspider + */ +public class JavaAssistClass implements InstrumentClass { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private JavaAssistByteCodeInstrumentor instrumentor; + private CtClass ctClass; + private static final int STATIC_INTERCEPTOR = 0; + private static final int SIMPLE_INTERCEPTOR = 1; + + private static final int NOT_DEFINE_INTERCEPTOR_ID = -1; + + private static final String FIELD_PREFIX = "__p"; + private static final String SETTER_PREFIX = "__set"; + private static final String GETTER_PREFIX = "__get"; + private static final String MARKER_CLASS_NAME = "com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue"; + + + public JavaAssistClass(JavaAssistByteCodeInstrumentor instrumentor, CtClass ctClass) { + this.instrumentor = instrumentor; + this.ctClass = ctClass; + } + + public boolean isInterface() { + return this.ctClass.isInterface(); + } + + public String getName() { + return this.ctClass.getName(); + } + + @Override + public boolean insertCodeBeforeConstructor(String[] args, String code) { + try { + CtConstructor constructor = getConstructor(args); + constructor.insertBefore(code); + return true; + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + return false; + } + } + + @Override + public boolean insertCodeAfterConstructor(String[] args, String code) { + try { + CtConstructor constructor = getConstructor(args); + constructor.insertAfter(code); + return true; + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + return false; + } + } + + @Override + public boolean insertCodeBeforeMethod(String methodName, String[] args, String code) { + try { + CtMethod method = getMethod(methodName, args); + method.insertBefore(code); + return true; + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + return false; + } + } + + @Override + public boolean insertCodeAfterMethod(String methodName, String[] args, String code) { + try { + CtMethod method = getMethod(methodName, args); + method.insertAfter(code); + return true; + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + return false; + } + } + + @Deprecated + public void addTraceVariable(String variableName, String setterName, String getterName, String variableType, String initValue) throws InstrumentException { + addTraceVariable0(variableName, setterName, getterName, variableType, initValue); + } + + @Deprecated + public void addTraceVariable(String variableName, String setterName, String getterName, String variableType) throws InstrumentException { + addTraceVariable0(variableName, setterName, getterName, variableType, null); + } + + @Deprecated + private void addTraceVariable0(String variableName, String setterName, String getterName, String variableType, String initValue) throws InstrumentException { + try { + CtClass type = instrumentor.getClassPool().get(variableType); + CtField traceVariable = new CtField(type, variableName, ctClass); + if (initValue == null) { + ctClass.addField(traceVariable); + } else { + ctClass.addField(traceVariable, initValue); + } + if (setterName != null) { + CtMethod setterMethod = CtNewMethod.setter(setterName, traceVariable); + ctClass.addMethod(setterMethod); + } + if (getterName != null) { + CtMethod getterMethod = CtNewMethod.getter(getterName, traceVariable); + ctClass.addMethod(getterMethod); + } + } catch (NotFoundException e) { + throw new InstrumentException(variableName + " addTraceVariable fail. Cause:" + e.getMessage(), e); + } catch (CannotCompileException e) { + throw new InstrumentException(variableName + " addTraceVariable fail. Cause:" + e.getMessage(), e); + } + } + + public void addTraceValue(Class traceValue) throws InstrumentException { + addTraceValue0(traceValue, null); + } + + public void addTraceValue(Class traceValue, String initValue) throws InstrumentException { + addTraceValue0(traceValue, initValue); + } + + public void addTraceValue0(Class traceValue, String initValue) throws InstrumentException { + if (traceValue == null) { + throw new NullPointerException("traceValue must not be null"); + } + // testcase에서 classLoader가 다를수 있어서 isAssignableFrom으로 안함. + // 추가로 수정하긴해야 될듯함. + final boolean marker = checkTraceValueMarker(traceValue); + if (!marker) { + throw new InstrumentException(traceValue + " marker interface not implements" ); + } + + try { + final CtClass ctValueHandler = instrumentor.getClassPool().get(traceValue.getName()); + + final java.lang.reflect.Method[] declaredMethods = traceValue.getDeclaredMethods(); + final String variableName = FIELD_PREFIX + ctValueHandler.getSimpleName(); + + final CtField traceVariableType = determineTraceValueType(variableName, declaredMethods); + + boolean requiredField = false; + for (java.lang.reflect.Method method : declaredMethods) { + // 2개 이상의 중복일때를 체크하지 않았음. + if (isSetter(method)) { + // setter + CtMethod setterMethod = CtNewMethod.setter(method.getName(), traceVariableType); + ctClass.addMethod(setterMethod); + requiredField = true; + } else if(isGetter(method)) { + // getter + CtMethod getterMethod = CtNewMethod.getter(method.getName(), traceVariableType); + ctClass.addMethod(getterMethod); + requiredField = true; + } + } + if (requiredField) { + ctClass.addInterface(ctValueHandler); + if (initValue == null) { + ctClass.addField(traceVariableType); + } else { + ctClass.addField(traceVariableType, initValue); + } + } + + } catch (NotFoundException e) { + throw new InstrumentException(traceValue + " implements fail. Cause:" + e.getMessage(), e); + } catch (CannotCompileException e) { + throw new InstrumentException(traceValue + " implements fail. Cause:" + e.getMessage(), e); + } + } + + + + private boolean checkTraceValueMarker(Class traceValue) { + for (Class anInterface : traceValue.getInterfaces()) { + if (MARKER_CLASS_NAME.equals(anInterface.getName())) { + return true; + } + } + return false; + } + + private boolean isGetter(java.lang.reflect.Method method) { + return method.getName().startsWith(GETTER_PREFIX); + } + + private boolean isSetter(java.lang.reflect.Method method) { + return method.getName().startsWith(SETTER_PREFIX); + } + + private CtField determineTraceValueType(String variableName, java.lang.reflect.Method[] declaredMethods) throws NotFoundException, CannotCompileException, InstrumentException { + Class getterReturnType = null; + Class setterType = null; + for (java.lang.reflect.Method method : declaredMethods) { + if (isGetter(method)) { + getterReturnType = method.getReturnType(); + } else if (isSetter(method)) { + Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length != 1) { + throw new InstrumentException("invalid setterParameter. parameterTypes:" + Arrays.toString(parameterTypes)); + } + setterType = parameterTypes[0]; + } + } + if (getterReturnType == null && setterType == null) { + throw new InstrumentException("getter or setter not found"); + } + if (getterReturnType != null && setterType != null) { + if(!getterReturnType.equals(setterType)) { + throw new InstrumentException("invalid setter or getter parameter"); + } + } + Class resolveType; + if (getterReturnType != null) { + resolveType = getterReturnType; + } else { + resolveType = setterType; + } + CtClass type = instrumentor.getClassPool().get(resolveType.getName()); + return new CtField(type, variableName, ctClass); + } + + public int addConstructorInterceptor(String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException { + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + final CtBehavior behavior = getBehavior(null, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); + return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false); + } + + public int addConstructorInterceptor(String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + final CtBehavior behavior = getBehavior(null, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); + return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false); + } + + public int addAllConstructorInterceptor(Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException{ + return addAllConstructorInterceptor(interceptor, Type.around); + } + + public int addAllConstructorInterceptor(Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + final CtConstructor[] constructorList = ctClass.getConstructors(); + final int length = constructorList.length; + if (length == 0) { + throw new NotFoundInstrumentException("Constructor not found."); + } + int interceptorId = 0; + if (length > 0) { + interceptorId = addInterceptor0(constructorList[0], null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false); + } + if (length > 1) { + for (int i = 1; i< length; i++) { + addInterceptor0(constructorList[i], null, null, interceptorId, Type.around, false); + } + } + return interceptorId; + } + + + @Override + public int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException { + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); + return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, true); + } + + @Override + public int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); + return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, true); + } + + @Override + public int addInterceptor(String methodName, String[] args, Interceptor interceptor) throws InstrumentException, NotFoundInstrumentException { + if (methodName == null) { + throw new NullPointerException("methodName must not be null"); + } + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); + return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false); + } + + @Override + public int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException, NotFoundInstrumentException { + final Scope scope = this.instrumentor.getScope(scopeName); + return addScopeInterceptor(methodName, args, interceptor, scope); + } + + + @Override + public int addScopeInterceptor(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException, NotFoundInstrumentException { + if (methodName == null) { + throw new NullPointerException("methodName must not be null"); + } + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + if (scope == null) { + throw new NullPointerException("scope must not be null"); + } + interceptor = wrapScopeInterceptor(interceptor, scope); + return addInterceptor(methodName, args, interceptor); + } + + /* + * (non-Javadoc) + * @see com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass#addScopeInterceptorIfDeclared(java.lang.String, java.lang.String[], com.nhn.pinpoint.bootstrap.interceptor.Interceptor, com.nhn.pinpoint.profiler.util.DepthScope) + */ + @Override + public int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, Scope scope) throws InstrumentException { + if (methodName == null) { + throw new NullPointerException("methodName must not be null"); + } + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + if (scope == null) { + throw new NullPointerException("scope must not be null"); + } + if (hasDeclaredMethod(methodName, args)) { + interceptor = wrapScopeInterceptor(interceptor, scope); + return addInterceptor(methodName, args, interceptor); + } else { + if (logger.isWarnEnabled()) { + logger.warn("Method is not declared. class={}, methodName={}, args={}", ctClass.getName(), methodName, Arrays.toString(args)); + } + return -1; + } + } + + @Override + public int addScopeInterceptorIfDeclared(String methodName, String[] args, Interceptor interceptor, String scopeName) throws InstrumentException { + final Scope scope = this.instrumentor.getScope(scopeName); + return addScopeInterceptorIfDeclared(methodName, args, interceptor, scope); + } + + private Interceptor wrapScopeInterceptor(Interceptor interceptor, Scope scope) { + final Logger interceptorLogger = LoggerFactory.getLogger(interceptor.getClass()); + + if (interceptor instanceof SimpleAroundInterceptor) { + if (interceptorLogger.isDebugEnabled()) { + return new DebugScopeDelegateSimpleInterceptor((SimpleAroundInterceptor)interceptor, scope); + } else { + return new ScopeDelegateSimpleInterceptor((SimpleAroundInterceptor)interceptor, scope); + } + } + else if (interceptor instanceof StaticAroundInterceptor) { + if (interceptorLogger.isDebugEnabled()) { + return new DebugScopeDelegateStaticInterceptor((StaticAroundInterceptor)interceptor, scope); + } else { + return new ScopeDelegateStaticInterceptor((StaticAroundInterceptor)interceptor, scope); + } + } + throw new IllegalArgumentException("unknown Interceptor Type:" + interceptor.getClass()); + + } + + @Override + public int reuseInterceptor(String methodName, String[] args, int interceptorId) throws InstrumentException, NotFoundInstrumentException { + final CtBehavior behavior = getBehavior(methodName, args, null, interceptorId); + return addInterceptor0(behavior, methodName, null, interceptorId, Type.around, false); + } + + @Override + public int reuseInterceptor(String methodName, String[] args, int interceptorId, Type type) throws InstrumentException, NotFoundInstrumentException { + final CtBehavior behavior = getBehavior(methodName, args, null, interceptorId); + return addInterceptor0(behavior, methodName, null, interceptorId, type, false); + } + + @Override + public int addInterceptor(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException { + if (interceptor == null) { + throw new IllegalArgumentException("interceptor is null"); + } + final CtBehavior behavior = getBehavior(methodName, args, interceptor, NOT_DEFINE_INTERCEPTOR_ID); + return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false); + } + + private CtBehavior getBehavior(String methodName, String[] args) throws NotFoundException { + if (methodName == null) { + return getConstructor(args); + } + return getMethod(methodName, args); + } + + private CtBehavior getBehavior(String methodName, String[] args, Interceptor interceptor, int interceptorId) throws NotFoundInstrumentException { + try { + return getBehavior(methodName, args); + } catch (NotFoundException e) { + // target method나 constructor를 차지 못했을 경우는 NotFoundInstrumentException을 던진다. + if (interceptor == null) { + throw new NotFoundInstrumentException(interceptorId + " add fail. Cause:" + e.getMessage(), e); + } else { + throw new NotFoundInstrumentException(interceptor.getClass().getSimpleName() + " add fail. Cause:" + e.getMessage(), e); + } + } + } + + private int addInterceptor0(CtBehavior behavior, String methodName, Interceptor interceptor, int interceptorId, Type type, boolean useContextClassLoader) throws InstrumentException, NotFoundInstrumentException { + try { + if (interceptor != null) { + if(interceptor instanceof StaticAroundInterceptor) { + StaticAroundInterceptor staticAroundInterceptor = (StaticAroundInterceptor) interceptor; + interceptorId = InterceptorRegistry.addInterceptor(staticAroundInterceptor); + } else if(interceptor instanceof SimpleAroundInterceptor) { + SimpleAroundInterceptor simpleAroundInterceptor = (SimpleAroundInterceptor) interceptor; + interceptorId = InterceptorRegistry.addSimpleInterceptor(simpleAroundInterceptor); + } else { + throw new InstrumentException("unsupported Interceptor Type:" + interceptor); + } + // traceContext는 가장먼제 inject되어야 한다. + if (interceptor instanceof TraceContextSupport) { + ((TraceContextSupport)interceptor).setTraceContext(instrumentor.getAgent().getTraceContext()); + } + if (interceptor instanceof ByteCodeMethodDescriptorSupport) { + setMethodDescriptor(behavior, (ByteCodeMethodDescriptorSupport) interceptor); + } + } else { + interceptor = InterceptorRegistry.findInterceptor(interceptorId); + } + // 이제는 aroundType 인터셉터만 받고 코드 인젝션을 별도 type으로 받아야 함. + if (interceptor instanceof StaticAroundInterceptor) { + switch (type) { + case around: + addStaticAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + break; + case before: + addStaticBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + break; + case after: + addStaticAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + break; + default: + throw new UnsupportedOperationException("unsupport type"); + } + } else if(interceptor instanceof SimpleAroundInterceptor) { + switch (type) { + case around: + addSimpleAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + break; + case before: + addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + break; + case after: + addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + break; + default: + throw new UnsupportedOperationException("unsupport type"); + } + } else { + throw new IllegalArgumentException("unsupported"); + } + return interceptorId; + } catch (NotFoundException e) { + throw new InstrumentException(interceptor.getClass().getSimpleName() + " add fail. Cause:" + e.getMessage(), e); + } catch (CannotCompileException e) { + throw new InstrumentException(interceptor.getClass().getSimpleName() + "add fail. Cause:" + e.getMessage(), e); + } + } + + private void setMethodDescriptor(CtBehavior behavior, ByteCodeMethodDescriptorSupport interceptor) throws NotFoundException { + DefaultMethodDescriptor methodDescriptor = new DefaultMethodDescriptor(); + + String methodName = behavior.getName(); + methodDescriptor.setMethodName(methodName); + + methodDescriptor.setClassName(ctClass.getName()); + + CtClass[] ctParameterTypes = behavior.getParameterTypes(); + String[] parameterTypes = JavaAssistUtils.getParameterType(ctParameterTypes); + methodDescriptor.setParameterTypes(parameterTypes); + + String[] parameterVariableName = JavaAssistUtils.getParameterVariableName(behavior); + methodDescriptor.setParameterVariableName(parameterVariableName); + + int lineNumber = JavaAssistUtils.getLineNumber(behavior); + methodDescriptor.setLineNumber(lineNumber); + + String parameterDescriptor = ApiUtils.mergeParameterVariableNameDescription(parameterTypes, parameterVariableName); + methodDescriptor.setParameterDescriptor(parameterDescriptor); + + String apiDescriptor = ApiUtils.mergeApiDescriptor(ctClass.getName(), methodName, parameterDescriptor); + methodDescriptor.setApiDescriptor(apiDescriptor); + + interceptor.setMethodDescriptor(methodDescriptor); + } + + private void addStaticAroundInterceptor(String methodName, int id, CtBehavior method, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { + addStaticBeforeInterceptor(methodName, id, method, useContextClassLoader); + addStaticAfterInterceptor(methodName, id, method, useContextClassLoader); + } + + private void addStaticBeforeInterceptor(String methodName, int id, CtBehavior behavior, boolean useContextClassLoader) throws CannotCompileException, NotFoundException { + addBeforeInterceptor(methodName, id, behavior, useContextClassLoader, STATIC_INTERCEPTOR); + } + + private void addStaticAfterInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { + addAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader, STATIC_INTERCEPTOR); + } + + private void addSimpleAroundInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { + addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader); + } + + private void addSimpleBeforeInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { + addBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader, SIMPLE_INTERCEPTOR); + } + + private void addSimpleAfterInterceptor(String methodName, int interceptorId, CtBehavior behavior, boolean useContextClassLoader) throws NotFoundException, CannotCompileException { + addAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader, SIMPLE_INTERCEPTOR); + } + + + + + private void addAfterInterceptor(String methodName, int id, CtBehavior behavior, boolean useContextClassLoader, int interceptorType) throws NotFoundException, CannotCompileException { + String returnType = getReturnType(behavior); + String target = getTarget(behavior); + + String parameterTypeString = null; + if (interceptorType == STATIC_INTERCEPTOR) { + parameterTypeString = JavaAssistUtils.getParameterDescription(behavior.getParameterTypes()); + } + final String parameter = getParameter(behavior); + + final CodeBuilder after = new CodeBuilder(); + if (useContextClassLoader) { + after.begin(); + beginAddFindInterceptorCode(id, after, interceptorType); + // TODO getMethod는 느림 캐쉬로 대체하던가 아니면 추가적인 방안이 필요함. + if (interceptorType == STATIC_INTERCEPTOR) { + after.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); + } else { + after.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); + } + after.format(" java.lang.reflect.Method method = interceptor.getClass().getMethod(\"%1$s\", methodArgsClassParams);", "after"); + if (interceptorType == STATIC_INTERCEPTOR) { + after.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, %6$s, null };", target, ctClass.getName(), methodName, parameterTypeString, parameter, returnType); + } else { + after.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, %2$s, %3$s, null };", target, parameter, returnType); + } + after.append(" method.invoke(interceptor, methodParams);"); + endAddFindInterceptorCode(after); + after.end(); + } else { + after.begin(); + + if (interceptorType == STATIC_INTERCEPTOR) { + after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id); + after.format(" interceptor.after(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, %6$s, null);", target, ctClass.getName(), methodName, parameterTypeString, parameter, returnType); + } else { + after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id); + after.format(" interceptor.after(%1$s, %2$s, %3$s, null);", target, parameter, returnType); + } + after.end(); + } + final String buildAfter = after.toString(); + if (isDebug) { + logger.debug("addAfterInterceptor after behavior:{} code:{}", behavior.getLongName(), buildAfter); + } + behavior.insertAfter(buildAfter); + + + CodeBuilder catchCode = new CodeBuilder(); + if (useContextClassLoader) { + catchCode.begin(); + beginAddFindInterceptorCode(id, catchCode, interceptorType); + if(interceptorType == STATIC_INTERCEPTOR) { + catchCode.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); + } else { + catchCode.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};"); + } + catchCode.format(" java.lang.reflect.Method method = interceptor.getClass().getMethod(\"%1$s\", methodArgsClassParams);", "after"); + if (interceptorType == STATIC_INTERCEPTOR) { + catchCode.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, null, $e };", target, ctClass.getName(), methodName, parameterTypeString, parameter); + } else { + catchCode.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, %2$s, null, $e };", target, parameter); + } + catchCode.append(" method.invoke(interceptor, methodParams);"); + endAddFindInterceptorCode(catchCode); + catchCode.append(" throw $e;"); + catchCode.end(); + } else { + catchCode.begin(); + if (interceptorType == STATIC_INTERCEPTOR) { + catchCode.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id); + catchCode.format(" interceptor.after(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, null, $e);", target, ctClass.getName(), methodName, parameterTypeString, parameter); + } else { + catchCode.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id); + catchCode.format(" interceptor.after(%1$s, %2$s, null, $e);", target, parameter); + } + catchCode.append(" throw $e;"); + catchCode.end(); + } + String buildCatch = catchCode.toString(); + if (isDebug) { + logger.debug("addAfterInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildCatch); + } + CtClass th = instrumentor.getClassPool().get("java.lang.Throwable"); + behavior.addCatch(buildCatch, th); + + } + + private void endAddFindInterceptorCode(CodeBuilder catchCode) { + catchCode.format("}"); + } + + private void beginAddFindInterceptorCode(int id, CodeBuilder after, int interceptorType) { + after.append("java.lang.ClassLoader contextClassLoader = java.lang.Thread.currentThread().getContextClassLoader();"); + after.append("if (contextClassLoader != null) {"); + after.append(" java.lang.Class interceptorRegistryClass = contextClassLoader.loadClass(\"com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry\");"); + if (interceptorType == STATIC_INTERCEPTOR) { + after.append(" java.lang.reflect.Method getInterceptorMethod = interceptorRegistryClass.getMethod(\"getInterceptor\", new java.lang.Class[]{ int.class });"); + } else { + after.append(" java.lang.reflect.Method getInterceptorMethod = interceptorRegistryClass.getMethod(\"getSimpleInterceptor\", new java.lang.Class[]{ int.class });"); + } + after.format(" java.lang.Object[] interceptorParams = new java.lang.Object[] { java.lang.Integer.valueOf(%1$d) };", id); + after.format(" java.lang.Object interceptor = getInterceptorMethod.invoke(interceptorRegistryClass, interceptorParams);"); + } + + private String getTarget(CtBehavior behavior) { + boolean staticMethod = JavaAssistUtils.isStaticBehavior(behavior); + if (staticMethod) { + return "null"; + } else { + return "this"; + } + } + + public String getReturnType(CtBehavior behavior) throws NotFoundException { + if (behavior instanceof CtMethod) { + CtClass returnType = ((CtMethod) behavior).getReturnType(); + if (CtClass.voidType == returnType) { + return "null"; + } + } + return "($w)$_"; + } + + + private void addBeforeInterceptor(String methodName, int id, CtBehavior behavior, boolean useContextClassLoader, int interceptorType) throws CannotCompileException, NotFoundException { + String target = getTarget(behavior); + // 인터셉터 호출시 최대한 연산량을 줄이기 위해서 정보는 가능한 정적 데이터로 생성한다. + String parameterDescription = null; + if (interceptorType == STATIC_INTERCEPTOR) { + parameterDescription = JavaAssistUtils.getParameterDescription(behavior.getParameterTypes()); + } + String parameter = getParameter(behavior); + + CodeBuilder code = new CodeBuilder(); + if (useContextClassLoader) { + code.begin(); +// java.lang.ClassLoader contextClassLoader = java.lang.Thread.currentThread().getContextClassLoader(); +// java.lang.Class interceptorRegistryClass = contextClassLoader.loadClass("com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry"); +// java.lang.reflect.Method getInterceptorMethod = interceptorRegistryClass.getMethod("getInterceptor", int.class); +// java.lang.Object interceptor = getInterceptorMethod.invoke(interceptorRegistryClass, 1); +// java.lang.reflect.Method beforeMethod = interceptor.getClass().getMethod("before", java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class); +// beforeMethod.invoke(interceptor, null, null, null, null, null); +// + beginAddFindInterceptorCode(id, code, interceptorType); + if(interceptorType == STATIC_INTERCEPTOR) { + code.append(" java.lang.Class[] beforeMethodParams = new Class[]{java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class};"); + } else { + code.append(" java.lang.Class[] beforeMethodParams = new Class[]{java.lang.Object.class, java.lang.Object[].class};"); + } + code.format(" java.lang.reflect.Method beforeMethod = interceptor.getClass().getMethod(\"%1$s\", beforeMethodParams);", "before"); + if(interceptorType == STATIC_INTERCEPTOR) { + code.format(" java.lang.Object[] beforeParams = new java.lang.Object[] { %1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s };", target, ctClass.getName(), methodName, parameterDescription, parameter); + } else { + code.format(" java.lang.Object[] beforeParams = new java.lang.Object[] { %1$s, %2$s };", target, parameter); + } + code.append(" beforeMethod.invoke(interceptor, beforeParams);"); + code.append("}"); + code.end(); + } else { + code.begin(); + if (interceptorType == STATIC_INTERCEPTOR) { + code.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id); + code.format(" interceptor.before(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s);", target, ctClass.getName(), methodName, parameterDescription, parameter); + } else { + // simpleInterceptor인덱스에서 검색하여 typecasting을 제거한다. + code.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id); + code.format(" interceptor.before(%1$s, %2$s);", target, parameter); + } + code.end(); + } + String buildBefore = code.toString(); + if (isDebug) { + logger.debug("addStaticBeforeInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildBefore); + } + + if (behavior instanceof CtConstructor) { + ((CtConstructor) behavior).insertBeforeBody(buildBefore); + } else { + behavior.insertBefore(buildBefore); + } + } + + private String getParameter(CtBehavior behavior) throws NotFoundException { + CtClass[] parameterTypes = behavior.getParameterTypes(); + if (parameterTypes.length == 0) { + return "null"; + } + return "$args"; + } + + public boolean addDebugLogBeforeAfterMethod() { + String className = this.ctClass.getName(); + LoggingInterceptor loggingInterceptor = new LoggingInterceptor(className); + int id = InterceptorRegistry.addInterceptor(loggingInterceptor); + try { + CtClass cc = this.instrumentor.getClassPool().get(className); + CtMethod[] methods = cc.getDeclaredMethods(); + + for (CtMethod method : methods) { + if (method.isEmpty()) { + if (isDebug) { + logger.debug("{} is empty.", method.getLongName()); + } + continue; + } + String methodName = method.getName(); + + // TODO method의 prameter type을 interceptor에 별도 추가해야 될것으로 보임. + String params = getParamsToString(method.getParameterTypes()); + addStaticAroundInterceptor(methodName, id, method, false); + } + return true; + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + } + return false; + } + + /** + * 제대로 동작안함 다시 봐야 될것 같음. 생성자일경우의 bytecode 수정시 에러가 남. + * + * @return + */ + @Deprecated + public boolean addDebugLogBeforeAfterConstructor() { + String className = this.ctClass.getName(); + LoggingInterceptor loggingInterceptor = new LoggingInterceptor(className); + int id = InterceptorRegistry.addInterceptor(loggingInterceptor); + try { + CtClass cc = this.instrumentor.getClassPool().get(className); + CtConstructor[] constructors = cc.getConstructors(); + + for (CtConstructor constructor : constructors) { + if (constructor.isEmpty()) { + if (isDebug) { + logger.debug("{} is empty.", constructor.getLongName()); + } + continue; + } + String constructorName = constructor.getName(); + String params = getParamsToString(constructor.getParameterTypes()); + + // constructor.insertAfter("{System.out.println(\"*****" + + // constructorName + " Constructor:Param=(" + params + + // ") is finished. \" + $args);}"); + // constructor.addCatch("{System.out.println(\"*****" + + // constructorName + " Constructor:Param=(" + params + + // ") is finished.\"); throw $e; }" + // , instrumentor.getClassPool().get("java.lang.Throwable")); + addStaticAroundInterceptor(constructorName, id, constructor, false); + } + return true; + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + } + return false; + } + + private String getParamsToString(CtClass[] params) throws NotFoundException { + StringBuilder sb = new StringBuilder(512); + if (params.length != 0) { + int paramsLength = params.length; + for (int loop = paramsLength - 1; loop > 0; loop--) { + sb.append(params[loop].getName()).append(","); + } + } + String paramsStr = sb.toString(); + if (isDebug) { + logger.debug("params type:{}", paramsStr); + } + return paramsStr; + } + + private CtMethod getMethod(String methodName, String[] args) throws NotFoundException { + CtClass[] params = JavaAssistUtils.getCtParameter(args, instrumentor.getClassPool()); + // cttime에는 직접 구현클래스를 조작해야 되므로 상속관계의 method를 찾으면 안됨. + return ctClass.getDeclaredMethod(methodName, params); + } + + private CtConstructor getConstructor(String[] args) throws NotFoundException { + CtClass[] params = JavaAssistUtils.getCtParameter(args, instrumentor.getClassPool()); + return ctClass.getDeclaredConstructor(params); + } + + + @Override + public byte[] toBytecode() { + try { + byte[] bytes = ctClass.toBytecode(); + ctClass.detach(); + return bytes; + } catch (IOException e) { + logger.info("IoException class:{} Caused:{}", ctClass.getName(), e.getMessage(), e); + } catch (CannotCompileException e) { + logger.info("CannotCompileException class:{} Caused:{}", ctClass.getName(), e.getMessage(), e); + } + return null; + } + + public Class toClass() throws InstrumentException { + try { + return ctClass.toClass(); + } catch (CannotCompileException e) { + throw new InstrumentException( "CannotCompileException class:" + ctClass.getName() + " " + e.getMessage(), e); + } + } + + public List getDeclaredMethods() throws NotFoundInstrumentException { + return getDeclaredMethods(SkipMethodFilter.FILTER); + } + + + public List getDeclaredMethods(MethodFilter methodFilter) throws NotFoundInstrumentException { + if (methodFilter == null) { + throw new NullPointerException("methodFilter must not be null"); + } + try { + final CtMethod[] declaredMethod = ctClass.getDeclaredMethods(); + final List candidateList = new ArrayList(declaredMethod.length); + for (CtMethod ctMethod : declaredMethod) { + if (methodFilter.filter(ctMethod)) { + continue; + } + String methodName = ctMethod.getName(); + CtClass[] paramTypes = ctMethod.getParameterTypes(); + String[] parameterType = JavaAssistUtils.getParameterType(paramTypes); + Method method = new Method(methodName, parameterType); + candidateList.add(method); + } + return candidateList; + } catch (NotFoundException e) { + throw new NotFoundInstrumentException("getDeclaredMethods(), Caused:" + e.getMessage(), e); + } + } + + public boolean isInterceptable() { + return !ctClass.isInterface() && !ctClass.isAnnotation() && !ctClass.isModified(); + } + + @Override + public boolean hasDeclaredMethod(String methodName, String[] args) { + try { + CtClass[] params = JavaAssistUtils.getCtParameter(args, instrumentor.getClassPool()); + CtMethod m = ctClass.getDeclaredMethod(methodName, params); + return m != null; + } catch (NotFoundException e) { + return false; + } + } + + /** + * 가능한 String methodName, String desc을 사용하자. 편한대신에 속도가 상대적으로 좀 느리다. + * @param methodName + * @param args + * @return + */ + @Override + public boolean hasMethod(String methodName, String[] args) { + final String parameterDescription = JavaAssistUtils.getParameterDescription(args); + final CtMethod[] methods = ctClass.getMethods(); + for (CtMethod method : methods) { + if (methodName.equals(method.getName()) && method.getMethodInfo2().getDescriptor().startsWith(parameterDescription)) { + return true; + } + + } + return false; + } + + @Override + public boolean hasMethod(String methodName, String desc) { + try { + CtMethod m = ctClass.getMethod(methodName, desc); + return m != null; + } catch (NotFoundException e) { + return false; + } + } + + @Override + public InstrumentClass getNestedClass(String className) { + try { + CtClass[] nestedClasses = ctClass.getNestedClasses(); + + if (nestedClasses == null || nestedClasses.length == 0) { + return null; + } + + for (CtClass nested : nestedClasses) { + if (nested.getName().equals(className)) { + return new JavaAssistClass(this.instrumentor, nested); + } + } + } catch (NotFoundException e) { + return null; + } + return null; + } + + @Override + public void addGetter(String getterName, String variableName, String variableType) throws InstrumentException { + try { + // FIXME getField, getDeclaredField둘 중 뭐가 나을지. 자식 클래스에 getter를 만들려면 getField가 나을 것 같기도 하고. + CtField traceVariable = ctClass.getField(variableName); + CtMethod getterMethod = CtNewMethod.getter(getterName, traceVariable); + ctClass.addMethod(getterMethod); + } catch (NotFoundException ex) { + throw new InstrumentException(variableName + " addVariableAccessor fail. Cause:" + ex.getMessage(), ex); + } catch (CannotCompileException ex) { + throw new InstrumentException(variableName + " addVariableAccessor fail. Cause:" + ex.getMessage(), ex); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Method.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Method.java index 767d03eb3390..fe7baa4d5240 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Method.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Method.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import java.util.List; - -/** - * @author emeroad - */ -public class Method { - private String methodName; - private String[] methodParams; - - public Method() { - } - - public Method(String methodName, String[] methodParams) { - if (methodName == null) { - throw new NullPointerException("methodName must not be null"); - } - if (methodParams == null) { - throw new NullPointerException("methodParams must not be null"); - } - this.methodName = methodName; - this.methodParams = methodParams; - } - - public String getMethodName() { - return methodName; - } - - public void setMethodName(String methodName) { - this.methodName = methodName; - } - - public String[] getMethodParams() { - return methodParams; - } - - public void setMethodParams(String[] methodParams) { - this.methodParams = methodParams; - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import java.util.List; + +/** + * @author emeroad + */ +public class Method { + private String methodName; + private String[] methodParams; + + public Method() { + } + + public Method(String methodName, String[] methodParams) { + if (methodName == null) { + throw new NullPointerException("methodName must not be null"); + } + if (methodParams == null) { + throw new NullPointerException("methodParams must not be null"); + } + this.methodName = methodName; + this.methodParams = methodParams; + } + + public String getMethodName() { + return methodName; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public String[] getMethodParams() { + return methodParams; + } + + public void setMethodParams(String[] methodParams) { + this.methodParams = methodParams; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodFilter.java index 58cee4eb32bc..275d22941f3f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodFilter.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import javassist.CtMethod; - -/** - * @author emeroad - */ -public interface MethodFilter { - boolean filter(CtMethod ctMethod); - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import javassist.CtMethod; + +/** + * @author emeroad + */ +public interface MethodFilter { + boolean filter(CtMethod ctMethod); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NamedClassPool.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NamedClassPool.java index 53c8e2abc5ed..11b213509a5f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NamedClassPool.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NamedClassPool.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import javassist.ClassPool; - -/** - * @author emeroad - */ -public class NamedClassPool extends ClassPool { - private final String name; - - public NamedClassPool(String name) { - this.name = name; - } - - public NamedClassPool(boolean useDefaultPath, String name) { - super(useDefaultPath); - this.name = name; - } - - public NamedClassPool(ClassPool parent, String name) { - super(parent); - this.name = name; - } - - public String getName() { - return name; - } - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import javassist.ClassPool; + +/** + * @author emeroad + */ +public class NamedClassPool extends ClassPool { + private final String name; + + public NamedClassPool(String name) { + this.name = name; + } + + public NamedClassPool(boolean useDefaultPath, String name) { + super(useDefaultPath); + this.name = name; + } + + public NamedClassPool(ClassPool parent, String name) { + super(parent); + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NotFoundInstrumentException.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NotFoundInstrumentException.java index 889ba02bb103..3f535d5e8963 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NotFoundInstrumentException.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/NotFoundInstrumentException.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -/** - * @author emeroad - */ -public class NotFoundInstrumentException extends InstrumentException { - - private static final long serialVersionUID = -9079014055408569735L; - - public NotFoundInstrumentException() { - } - - public NotFoundInstrumentException(String message) { - super(message); - } - - public NotFoundInstrumentException(String message, Throwable cause) { - super(message, cause); - } - - public NotFoundInstrumentException(Throwable cause) { - super(cause); - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +/** + * @author emeroad + */ +public class NotFoundInstrumentException extends InstrumentException { + + private static final long serialVersionUID = -9079014055408569735L; + + public NotFoundInstrumentException() { + } + + public NotFoundInstrumentException(String message) { + super(message); + } + + public NotFoundInstrumentException(String message, Throwable cause) { + super(message, cause); + } + + public NotFoundInstrumentException(Throwable cause) { + super(cause); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/SkipMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/SkipMethodFilter.java index 71d5506e6210..0affbcce2960 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/SkipMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/SkipMethodFilter.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import javassist.CtMethod; - -/** - * @author emeroad - */ -public class SkipMethodFilter implements MethodFilter { - public static final MethodFilter FILTER = new SkipMethodFilter(); - - @Override - public boolean filter(CtMethod ctMethod) { - return false; - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import javassist.CtMethod; + +/** + * @author emeroad + */ +public class SkipMethodFilter implements MethodFilter { + public static final MethodFilter FILTER = new SkipMethodFilter(); + + @Override + public boolean filter(CtMethod ctMethod) { + return false; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Type.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Type.java index 93604934c0c4..d42548a4bb24 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Type.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/Type.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -/** - * @author emeroad - */ -public enum Type { - around(), before(), after() -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +/** + * @author emeroad + */ +public enum Type { + around(), before(), after() +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinder.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinder.java index 9ec3a5d9e176..7b9150e44cd2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinder.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinder.java @@ -1,40 +1,40 @@ -package com.nhn.pinpoint.profiler.logging; - -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerBinder; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class Slf4jLoggerBinder implements PLoggerBinder { - - private ConcurrentMap loggerCache = new ConcurrentHashMap(256, 0.75f, 128); - - @Override - public PLogger getLogger(String name) { - - final PLogger hitPLogger = loggerCache.get(name); - if (hitPLogger != null) { - return hitPLogger; - } - - org.slf4j.Logger slf4jLogger = LoggerFactory.getLogger(name); - - final Slf4jPLoggerAdapter slf4jLoggerAdapter = new Slf4jPLoggerAdapter(slf4jLogger); - final PLogger before = loggerCache.putIfAbsent(name, slf4jLoggerAdapter); - if (before != null) { - return before; - } - return slf4jLoggerAdapter; - } - - @Override - public void shutdown() { - // 안해도 될것도 같고. LoggerFactory의unregister만 해도 될려나? - loggerCache = null; - } -} +package com.nhn.pinpoint.profiler.logging; + +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerBinder; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class Slf4jLoggerBinder implements PLoggerBinder { + + private ConcurrentMap loggerCache = new ConcurrentHashMap(256, 0.75f, 128); + + @Override + public PLogger getLogger(String name) { + + final PLogger hitPLogger = loggerCache.get(name); + if (hitPLogger != null) { + return hitPLogger; + } + + org.slf4j.Logger slf4jLogger = LoggerFactory.getLogger(name); + + final Slf4jPLoggerAdapter slf4jLoggerAdapter = new Slf4jPLoggerAdapter(slf4jLogger); + final PLogger before = loggerCache.putIfAbsent(name, slf4jLoggerAdapter); + if (before != null) { + return before; + } + return slf4jLoggerAdapter; + } + + @Override + public void shutdown() { + // 안해도 될것도 같고. LoggerFactory의unregister만 해도 될려나? + loggerCache = null; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinderInitializer.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinderInitializer.java index fc90155a2028..9d3582d5736c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinderInitializer.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jLoggerBinderInitializer.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.profiler.logging; - -import com.nhn.pinpoint.bootstrap.logging.PLoggerBinder; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -/** - * TestCase용의 쉽게 loggerBinder를 등록삭제할수 있는 api - * - * @author emeroad - */ -public class Slf4jLoggerBinderInitializer { - - private static final PLoggerBinder loggerBinder = new Slf4jLoggerBinder(); - - public static void beforeClass() { - PLoggerFactory.initialize(loggerBinder); - } - - public static void afterClass() { - PLoggerFactory.unregister(loggerBinder); - } -} +package com.nhn.pinpoint.profiler.logging; + +import com.nhn.pinpoint.bootstrap.logging.PLoggerBinder; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; + +/** + * TestCase용의 쉽게 loggerBinder를 등록삭제할수 있는 api + * + * @author emeroad + */ +public class Slf4jLoggerBinderInitializer { + + private static final PLoggerBinder loggerBinder = new Slf4jLoggerBinder(); + + public static void beforeClass() { + PLoggerFactory.initialize(loggerBinder); + } + + public static void afterClass() { + PLoggerFactory.unregister(loggerBinder); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jPLoggerAdapter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jPLoggerAdapter.java index 0b5ee119c244..4913fd28fa88 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jPLoggerAdapter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/logging/Slf4jPLoggerAdapter.java @@ -1,471 +1,471 @@ -package com.nhn.pinpoint.profiler.logging; - -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import org.slf4j.Marker; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.URL; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.*; - -/** - * @author emeroad - */ -public class Slf4jPLoggerAdapter implements PLogger { - public static final int BUFFER_SIZE = 512; - - private static final Map, Class> SIMPLE_TYPE = new IdentityHashMap, Class>(); - static { - SIMPLE_TYPE.put(String.class, String.class); - SIMPLE_TYPE.put(Boolean.class, Boolean.class); - SIMPLE_TYPE.put(boolean.class, boolean.class); - SIMPLE_TYPE.put(Byte.class, Byte.class); - SIMPLE_TYPE.put(byte.class, byte.class); - SIMPLE_TYPE.put(Short.class, Short.class); - SIMPLE_TYPE.put(short.class, short.class); - SIMPLE_TYPE.put(Integer.class, Integer.class); - SIMPLE_TYPE.put(int.class, int.class); - SIMPLE_TYPE.put(Long.class, Long.class); - SIMPLE_TYPE.put(long.class, long.class); - SIMPLE_TYPE.put(Float.class, Float.class); - SIMPLE_TYPE.put(float.class, float.class); - SIMPLE_TYPE.put(Double.class, Double.class); - SIMPLE_TYPE.put(double.class, double.class); - SIMPLE_TYPE.put(Character.class, Character.class); - SIMPLE_TYPE.put(char.class, char.class); - SIMPLE_TYPE.put(BigDecimal.class, BigDecimal.class); - SIMPLE_TYPE.put(StringBuffer.class, StringBuffer.class); - SIMPLE_TYPE.put(BigInteger.class, BigInteger.class); - SIMPLE_TYPE.put(Class.class, Class.class); - SIMPLE_TYPE.put(java.sql.Date.class, java.sql.Date.class); - SIMPLE_TYPE.put(java.util.Date.class, java.util.Date.class); - SIMPLE_TYPE.put(Time.class, Time.class); - SIMPLE_TYPE.put(Timestamp.class, Timestamp.class); - SIMPLE_TYPE.put(Calendar.class, Calendar.class); - SIMPLE_TYPE.put(GregorianCalendar.class, GregorianCalendar.class); - SIMPLE_TYPE.put(URL.class, URL.class); - SIMPLE_TYPE.put(Object.class, Object.class); - } - - - private final org.slf4j.Logger logger; - - public Slf4jPLoggerAdapter(org.slf4j.Logger logger) { - if (logger == null) { - throw new NullPointerException("logger must not be null"); - } - this.logger = logger; - } - - public String getName() { - return logger.getName(); - } - - @Override - public void beforeInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { - StringBuilder sb = new StringBuilder(BUFFER_SIZE); - sb.append("before "); - logMethod(sb, target, className, methodName, parameterDescription, args); - logger.debug(sb.toString()); - } - - @Override - public void beforeInterceptor(Object target, Object[] args) { - StringBuilder sb = new StringBuilder(BUFFER_SIZE); - sb.append("before "); - logMethod(sb, target, args); - logger.debug(sb.toString()); - } - - @Override - public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - StringBuilder sb = new StringBuilder(BUFFER_SIZE); - sb.append("after "); - logMethod(sb, target, className, methodName, parameterDescription, args); - logResult(sb, result, throwable); - - } - - - - @Override - public void afterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { - StringBuilder sb = new StringBuilder(BUFFER_SIZE); - sb.append("after "); - logMethod(sb, target, args); - logResult(sb, result, throwable); - if (throwable == null) { - logger.debug(sb.toString()); - } else { - logger.debug(sb.toString(), throwable); - } - } - - private static void logResult(StringBuilder sb, Object result, Throwable throwable) { - if (throwable == null) { - sb.append(" result:"); - sb.append(normalizedParameter(result)); - } else { - sb.append(" Caused:"); - sb.append(throwable.getMessage()); - } - } - - @Override - public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { - StringBuilder sb = new StringBuilder(BUFFER_SIZE); - sb.append("after "); - logMethod(sb, target, className, methodName, parameterDescription, args); - logger.debug(sb.toString()); - } - - @Override - public void afterInterceptor(Object target, Object[] args) { - StringBuilder sb = new StringBuilder(BUFFER_SIZE); - sb.append("after "); - logMethod(sb, target, args); - logger.debug(sb.toString()); - } - - private static void logMethod(StringBuilder sb, Object target, String className, String methodName, String parameterDescription, Object[] args) { - sb.append(getTarget(target)); - sb.append(' '); - sb.append(className); - sb.append(' '); - sb.append(methodName); - sb.append(parameterDescription); - sb.append(" args:"); - appendParameterList(sb, args); - } - - private static void logMethod(StringBuilder sb, Object target, Object[] args) { - sb.append(getTarget(target)); - sb.append(' '); - sb.append(" args:"); - appendParameterList(sb, args); - } - - private static String getTarget(Object target) { - // toString의 경우 sideeffect가 발생할수 있으므로 className을 호출하는것으로 변경함. - if (target == null) { - return "target=null"; - } else { - return target.getClass().getName(); - } - } - - private static void appendParameterList(StringBuilder sb, Object[] args) { - if (args == null) { - sb.append("()"); - return; - } - if (args.length == 0) { - sb.append("()"); - return; - } - if (args.length > 0) { - sb.append('('); - sb.append(normalizedParameter(args[0])); - for (int i = 1; i < args.length; i++) { - sb.append(", "); - sb.append(normalizedParameter(args[i])); - } - sb.append(')'); - } - return; - } - - private static String normalizedParameter(Object arg) { - // toString을 막 호출할 경우 사이드 이펙트가 있을수 있어 수정함. - if (arg == null) { - return "null"; - } else { - if (isSimpleType(arg)) { - // 안전한 타임에 대해서만 toString을 호출하도록 SimpleType 검사 - return arg.toString(); - } else { - return arg.getClass().getSimpleName(); - } - } - } - - private static boolean isSimpleType(Object arg) { - Class find = SIMPLE_TYPE.get(arg.getClass()); - if (find == null) { - return false; - } - return true; - } - - @Override - public boolean isTraceEnabled() { - return logger.isTraceEnabled(); - } - - @Override - public void trace(String msg) { - logger.trace(msg); - } - - @Override - public void trace(String format, Object arg) { - logger.trace(format, arg); - } - - @Override - public void trace(String format, Object arg1, Object arg2) { - logger.trace(format, arg1, arg2); - } - - @Override - public void trace(String format, Object[] argArray) { - logger.trace(format, argArray); - } - - @Override - public void trace(String msg, Throwable t) { - logger.trace(msg, t); - } - - public boolean isTraceEnabled(Marker marker) { - return logger.isTraceEnabled(marker); - } - - public void trace(Marker marker, String msg) { - logger.trace(marker, msg); - } - - public void trace(Marker marker, String format, Object arg) { - logger.trace(marker, format, arg); - } - - public void trace(Marker marker, String format, Object arg1, Object arg2) { - logger.trace(marker, format, arg1, arg2); - } - - public void trace(Marker marker, String format, Object[] argArray) { - logger.trace(marker, format, argArray); - } - - public void trace(Marker marker, String msg, Throwable t) { - logger.trace(marker, msg, t); - } - - @Override - public boolean isDebugEnabled() { - return logger.isDebugEnabled(); - } - - @Override - public void debug(String msg) { - logger.debug(msg); - } - - @Override - public void debug(String format, Object arg) { - logger.debug(format, arg); - } - - @Override - public void debug(String format, Object arg1, Object arg2) { - logger.debug(format, arg1, arg2); - } - - @Override - public void debug(String format, Object[] argArray) { - logger.debug(format, argArray); - } - - @Override - public void debug(String msg, Throwable t) { - logger.debug(msg, t); - } - - public boolean isDebugEnabled(Marker marker) { - return logger.isDebugEnabled(marker); - } - - public void debug(Marker marker, String msg) { - logger.debug(marker, msg); - } - - public void debug(Marker marker, String format, Object arg) { - logger.debug(marker, format, arg); - } - - public void debug(Marker marker, String format, Object arg1, Object arg2) { - logger.debug(marker, format, arg1, arg2); - } - - public void debug(Marker marker, String format, Object[] argArray) { - logger.debug(marker, format, argArray); - } - - public void debug(Marker marker, String msg, Throwable t) { - logger.debug(marker, msg, t); - } - - @Override - public boolean isInfoEnabled() { - return logger.isInfoEnabled(); - } - - @Override - public void info(String msg) { - logger.info(msg); - } - - @Override - public void info(String format, Object arg) { - logger.info(format, arg); - } - - @Override - public void info(String format, Object arg1, Object arg2) { - logger.info(format, arg1, arg2); - } - - @Override - public void info(String format, Object[] argArray) { - logger.info(format, argArray); - } - - @Override - public void info(String msg, Throwable t) { - logger.info(msg, t); - } - - public boolean isInfoEnabled(Marker marker) { - return logger.isInfoEnabled(marker); - } - - public void info(Marker marker, String msg) { - logger.info(marker, msg); - } - - public void info(Marker marker, String format, Object arg) { - logger.info(marker, format, arg); - } - - public void info(Marker marker, String format, Object arg1, Object arg2) { - logger.info(marker, format, arg1, arg2); - } - - public void info(Marker marker, String format, Object[] argArray) { - logger.info(marker, format, argArray); - } - - public void info(Marker marker, String msg, Throwable t) { - logger.info(marker, msg, t); - } - - @Override - public boolean isWarnEnabled() { - return logger.isWarnEnabled(); - } - - @Override - public void warn(String msg) { - logger.warn(msg); - } - - @Override - public void warn(String format, Object arg) { - logger.warn(format, arg); - } - - @Override - public void warn(String format, Object[] argArray) { - logger.warn(format, argArray); - } - - @Override - public void warn(String format, Object arg1, Object arg2) { - logger.warn(format, arg1, arg2); - } - - @Override - public void warn(String msg, Throwable t) { - logger.warn(msg, t); - } - - public boolean isWarnEnabled(Marker marker) { - return logger.isWarnEnabled(marker); - } - - public void warn(Marker marker, String msg) { - logger.warn(marker, msg); - } - - public void warn(Marker marker, String format, Object arg) { - logger.warn(marker, format, arg); - } - - public void warn(Marker marker, String format, Object arg1, Object arg2) { - logger.warn(marker, format, arg1, arg2); - } - - public void warn(Marker marker, String format, Object[] argArray) { - logger.warn(marker, format, argArray); - } - - public void warn(Marker marker, String msg, Throwable t) { - logger.warn(marker, msg, t); - } - - @Override - public boolean isErrorEnabled() { - return logger.isErrorEnabled(); - } - - @Override - public void error(String msg) { - logger.error(msg); - } - - @Override - public void error(String format, Object arg) { - logger.error(format, arg); - } - - @Override - public void error(String format, Object arg1, Object arg2) { - logger.error(format, arg1, arg2); - } - - @Override - public void error(String format, Object[] argArray) { - logger.error(format, argArray); - } - - @Override - public void error(String msg, Throwable t) { - logger.error(msg, t); - } - - public boolean isErrorEnabled(Marker marker) { - return logger.isErrorEnabled(marker); - } - - public void error(Marker marker, String msg) { - logger.error(marker, msg); - } - - public void error(Marker marker, String format, Object arg) { - logger.error(marker, format, arg); - } - - public void error(Marker marker, String format, Object arg1, Object arg2) { - logger.error(marker, format, arg1, arg2); - } - - public void error(Marker marker, String format, Object[] argArray) { - logger.error(marker, format, argArray); - } - - public void error(Marker marker, String msg, Throwable t) { - logger.error(marker, msg, t); - } -} +package com.nhn.pinpoint.profiler.logging; + +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import org.slf4j.Marker; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URL; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.*; + +/** + * @author emeroad + */ +public class Slf4jPLoggerAdapter implements PLogger { + public static final int BUFFER_SIZE = 512; + + private static final Map, Class> SIMPLE_TYPE = new IdentityHashMap, Class>(); + static { + SIMPLE_TYPE.put(String.class, String.class); + SIMPLE_TYPE.put(Boolean.class, Boolean.class); + SIMPLE_TYPE.put(boolean.class, boolean.class); + SIMPLE_TYPE.put(Byte.class, Byte.class); + SIMPLE_TYPE.put(byte.class, byte.class); + SIMPLE_TYPE.put(Short.class, Short.class); + SIMPLE_TYPE.put(short.class, short.class); + SIMPLE_TYPE.put(Integer.class, Integer.class); + SIMPLE_TYPE.put(int.class, int.class); + SIMPLE_TYPE.put(Long.class, Long.class); + SIMPLE_TYPE.put(long.class, long.class); + SIMPLE_TYPE.put(Float.class, Float.class); + SIMPLE_TYPE.put(float.class, float.class); + SIMPLE_TYPE.put(Double.class, Double.class); + SIMPLE_TYPE.put(double.class, double.class); + SIMPLE_TYPE.put(Character.class, Character.class); + SIMPLE_TYPE.put(char.class, char.class); + SIMPLE_TYPE.put(BigDecimal.class, BigDecimal.class); + SIMPLE_TYPE.put(StringBuffer.class, StringBuffer.class); + SIMPLE_TYPE.put(BigInteger.class, BigInteger.class); + SIMPLE_TYPE.put(Class.class, Class.class); + SIMPLE_TYPE.put(java.sql.Date.class, java.sql.Date.class); + SIMPLE_TYPE.put(java.util.Date.class, java.util.Date.class); + SIMPLE_TYPE.put(Time.class, Time.class); + SIMPLE_TYPE.put(Timestamp.class, Timestamp.class); + SIMPLE_TYPE.put(Calendar.class, Calendar.class); + SIMPLE_TYPE.put(GregorianCalendar.class, GregorianCalendar.class); + SIMPLE_TYPE.put(URL.class, URL.class); + SIMPLE_TYPE.put(Object.class, Object.class); + } + + + private final org.slf4j.Logger logger; + + public Slf4jPLoggerAdapter(org.slf4j.Logger logger) { + if (logger == null) { + throw new NullPointerException("logger must not be null"); + } + this.logger = logger; + } + + public String getName() { + return logger.getName(); + } + + @Override + public void beforeInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { + StringBuilder sb = new StringBuilder(BUFFER_SIZE); + sb.append("before "); + logMethod(sb, target, className, methodName, parameterDescription, args); + logger.debug(sb.toString()); + } + + @Override + public void beforeInterceptor(Object target, Object[] args) { + StringBuilder sb = new StringBuilder(BUFFER_SIZE); + sb.append("before "); + logMethod(sb, target, args); + logger.debug(sb.toString()); + } + + @Override + public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + StringBuilder sb = new StringBuilder(BUFFER_SIZE); + sb.append("after "); + logMethod(sb, target, className, methodName, parameterDescription, args); + logResult(sb, result, throwable); + + } + + + + @Override + public void afterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { + StringBuilder sb = new StringBuilder(BUFFER_SIZE); + sb.append("after "); + logMethod(sb, target, args); + logResult(sb, result, throwable); + if (throwable == null) { + logger.debug(sb.toString()); + } else { + logger.debug(sb.toString(), throwable); + } + } + + private static void logResult(StringBuilder sb, Object result, Throwable throwable) { + if (throwable == null) { + sb.append(" result:"); + sb.append(normalizedParameter(result)); + } else { + sb.append(" Caused:"); + sb.append(throwable.getMessage()); + } + } + + @Override + public void afterInterceptor(Object target, String className, String methodName, String parameterDescription, Object[] args) { + StringBuilder sb = new StringBuilder(BUFFER_SIZE); + sb.append("after "); + logMethod(sb, target, className, methodName, parameterDescription, args); + logger.debug(sb.toString()); + } + + @Override + public void afterInterceptor(Object target, Object[] args) { + StringBuilder sb = new StringBuilder(BUFFER_SIZE); + sb.append("after "); + logMethod(sb, target, args); + logger.debug(sb.toString()); + } + + private static void logMethod(StringBuilder sb, Object target, String className, String methodName, String parameterDescription, Object[] args) { + sb.append(getTarget(target)); + sb.append(' '); + sb.append(className); + sb.append(' '); + sb.append(methodName); + sb.append(parameterDescription); + sb.append(" args:"); + appendParameterList(sb, args); + } + + private static void logMethod(StringBuilder sb, Object target, Object[] args) { + sb.append(getTarget(target)); + sb.append(' '); + sb.append(" args:"); + appendParameterList(sb, args); + } + + private static String getTarget(Object target) { + // toString의 경우 sideeffect가 발생할수 있으므로 className을 호출하는것으로 변경함. + if (target == null) { + return "target=null"; + } else { + return target.getClass().getName(); + } + } + + private static void appendParameterList(StringBuilder sb, Object[] args) { + if (args == null) { + sb.append("()"); + return; + } + if (args.length == 0) { + sb.append("()"); + return; + } + if (args.length > 0) { + sb.append('('); + sb.append(normalizedParameter(args[0])); + for (int i = 1; i < args.length; i++) { + sb.append(", "); + sb.append(normalizedParameter(args[i])); + } + sb.append(')'); + } + return; + } + + private static String normalizedParameter(Object arg) { + // toString을 막 호출할 경우 사이드 이펙트가 있을수 있어 수정함. + if (arg == null) { + return "null"; + } else { + if (isSimpleType(arg)) { + // 안전한 타임에 대해서만 toString을 호출하도록 SimpleType 검사 + return arg.toString(); + } else { + return arg.getClass().getSimpleName(); + } + } + } + + private static boolean isSimpleType(Object arg) { + Class find = SIMPLE_TYPE.get(arg.getClass()); + if (find == null) { + return false; + } + return true; + } + + @Override + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + @Override + public void trace(String msg) { + logger.trace(msg); + } + + @Override + public void trace(String format, Object arg) { + logger.trace(format, arg); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + logger.trace(format, arg1, arg2); + } + + @Override + public void trace(String format, Object[] argArray) { + logger.trace(format, argArray); + } + + @Override + public void trace(String msg, Throwable t) { + logger.trace(msg, t); + } + + public boolean isTraceEnabled(Marker marker) { + return logger.isTraceEnabled(marker); + } + + public void trace(Marker marker, String msg) { + logger.trace(marker, msg); + } + + public void trace(Marker marker, String format, Object arg) { + logger.trace(marker, format, arg); + } + + public void trace(Marker marker, String format, Object arg1, Object arg2) { + logger.trace(marker, format, arg1, arg2); + } + + public void trace(Marker marker, String format, Object[] argArray) { + logger.trace(marker, format, argArray); + } + + public void trace(Marker marker, String msg, Throwable t) { + logger.trace(marker, msg, t); + } + + @Override + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + public void debug(String msg) { + logger.debug(msg); + } + + @Override + public void debug(String format, Object arg) { + logger.debug(format, arg); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + logger.debug(format, arg1, arg2); + } + + @Override + public void debug(String format, Object[] argArray) { + logger.debug(format, argArray); + } + + @Override + public void debug(String msg, Throwable t) { + logger.debug(msg, t); + } + + public boolean isDebugEnabled(Marker marker) { + return logger.isDebugEnabled(marker); + } + + public void debug(Marker marker, String msg) { + logger.debug(marker, msg); + } + + public void debug(Marker marker, String format, Object arg) { + logger.debug(marker, format, arg); + } + + public void debug(Marker marker, String format, Object arg1, Object arg2) { + logger.debug(marker, format, arg1, arg2); + } + + public void debug(Marker marker, String format, Object[] argArray) { + logger.debug(marker, format, argArray); + } + + public void debug(Marker marker, String msg, Throwable t) { + logger.debug(marker, msg, t); + } + + @Override + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + @Override + public void info(String msg) { + logger.info(msg); + } + + @Override + public void info(String format, Object arg) { + logger.info(format, arg); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + logger.info(format, arg1, arg2); + } + + @Override + public void info(String format, Object[] argArray) { + logger.info(format, argArray); + } + + @Override + public void info(String msg, Throwable t) { + logger.info(msg, t); + } + + public boolean isInfoEnabled(Marker marker) { + return logger.isInfoEnabled(marker); + } + + public void info(Marker marker, String msg) { + logger.info(marker, msg); + } + + public void info(Marker marker, String format, Object arg) { + logger.info(marker, format, arg); + } + + public void info(Marker marker, String format, Object arg1, Object arg2) { + logger.info(marker, format, arg1, arg2); + } + + public void info(Marker marker, String format, Object[] argArray) { + logger.info(marker, format, argArray); + } + + public void info(Marker marker, String msg, Throwable t) { + logger.info(marker, msg, t); + } + + @Override + public boolean isWarnEnabled() { + return logger.isWarnEnabled(); + } + + @Override + public void warn(String msg) { + logger.warn(msg); + } + + @Override + public void warn(String format, Object arg) { + logger.warn(format, arg); + } + + @Override + public void warn(String format, Object[] argArray) { + logger.warn(format, argArray); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + logger.warn(format, arg1, arg2); + } + + @Override + public void warn(String msg, Throwable t) { + logger.warn(msg, t); + } + + public boolean isWarnEnabled(Marker marker) { + return logger.isWarnEnabled(marker); + } + + public void warn(Marker marker, String msg) { + logger.warn(marker, msg); + } + + public void warn(Marker marker, String format, Object arg) { + logger.warn(marker, format, arg); + } + + public void warn(Marker marker, String format, Object arg1, Object arg2) { + logger.warn(marker, format, arg1, arg2); + } + + public void warn(Marker marker, String format, Object[] argArray) { + logger.warn(marker, format, argArray); + } + + public void warn(Marker marker, String msg, Throwable t) { + logger.warn(marker, msg, t); + } + + @Override + public boolean isErrorEnabled() { + return logger.isErrorEnabled(); + } + + @Override + public void error(String msg) { + logger.error(msg); + } + + @Override + public void error(String format, Object arg) { + logger.error(format, arg); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + logger.error(format, arg1, arg2); + } + + @Override + public void error(String format, Object[] argArray) { + logger.error(format, argArray); + } + + @Override + public void error(String msg, Throwable t) { + logger.error(msg, t); + } + + public boolean isErrorEnabled(Marker marker) { + return logger.isErrorEnabled(marker); + } + + public void error(Marker marker, String msg) { + logger.error(marker, msg); + } + + public void error(Marker marker, String format, Object arg) { + logger.error(marker, format, arg); + } + + public void error(Marker marker, String format, Object arg1, Object arg2) { + logger.error(marker, format, arg1, arg2); + } + + public void error(Marker marker, String format, Object[] argArray) { + logger.error(marker, format, argArray); + } + + public void error(Marker marker, String msg, Throwable t) { + logger.error(marker, msg, t); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/LRUCache.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/LRUCache.java index 00b79495d8fa..6373d3b52971 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/LRUCache.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/LRUCache.java @@ -1,49 +1,49 @@ -package com.nhn.pinpoint.profiler.metadata; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; - -import java.util.concurrent.ConcurrentMap; - - -/** - * concurrent lru cache - * @author emeroad - */ -public class LRUCache { - - private static final Object V = new Object(); - public static final int DEFAULT_CACHE_SIZE = 1024; - - private final ConcurrentMap cache; - - - public LRUCache(int maxCacheSize) { - final CacheBuilder cacheBuilder = CacheBuilder.newBuilder(); - cacheBuilder.concurrencyLevel(32); - cacheBuilder.initialCapacity(maxCacheSize); - cacheBuilder.maximumSize(maxCacheSize); - Cache localCache = cacheBuilder.build(); - this.cache = localCache.asMap(); - } - - public LRUCache() { - this(DEFAULT_CACHE_SIZE); - } - - - public boolean put(T value) { - - Object oldValue = cache.putIfAbsent(value, V); - if (oldValue == null) { - return true; - } - return false; - - } - - public long getSize() { - return cache.size(); - } - -} +package com.nhn.pinpoint.profiler.metadata; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +import java.util.concurrent.ConcurrentMap; + + +/** + * concurrent lru cache + * @author emeroad + */ +public class LRUCache { + + private static final Object V = new Object(); + public static final int DEFAULT_CACHE_SIZE = 1024; + + private final ConcurrentMap cache; + + + public LRUCache(int maxCacheSize) { + final CacheBuilder cacheBuilder = CacheBuilder.newBuilder(); + cacheBuilder.concurrencyLevel(32); + cacheBuilder.initialCapacity(maxCacheSize); + cacheBuilder.maximumSize(maxCacheSize); + Cache localCache = cacheBuilder.build(); + this.cache = localCache.asMap(); + } + + public LRUCache() { + this(DEFAULT_CACHE_SIZE); + } + + + public boolean put(T value) { + + Object oldValue = cache.putIfAbsent(value, V); + if (oldValue == null) { + return true; + } + return false; + + } + + public long getSize() { + return cache.size(); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/Result.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/Result.java index 8c2022f7ed1b..d4c17e9da946 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/Result.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/Result.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.profiler.metadata; - -/** - * @author emeroad - */ -public class Result { - - private final boolean newValue; - private final int id; - - public Result(boolean newValue, int id) { - this.newValue = newValue; - this.id = id; - } - - public boolean isNewValue() { - return newValue; - } - - public int getId() { - return id; - } - -} +package com.nhn.pinpoint.profiler.metadata; + +/** + * @author emeroad + */ +public class Result { + + private final boolean newValue; + private final int id; + + public Result(boolean newValue, int id) { + this.newValue = newValue; + this.id = id; + } + + public boolean isNewValue() { + return newValue; + } + + public int getId() { + return id; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/SimpleCache.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/SimpleCache.java index 850d026d3d29..76e0eccfdb23 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/SimpleCache.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/metadata/SimpleCache.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.profiler.metadata; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.nhn.pinpoint.common.util.BytesUtils; - -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class SimpleCache { - // 0인값은 존재 하지 않음을 나타냄. - private final AtomicInteger idGen; - private final ConcurrentMap cache; - - - public SimpleCache() { - this(1024, 1); - } - - public SimpleCache(int cacheSize) { - this(cacheSize, 1); - } - - public SimpleCache(int cacheSize, int startValue) { - idGen = new AtomicInteger(startValue); - cache = createCache(cacheSize); - } - - private ConcurrentMap createCache(int maxCacheSize) { - final CacheBuilder cacheBuilder = CacheBuilder.newBuilder(); - cacheBuilder.concurrencyLevel(64); - cacheBuilder.initialCapacity(maxCacheSize); - cacheBuilder.maximumSize(maxCacheSize); - Cache localCache = cacheBuilder.build(); - ConcurrentMap cache = localCache.asMap(); - return cache; - } - - public Result put(T value) { - final Result find = this.cache.get(value); - if (find != null) { - return find; - } - //음수까지 활용하여 가능한 데이터 인코딩을 작게 유지되게 함. - final int newId = BytesUtils.zigzagToInt(idGen.getAndIncrement()); - final Result result = new Result(false, newId); - final Result before = this.cache.putIfAbsent(value, result); - if (before != null) { - return before; - } - return new Result(true, newId); - } - -} +package com.nhn.pinpoint.profiler.metadata; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.nhn.pinpoint.common.util.BytesUtils; + +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class SimpleCache { + // 0인값은 존재 하지 않음을 나타냄. + private final AtomicInteger idGen; + private final ConcurrentMap cache; + + + public SimpleCache() { + this(1024, 1); + } + + public SimpleCache(int cacheSize) { + this(cacheSize, 1); + } + + public SimpleCache(int cacheSize, int startValue) { + idGen = new AtomicInteger(startValue); + cache = createCache(cacheSize); + } + + private ConcurrentMap createCache(int maxCacheSize) { + final CacheBuilder cacheBuilder = CacheBuilder.newBuilder(); + cacheBuilder.concurrencyLevel(64); + cacheBuilder.initialCapacity(maxCacheSize); + cacheBuilder.maximumSize(maxCacheSize); + Cache localCache = cacheBuilder.build(); + ConcurrentMap cache = localCache.asMap(); + return cache; + } + + public Result put(T value) { + final Result find = this.cache.get(value); + if (find != null) { + return find; + } + //음수까지 활용하여 가능한 데이터 인코딩을 작게 유지되게 함. + final int newId = BytesUtils.zigzagToInt(idGen.getAndIncrement()); + final Result result = new Result(false, newId); + final Result before = this.cache.putIfAbsent(value, result); + if (before != null) { + return before; + } + return new Result(true, newId); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java index a1f1fb7029d4..369a7fa0d902 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java @@ -38,10 +38,7 @@ import com.nhn.pinpoint.profiler.modifier.db.cubrid.CubridStatementModifier; import com.nhn.pinpoint.profiler.modifier.db.dbcp.DBCPBasicDataSourceModifier; import com.nhn.pinpoint.profiler.modifier.db.dbcp.DBCPPoolGuardConnectionWrapperModifier; -import com.nhn.pinpoint.profiler.modifier.db.mssql.MSSQLConnectionModifier; -import com.nhn.pinpoint.profiler.modifier.db.mssql.MSSQLPreparedStatementModifier; -import com.nhn.pinpoint.profiler.modifier.db.mssql.MSSQLResultSetModifier; -import com.nhn.pinpoint.profiler.modifier.db.mssql.MSSQLStatementModifier; +import com.nhn.pinpoint.profiler.modifier.db.jtds.*; import com.nhn.pinpoint.profiler.modifier.db.mysql.MySQLConnectionImplModifier; import com.nhn.pinpoint.profiler.modifier.db.mysql.MySQLConnectionModifier; import com.nhn.pinpoint.profiler.modifier.db.mysql.MySQLNonRegisteringDriverModifier; @@ -69,10 +66,9 @@ import com.nhn.pinpoint.profiler.modifier.servlet.HttpServletModifier; import com.nhn.pinpoint.profiler.modifier.servlet.SpringFrameworkServletModifier; import com.nhn.pinpoint.profiler.modifier.spring.orm.ibatis.SqlMapClientTemplateModifier; -import com.nhn.pinpoint.profiler.modifier.tomcat.CatalinaModifier; import com.nhn.pinpoint.profiler.modifier.tomcat.StandardHostValveInvokeModifier; +import com.nhn.pinpoint.profiler.modifier.tomcat.StandardServiceModifier; import com.nhn.pinpoint.profiler.modifier.tomcat.TomcatConnectorModifier; -import com.nhn.pinpoint.profiler.modifier.tomcat.TomcatStandardServiceModifier; /** * @author emeroad @@ -210,14 +206,11 @@ public void addTomcatModifier() { SpringFrameworkServletModifier springServletModifier = new SpringFrameworkServletModifier(byteCodeInstrumentor, agent); addModifier(springServletModifier); - Modifier tomcatStandardServiceModifier = new TomcatStandardServiceModifier(byteCodeInstrumentor, agent); + Modifier tomcatStandardServiceModifier = new StandardServiceModifier(byteCodeInstrumentor, agent); addModifier(tomcatStandardServiceModifier); Modifier tomcatConnectorModifier = new TomcatConnectorModifier(byteCodeInstrumentor, agent); addModifier(tomcatConnectorModifier); - - Modifier tomcatCatalinaModifier = new CatalinaModifier(byteCodeInstrumentor, agent); - addModifier(tomcatCatalinaModifier); } public void addJdbcModifier() { @@ -230,9 +223,8 @@ public void addJdbcModifier() { addMySqlDriver(); } - if (profilerConfig.isJdbcProfileMsSql()) { -// 아직 개발이 안됨 -// addMsSqlDriver(); + if (profilerConfig.isJdbcProfileJtds()) { + addJtdsDriver(); } if (profilerConfig.isJdbcProfileOracle()) { @@ -276,18 +268,23 @@ private void addMySqlDriver() { // addModifier(mysqlResultSetModifier); } - private void addMsSqlDriver() { + private void addJtdsDriver() { + JtdsDriverModifier jtdsDriverModifier = new JtdsDriverModifier(byteCodeInstrumentor, agent); + addModifier(jtdsDriverModifier); + + Modifier jdbc2ConnectionModifier = new Jdbc2ConnectionModifier(byteCodeInstrumentor, agent); + addModifier(jdbc2ConnectionModifier); - Modifier mssqlConnectionModifier = new MSSQLConnectionModifier(byteCodeInstrumentor, agent); - addModifier(mssqlConnectionModifier); + Modifier jdbc4_1ConnectionModifier = new Jdbc4_1ConnectionModifier(byteCodeInstrumentor, agent); + addModifier(jdbc4_1ConnectionModifier); - Modifier mssqlStatementModifier = new MSSQLStatementModifier(byteCodeInstrumentor, agent); + Modifier mssqlStatementModifier = new JtdsStatementModifier(byteCodeInstrumentor, agent); addModifier(mssqlStatementModifier); - Modifier mssqlPreparedStatementModifier = new MSSQLPreparedStatementModifier(byteCodeInstrumentor, agent); + Modifier mssqlPreparedStatementModifier = new JtdsPreparedStatementModifier(byteCodeInstrumentor, agent); addModifier(mssqlPreparedStatementModifier); - Modifier mssqlResultSetModifier = new MSSQLResultSetModifier(byteCodeInstrumentor, agent); + Modifier mssqlResultSetModifier = new JtdsResultSetModifier(byteCodeInstrumentor, agent); addModifier(mssqlResultSetModifier); } @@ -367,6 +364,19 @@ public void addOrmModifier() { addMyBatisSupport(); } + public void addRedisSupport() { + addModifier(new JedisClientModifier(byteCodeInstrumentor, agent)); + addModifier(new JedisModifier(byteCodeInstrumentor, agent)); + addModifier(new JedisPipelineModifier(byteCodeInstrumentor, agent)); + } + + public void addNBaseArcSupport() { + addModifier(new GatewayModifier(byteCodeInstrumentor, agent)); + addModifier(new GatewayServerModifier(byteCodeInstrumentor, agent)); + addModifier(new RedisClusterModifier(byteCodeInstrumentor, agent)); + addModifier(new RedisClusterPipelineModifier(byteCodeInstrumentor, agent)); + } + private void addIBatisSupport() { if (profilerConfig.isIBatisEnabled()) { addModifier(new SqlMapSessionImplModifier(byteCodeInstrumentor, agent)); @@ -381,24 +391,4 @@ private void addMyBatisSupport() { addModifier(new SqlSessionTemplateModifier(byteCodeInstrumentor, agent)); } } - - - public void addRedisSupport() { - if (profilerConfig.isRedisEnabled()) { - addModifier(new JedisClientModifier(byteCodeInstrumentor, agent)); - addModifier(new JedisModifier(byteCodeInstrumentor, agent)); - addModifier(new JedisPipelineModifier(byteCodeInstrumentor, agent)); - } - } - - public void addNBaseArcSupport() { - if (profilerConfig.isNBaseArcEnabled()) { - addModifier(new GatewayModifier(byteCodeInstrumentor, agent)); - addModifier(new GatewayServerModifier(byteCodeInstrumentor, agent)); - addModifier(new RedisClusterModifier(byteCodeInstrumentor, agent)); - addModifier(new RedisClusterPipelineModifier(byteCodeInstrumentor, agent)); - } - } - - -} \ No newline at end of file +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/InterceptorConstant.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/InterceptorConstant.java index fa1bbfb1a89c..3f71a057fab1 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/InterceptorConstant.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/InterceptorConstant.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.profiler.modifier; - -/** - * @author emeroad - */ -public class InterceptorConstant { - -} +package com.nhn.pinpoint.profiler.modifier; + +/** + * @author emeroad + */ +public class InterceptorConstant { + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/Modifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/Modifier.java index f6a9fa481c83..3a595d4d76a2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/Modifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/Modifier.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.profiler.modifier; - -import java.security.ProtectionDomain; - -/** - * @author emeroad - */ -public interface Modifier { - byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer); - - String getTargetClass(); -} +package com.nhn.pinpoint.profiler.modifier; + +import java.security.ProtectionDomain; + +/** + * @author emeroad + */ +public interface Modifier { + byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer); + + String getTargetClass(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/ModifierRegistry.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/ModifierRegistry.java index b17379be51e5..9146211b9d22 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/ModifierRegistry.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/ModifierRegistry.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.profiler.modifier; - -/** - * @author emeroad - */ -public interface ModifierRegistry { - - Modifier findModifier(String className); - -} +package com.nhn.pinpoint.profiler.modifier; + +/** + * @author emeroad + */ +public interface ModifierRegistry { + + Modifier findModifier(String className); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ArcusMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ArcusMethodFilter.java index bc9f4af0bd5e..fd706286f7ba 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ArcusMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ArcusMethodFilter.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import javassist.CtMethod; - -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -/** - * @author emeroad - */ -public class ArcusMethodFilter implements MethodFilter { - private final static Object FIND = new Object(); - private final static Map WHITE_LIST_API; - - static { - WHITE_LIST_API = createRule(); - } - - private static Map createRule() { - String[] apiList = { - "asyncBopCreate", - "asyncBopDelete", - "asyncBopGet", - "asyncBopGetBulk", - "asyncBopGetItemCount", - "asyncBopInsert", - "asyncBopInsertBulk", - "asyncBopPipedInsertBulk", - "asyncBopSortMergeGet", - "asyncBopUpdate", - "asyncGetAttr", - "asyncLopCreate", - "asyncLopDelete", - "asyncLopGet", - "asyncLopInsert", - "asyncLopInsertBulk", - "asyncLopPipedInsertBulk", - "asyncSetAttr", - "asyncSetBulk", - "asyncSopCreate", - "asyncSopDelete", - "asyncSopExist", - "asyncSopGet", - "asyncSopInsert", - "asyncSopInsertBulk", - "asyncSopPipedExistBulk", - "asyncSopPipedInsertBulk" - }; - Map rule = new HashMap(); - for (String api : apiList) { - rule.put(api, FIND); - } - return rule; - } - - public ArcusMethodFilter() { - } - - @Override - public boolean filter(CtMethod ctMethod) { - final int modifiers = ctMethod.getModifiers(); - if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - return true; - } - if (WHITE_LIST_API.get(ctMethod.getName()) == FIND) { - return false; - } - return true; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import javassist.CtMethod; + +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +/** + * @author emeroad + */ +public class ArcusMethodFilter implements MethodFilter { + private final static Object FIND = new Object(); + private final static Map WHITE_LIST_API; + + static { + WHITE_LIST_API = createRule(); + } + + private static Map createRule() { + String[] apiList = { + "asyncBopCreate", + "asyncBopDelete", + "asyncBopGet", + "asyncBopGetBulk", + "asyncBopGetItemCount", + "asyncBopInsert", + "asyncBopInsertBulk", + "asyncBopPipedInsertBulk", + "asyncBopSortMergeGet", + "asyncBopUpdate", + "asyncGetAttr", + "asyncLopCreate", + "asyncLopDelete", + "asyncLopGet", + "asyncLopInsert", + "asyncLopInsertBulk", + "asyncLopPipedInsertBulk", + "asyncSetAttr", + "asyncSetBulk", + "asyncSopCreate", + "asyncSopDelete", + "asyncSopExist", + "asyncSopGet", + "asyncSopInsert", + "asyncSopInsertBulk", + "asyncSopPipedExistBulk", + "asyncSopPipedInsertBulk" + }; + Map rule = new HashMap(); + for (String api : apiList) { + rule.put(api, FIND); + } + return rule; + } + + public ArcusMethodFilter() { + } + + @Override + public boolean filter(CtMethod ctMethod) { + final int modifiers = ctMethod.getModifiers(); + if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return true; + } + if (WHITE_LIST_API.get(ctMethod.getName()) == FIND) { + return false; + } + return true; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/CollectionFutureModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/CollectionFutureModifier.java index cb66393ed73f..a738c53a5bc9 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/CollectionFutureModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/CollectionFutureModifier.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class CollectionFutureModifier extends AbstractFutureModifier { - - public CollectionFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return "net/spy/memcached/internal/CollectionFuture"; - - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class CollectionFutureModifier extends AbstractFutureModifier { + + public CollectionFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return "net/spy/memcached/internal/CollectionFuture"; + + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifier.java index bf118c6ea0b2..9ded0e257e71 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifier.java @@ -1,59 +1,59 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.arcus.interceptor.ArcusScope; -import com.nhn.pinpoint.profiler.modifier.arcus.interceptor.FrontCacheGetFutureConstructInterceptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.security.ProtectionDomain; - -/** - * @author harebox - */ -public class FrontCacheGetFutureModifier extends AbstractModifier { - - protected Logger logger; - - public FrontCacheGetFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifying. {}", javassistClassName); - } - - try { - InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); - - aClass.addTraceVariable("__cacheName", "__setCacheName", "__getCacheName", "java.lang.String"); - aClass.addTraceVariable("__cacheKey", "__setCacheKey", "__getCacheKey", "java.lang.String"); - - Interceptor frontCacheGetFutureConstructInterceptor = new FrontCacheGetFutureConstructInterceptor(); - aClass.addConstructorInterceptor(new String[]{"net.sf.ehcache.Element"}, frontCacheGetFutureConstructInterceptor); - - SimpleAroundInterceptor frontCacheGetFutureGetInterceptor = (SimpleAroundInterceptor) byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.modifier.arcus.interceptor.FrontCacheGetFutureGetInterceptor"); - aClass.addScopeInterceptor("get", new String[]{Long.TYPE.toString(), "java.util.concurrent.TimeUnit"}, frontCacheGetFutureGetInterceptor, ArcusScope.SCOPE); - aClass.addScopeInterceptor("get", new String[]{}, frontCacheGetFutureGetInterceptor, ArcusScope.SCOPE); - - return aClass.toBytecode(); - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - return null; - } - } - - @Override - public String getTargetClass() { - return "net/spy/memcached/plugin/FrontCacheGetFuture"; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.arcus.interceptor.ArcusScope; +import com.nhn.pinpoint.profiler.modifier.arcus.interceptor.FrontCacheGetFutureConstructInterceptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.ProtectionDomain; + +/** + * @author harebox + */ +public class FrontCacheGetFutureModifier extends AbstractModifier { + + protected Logger logger; + + public FrontCacheGetFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifying. {}", javassistClassName); + } + + try { + InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); + + aClass.addTraceVariable("__cacheName", "__setCacheName", "__getCacheName", "java.lang.String"); + aClass.addTraceVariable("__cacheKey", "__setCacheKey", "__getCacheKey", "java.lang.String"); + + Interceptor frontCacheGetFutureConstructInterceptor = new FrontCacheGetFutureConstructInterceptor(); + aClass.addConstructorInterceptor(new String[]{"net.sf.ehcache.Element"}, frontCacheGetFutureConstructInterceptor); + + SimpleAroundInterceptor frontCacheGetFutureGetInterceptor = (SimpleAroundInterceptor) byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.modifier.arcus.interceptor.FrontCacheGetFutureGetInterceptor"); + aClass.addScopeInterceptor("get", new String[]{Long.TYPE.toString(), "java.util.concurrent.TimeUnit"}, frontCacheGetFutureGetInterceptor, ArcusScope.SCOPE); + aClass.addScopeInterceptor("get", new String[]{}, frontCacheGetFutureGetInterceptor, ArcusScope.SCOPE); + + return aClass.toBytecode(); + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + return null; + } + } + + @Override + public String getTargetClass() { + return "net/spy/memcached/plugin/FrontCacheGetFuture"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheMemcachedMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheMemcachedMethodFilter.java index 6d00c2283965..156e8b5623b7 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheMemcachedMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheMemcachedMethodFilter.java @@ -1,65 +1,65 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import javassist.CtMethod; - -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -/** - * @author emeroad - * @author harebox - */ -public class FrontCacheMemcachedMethodFilter implements MethodFilter { - private final static Object FIND = new Object(); - private final static Map WHITE_LIST_API; - - static { - WHITE_LIST_API = createRule(); - } - - private static Map createRule() { - String[] apiList = { - "add", - "append", - "asyncCAS", - "asyncDecr", - "asyncGet", - "asyncGetBulk", - "asyncGets", - "asyncIncr", - "cas", - "decr", - "delete", - "get", - "getBulk", - "gets", - "incr", - "prepend", - "replace", - "set", - "putFrontCache" - }; - Map rule = new HashMap(); - for (String api : apiList) { - rule.put(api, FIND); - } - return rule; - } - - public FrontCacheMemcachedMethodFilter() { - } - - @Override - public boolean filter(CtMethod ctMethod) { - final int modifiers = ctMethod.getModifiers(); - if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - return true; - } - if (WHITE_LIST_API.get(ctMethod.getName()) == FIND) { - return false; - } - return true; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import javassist.CtMethod; + +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +/** + * @author emeroad + * @author harebox + */ +public class FrontCacheMemcachedMethodFilter implements MethodFilter { + private final static Object FIND = new Object(); + private final static Map WHITE_LIST_API; + + static { + WHITE_LIST_API = createRule(); + } + + private static Map createRule() { + String[] apiList = { + "add", + "append", + "asyncCAS", + "asyncDecr", + "asyncGet", + "asyncGetBulk", + "asyncGets", + "asyncIncr", + "cas", + "decr", + "delete", + "get", + "getBulk", + "gets", + "incr", + "prepend", + "replace", + "set", + "putFrontCache" + }; + Map rule = new HashMap(); + for (String api : apiList) { + rule.put(api, FIND); + } + return rule; + } + + public FrontCacheMemcachedMethodFilter() { + } + + @Override + public boolean filter(CtMethod ctMethod) { + final int modifiers = ctMethod.getModifiers(); + if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return true; + } + if (WHITE_LIST_API.get(ctMethod.getName()) == FIND) { + return false; + } + return true; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/GetFutureModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/GetFutureModifier.java index 31eeab62ef4d..065a787fb517 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/GetFutureModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/GetFutureModifier.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class GetFutureModifier extends AbstractFutureModifier { - - public GetFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return "net/spy/memcached/internal/GetFuture"; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class GetFutureModifier extends AbstractFutureModifier { + + public GetFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return "net/spy/memcached/internal/GetFuture"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ImmediateFutureModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ImmediateFutureModifier.java index 166f74ddfdaa..e72311e6dcb3 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ImmediateFutureModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ImmediateFutureModifier.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class ImmediateFutureModifier extends AbstractFutureModifier { - - public ImmediateFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return "net/spy/memcached/internal/ImmediateFuture"; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class ImmediateFutureModifier extends AbstractFutureModifier { + + public ImmediateFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return "net/spy/memcached/internal/ImmediateFuture"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/MemcachedMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/MemcachedMethodFilter.java index f374c6c7fccf..9d13f805ba6f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/MemcachedMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/MemcachedMethodFilter.java @@ -1,63 +1,63 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import javassist.CtMethod; - -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -/** - * @author emeroad - */ -public class MemcachedMethodFilter implements MethodFilter { - private final static Object FIND = new Object(); - private final static Map WHITE_LIST_API; - - static { - WHITE_LIST_API = createRule(); - } - - private static Map createRule() { - String[] apiList = { - "add", - "append", - "asyncCAS", - "asyncDecr", - "asyncGet", - "asyncGetBulk", - "asyncGets", - "asyncIncr", - "cas", - "decr", - "delete", - "get", - "getBulk", - "gets", - "incr", - "prepend", - "replace", - "set" - }; - Map rule = new HashMap(); - for (String api : apiList) { - rule.put(api, FIND); - } - return rule; - } - - public MemcachedMethodFilter() { - } - - @Override - public boolean filter(CtMethod ctMethod) { - final int modifiers = ctMethod.getModifiers(); - if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - return true; - } - if (WHITE_LIST_API.get(ctMethod.getName()) == FIND) { - return false; - } - return true; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import javassist.CtMethod; + +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +/** + * @author emeroad + */ +public class MemcachedMethodFilter implements MethodFilter { + private final static Object FIND = new Object(); + private final static Map WHITE_LIST_API; + + static { + WHITE_LIST_API = createRule(); + } + + private static Map createRule() { + String[] apiList = { + "add", + "append", + "asyncCAS", + "asyncDecr", + "asyncGet", + "asyncGetBulk", + "asyncGets", + "asyncIncr", + "cas", + "decr", + "delete", + "get", + "getBulk", + "gets", + "incr", + "prepend", + "replace", + "set" + }; + Map rule = new HashMap(); + for (String api : apiList) { + rule.put(api, FIND); + } + return rule; + } + + public MemcachedMethodFilter() { + } + + @Override + public boolean filter(CtMethod ctMethod) { + final int modifiers = ctMethod.getModifiers(); + if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return true; + } + if (WHITE_LIST_API.get(ctMethod.getName()) == FIND) { + return false; + } + return true; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/OperationFutureModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/OperationFutureModifier.java index 05a825aabce3..9eaed700e6c5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/OperationFutureModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/OperationFutureModifier.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class OperationFutureModifier extends AbstractFutureModifier { - - - public OperationFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return "net/spy/memcached/internal/OperationFuture"; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class OperationFutureModifier extends AbstractFutureModifier { + + + public OperationFutureModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return "net/spy/memcached/internal/OperationFuture"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ParameterUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ParameterUtils.java index c25f5a724442..3051138cb4c4 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ParameterUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/ParameterUtils.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.profiler.interceptor.bci.Method; - -/** - * @author emeroad - */ -public class ParameterUtils { - - public static int findFirstString(Method method, int maxIndex) { - if (method == null) { - return -1; - } - final String[] methodParams = method.getMethodParams(); - final int minIndex = Math.min(methodParams.length, maxIndex); - for(int i =0; i < minIndex; i++) { - if ("java.lang.String".equals(methodParams[i])) { - return i; - } - } - return -1; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.profiler.interceptor.bci.Method; + +/** + * @author emeroad + */ +public class ParameterUtils { + + public static int findFirstString(Method method, int maxIndex) { + if (method == null) { + return -1; + } + final String[] methodParams = method.getMethodParams(); + final int minIndex = Math.min(methodParams.length, maxIndex); + for(int i =0; i < minIndex; i++) { + if ("java.lang.String".equals(methodParams[i])) { + return i; + } + } + return -1; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/AddOpInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/AddOpInterceptor.java index ba12029f3e10..c092e4d4aa5a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/AddOpInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/AddOpInterceptor.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import net.spy.memcached.ops.Operation; - -import com.nhn.pinpoint.bootstrap.util.MetaObject; - -/** - * - * @author netspider - * @author emeroad - */ -public class AddOpInterceptor implements SimpleAroundInterceptor, TargetClassLoader { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject getServiceCode = new MetaObject("__getServiceCode"); - private MetaObject setServiceCode = new MetaObject("__setServiceCode", String.class); - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - String serviceCode = getServiceCode.invoke(target); - Operation op = (Operation) args[1]; - - setServiceCode.invoke(op, serviceCode); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import net.spy.memcached.ops.Operation; + +import com.nhn.pinpoint.bootstrap.util.MetaObject; + +/** + * + * @author netspider + * @author emeroad + */ +public class AddOpInterceptor implements SimpleAroundInterceptor, TargetClassLoader { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject getServiceCode = new MetaObject("__getServiceCode"); + private MetaObject setServiceCode = new MetaObject("__setServiceCode", String.class); + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + String serviceCode = getServiceCode.invoke(target); + Operation op = (Operation) args[1]; + + setServiceCode.invoke(op, serviceCode); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ApiInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ApiInterceptor.java index f7e418d83b31..59b57d9d78e4 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ApiInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ApiInterceptor.java @@ -1,80 +1,80 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.concurrent.Future; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import net.spy.memcached.MemcachedNode; -import net.spy.memcached.internal.OperationFuture; -import net.spy.memcached.ops.Operation; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.util.MetaObject; - -/** - * @author emeroad - */ -public class ApiInterceptor extends SpanEventSimpleAroundInterceptor implements ParameterExtractorSupport, TargetClassLoader { - - - private MetaObject getOperation = new MetaObject("__getOperation"); - private MetaObject getServiceCode = new MetaObject("__getServiceCode"); - - private ParameterExtractor parameterExtractor; - - public ApiInterceptor() { - super(ApiInterceptor.class); - } - - @Override - public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { - trace.markBeforeTime(); - } - - @Override - public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - - if (parameterExtractor != null) { - final int index = parameterExtractor.getIndex(); - final Object recordObject = parameterExtractor.extractObject(args); - trace.recordApi(getMethodDescriptor(), recordObject, index); - } else { - trace.recordApi(getMethodDescriptor()); - } - - // find the target node - if (result instanceof Future) { - Operation op = (Operation) getOperation.invoke(((Future)result)); - if (op != null) { - MemcachedNode handlingNode = op.getHandlingNode(); - SocketAddress socketAddress = handlingNode.getSocketAddress(); - if (socketAddress instanceof InetSocketAddress) { - InetSocketAddress address = (InetSocketAddress) socketAddress; - trace.recordEndPoint(address.getHostName() + ":" + address.getPort()); - } - } else { - logger.info("operation not found"); - } - } - - // determine the service type - String serviceCode = (String) getServiceCode.invoke(target); - if (serviceCode != null) { - trace.recordDestinationId(serviceCode); - trace.recordServiceType(ServiceType.ARCUS); - } else { - trace.recordDestinationId("MEMCACHED"); - trace.recordServiceType(ServiceType.MEMCACHED); - } - - trace.markAfterTime(); - } - - @Override - public void setParameterExtractor(ParameterExtractor parameterExtractor) { - this.parameterExtractor = parameterExtractor; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.concurrent.Future; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import net.spy.memcached.MemcachedNode; +import net.spy.memcached.internal.OperationFuture; +import net.spy.memcached.ops.Operation; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.util.MetaObject; + +/** + * @author emeroad + */ +public class ApiInterceptor extends SpanEventSimpleAroundInterceptor implements ParameterExtractorSupport, TargetClassLoader { + + + private MetaObject getOperation = new MetaObject("__getOperation"); + private MetaObject getServiceCode = new MetaObject("__getServiceCode"); + + private ParameterExtractor parameterExtractor; + + public ApiInterceptor() { + super(ApiInterceptor.class); + } + + @Override + public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { + trace.markBeforeTime(); + } + + @Override + public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + + if (parameterExtractor != null) { + final int index = parameterExtractor.getIndex(); + final Object recordObject = parameterExtractor.extractObject(args); + trace.recordApi(getMethodDescriptor(), recordObject, index); + } else { + trace.recordApi(getMethodDescriptor()); + } + + // find the target node + if (result instanceof Future) { + Operation op = (Operation) getOperation.invoke(((Future)result)); + if (op != null) { + MemcachedNode handlingNode = op.getHandlingNode(); + SocketAddress socketAddress = handlingNode.getSocketAddress(); + if (socketAddress instanceof InetSocketAddress) { + InetSocketAddress address = (InetSocketAddress) socketAddress; + trace.recordEndPoint(address.getHostName() + ":" + address.getPort()); + } + } else { + logger.info("operation not found"); + } + } + + // determine the service type + String serviceCode = (String) getServiceCode.invoke(target); + if (serviceCode != null) { + trace.recordDestinationId(serviceCode); + trace.recordServiceType(ServiceType.ARCUS); + } else { + trace.recordDestinationId("MEMCACHED"); + trace.recordServiceType(ServiceType.MEMCACHED); + } + + trace.markAfterTime(); + } + + @Override + public void setParameterExtractor(ParameterExtractor parameterExtractor) { + this.parameterExtractor = parameterExtractor; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ArcusScope.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ArcusScope.java index 9db292a81604..bffbcf3d416f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ArcusScope.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/ArcusScope.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * @author emeroad - */ -public class ArcusScope { - public static final DepthScope SCOPE = new DepthScope("ArcusScope"); -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * @author emeroad + */ +public class ArcusScope { + public static final DepthScope SCOPE = new DepthScope("ArcusScope"); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationCancelInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationCancelInterceptor.java index cb01e4e41862..e0b0f67740ca 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationCancelInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationCancelInterceptor.java @@ -1,53 +1,53 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.context.AsyncTrace; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.profiler.context.DefaultAsyncTrace; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.TimeObject; -import net.spy.memcached.protocol.BaseOperationImpl; - -import com.nhn.pinpoint.bootstrap.util.MetaObject; - -/** - * @author emeroad - */ -@Deprecated -public class BaseOperationCancelInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject getAsyncTrace = new MetaObject("__getAsyncTrace"); - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - AsyncTrace asyncTrace = (AsyncTrace) getAsyncTrace.invoke(target); - if (asyncTrace == null) { - logger.debug("asyncTrace not found "); - return; - } - - if (asyncTrace.getState() != DefaultAsyncTrace.STATE_INIT) { - // 이미 동작 완료된 상태임. - return; - } - - BaseOperationImpl baseOperation = (BaseOperationImpl) target; - if (!baseOperation.isCancelled()) { - TimeObject timeObject = (TimeObject) asyncTrace.getAttachObject(); - timeObject.markCancelTime(); - } - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.context.AsyncTrace; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.profiler.context.DefaultAsyncTrace; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.TimeObject; +import net.spy.memcached.protocol.BaseOperationImpl; + +import com.nhn.pinpoint.bootstrap.util.MetaObject; + +/** + * @author emeroad + */ +@Deprecated +public class BaseOperationCancelInterceptor implements SimpleAroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject getAsyncTrace = new MetaObject("__getAsyncTrace"); + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + AsyncTrace asyncTrace = (AsyncTrace) getAsyncTrace.invoke(target); + if (asyncTrace == null) { + logger.debug("asyncTrace not found "); + return; + } + + if (asyncTrace.getState() != DefaultAsyncTrace.STATE_INIT) { + // 이미 동작 완료된 상태임. + return; + } + + BaseOperationImpl baseOperation = (BaseOperationImpl) target; + if (!baseOperation.isCancelled()) { + TimeObject timeObject = (TimeObject) asyncTrace.getAttachObject(); + timeObject.markCancelTime(); + } + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationConstructInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationConstructInterceptor.java index 9666623c4f9e..0a37326421f9 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationConstructInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationConstructInterceptor.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.MetaObject; - - -/** - * @author emeroad - */ -@Deprecated -public class BaseOperationConstructInterceptor implements SimpleAroundInterceptor, TraceContextSupport { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject setAsyncTrace = new MetaObject("__setAsyncTrace", Object.class); - private TraceContext traceContext; - - @Override - public void before(Object target, Object[] args) { - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - Trace trace = traceContext.currentTraceObject(); - - if (trace == null) { - return; - } - - // 일단 이벤트가 세지 않는다는 가정하에 별도 timeout처리가 없음. -// AsyncTrace asyncTrace = trace.createAsyncTrace(); -// asyncTrace.markBeforeTime(); -// -// asyncTrace.setAttachObject(new TimeObject()); -// -// setAsyncTrace.invoke(target, asyncTrace); - } - - @Override - public void setTraceContext(TraceContext traceContext) { - - this.traceContext = traceContext; - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.MetaObject; + + +/** + * @author emeroad + */ +@Deprecated +public class BaseOperationConstructInterceptor implements SimpleAroundInterceptor, TraceContextSupport { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject setAsyncTrace = new MetaObject("__setAsyncTrace", Object.class); + private TraceContext traceContext; + + @Override + public void before(Object target, Object[] args) { + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + Trace trace = traceContext.currentTraceObject(); + + if (trace == null) { + return; + } + + // 일단 이벤트가 세지 않는다는 가정하에 별도 timeout처리가 없음. +// AsyncTrace asyncTrace = trace.createAsyncTrace(); +// asyncTrace.markBeforeTime(); +// +// asyncTrace.setAttachObject(new TimeObject()); +// +// setAsyncTrace.invoke(target, asyncTrace); + } + + @Override + public void setTraceContext(TraceContext traceContext) { + + this.traceContext = traceContext; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptor.java index e067033b4a12..7e774658f76a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptor.java @@ -1,161 +1,161 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; - -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.bootstrap.context.AsyncTrace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.TimeObject; -import net.spy.memcached.MemcachedNode; -import net.spy.memcached.ops.OperationState; -import net.spy.memcached.protocol.BaseOperationImpl; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.util.MetaObject; - -/** - * @author emeroad - */ -@Deprecated -public class BaseOperationTransitionStateInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private static final Charset UTF8 = Charset.forName("UTF-8"); - - private MetaObject getAsyncTrace = new MetaObject("__getAsyncTrace"); - private MetaObject getServiceCode = new MetaObject("__getServiceCode"); - - private MethodDescriptor methodDescriptor; - private TraceContext traceContext; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - AsyncTrace asyncTrace = (AsyncTrace) getAsyncTrace.invoke(target); - if (asyncTrace == null) { - if (isDebug) { - logger.debug("asyncTrace not found"); - } - return; - } - // TODO null 체크가 필요하지 않나하는데? 일단 사용하지 않는 interceptor이므로 TODO만 붙여 둔다. - OperationState newState = (OperationState) args[0]; - - BaseOperationImpl baseOperation = (BaseOperationImpl) target; - if (newState == OperationState.READING) { - if (isDebug) { - logger.debug("event:{} asyncTrace:{}", newState, asyncTrace); - } - if (asyncTrace.getState() != AsyncTrace.STATE_INIT) { - return; - } - MemcachedNode handlingNode = baseOperation.getHandlingNode(); - SocketAddress socketAddress = handlingNode.getSocketAddress(); - if (socketAddress instanceof InetSocketAddress) { - InetSocketAddress address = (InetSocketAddress) socketAddress; - asyncTrace.recordEndPoint(address.getHostName() + ":" + address.getPort()); - } - - String serviceCode = (String) getServiceCode.invoke(target); - - if (serviceCode == null) { - serviceCode = "UNKNOWN"; - } - - ServiceType svcType = ServiceType.ARCUS; - - if(serviceCode.equals(ServiceType.MEMCACHED.getDesc())) { - svcType = ServiceType.MEMCACHED; - } - - asyncTrace.recordServiceType(svcType); -// asyncTrace.recordRpcName(baseOperation.getClass().getSimpleName()); - asyncTrace.recordApi(methodDescriptor); - - asyncTrace.recordDestinationId(serviceCode); - - String cmd = getCommand(baseOperation); -// asyncTrace.recordAttribute(AnnotationKey.ARCUS_COMMAND, cmd); - - // TimeObject timeObject = (TimeObject) - // asyncTrace.getFrameObject(); - // timeObject.markSendTime(); - - // long createTime = asyncTrace.getBeforeTime(); - asyncTrace.markAfterTime(); -// asyncTrace.traceBlockEnd(); - } else if (newState == OperationState.COMPLETE || isArcusTimeout(newState)) { - if (isDebug) { - logger.debug("event:{} asyncTrace:{}", newState, asyncTrace); - } - boolean fire = asyncTrace.fire(); - if (!fire) { - return; - } - Exception exception = baseOperation.getException(); - asyncTrace.recordException(exception); - - if (!baseOperation.isCancelled()) { - TimeObject timeObject = (TimeObject) asyncTrace.getAttachObject(); - // asyncTrace.record(Annotation.ClientRecv, timeObject.getSendTime()); - asyncTrace.markAfterTime(); - asyncTrace.traceBlockEnd(); - } else { - asyncTrace.recordAttribute(AnnotationKey.EXCEPTION, "cancelled by user"); - TimeObject timeObject = (TimeObject) asyncTrace.getAttachObject(); - // asyncTrace.record(Annotation.ClientRecv, timeObject.getCancelTime()); - asyncTrace.markAfterTime(); - asyncTrace.traceBlockEnd(); - } - } - } - - private boolean isArcusTimeout(OperationState newState) { - if (newState == null) { - return false; - } - // arcus에만 추가된 타입이라. 따로 처리함. - return "TIMEDOUT".equals(newState.toString()); - } - - private String getCommand(BaseOperationImpl baseOperation) { - ByteBuffer buffer = baseOperation.getBuffer(); - if (buffer == null) { - return "UNKNOWN"; - } - // System.out.println(buffer.array().length + " po:" + buffer.position() - // + " limit:" + buffer.limit() + " remaining" - // + buffer.remaining() + " aoffset:" + buffer.arrayOffset()); - return new String(buffer.array(), UTF8); - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.methodDescriptor = descriptor; - this.traceContext.cacheApi(descriptor); - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.bootstrap.context.AsyncTrace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.TimeObject; +import net.spy.memcached.MemcachedNode; +import net.spy.memcached.ops.OperationState; +import net.spy.memcached.protocol.BaseOperationImpl; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.util.MetaObject; + +/** + * @author emeroad + */ +@Deprecated +public class BaseOperationTransitionStateInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + private MetaObject getAsyncTrace = new MetaObject("__getAsyncTrace"); + private MetaObject getServiceCode = new MetaObject("__getServiceCode"); + + private MethodDescriptor methodDescriptor; + private TraceContext traceContext; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + AsyncTrace asyncTrace = (AsyncTrace) getAsyncTrace.invoke(target); + if (asyncTrace == null) { + if (isDebug) { + logger.debug("asyncTrace not found"); + } + return; + } + // TODO null 체크가 필요하지 않나하는데? 일단 사용하지 않는 interceptor이므로 TODO만 붙여 둔다. + OperationState newState = (OperationState) args[0]; + + BaseOperationImpl baseOperation = (BaseOperationImpl) target; + if (newState == OperationState.READING) { + if (isDebug) { + logger.debug("event:{} asyncTrace:{}", newState, asyncTrace); + } + if (asyncTrace.getState() != AsyncTrace.STATE_INIT) { + return; + } + MemcachedNode handlingNode = baseOperation.getHandlingNode(); + SocketAddress socketAddress = handlingNode.getSocketAddress(); + if (socketAddress instanceof InetSocketAddress) { + InetSocketAddress address = (InetSocketAddress) socketAddress; + asyncTrace.recordEndPoint(address.getHostName() + ":" + address.getPort()); + } + + String serviceCode = (String) getServiceCode.invoke(target); + + if (serviceCode == null) { + serviceCode = "UNKNOWN"; + } + + ServiceType svcType = ServiceType.ARCUS; + + if(serviceCode.equals(ServiceType.MEMCACHED.getDesc())) { + svcType = ServiceType.MEMCACHED; + } + + asyncTrace.recordServiceType(svcType); +// asyncTrace.recordRpcName(baseOperation.getClass().getSimpleName()); + asyncTrace.recordApi(methodDescriptor); + + asyncTrace.recordDestinationId(serviceCode); + + String cmd = getCommand(baseOperation); +// asyncTrace.recordAttribute(AnnotationKey.ARCUS_COMMAND, cmd); + + // TimeObject timeObject = (TimeObject) + // asyncTrace.getFrameObject(); + // timeObject.markSendTime(); + + // long createTime = asyncTrace.getBeforeTime(); + asyncTrace.markAfterTime(); +// asyncTrace.traceBlockEnd(); + } else if (newState == OperationState.COMPLETE || isArcusTimeout(newState)) { + if (isDebug) { + logger.debug("event:{} asyncTrace:{}", newState, asyncTrace); + } + boolean fire = asyncTrace.fire(); + if (!fire) { + return; + } + Exception exception = baseOperation.getException(); + asyncTrace.recordException(exception); + + if (!baseOperation.isCancelled()) { + TimeObject timeObject = (TimeObject) asyncTrace.getAttachObject(); + // asyncTrace.record(Annotation.ClientRecv, timeObject.getSendTime()); + asyncTrace.markAfterTime(); + asyncTrace.traceBlockEnd(); + } else { + asyncTrace.recordAttribute(AnnotationKey.EXCEPTION, "cancelled by user"); + TimeObject timeObject = (TimeObject) asyncTrace.getAttachObject(); + // asyncTrace.record(Annotation.ClientRecv, timeObject.getCancelTime()); + asyncTrace.markAfterTime(); + asyncTrace.traceBlockEnd(); + } + } + } + + private boolean isArcusTimeout(OperationState newState) { + if (newState == null) { + return false; + } + // arcus에만 추가된 타입이라. 따로 처리함. + return "TIMEDOUT".equals(newState.toString()); + } + + private String getCommand(BaseOperationImpl baseOperation) { + ByteBuffer buffer = baseOperation.getBuffer(); + if (buffer == null) { + return "UNKNOWN"; + } + // System.out.println(buffer.array().length + " po:" + buffer.position() + // + " limit:" + buffer.limit() + " remaining" + // + buffer.remaining() + " aoffset:" + buffer.arrayOffset()); + return new String(buffer.array(), UTF8); + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.methodDescriptor = descriptor; + this.traceContext.cacheApi(descriptor); + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/CacheManagerConstructInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/CacheManagerConstructInterceptor.java index d01cf86d544a..f8810b70341f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/CacheManagerConstructInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/CacheManagerConstructInterceptor.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.MetaObject; - -/** - * - * @author netspider - * @author emeroad - */ -public class CacheManagerConstructInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject setServiceCode = new MetaObject("__setServiceCode", String.class); - - @Override - public void before(Object target, Object[] args) { - - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - setServiceCode.invoke(target, (String) args[1]); - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.MetaObject; + +/** + * + * @author netspider + * @author emeroad + */ +public class CacheManagerConstructInterceptor implements SimpleAroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject setServiceCode = new MetaObject("__setServiceCode", String.class); + + @Override + public void before(Object target, Object[] args) { + + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + setServiceCode.invoke(target, (String) args[1]); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureConstructInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureConstructInterceptor.java index e8d8faac9e75..35bf556da972 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureConstructInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureConstructInterceptor.java @@ -1,45 +1,45 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.MetaObject; -import net.sf.ehcache.Element; - -/** - * @author harebox - */ -public class FrontCacheGetFutureConstructInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - // TODO This should be extracted from FrontCacheMemcachedClient. - private static final String DEFAULT_FRONTCACHE_NAME = "front"; - - private MetaObject setCacheName = new MetaObject("__setCacheName", String.class); - private MetaObject setCacheKey = new MetaObject("__setCacheKey", String.class); - - @Override - public void before(Object target, Object[] args) { - // do nothing. - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - try { - setCacheName.invoke(target, DEFAULT_FRONTCACHE_NAME); - - if (args[0] instanceof Element) { - Element element = (Element) args[0]; - setCacheKey.invoke(target, element.getObjectKey()); - } - } catch (Exception e) { - logger.error("failed to add metadata: {}", e); - } - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.MetaObject; +import net.sf.ehcache.Element; + +/** + * @author harebox + */ +public class FrontCacheGetFutureConstructInterceptor implements SimpleAroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + // TODO This should be extracted from FrontCacheMemcachedClient. + private static final String DEFAULT_FRONTCACHE_NAME = "front"; + + private MetaObject setCacheName = new MetaObject("__setCacheName", String.class); + private MetaObject setCacheKey = new MetaObject("__setCacheKey", String.class); + + @Override + public void before(Object target, Object[] args) { + // do nothing. + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + try { + setCacheName.invoke(target, DEFAULT_FRONTCACHE_NAME); + + if (args[0] instanceof Element) { + Element element = (Element) args[0]; + setCacheKey.invoke(target, element.getObjectKey()); + } + } catch (Exception e) { + logger.error("failed to add metadata: {}", e); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureGetInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureGetInterceptor.java index afe77de4e8ee..b82ee8c897c6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureGetInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FrontCacheGetFutureGetInterceptor.java @@ -1,82 +1,82 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.MetaObject; -import com.nhn.pinpoint.common.ServiceType; - -/** - * @author harebox - */ -public class FrontCacheGetFutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject getCacheName = new MetaObject("__getCacheName"); - private MetaObject getCacheKey = new MetaObject("__getCacheKey"); - - private MethodDescriptor methodDescriptor; - private TraceContext traceContext; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - try { - trace.recordApi(methodDescriptor); - -// String cacheKey = (String) getCacheKey.invoke(target); -// if (cacheKey != null) { -// // annotate it. -// } - - String cacheName = (String) getCacheName.invoke(target); - if (cacheName != null) { - trace.recordDestinationId(cacheName); - } - - trace.recordServiceType(ServiceType.ARCUS_EHCACHE_FUTURE_GET); - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.methodDescriptor = descriptor; - this.traceContext.cacheApi(descriptor); - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.MetaObject; +import com.nhn.pinpoint.common.ServiceType; + +/** + * @author harebox + */ +public class FrontCacheGetFutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject getCacheName = new MetaObject("__getCacheName"); + private MetaObject getCacheKey = new MetaObject("__getCacheKey"); + + private MethodDescriptor methodDescriptor; + private TraceContext traceContext; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + try { + trace.recordApi(methodDescriptor); + +// String cacheKey = (String) getCacheKey.invoke(target); +// if (cacheKey != null) { +// // annotate it. +// } + + String cacheName = (String) getCacheName.invoke(target); + if (cacheName != null) { + trace.recordDestinationId(cacheName); + } + + trace.recordServiceType(ServiceType.ARCUS_EHCACHE_FUTURE_GET); + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.methodDescriptor = descriptor; + this.traceContext.cacheApi(descriptor); + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureGetInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureGetInterceptor.java index be47231e34b2..40eb3d889dda 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureGetInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureGetInterceptor.java @@ -1,115 +1,115 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import net.spy.memcached.MemcachedNode; -import net.spy.memcached.ops.Operation; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.util.MetaObject; - -/** - * @author emeroad - */ -public class FutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject getOperation = new MetaObject("__getOperation"); - private MetaObject getServiceCode = new MetaObject("__getServiceCode"); - - private MethodDescriptor methodDescriptor; - private TraceContext traceContext; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - try { - trace.recordApi(methodDescriptor); -// 중요한 파라미터가 아님 레코딩 안함. -// String annotation = "future.get() timeout:" + args[0] + " " + ((TimeUnit)args[1]).name(); -// trace.recordAttribute(AnnotationKey.ARCUS_COMMAND, annotation); - - // find the target node - final Operation op = (Operation) getOperation.invoke(target); - if (op != null) { - MemcachedNode handlingNode = op.getHandlingNode(); - if (handlingNode != null) { - SocketAddress socketAddress = handlingNode.getSocketAddress(); - if (socketAddress instanceof InetSocketAddress) { - InetSocketAddress address = (InetSocketAddress) socketAddress; - trace.recordEndPoint(address.getHostName() + ":" + address.getPort()); - } - } else { - logger.info("no handling node"); - } - } else { - logger.info("operation not found"); - } - - // determine the service type - String serviceCode = (String) getServiceCode.invoke((Operation)op); - if (serviceCode != null) { - trace.recordDestinationId(serviceCode); - trace.recordServiceType(ServiceType.ARCUS_FUTURE_GET); - } else { - trace.recordDestinationId("MEMCACHED"); - trace.recordServiceType(ServiceType.MEMCACHED_FUTURE_GET); - } - - if (op != null) { - trace.recordException(op.getException()); - } -// cancel일때 exception은 안던지는 것인가? -// if (op.isCancelled()) { -// trace.recordAttribute(AnnotationKey.EXCEPTION, "cancelled by user"); -// } - - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.methodDescriptor = descriptor; - this.traceContext.cacheApi(descriptor); - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import net.spy.memcached.MemcachedNode; +import net.spy.memcached.ops.Operation; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.util.MetaObject; + +/** + * @author emeroad + */ +public class FutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject getOperation = new MetaObject("__getOperation"); + private MetaObject getServiceCode = new MetaObject("__getServiceCode"); + + private MethodDescriptor methodDescriptor; + private TraceContext traceContext; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + try { + trace.recordApi(methodDescriptor); +// 중요한 파라미터가 아님 레코딩 안함. +// String annotation = "future.get() timeout:" + args[0] + " " + ((TimeUnit)args[1]).name(); +// trace.recordAttribute(AnnotationKey.ARCUS_COMMAND, annotation); + + // find the target node + final Operation op = (Operation) getOperation.invoke(target); + if (op != null) { + MemcachedNode handlingNode = op.getHandlingNode(); + if (handlingNode != null) { + SocketAddress socketAddress = handlingNode.getSocketAddress(); + if (socketAddress instanceof InetSocketAddress) { + InetSocketAddress address = (InetSocketAddress) socketAddress; + trace.recordEndPoint(address.getHostName() + ":" + address.getPort()); + } + } else { + logger.info("no handling node"); + } + } else { + logger.info("operation not found"); + } + + // determine the service type + String serviceCode = (String) getServiceCode.invoke((Operation)op); + if (serviceCode != null) { + trace.recordDestinationId(serviceCode); + trace.recordServiceType(ServiceType.ARCUS_FUTURE_GET); + } else { + trace.recordDestinationId("MEMCACHED"); + trace.recordServiceType(ServiceType.MEMCACHED_FUTURE_GET); + } + + if (op != null) { + trace.recordException(op.getException()); + } +// cancel일때 exception은 안던지는 것인가? +// if (op.isCancelled()) { +// trace.recordAttribute(AnnotationKey.EXCEPTION, "cancelled by user"); +// } + + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.methodDescriptor = descriptor; + this.traceContext.cacheApi(descriptor); + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureSetOperationInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureSetOperationInterceptor.java index 38748e83455b..85c2d9b62a23 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureSetOperationInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/FutureSetOperationInterceptor.java @@ -1,36 +1,36 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import net.spy.memcached.ops.Operation; - -import com.nhn.pinpoint.bootstrap.util.MetaObject; - - -/** - * @author harebox - * @author emeroad - */ -public class FutureSetOperationInterceptor implements SimpleAroundInterceptor, TargetClassLoader { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject setOperation = new MetaObject("__setOperation", Operation.class); - - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - setOperation.invoke(target, (Operation) args[0]); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import net.spy.memcached.ops.Operation; + +import com.nhn.pinpoint.bootstrap.util.MetaObject; + + +/** + * @author harebox + * @author emeroad + */ +public class FutureSetOperationInterceptor implements SimpleAroundInterceptor, TargetClassLoader { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject setOperation = new MetaObject("__setOperation", Operation.class); + + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + setOperation.invoke(target, (Operation) args[0]); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/IndexParameterExtractor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/IndexParameterExtractor.java index 187e3b042756..dd2795153d38 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/IndexParameterExtractor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/IndexParameterExtractor.java @@ -1,30 +1,30 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.ParameterExtractor; - -/** - * @author emeroad - */ -public class IndexParameterExtractor implements ParameterExtractor { - - private final int index; - - public IndexParameterExtractor(int index) { - this.index = index; - } - - @Override - public int getIndex() { - return index; - } - - @Override - public Object extractObject(Object[] parameterList) { - if (parameterList == null) { - return NULL; - } - return parameterList[index]; - } - - -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.ParameterExtractor; + +/** + * @author emeroad + */ +public class IndexParameterExtractor implements ParameterExtractor { + + private final int index; + + public IndexParameterExtractor(int index) { + this.index = index; + } + + @Override + public int getIndex() { + return index; + } + + @Override + public Object extractObject(Object[] parameterList) { + if (parameterList == null) { + return NULL; + } + return parameterList[index]; + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/SetCacheManagerInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/SetCacheManagerInterceptor.java index 2e49761e1228..6711b525e4c7 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/SetCacheManagerInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/SetCacheManagerInterceptor.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import net.spy.memcached.CacheManager; -import net.spy.memcached.MemcachedClient; - - -import com.nhn.pinpoint.bootstrap.util.MetaObject; - -/** - * - * @author netspider - * @author emeroad - */ -public class SetCacheManagerInterceptor implements SimpleAroundInterceptor, TargetClassLoader { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MetaObject getServiceCode = new MetaObject("__getServiceCode"); - private MetaObject setServiceCode = new MetaObject("__setServiceCode", String.class); - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - CacheManager cm = (CacheManager) args[0]; - String serviceCode = getServiceCode.invoke(cm); - - setServiceCode.invoke((MemcachedClient) target, serviceCode); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import net.spy.memcached.CacheManager; +import net.spy.memcached.MemcachedClient; + + +import com.nhn.pinpoint.bootstrap.util.MetaObject; + +/** + * + * @author netspider + * @author emeroad + */ +public class SetCacheManagerInterceptor implements SimpleAroundInterceptor, TargetClassLoader { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MetaObject getServiceCode = new MetaObject("__getServiceCode"); + private MetaObject setServiceCode = new MetaObject("__setServiceCode", String.class); + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + CacheManager cm = (CacheManager) args[0]; + String serviceCode = getServiceCode.invoke(cm); + + setServiceCode.invoke((MemcachedClient) target, serviceCode); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/HttpHostParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/HttpHostParser.java index 0814f243e294..bf9830748b1a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/HttpHostParser.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/HttpHostParser.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.profiler.modifier.connector; - -/** - * - */ -public class HttpHostParser { - - public static String parseUrl(String url) { - return null; - } -} +package com.nhn.pinpoint.profiler.modifier.connector; + +/** + * + */ +public class HttpHostParser { + + public static String parseUrl(String url) { + return null; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/asynchttpclient/interceptor/ExecuteRequestInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/asynchttpclient/interceptor/ExecuteRequestInterceptor.java index 1601ea4f8370..b13af34dd48c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/asynchttpclient/interceptor/ExecuteRequestInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/asynchttpclient/interceptor/ExecuteRequestInterceptor.java @@ -1,387 +1,387 @@ -package com.nhn.pinpoint.profiler.modifier.connector.asynchttpclient.interceptor; - -import java.io.InputStream; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.config.DumpType; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.Header; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.sampler.SamplingFlagUtils; -import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; -import com.nhn.pinpoint.bootstrap.util.SimpleSampler; -import com.nhn.pinpoint.bootstrap.util.SimpleSamplerFactory; -import com.nhn.pinpoint.bootstrap.util.StringUtils; -import com.ning.http.client.FluentCaseInsensitiveStringsMap; -import com.ning.http.client.FluentStringsMap; -import com.ning.http.client.Part; -import com.ning.http.client.Request.EntityWriter; -import com.ning.http.client.cookie.Cookie; - -/** - * intercept com.ning.http.client.AsyncHttpClient.executeRequest(Request, - * AsyncHandler) - * - * @author netspider - * - */ -public class ExecuteRequestInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { - - protected PLogger logger; - protected boolean isDebug; - - protected TraceContext traceContext; - protected MethodDescriptor descriptor; - - protected boolean dumpCookie; - protected DumpType cookieDumpType; - protected SimpleSampler cookieSampler; - protected int cookieDumpSize; - - protected boolean dumpEntity; - protected DumpType entityDumpType; - protected SimpleSampler entitySampler; - protected int entityDumpSize; - - protected boolean dumpParam; - protected DumpType paramDumpType; - protected SimpleSampler paramSampler; - protected int paramDumpSize; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - final Trace trace = traceContext.currentRawTraceObject(); - if (trace == null) { - return; - } - - if (args.length == 0 || !(args[0] instanceof com.ning.http.client.Request)) { - return; - } - - final com.ning.http.client.Request httpRequest = (com.ning.http.client.Request) args[0]; - - final boolean sampling = trace.canSampled(); - - if (!sampling) { - if (isDebug) { - logger.debug("set Sampling flag=false"); - } - if (httpRequest != null) { - final FluentCaseInsensitiveStringsMap httpRequestHeaders = httpRequest.getHeaders(); - httpRequestHeaders.add(Header.HTTP_SAMPLED.toString(), SamplingFlagUtils.SAMPLING_RATE_FALSE); - } - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - - TraceId nextId = trace.getTraceId().getNextTraceId(); - trace.recordNextSpanId(nextId.getSpanId()); - trace.recordServiceType(ServiceType.HTTP_CLIENT); - - if (httpRequest != null) { - final FluentCaseInsensitiveStringsMap httpRequestHeaders = httpRequest.getHeaders(); - httpRequestHeaders.add(Header.HTTP_TRACE_ID.toString(), nextId.getTransactionId()); - httpRequestHeaders.add(Header.HTTP_SPAN_ID.toString(), String.valueOf(nextId.getSpanId())); - httpRequestHeaders.add(Header.HTTP_PARENT_SPAN_ID.toString(), String.valueOf(nextId.getParentSpanId())); - httpRequestHeaders.add(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); - httpRequestHeaders.add(Header.HTTP_PARENT_APPLICATION_NAME.toString(), traceContext.getApplicationName()); - httpRequestHeaders.add(Header.HTTP_PARENT_APPLICATION_TYPE.toString(), Short.toString(traceContext.getServerTypeCode())); - } - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - // result는 로깅하지 않는다. - logger.afterInterceptor(target, args); - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - if (args.length == 0 || !(args[0] instanceof com.ning.http.client.Request)) { - return; - } - - try { - final com.ning.http.client.Request httpRequest = (com.ning.http.client.Request) args[0]; - - if (httpRequest != null) { - // httpRequest에 뭔가 access하는 작업은 위험이 있으므로 after에서 작업한다. - trace.recordAttribute(AnnotationKey.HTTP_URL, httpRequest.getUrl()); - - String endpoint = getEndpoint(httpRequest.getURI().getHost(), httpRequest.getURI().getPort()); - trace.recordDestinationId(endpoint); - - recordHttpRequest(trace, httpRequest, throwable); - } - - trace.recordApi(descriptor); - trace.recordException(throwable); - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - private String getEndpoint(String host, int port) { - if (host == null) { - return "UnknownHttpClient"; - } - if (port < 0) { - return host; - } - StringBuilder sb = new StringBuilder(host.length() + 8); - sb.append(host); - sb.append(':'); - sb.append(port); - return sb.toString(); - } - - private void recordHttpRequest(Trace trace, com.ning.http.client.Request httpRequest, Throwable throwable) { - final boolean isException = InterceptorUtils.isThrowable(throwable); - if (dumpCookie) { - if (DumpType.ALWAYS == cookieDumpType) { - recordCookie(httpRequest, trace); - } else if (DumpType.EXCEPTION == cookieDumpType && isException) { - recordCookie(httpRequest, trace); - } - } - if (dumpEntity) { - if (DumpType.ALWAYS == entityDumpType) { - recordEntity(httpRequest, trace); - } else if (DumpType.EXCEPTION == entityDumpType && isException) { - recordEntity(httpRequest, trace); - } - } - if (dumpParam) { - if (DumpType.ALWAYS == paramDumpType) { - recordParam(httpRequest, trace); - } else if (DumpType.EXCEPTION == paramDumpType && isException) { - recordParam(httpRequest, trace); - } - } - } - - protected void recordCookie(com.ning.http.client.Request httpRequest, Trace trace) { - if (cookieSampler.isSampling()) { - Collection cookies = httpRequest.getCookies(); - - if (cookies.isEmpty()) { - return; - } - - StringBuilder sb = new StringBuilder(cookieDumpSize * 2); - Iterator iterator = cookies.iterator(); - while (iterator.hasNext()) { - Cookie cookie = iterator.next(); - sb.append(cookie.getName()).append("=").append(cookie.getValue()); - if (iterator.hasNext()) { - sb.append(","); - } - } - trace.recordAttribute(AnnotationKey.HTTP_COOKIE, StringUtils.drop(sb.toString(), cookieDumpSize)); - } - } - - protected void recordEntity(final com.ning.http.client.Request httpRequest, final Trace trace) { - if (entitySampler.isSampling()) { - recordNonMultipartData(httpRequest, trace); - recordMultipartData(httpRequest, trace); - } - } - - /** - *
-	 * body는 string, byte, stream, entitywriter 중 하나가 입력된다.
-	 * 여기에서는 stringdata만 수집하고 나머지는 일단 수집 안함.
-	 * 
- * - * @param httpRequest - * @param trace - */ - protected void recordNonMultipartData(final com.ning.http.client.Request httpRequest, final Trace trace) { - final String stringData = httpRequest.getStringData(); - if (stringData != null) { - trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, StringUtils.drop(stringData, entityDumpSize)); - return; - } - - final byte[] byteData = httpRequest.getByteData(); - if (byteData != null) { - trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, "BYTE_DATA"); - return; - } - - final InputStream streamData = httpRequest.getStreamData(); - if (streamData != null) { - trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, "STREAM_DATA"); - return; - } - - final EntityWriter entityWriter = httpRequest.getEntityWriter(); - if (entityWriter != null) { - trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, "STREAM_DATA"); - return; - } - } - - /** - * record http multipart data - * - * @param httpRequest - * @param trace - */ - protected void recordMultipartData(final com.ning.http.client.Request httpRequest, final Trace trace) { - List parts = httpRequest.getParts(); - if (parts != null && parts.isEmpty()) { - StringBuilder sb = new StringBuilder(entityDumpSize * 2); - Iterator iterator = parts.iterator(); - while (iterator.hasNext()) { - Part part = iterator.next(); - if (part instanceof com.ning.http.client.ByteArrayPart) { - com.ning.http.client.ByteArrayPart p = (com.ning.http.client.ByteArrayPart) part; - sb.append(part.getName()); - sb.append("=BYTE_ARRAY_"); - sb.append(p.getData().length); - } else if (part instanceof com.ning.http.client.FilePart) { - com.ning.http.client.FilePart p = (com.ning.http.client.FilePart) part; - sb.append(part.getName()); - sb.append("=FILE_"); - sb.append(p.getMimeType()); - } else if (part instanceof com.ning.http.client.StringPart) { - com.ning.http.client.StringPart p = (com.ning.http.client.StringPart) part; - sb.append(part.getName()); - sb.append("="); - sb.append(p.getValue()); - } else if (part instanceof com.ning.http.multipart.FilePart) { - com.ning.http.multipart.FilePart p = (com.ning.http.multipart.FilePart) part; - sb.append(part.getName()); - sb.append("=FILE_"); - sb.append(p.getContentType()); - } else if (part instanceof com.ning.http.multipart.StringPart) { - com.ning.http.multipart.StringPart p = (com.ning.http.multipart.StringPart) part; - sb.append(part.getName()); - // string을 꺼내오는 방법이 없고, apache http client의 adaptation - // class라 무시. - sb.append("=STRING"); - } - - if (sb.length() >= entityDumpSize) { - break; - } - - if (iterator.hasNext()) { - sb.append(","); - } - } - trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, StringUtils.drop(sb.toString(), entityDumpSize)); - } - } - - /** - * record http request parameter - * - * @param httpRequest - * @param trace - */ - protected void recordParam(final com.ning.http.client.Request httpRequest, final Trace trace) { - if (paramSampler.isSampling()) { - FluentStringsMap requestParams = httpRequest.getParams(); - if (requestParams != null) { - String params = paramsToString(requestParams, paramDumpSize); - trace.recordAttribute(AnnotationKey.HTTP_PARAM, StringUtils.drop(params, paramDumpSize)); - } - } - } - - /** - * com.ning.http.client.FluentStringsMap.toString()에서 큰따옴표, 공백, 세미콜론을 제거한 버전 - * - * @param params - * @param limit - * @return - */ - private String paramsToString(FluentStringsMap params, int limit) { - StringBuilder result = new StringBuilder(limit * 2); - - for (Map.Entry> entry : params.entrySet()) { - if (result.length() > 0) { - result.append(","); - } - result.append(entry.getKey()); - result.append("="); - - boolean needsComma = false; - - for (String value : entry.getValue()) { - if (needsComma) { - result.append(", "); - } else { - needsComma = true; - } - result.append(value); - } - - if (result.length() >= limit) { - break; - } - } - return result.toString(); - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - - final ProfilerConfig profilerConfig = traceContext.getProfilerConfig(); - this.dumpCookie = profilerConfig.isNingAsyncHttpClientProfileCookie(); - this.cookieDumpType = profilerConfig.getNingAsyncHttpClientProfileCookieDumpType(); - this.cookieDumpSize = profilerConfig.getNingAsyncHttpClientProfileCookieDumpSize(); - if (dumpCookie) { - this.cookieSampler = SimpleSamplerFactory.createSampler(dumpCookie, profilerConfig.getNingAsyncHttpClientProfileCookieSamplingRate()); - } - - this.dumpEntity = profilerConfig.isNingAsyncHttpClientProfileEntity(); - this.entityDumpType = profilerConfig.getNingAsyncHttpClientProfileEntityDumpType(); - this.entityDumpSize = profilerConfig.getNingAsyncHttpClientProfileEntityDumpSize(); - if (dumpEntity) { - this.entitySampler = SimpleSamplerFactory.createSampler(dumpEntity, profilerConfig.getNingAsyncHttpClientProfileEntitySamplingRate()); - } - - this.dumpParam = profilerConfig.isNingAsyncHttpClientProfileParam(); - this.paramDumpType = profilerConfig.getNingAsyncHttpClientProfileParamDumpType(); - this.paramDumpSize = profilerConfig.getNingAsyncHttpClientProfileParamDumpSize(); - if (dumpParam) { - this.paramSampler = SimpleSamplerFactory.createSampler(dumpParam, profilerConfig.getNingAsyncHttpClientProfileParamSamplingRate()); - } - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.descriptor = descriptor; - traceContext.cacheApi(descriptor); - } -} +package com.nhn.pinpoint.profiler.modifier.connector.asynchttpclient.interceptor; + +import java.io.InputStream; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.config.DumpType; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.context.Header; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.sampler.SamplingFlagUtils; +import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; +import com.nhn.pinpoint.bootstrap.util.SimpleSampler; +import com.nhn.pinpoint.bootstrap.util.SimpleSamplerFactory; +import com.nhn.pinpoint.bootstrap.util.StringUtils; +import com.ning.http.client.FluentCaseInsensitiveStringsMap; +import com.ning.http.client.FluentStringsMap; +import com.ning.http.client.Part; +import com.ning.http.client.Request.EntityWriter; +import com.ning.http.client.cookie.Cookie; + +/** + * intercept com.ning.http.client.AsyncHttpClient.executeRequest(Request, + * AsyncHandler) + * + * @author netspider + * + */ +public class ExecuteRequestInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { + + protected PLogger logger; + protected boolean isDebug; + + protected TraceContext traceContext; + protected MethodDescriptor descriptor; + + protected boolean dumpCookie; + protected DumpType cookieDumpType; + protected SimpleSampler cookieSampler; + protected int cookieDumpSize; + + protected boolean dumpEntity; + protected DumpType entityDumpType; + protected SimpleSampler entitySampler; + protected int entityDumpSize; + + protected boolean dumpParam; + protected DumpType paramDumpType; + protected SimpleSampler paramSampler; + protected int paramDumpSize; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + final Trace trace = traceContext.currentRawTraceObject(); + if (trace == null) { + return; + } + + if (args.length == 0 || !(args[0] instanceof com.ning.http.client.Request)) { + return; + } + + final com.ning.http.client.Request httpRequest = (com.ning.http.client.Request) args[0]; + + final boolean sampling = trace.canSampled(); + + if (!sampling) { + if (isDebug) { + logger.debug("set Sampling flag=false"); + } + if (httpRequest != null) { + final FluentCaseInsensitiveStringsMap httpRequestHeaders = httpRequest.getHeaders(); + httpRequestHeaders.add(Header.HTTP_SAMPLED.toString(), SamplingFlagUtils.SAMPLING_RATE_FALSE); + } + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + + TraceId nextId = trace.getTraceId().getNextTraceId(); + trace.recordNextSpanId(nextId.getSpanId()); + trace.recordServiceType(ServiceType.HTTP_CLIENT); + + if (httpRequest != null) { + final FluentCaseInsensitiveStringsMap httpRequestHeaders = httpRequest.getHeaders(); + httpRequestHeaders.add(Header.HTTP_TRACE_ID.toString(), nextId.getTransactionId()); + httpRequestHeaders.add(Header.HTTP_SPAN_ID.toString(), String.valueOf(nextId.getSpanId())); + httpRequestHeaders.add(Header.HTTP_PARENT_SPAN_ID.toString(), String.valueOf(nextId.getParentSpanId())); + httpRequestHeaders.add(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); + httpRequestHeaders.add(Header.HTTP_PARENT_APPLICATION_NAME.toString(), traceContext.getApplicationName()); + httpRequestHeaders.add(Header.HTTP_PARENT_APPLICATION_TYPE.toString(), Short.toString(traceContext.getServerTypeCode())); + } + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + // result는 로깅하지 않는다. + logger.afterInterceptor(target, args); + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + if (args.length == 0 || !(args[0] instanceof com.ning.http.client.Request)) { + return; + } + + try { + final com.ning.http.client.Request httpRequest = (com.ning.http.client.Request) args[0]; + + if (httpRequest != null) { + // httpRequest에 뭔가 access하는 작업은 위험이 있으므로 after에서 작업한다. + trace.recordAttribute(AnnotationKey.HTTP_URL, httpRequest.getUrl()); + + String endpoint = getEndpoint(httpRequest.getURI().getHost(), httpRequest.getURI().getPort()); + trace.recordDestinationId(endpoint); + + recordHttpRequest(trace, httpRequest, throwable); + } + + trace.recordApi(descriptor); + trace.recordException(throwable); + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + private String getEndpoint(String host, int port) { + if (host == null) { + return "UnknownHttpClient"; + } + if (port < 0) { + return host; + } + StringBuilder sb = new StringBuilder(host.length() + 8); + sb.append(host); + sb.append(':'); + sb.append(port); + return sb.toString(); + } + + private void recordHttpRequest(Trace trace, com.ning.http.client.Request httpRequest, Throwable throwable) { + final boolean isException = InterceptorUtils.isThrowable(throwable); + if (dumpCookie) { + if (DumpType.ALWAYS == cookieDumpType) { + recordCookie(httpRequest, trace); + } else if (DumpType.EXCEPTION == cookieDumpType && isException) { + recordCookie(httpRequest, trace); + } + } + if (dumpEntity) { + if (DumpType.ALWAYS == entityDumpType) { + recordEntity(httpRequest, trace); + } else if (DumpType.EXCEPTION == entityDumpType && isException) { + recordEntity(httpRequest, trace); + } + } + if (dumpParam) { + if (DumpType.ALWAYS == paramDumpType) { + recordParam(httpRequest, trace); + } else if (DumpType.EXCEPTION == paramDumpType && isException) { + recordParam(httpRequest, trace); + } + } + } + + protected void recordCookie(com.ning.http.client.Request httpRequest, Trace trace) { + if (cookieSampler.isSampling()) { + Collection cookies = httpRequest.getCookies(); + + if (cookies.isEmpty()) { + return; + } + + StringBuilder sb = new StringBuilder(cookieDumpSize * 2); + Iterator iterator = cookies.iterator(); + while (iterator.hasNext()) { + Cookie cookie = iterator.next(); + sb.append(cookie.getName()).append("=").append(cookie.getValue()); + if (iterator.hasNext()) { + sb.append(","); + } + } + trace.recordAttribute(AnnotationKey.HTTP_COOKIE, StringUtils.drop(sb.toString(), cookieDumpSize)); + } + } + + protected void recordEntity(final com.ning.http.client.Request httpRequest, final Trace trace) { + if (entitySampler.isSampling()) { + recordNonMultipartData(httpRequest, trace); + recordMultipartData(httpRequest, trace); + } + } + + /** + *
+	 * body는 string, byte, stream, entitywriter 중 하나가 입력된다.
+	 * 여기에서는 stringdata만 수집하고 나머지는 일단 수집 안함.
+	 * 
+ * + * @param httpRequest + * @param trace + */ + protected void recordNonMultipartData(final com.ning.http.client.Request httpRequest, final Trace trace) { + final String stringData = httpRequest.getStringData(); + if (stringData != null) { + trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, StringUtils.drop(stringData, entityDumpSize)); + return; + } + + final byte[] byteData = httpRequest.getByteData(); + if (byteData != null) { + trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, "BYTE_DATA"); + return; + } + + final InputStream streamData = httpRequest.getStreamData(); + if (streamData != null) { + trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, "STREAM_DATA"); + return; + } + + final EntityWriter entityWriter = httpRequest.getEntityWriter(); + if (entityWriter != null) { + trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, "STREAM_DATA"); + return; + } + } + + /** + * record http multipart data + * + * @param httpRequest + * @param trace + */ + protected void recordMultipartData(final com.ning.http.client.Request httpRequest, final Trace trace) { + List parts = httpRequest.getParts(); + if (parts != null && parts.isEmpty()) { + StringBuilder sb = new StringBuilder(entityDumpSize * 2); + Iterator iterator = parts.iterator(); + while (iterator.hasNext()) { + Part part = iterator.next(); + if (part instanceof com.ning.http.client.ByteArrayPart) { + com.ning.http.client.ByteArrayPart p = (com.ning.http.client.ByteArrayPart) part; + sb.append(part.getName()); + sb.append("=BYTE_ARRAY_"); + sb.append(p.getData().length); + } else if (part instanceof com.ning.http.client.FilePart) { + com.ning.http.client.FilePart p = (com.ning.http.client.FilePart) part; + sb.append(part.getName()); + sb.append("=FILE_"); + sb.append(p.getMimeType()); + } else if (part instanceof com.ning.http.client.StringPart) { + com.ning.http.client.StringPart p = (com.ning.http.client.StringPart) part; + sb.append(part.getName()); + sb.append("="); + sb.append(p.getValue()); + } else if (part instanceof com.ning.http.multipart.FilePart) { + com.ning.http.multipart.FilePart p = (com.ning.http.multipart.FilePart) part; + sb.append(part.getName()); + sb.append("=FILE_"); + sb.append(p.getContentType()); + } else if (part instanceof com.ning.http.multipart.StringPart) { + com.ning.http.multipart.StringPart p = (com.ning.http.multipart.StringPart) part; + sb.append(part.getName()); + // string을 꺼내오는 방법이 없고, apache http client의 adaptation + // class라 무시. + sb.append("=STRING"); + } + + if (sb.length() >= entityDumpSize) { + break; + } + + if (iterator.hasNext()) { + sb.append(","); + } + } + trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, StringUtils.drop(sb.toString(), entityDumpSize)); + } + } + + /** + * record http request parameter + * + * @param httpRequest + * @param trace + */ + protected void recordParam(final com.ning.http.client.Request httpRequest, final Trace trace) { + if (paramSampler.isSampling()) { + FluentStringsMap requestParams = httpRequest.getParams(); + if (requestParams != null) { + String params = paramsToString(requestParams, paramDumpSize); + trace.recordAttribute(AnnotationKey.HTTP_PARAM, StringUtils.drop(params, paramDumpSize)); + } + } + } + + /** + * com.ning.http.client.FluentStringsMap.toString()에서 큰따옴표, 공백, 세미콜론을 제거한 버전 + * + * @param params + * @param limit + * @return + */ + private String paramsToString(FluentStringsMap params, int limit) { + StringBuilder result = new StringBuilder(limit * 2); + + for (Map.Entry> entry : params.entrySet()) { + if (result.length() > 0) { + result.append(","); + } + result.append(entry.getKey()); + result.append("="); + + boolean needsComma = false; + + for (String value : entry.getValue()) { + if (needsComma) { + result.append(", "); + } else { + needsComma = true; + } + result.append(value); + } + + if (result.length() >= limit) { + break; + } + } + return result.toString(); + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + + final ProfilerConfig profilerConfig = traceContext.getProfilerConfig(); + this.dumpCookie = profilerConfig.isNingAsyncHttpClientProfileCookie(); + this.cookieDumpType = profilerConfig.getNingAsyncHttpClientProfileCookieDumpType(); + this.cookieDumpSize = profilerConfig.getNingAsyncHttpClientProfileCookieDumpSize(); + if (dumpCookie) { + this.cookieSampler = SimpleSamplerFactory.createSampler(dumpCookie, profilerConfig.getNingAsyncHttpClientProfileCookieSamplingRate()); + } + + this.dumpEntity = profilerConfig.isNingAsyncHttpClientProfileEntity(); + this.entityDumpType = profilerConfig.getNingAsyncHttpClientProfileEntityDumpType(); + this.entityDumpSize = profilerConfig.getNingAsyncHttpClientProfileEntityDumpSize(); + if (dumpEntity) { + this.entitySampler = SimpleSamplerFactory.createSampler(dumpEntity, profilerConfig.getNingAsyncHttpClientProfileEntitySamplingRate()); + } + + this.dumpParam = profilerConfig.isNingAsyncHttpClientProfileParam(); + this.paramDumpType = profilerConfig.getNingAsyncHttpClientProfileParamDumpType(); + this.paramDumpSize = profilerConfig.getNingAsyncHttpClientProfileParamDumpSize(); + if (dumpParam) { + this.paramSampler = SimpleSamplerFactory.createSampler(dumpParam, profilerConfig.getNingAsyncHttpClientProfileParamSamplingRate()); + } + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + traceContext.cacheApi(descriptor); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AbstractHttpRequestExecute.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AbstractHttpRequestExecute.java index f55698cb1be0..c5ac1b810e0f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AbstractHttpRequestExecute.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AbstractHttpRequestExecute.java @@ -1,298 +1,298 @@ -package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; - -import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; -import com.nhn.pinpoint.bootstrap.util.SimpleSampler; -import com.nhn.pinpoint.bootstrap.util.SimpleSamplerFactory; -import com.nhn.pinpoint.bootstrap.util.StringUtils; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.config.DumpType; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.Header; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.pair.NameIntValuePair; -import com.nhn.pinpoint.bootstrap.sampler.SamplingFlagUtils; -import org.apache.http.*; -import org.apache.http.protocol.HTTP; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; - -/** - * @author emeroad - */ -public abstract class AbstractHttpRequestExecute implements TraceContextSupport, ByteCodeMethodDescriptorSupport, SimpleAroundInterceptor { - - protected PLogger logger; - protected boolean isDebug; - - protected TraceContext traceContext; - protected MethodDescriptor descriptor; - - protected boolean cookie; - protected DumpType cookieDumpType; - protected SimpleSampler cookieSampler; - - protected boolean entity; - protected DumpType entityDumpType; - protected SimpleSampler entitySampler; - - abstract NameIntValuePair getHost(Object[] args); - - abstract HttpRequest getHttpRequest(Object[] args); - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - final Trace trace = traceContext.currentRawTraceObject(); - if (trace == null) { - return; - } - - final HttpRequest httpRequest = getHttpRequest(args); - - final boolean sampling = trace.canSampled(); - if (!sampling) { - if(isDebug) { - logger.debug("set Sampling flag=false"); - } - if (httpRequest != null) { - httpRequest.addHeader(Header.HTTP_SAMPLED.toString(), SamplingFlagUtils.SAMPLING_RATE_FALSE); - } - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - - TraceId nextId = trace.getTraceId().getNextTraceId(); - trace.recordNextSpanId(nextId.getSpanId()); - trace.recordServiceType(ServiceType.HTTP_CLIENT); - - if (httpRequest != null) { - httpRequest.addHeader(Header.HTTP_TRACE_ID.toString(), nextId.getTransactionId()); - httpRequest.addHeader(Header.HTTP_SPAN_ID.toString(), String.valueOf(nextId.getSpanId())); - - httpRequest.addHeader(Header.HTTP_PARENT_SPAN_ID.toString(), String.valueOf(nextId.getParentSpanId())); - - httpRequest.addHeader(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); - httpRequest.addHeader(Header.HTTP_PARENT_APPLICATION_NAME.toString(), traceContext.getApplicationName()); - httpRequest.addHeader(Header.HTTP_PARENT_APPLICATION_TYPE.toString(), Short.toString(traceContext.getServerTypeCode())); - } - } - - - - private String getEndpoint(String host, int port) { - if (host == null) { - return "UnknownHttpClient"; - } - if (port < 0) { - return host; - } - StringBuilder sb = new StringBuilder(host.length() + 8); - sb.append(host); - sb.append(':'); - sb.append(port); - return sb.toString(); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - // result는 로깅하지 않는다. - logger.afterInterceptor(target, args); - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - try { - final HttpRequest httpRequest = getHttpRequest(args); - if (httpRequest != null) { - // httpRequest에 뭔가 access하는 작업은 위험이 있으므로 after에서 작업한다. - trace.recordAttribute(AnnotationKey.HTTP_URL, httpRequest.getRequestLine().getUri()); - final NameIntValuePair host = getHost(args); - if (host != null) { - int port = host.getValue(); - String endpoint = getEndpoint(host.getName(), port); - trace.recordDestinationId(endpoint); - } - - recordHttpRequest(trace, httpRequest, throwable); - } - trace.recordApi(descriptor); - trace.recordException(throwable); - - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - private void recordHttpRequest(Trace trace, HttpRequest httpRequest, Throwable throwable) { - final boolean isException = InterceptorUtils.isThrowable(throwable); - if (cookie) { - if (DumpType.ALWAYS == cookieDumpType) { - recordCookie(httpRequest, trace); - } else if(DumpType.EXCEPTION == cookieDumpType && isException){ - recordCookie(httpRequest, trace); - } - } - if (entity) { - if (DumpType.ALWAYS == entityDumpType) { - recordEntity(httpRequest, trace); - } else if(DumpType.EXCEPTION == entityDumpType && isException) { - recordEntity(httpRequest, trace); - } - } - } - - protected void recordCookie(HttpMessage httpMessage, Trace trace) { - org.apache.http.Header[] cookies = httpMessage.getHeaders("Cookie"); - for (org.apache.http.Header header: cookies) { - final String value = header.getValue(); - if (value != null && !value.isEmpty()) { - if (cookieSampler.isSampling()) { - trace.recordAttribute(AnnotationKey.HTTP_COOKIE, StringUtils.drop(value, 1024)); - } - // Cookie값이 2개 이상일수가 있나? - // 밑에서 break 를 쓰니 PMD에서 걸려서 수정함. - return; - } - } - } - - protected void recordEntity(HttpMessage httpMessage, Trace trace) { - if (httpMessage instanceof HttpEntityEnclosingRequest) { - final HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) httpMessage; - try { - final HttpEntity entity = entityRequest.getEntity(); - if (entity != null && entity.isRepeatable() && entity.getContentLength() > 0) { - if (entitySampler.isSampling()) { - final String entityString = entityUtilsToString(entity, "UTF8", 1024); - trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, StringUtils.drop(entityString, 1024)); - } - } - } catch (IOException e) { - logger.debug("HttpEntityEnclosingRequest entity record fail. Caused:{}", e.getMessage(), e); - } - } - } - - /** - * copy: EntityUtils - * Get the entity content as a String, using the provided default character set - * if none is found in the entity. - * If defaultCharset is null, the default "ISO-8859-1" is used. - * - * @param entity must not be null - * @param defaultCharset character set to be applied if none found in the entity - * @return the entity content as a String. May be null if - * {@link HttpEntity#getContent()} is null. - * @throws ParseException if header elements cannot be parsed - * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE - * @throws IOException if an error occurs reading the input stream - */ - public static String entityUtilsToString(final HttpEntity entity, final String defaultCharset, int maxLength) throws IOException, ParseException { - if (entity == null) { - throw new IllegalArgumentException("HTTP entity may not be null"); - } - final InputStream instream = entity.getContent(); - if (instream == null) { - return null; - } - try { - if (entity.getContentLength() > Integer.MAX_VALUE) { - return "HTTP entity too large to be buffered in memory length:" + entity.getContentLength(); - } - int i = (int)entity.getContentLength(); - if (i < 0) { - i = 4096; - } - String charset = getContentCharSet(entity); - if (charset == null) { - charset = defaultCharset; - } - if (charset == null) { - charset = HTTP.DEFAULT_CONTENT_CHARSET; - } - Reader reader = new InputStreamReader(instream, charset); - final StringBuilder buffer = new StringBuilder(maxLength * 2); - char[] tmp = new char[1024]; - int l; - while((l = reader.read(tmp)) != -1) { - buffer.append(tmp, 0, l); - // maxLength 이상 읽었을 경우 stream을 그만 읽는다. - if (buffer.length() >= maxLength) { - break; - } - } - return buffer.toString(); - } finally { - instream.close(); - } - } - - /** - * copy: EntityUtils - * Obtains character set of the entity, if known. - * - * @param entity must not be null - * @return the character set, or null if not found - * @throws ParseException if header elements cannot be parsed - * @throws IllegalArgumentException if entity is null - */ - public static String getContentCharSet(final HttpEntity entity) throws ParseException { - if (entity == null) { - throw new IllegalArgumentException("HTTP entity may not be null"); - } - String charset = null; - if (entity.getContentType() != null) { - HeaderElement values[] = entity.getContentType().getElements(); - if (values.length > 0) { - NameValuePair param = values[0].getParameterByName("charset"); - if (param != null) { - charset = param.getValue(); - } - } - } - return charset; - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - - final ProfilerConfig profilerConfig = traceContext.getProfilerConfig(); - this.cookie = profilerConfig.isApacheHttpClient4ProfileCookie(); - this.cookieDumpType = profilerConfig.getApacheHttpClient4ProfileCookieDumpType(); - if (cookie){ - this.cookieSampler = SimpleSamplerFactory.createSampler(cookie, profilerConfig.getApacheHttpClient4ProfileCookieSamplingRate()); - } - - this.entity = profilerConfig.isApacheHttpClient4ProfileEntity(); - this.entityDumpType = profilerConfig.getApacheHttpClient4ProfileEntityDumpType(); - if (entity) { - this.entitySampler = SimpleSamplerFactory.createSampler(entity, profilerConfig.getApacheHttpClient4ProfileEntitySamplingRate()); - } - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.descriptor = descriptor; - traceContext.cacheApi(descriptor); - } -} +package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; + +import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; +import com.nhn.pinpoint.bootstrap.util.SimpleSampler; +import com.nhn.pinpoint.bootstrap.util.SimpleSamplerFactory; +import com.nhn.pinpoint.bootstrap.util.StringUtils; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.config.DumpType; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.context.Header; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.pair.NameIntValuePair; +import com.nhn.pinpoint.bootstrap.sampler.SamplingFlagUtils; +import org.apache.http.*; +import org.apache.http.protocol.HTTP; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * @author emeroad + */ +public abstract class AbstractHttpRequestExecute implements TraceContextSupport, ByteCodeMethodDescriptorSupport, SimpleAroundInterceptor { + + protected PLogger logger; + protected boolean isDebug; + + protected TraceContext traceContext; + protected MethodDescriptor descriptor; + + protected boolean cookie; + protected DumpType cookieDumpType; + protected SimpleSampler cookieSampler; + + protected boolean entity; + protected DumpType entityDumpType; + protected SimpleSampler entitySampler; + + abstract NameIntValuePair getHost(Object[] args); + + abstract HttpRequest getHttpRequest(Object[] args); + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + final Trace trace = traceContext.currentRawTraceObject(); + if (trace == null) { + return; + } + + final HttpRequest httpRequest = getHttpRequest(args); + + final boolean sampling = trace.canSampled(); + if (!sampling) { + if(isDebug) { + logger.debug("set Sampling flag=false"); + } + if (httpRequest != null) { + httpRequest.addHeader(Header.HTTP_SAMPLED.toString(), SamplingFlagUtils.SAMPLING_RATE_FALSE); + } + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + + TraceId nextId = trace.getTraceId().getNextTraceId(); + trace.recordNextSpanId(nextId.getSpanId()); + trace.recordServiceType(ServiceType.HTTP_CLIENT); + + if (httpRequest != null) { + httpRequest.addHeader(Header.HTTP_TRACE_ID.toString(), nextId.getTransactionId()); + httpRequest.addHeader(Header.HTTP_SPAN_ID.toString(), String.valueOf(nextId.getSpanId())); + + httpRequest.addHeader(Header.HTTP_PARENT_SPAN_ID.toString(), String.valueOf(nextId.getParentSpanId())); + + httpRequest.addHeader(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); + httpRequest.addHeader(Header.HTTP_PARENT_APPLICATION_NAME.toString(), traceContext.getApplicationName()); + httpRequest.addHeader(Header.HTTP_PARENT_APPLICATION_TYPE.toString(), Short.toString(traceContext.getServerTypeCode())); + } + } + + + + private String getEndpoint(String host, int port) { + if (host == null) { + return "UnknownHttpClient"; + } + if (port < 0) { + return host; + } + StringBuilder sb = new StringBuilder(host.length() + 8); + sb.append(host); + sb.append(':'); + sb.append(port); + return sb.toString(); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + // result는 로깅하지 않는다. + logger.afterInterceptor(target, args); + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + try { + final HttpRequest httpRequest = getHttpRequest(args); + if (httpRequest != null) { + // httpRequest에 뭔가 access하는 작업은 위험이 있으므로 after에서 작업한다. + trace.recordAttribute(AnnotationKey.HTTP_URL, httpRequest.getRequestLine().getUri()); + final NameIntValuePair host = getHost(args); + if (host != null) { + int port = host.getValue(); + String endpoint = getEndpoint(host.getName(), port); + trace.recordDestinationId(endpoint); + } + + recordHttpRequest(trace, httpRequest, throwable); + } + trace.recordApi(descriptor); + trace.recordException(throwable); + + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + private void recordHttpRequest(Trace trace, HttpRequest httpRequest, Throwable throwable) { + final boolean isException = InterceptorUtils.isThrowable(throwable); + if (cookie) { + if (DumpType.ALWAYS == cookieDumpType) { + recordCookie(httpRequest, trace); + } else if(DumpType.EXCEPTION == cookieDumpType && isException){ + recordCookie(httpRequest, trace); + } + } + if (entity) { + if (DumpType.ALWAYS == entityDumpType) { + recordEntity(httpRequest, trace); + } else if(DumpType.EXCEPTION == entityDumpType && isException) { + recordEntity(httpRequest, trace); + } + } + } + + protected void recordCookie(HttpMessage httpMessage, Trace trace) { + org.apache.http.Header[] cookies = httpMessage.getHeaders("Cookie"); + for (org.apache.http.Header header: cookies) { + final String value = header.getValue(); + if (value != null && !value.isEmpty()) { + if (cookieSampler.isSampling()) { + trace.recordAttribute(AnnotationKey.HTTP_COOKIE, StringUtils.drop(value, 1024)); + } + // Cookie값이 2개 이상일수가 있나? + // 밑에서 break 를 쓰니 PMD에서 걸려서 수정함. + return; + } + } + } + + protected void recordEntity(HttpMessage httpMessage, Trace trace) { + if (httpMessage instanceof HttpEntityEnclosingRequest) { + final HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) httpMessage; + try { + final HttpEntity entity = entityRequest.getEntity(); + if (entity != null && entity.isRepeatable() && entity.getContentLength() > 0) { + if (entitySampler.isSampling()) { + final String entityString = entityUtilsToString(entity, "UTF8", 1024); + trace.recordAttribute(AnnotationKey.HTTP_PARAM_ENTITY, StringUtils.drop(entityString, 1024)); + } + } + } catch (IOException e) { + logger.debug("HttpEntityEnclosingRequest entity record fail. Caused:{}", e.getMessage(), e); + } + } + } + + /** + * copy: EntityUtils + * Get the entity content as a String, using the provided default character set + * if none is found in the entity. + * If defaultCharset is null, the default "ISO-8859-1" is used. + * + * @param entity must not be null + * @param defaultCharset character set to be applied if none found in the entity + * @return the entity content as a String. May be null if + * {@link HttpEntity#getContent()} is null. + * @throws ParseException if header elements cannot be parsed + * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE + * @throws IOException if an error occurs reading the input stream + */ + public static String entityUtilsToString(final HttpEntity entity, final String defaultCharset, int maxLength) throws IOException, ParseException { + if (entity == null) { + throw new IllegalArgumentException("HTTP entity may not be null"); + } + final InputStream instream = entity.getContent(); + if (instream == null) { + return null; + } + try { + if (entity.getContentLength() > Integer.MAX_VALUE) { + return "HTTP entity too large to be buffered in memory length:" + entity.getContentLength(); + } + int i = (int)entity.getContentLength(); + if (i < 0) { + i = 4096; + } + String charset = getContentCharSet(entity); + if (charset == null) { + charset = defaultCharset; + } + if (charset == null) { + charset = HTTP.DEFAULT_CONTENT_CHARSET; + } + Reader reader = new InputStreamReader(instream, charset); + final StringBuilder buffer = new StringBuilder(maxLength * 2); + char[] tmp = new char[1024]; + int l; + while((l = reader.read(tmp)) != -1) { + buffer.append(tmp, 0, l); + // maxLength 이상 읽었을 경우 stream을 그만 읽는다. + if (buffer.length() >= maxLength) { + break; + } + } + return buffer.toString(); + } finally { + instream.close(); + } + } + + /** + * copy: EntityUtils + * Obtains character set of the entity, if known. + * + * @param entity must not be null + * @return the character set, or null if not found + * @throws ParseException if header elements cannot be parsed + * @throws IllegalArgumentException if entity is null + */ + public static String getContentCharSet(final HttpEntity entity) throws ParseException { + if (entity == null) { + throw new IllegalArgumentException("HTTP entity may not be null"); + } + String charset = null; + if (entity.getContentType() != null) { + HeaderElement values[] = entity.getContentType().getElements(); + if (values.length > 0) { + NameValuePair param = values[0].getParameterByName("charset"); + if (param != null) { + charset = param.getValue(); + } + } + } + return charset; + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + + final ProfilerConfig profilerConfig = traceContext.getProfilerConfig(); + this.cookie = profilerConfig.isApacheHttpClient4ProfileCookie(); + this.cookieDumpType = profilerConfig.getApacheHttpClient4ProfileCookieDumpType(); + if (cookie){ + this.cookieSampler = SimpleSamplerFactory.createSampler(cookie, profilerConfig.getApacheHttpClient4ProfileCookieSamplingRate()); + } + + this.entity = profilerConfig.isApacheHttpClient4ProfileEntity(); + this.entityDumpType = profilerConfig.getApacheHttpClient4ProfileEntityDumpType(); + if (entity) { + this.entitySampler = SimpleSamplerFactory.createSampler(entity, profilerConfig.getApacheHttpClient4ProfileEntitySamplingRate()); + } + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + traceContext.cacheApi(descriptor); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncClientExecuteInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncClientExecuteInterceptor.java index a11aebf41fc5..c8c72fdbdcfa 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncClientExecuteInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncClientExecuteInterceptor.java @@ -1,54 +1,54 @@ -package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.pair.NameIntValuePair; - -/** - * - * suitable target method - *
- * org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(HttpHost, HttpRequest, HttpContext, FutureCallback)
- * 
- * - * original code of method. - *
- * 
- * public Future execute(
- *     final HttpHost target,
- *     final HttpRequest request,
- *     final HttpContext context,
- *     final FutureCallback callback) {
- *     
- *     return execute(
- *         HttpAsyncMethods.create(target, request),
- *         HttpAsyncMethods.createConsumer(),
- *         context,
- *         callback);
- * }
- * 
- * 
- * - * @author netspider - * - */ -public class AsyncClientExecuteInterceptor extends AbstractHttpRequestExecute implements TargetClassLoader { - - @Override - protected NameIntValuePair getHost(Object[] args) { - if (args[0] instanceof org.apache.http.HttpHost) { - final org.apache.http.HttpHost httpHost = (org.apache.http.HttpHost) args[0]; - return new NameIntValuePair(httpHost.getHostName(), httpHost.getPort()); - } else { - return null; - } - } - - @Override - protected org.apache.http.HttpRequest getHttpRequest(final Object[] args) { - if (args[1] instanceof org.apache.http.HttpRequest) { - return (org.apache.http.HttpRequest) args[1]; - } else { - return null; - } - } +package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.pair.NameIntValuePair; + +/** + * + * suitable target method + *
+ * org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(HttpHost, HttpRequest, HttpContext, FutureCallback)
+ * 
+ * + * original code of method. + *
+ * 
+ * public Future execute(
+ *     final HttpHost target,
+ *     final HttpRequest request,
+ *     final HttpContext context,
+ *     final FutureCallback callback) {
+ *     
+ *     return execute(
+ *         HttpAsyncMethods.create(target, request),
+ *         HttpAsyncMethods.createConsumer(),
+ *         context,
+ *         callback);
+ * }
+ * 
+ * 
+ * + * @author netspider + * + */ +public class AsyncClientExecuteInterceptor extends AbstractHttpRequestExecute implements TargetClassLoader { + + @Override + protected NameIntValuePair getHost(Object[] args) { + if (args[0] instanceof org.apache.http.HttpHost) { + final org.apache.http.HttpHost httpHost = (org.apache.http.HttpHost) args[0]; + return new NameIntValuePair(httpHost.getHostName(), httpHost.getPort()); + } else { + return null; + } + } + + @Override + protected org.apache.http.HttpRequest getHttpRequest(final Object[] args) { + if (args[1] instanceof org.apache.http.HttpRequest) { + return (org.apache.http.HttpRequest) args[1]; + } else { + return null; + } + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncInternalClientExecuteInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncInternalClientExecuteInterceptor.java index b52e151f4377..4b4a1ff69b44 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncInternalClientExecuteInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/AsyncInternalClientExecuteInterceptor.java @@ -1,100 +1,100 @@ -package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; - -import org.apache.http.HttpHost; - -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.pair.NameIntValuePair; - -/** - * - * suitable target method - * - *
- * org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(HttpAsyncRequestProducer, HttpAsyncResponseConsumer, HttpContext, FutureCallback)
- * org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(HttpAsyncRequestProducer, HttpAsyncResponseConsumer, FutureCallback)
- * 
- * - * original code of method. - * - *
- * 
- * // org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute
- * public  Future execute(
- *     final org.apache.http.nio.protocol.HttpAsyncRequestProducer requestProducer,
- *     final org.apache.http.nio.protocol.HttpAsyncResponseConsumer responseConsumer,
- * 	   final org.apache.http.protocol.HttpContext context,
- * 	   final org.apache.http.concurrent.FutureCallback callback) {
- * 
- * 	   final Status status = getStatus();
- * 	   Asserts.check(status == Status.ACTIVE, "Request cannot be executed; I/O reactor status: %s", status);
- * 
- * 	   final BasicFuture future = new BasicFuture(callback);
- * 	   final HttpClientContext localcontext = HttpClientContext.adapt(context != null ? context : new BasicHttpContext());
- * 	   setupContext(localcontext);
- * 
- * 	   @SuppressWarnings("resource")
- * 	   final DefaultClientExchangeHandlerImpl handler = new DefaultClientExchangeHandlerImpl(
- * 	       this.log,
- * 	       requestProducer,
- * 	       responseConsumer,
- * 	       localcontext,
- * 	       future,
- * 	       this.connmgr,
- * 	       this.exec);
- * 
- * 	   try {
- * 	       handler.start();
- * 	   } catch (final Exception ex) {
- * 	       handler.failed(ex);
- * 	   }
- * 	   return future;
- * }
- * 
- * OR
- * 
- * // org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute
- * public  Future execute(
- *     final HttpAsyncRequestProducer requestProducer,
- *     final HttpAsyncResponseConsumer responseConsumer,
- *     final FutureCallback callback) {
- *     
- *     return execute(requestProducer, responseConsumer, new BasicHttpContext(), callback);
- * }
- * 
- * 
- * - * - * @author netspider - * - */ -public class AsyncInternalClientExecuteInterceptor extends AbstractHttpRequestExecute implements TargetClassLoader { - - @Override - protected NameIntValuePair getHost(Object[] args) { - if (!(args[0] instanceof org.apache.http.nio.protocol.HttpAsyncRequestProducer)) { - return null; - } - - final org.apache.http.nio.protocol.HttpAsyncRequestProducer producer = (org.apache.http.nio.protocol.HttpAsyncRequestProducer) args[0]; - final HttpHost httpHost = producer.getTarget(); - - return new NameIntValuePair(httpHost.getHostName(), httpHost.getPort()); - } - - @Override - protected org.apache.http.HttpRequest getHttpRequest(final Object[] args) { - if (!(args[0] instanceof org.apache.http.nio.protocol.HttpAsyncRequestProducer)) { - return null; - } - final org.apache.http.nio.protocol.HttpAsyncRequestProducer producer = (org.apache.http.nio.protocol.HttpAsyncRequestProducer) args[0]; - try { - /** - * FIXME org.apache.http.nio.protocol.BasicAsyncRequestProducer. - * generateRequest() 는 문제가 되지 않지만 다른 구현체는 문제가 될 수 있다. - */ - return producer.generateRequest(); - } catch (Exception e) { - return null; - } - } -} +package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; + +import org.apache.http.HttpHost; + +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.pair.NameIntValuePair; + +/** + * + * suitable target method + * + *
+ * org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(HttpAsyncRequestProducer, HttpAsyncResponseConsumer, HttpContext, FutureCallback)
+ * org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(HttpAsyncRequestProducer, HttpAsyncResponseConsumer, FutureCallback)
+ * 
+ * + * original code of method. + * + *
+ * 
+ * // org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute
+ * public  Future execute(
+ *     final org.apache.http.nio.protocol.HttpAsyncRequestProducer requestProducer,
+ *     final org.apache.http.nio.protocol.HttpAsyncResponseConsumer responseConsumer,
+ * 	   final org.apache.http.protocol.HttpContext context,
+ * 	   final org.apache.http.concurrent.FutureCallback callback) {
+ * 
+ * 	   final Status status = getStatus();
+ * 	   Asserts.check(status == Status.ACTIVE, "Request cannot be executed; I/O reactor status: %s", status);
+ * 
+ * 	   final BasicFuture future = new BasicFuture(callback);
+ * 	   final HttpClientContext localcontext = HttpClientContext.adapt(context != null ? context : new BasicHttpContext());
+ * 	   setupContext(localcontext);
+ * 
+ * 	   @SuppressWarnings("resource")
+ * 	   final DefaultClientExchangeHandlerImpl handler = new DefaultClientExchangeHandlerImpl(
+ * 	       this.log,
+ * 	       requestProducer,
+ * 	       responseConsumer,
+ * 	       localcontext,
+ * 	       future,
+ * 	       this.connmgr,
+ * 	       this.exec);
+ * 
+ * 	   try {
+ * 	       handler.start();
+ * 	   } catch (final Exception ex) {
+ * 	       handler.failed(ex);
+ * 	   }
+ * 	   return future;
+ * }
+ * 
+ * OR
+ * 
+ * // org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute
+ * public  Future execute(
+ *     final HttpAsyncRequestProducer requestProducer,
+ *     final HttpAsyncResponseConsumer responseConsumer,
+ *     final FutureCallback callback) {
+ *     
+ *     return execute(requestProducer, responseConsumer, new BasicHttpContext(), callback);
+ * }
+ * 
+ * 
+ * + * + * @author netspider + * + */ +public class AsyncInternalClientExecuteInterceptor extends AbstractHttpRequestExecute implements TargetClassLoader { + + @Override + protected NameIntValuePair getHost(Object[] args) { + if (!(args[0] instanceof org.apache.http.nio.protocol.HttpAsyncRequestProducer)) { + return null; + } + + final org.apache.http.nio.protocol.HttpAsyncRequestProducer producer = (org.apache.http.nio.protocol.HttpAsyncRequestProducer) args[0]; + final HttpHost httpHost = producer.getTarget(); + + return new NameIntValuePair(httpHost.getHostName(), httpHost.getPort()); + } + + @Override + protected org.apache.http.HttpRequest getHttpRequest(final Object[] args) { + if (!(args[0] instanceof org.apache.http.nio.protocol.HttpAsyncRequestProducer)) { + return null; + } + final org.apache.http.nio.protocol.HttpAsyncRequestProducer producer = (org.apache.http.nio.protocol.HttpAsyncRequestProducer) args[0]; + try { + /** + * FIXME org.apache.http.nio.protocol.BasicAsyncRequestProducer. + * generateRequest() 는 문제가 되지 않지만 다른 구현체는 문제가 될 수 있다. + */ + return producer.generateRequest(); + } catch (Exception e) { + return null; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureCompletedInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureCompletedInterceptor.java index f955195aa288..0f587d2e96d7 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureCompletedInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureCompletedInterceptor.java @@ -1,97 +1,97 @@ -package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.common.ServiceType; - -/** - * - * suitable method - *
- * org.apache.http.concurrent.BasicFuture.completed(T)
- * 
- * - * original code of method - * - *
- * 	public boolean completed(final T result) {
- * 		synchronized (this) {
- * 			if (this.completed) {
- * 				return false;
- * 			}
- * 			this.completed = true;
- * 			this.result = result;
- * 			notifyAll();
- * 		}
- * 		if (this.callback != null) {
- * 			this.callback.completed(result);
- * 		}
- * 		return true;
- * 	}
- * 
- *
- * - * @author netspider - * - */ -public class BasicFutureCompletedInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { - - protected PLogger logger; - protected boolean isDebug; - - protected TraceContext traceContext; - protected MethodDescriptor descriptor; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - trace.recordServiceType(ServiceType.HTTP_CLIENT_INTERNAL); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - try { - trace.recordApi(descriptor); - trace.recordException(throwable); - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.descriptor = descriptor; - traceContext.cacheApi(descriptor); - } -} +package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.common.ServiceType; + +/** + * + * suitable method + *
+ * org.apache.http.concurrent.BasicFuture.completed(T)
+ * 
+ * + * original code of method + * + *
+ * 	public boolean completed(final T result) {
+ * 		synchronized (this) {
+ * 			if (this.completed) {
+ * 				return false;
+ * 			}
+ * 			this.completed = true;
+ * 			this.result = result;
+ * 			notifyAll();
+ * 		}
+ * 		if (this.callback != null) {
+ * 			this.callback.completed(result);
+ * 		}
+ * 		return true;
+ * 	}
+ * 
+ *
+ * + * @author netspider + * + */ +public class BasicFutureCompletedInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { + + protected PLogger logger; + protected boolean isDebug; + + protected TraceContext traceContext; + protected MethodDescriptor descriptor; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + trace.recordServiceType(ServiceType.HTTP_CLIENT_INTERNAL); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + try { + trace.recordApi(descriptor); + trace.recordException(throwable); + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + traceContext.cacheApi(descriptor); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureFailedInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureFailedInterceptor.java index f9eb9df306c4..8ec9f4e1e691 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureFailedInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureFailedInterceptor.java @@ -1,97 +1,97 @@ -package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.common.ServiceType; - -/** - * - * suitable method - *
- * org.apache.http.concurrent.BasicFuture.failed(Exception)
- * 
- * - * original code of method - * - *
- * 	public boolean failed(final Exception exception) {
- * 		synchronized (this) {
- * 			if (this.completed) {
- * 				return false;
- * 			}
- * 			this.completed = true;
- * 			this.ex = exception;
- * 			notifyAll();
- * 		}
- * 		if (this.callback != null) {
- * 			this.callback.failed(exception);
- * 		}
- * 		return true;
- * 	}
- * 
- *
- * - * @author netspider - * - */ -public class BasicFutureFailedInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { - - protected PLogger logger; - protected boolean isDebug; - - protected TraceContext traceContext; - protected MethodDescriptor descriptor; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - trace.recordServiceType(ServiceType.HTTP_CLIENT_INTERNAL); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - try { - trace.recordApi(descriptor); - trace.recordException(throwable); - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.descriptor = descriptor; - traceContext.cacheApi(descriptor); - } -} +package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.common.ServiceType; + +/** + * + * suitable method + *
+ * org.apache.http.concurrent.BasicFuture.failed(Exception)
+ * 
+ * + * original code of method + * + *
+ * 	public boolean failed(final Exception exception) {
+ * 		synchronized (this) {
+ * 			if (this.completed) {
+ * 				return false;
+ * 			}
+ * 			this.completed = true;
+ * 			this.ex = exception;
+ * 			notifyAll();
+ * 		}
+ * 		if (this.callback != null) {
+ * 			this.callback.failed(exception);
+ * 		}
+ * 		return true;
+ * 	}
+ * 
+ *
+ * + * @author netspider + * + */ +public class BasicFutureFailedInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { + + protected PLogger logger; + protected boolean isDebug; + + protected TraceContext traceContext; + protected MethodDescriptor descriptor; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + trace.recordServiceType(ServiceType.HTTP_CLIENT_INTERNAL); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + try { + trace.recordApi(descriptor); + trace.recordException(throwable); + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + traceContext.cacheApi(descriptor); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureGetInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureGetInterceptor.java index 2e5f50c6a2bd..c1dfcb263688 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureGetInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/BasicFutureGetInterceptor.java @@ -1,113 +1,113 @@ -package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.common.ServiceType; - -/** - * suitable method - * - *
- * org.apache.http.concurrent.BasicFuture.get()
- * org.apache.http.concurrent.BasicFuture.get(long, TimeUnit)
- * 
- * - * - *
- * 	public synchronized T get() throws InterruptedException, ExecutionException {
- * 		while (!this.completed) {
- * 			wait();
- * 		}
- * 		return getResult();
- * 	}
- * 
- * 	public synchronized T get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
- * 		Args.notNull(unit, "Time unit");
- * 		final long msecs = unit.toMillis(timeout);
- * 		final long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis();
- * 		long waitTime = msecs;
- * 		if (this.completed) {
- * 			return getResult();
- * 		} else if (waitTime <= 0) {
- * 			throw new TimeoutException();
- * 		} else {
- * 			for (;;) {
- * 				wait(waitTime);
- * 				if (this.completed) {
- * 					return getResult();
- * 				} else {
- * 					waitTime = msecs - (System.currentTimeMillis() - startTime);
- * 					if (waitTime <= 0) {
- * 						throw new TimeoutException();
- * 					}
- * 				}
- * 			}
- * 		}
- * 	}
- * 
- *
- * - * @author netspider - * - */ -public class BasicFutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { - - protected PLogger logger; - protected boolean isDebug; - - protected TraceContext traceContext; - protected MethodDescriptor descriptor; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - trace.recordServiceType(ServiceType.HTTP_CLIENT_INTERNAL); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - try { - trace.recordApi(descriptor); - trace.recordException(throwable); - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.descriptor = descriptor; - traceContext.cacheApi(descriptor); - } -} +package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.common.ServiceType; + +/** + * suitable method + * + *
+ * org.apache.http.concurrent.BasicFuture.get()
+ * org.apache.http.concurrent.BasicFuture.get(long, TimeUnit)
+ * 
+ * + * + *
+ * 	public synchronized T get() throws InterruptedException, ExecutionException {
+ * 		while (!this.completed) {
+ * 			wait();
+ * 		}
+ * 		return getResult();
+ * 	}
+ * 
+ * 	public synchronized T get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ * 		Args.notNull(unit, "Time unit");
+ * 		final long msecs = unit.toMillis(timeout);
+ * 		final long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis();
+ * 		long waitTime = msecs;
+ * 		if (this.completed) {
+ * 			return getResult();
+ * 		} else if (waitTime <= 0) {
+ * 			throw new TimeoutException();
+ * 		} else {
+ * 			for (;;) {
+ * 				wait(waitTime);
+ * 				if (this.completed) {
+ * 					return getResult();
+ * 				} else {
+ * 					waitTime = msecs - (System.currentTimeMillis() - startTime);
+ * 					if (waitTime <= 0) {
+ * 						throw new TimeoutException();
+ * 					}
+ * 				}
+ * 			}
+ * 		}
+ * 	}
+ * 
+ *
+ * + * @author netspider + * + */ +public class BasicFutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader { + + protected PLogger logger; + protected boolean isDebug; + + protected TraceContext traceContext; + protected MethodDescriptor descriptor; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + trace.recordServiceType(ServiceType.HTTP_CLIENT_INTERNAL); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + try { + trace.recordApi(descriptor); + trace.recordException(throwable); + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + traceContext.cacheApi(descriptor); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/HttpClient4Scope.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/HttpClient4Scope.java index 649527bab1c0..907dc12daa41 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/HttpClient4Scope.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/httpclient4/interceptor/HttpClient4Scope.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; - -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * @author emeroad - */ -public class HttpClient4Scope { - public static final DepthScope SCOPE = new DepthScope("HTTPClient4Scope"); -} +package com.nhn.pinpoint.profiler.modifier.connector.httpclient4.interceptor; + +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * @author emeroad + */ +public class HttpClient4Scope { + public static final DepthScope SCOPE = new DepthScope("HTTPClient4Scope"); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/jdkhttpconnector/HttpURLConnectionModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/jdkhttpconnector/HttpURLConnectionModifier.java index 5936d60667d6..8314cb42d525 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/jdkhttpconnector/HttpURLConnectionModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/connector/jdkhttpconnector/HttpURLConnectionModifier.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.profiler.modifier.connector.jdkhttpconnector; - -import java.security.ProtectionDomain; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.connector.jdkhttpconnector.interceptor.ConnectMethodInterceptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * TODO classloader문제 있음. - * @author netspider - * - */ -public class HttpURLConnectionModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public HttpURLConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "sun/net/www/protocol/http/HttpURLConnection"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - - byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); - ConnectMethodInterceptor connectMethodInterceptor = new ConnectMethodInterceptor(); - aClass.addInterceptorCallByContextClassLoader("connect", null, connectMethodInterceptor); - - return aClass.toBytecode(); - } catch (InstrumentException e) { - logger.warn("HttpURLConnectionModifier fail. Caused:", e.getMessage(), e); - return null; - } - } +package com.nhn.pinpoint.profiler.modifier.connector.jdkhttpconnector; + +import java.security.ProtectionDomain; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.connector.jdkhttpconnector.interceptor.ConnectMethodInterceptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * TODO classloader문제 있음. + * @author netspider + * + */ +public class HttpURLConnectionModifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public HttpURLConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "sun/net/www/protocol/http/HttpURLConnection"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + + byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); + ConnectMethodInterceptor connectMethodInterceptor = new ConnectMethodInterceptor(); + aClass.addInterceptorCallByContextClassLoader("connect", null, connectMethodInterceptor); + + return aClass.toBytecode(); + } catch (InstrumentException e) { + logger.warn("HttpURLConnectionModifier fail. Caused:", e.getMessage(), e); + return null; + } + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/ConnectionStringParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/ConnectionStringParser.java index a13a013b0ff0..33360f6101a7 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/ConnectionStringParser.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/ConnectionStringParser.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.profiler.modifier.db; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; - -/** - * @author emeroad - */ -public interface ConnectionStringParser { - DatabaseInfo parse(String url); -} +package com.nhn.pinpoint.profiler.modifier.db; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; + +/** + * @author emeroad + */ +public interface ConnectionStringParser { + DatabaseInfo parse(String url); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/DefaultDatabaseInfo.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/DefaultDatabaseInfo.java index b8c1c20868d0..4901846a12aa 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/DefaultDatabaseInfo.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/DefaultDatabaseInfo.java @@ -1,100 +1,100 @@ -package com.nhn.pinpoint.profiler.modifier.db; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; - -import java.util.List; - -/** - * @author emeroad - */ -public class DefaultDatabaseInfo implements DatabaseInfo { - - private ServiceType type = ServiceType.UNKNOWN_DB; - private ServiceType executeQueryType = ServiceType.UNKNOWN_DB_EXECUTE_QUERY; - private String databaseId; - // 입력된 url을 보정하지 않은 값 - private String realUrl; - private String normalizedUrl; - private List host; - private String multipleHost; - - public DefaultDatabaseInfo(ServiceType type, ServiceType executeQueryType, String realUrl, String normalizedUrl, List host, String databaseId) { - if (type == null) { - throw new NullPointerException("type must not be null"); - } - if (executeQueryType == null) { - throw new NullPointerException("executeQueryType must not be null"); - } - this.type = type; - this.executeQueryType = executeQueryType; - this.realUrl = realUrl; - this.normalizedUrl = normalizedUrl; - this.host = host; - this.multipleHost = merge(host); - this.databaseId = databaseId; - } - - private String merge(List host) { - if (host.isEmpty()) { - return ""; - } - String single = host.get(0); - StringBuilder sb = new StringBuilder(); - sb.append(single); - for(int i =1; i getHost() { - // host와 port의 경우 replication 설정등으로 n개가 될수 있어 애매하다. - return host; - } - - @Override - public String getMultipleHost() { - return multipleHost; - } - - @Override - public String getDatabaseId() { - return databaseId; - } - - @Override - public String getRealUrl() { - return realUrl; - } - - @Override - public String getUrl() { - return normalizedUrl; - } - - @Override - public ServiceType getType() { - return type; - } - - @Override - public ServiceType getExecuteQueryType() { - return executeQueryType; - } - - @Override - public String toString() { - return "DatabaseInfo{" + - "type=" + type + - ", executeQueryType=" + executeQueryType + - ", databaseId='" + databaseId + '\'' + - ", realUrl='" + realUrl + '\'' + - ", normalizedUrl='" + normalizedUrl + '\'' + - ", host=" + host + - '}'; - } -} +package com.nhn.pinpoint.profiler.modifier.db; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; + +import java.util.List; + +/** + * @author emeroad + */ +public class DefaultDatabaseInfo implements DatabaseInfo { + + private ServiceType type = ServiceType.UNKNOWN_DB; + private ServiceType executeQueryType = ServiceType.UNKNOWN_DB_EXECUTE_QUERY; + private String databaseId; + // 입력된 url을 보정하지 않은 값 + private String realUrl; + private String normalizedUrl; + private List host; + private String multipleHost; + + public DefaultDatabaseInfo(ServiceType type, ServiceType executeQueryType, String realUrl, String normalizedUrl, List host, String databaseId) { + if (type == null) { + throw new NullPointerException("type must not be null"); + } + if (executeQueryType == null) { + throw new NullPointerException("executeQueryType must not be null"); + } + this.type = type; + this.executeQueryType = executeQueryType; + this.realUrl = realUrl; + this.normalizedUrl = normalizedUrl; + this.host = host; + this.multipleHost = merge(host); + this.databaseId = databaseId; + } + + private String merge(List host) { + if (host.isEmpty()) { + return ""; + } + String single = host.get(0); + StringBuilder sb = new StringBuilder(); + sb.append(single); + for(int i =1; i getHost() { + // host와 port의 경우 replication 설정등으로 n개가 될수 있어 애매하다. + return host; + } + + @Override + public String getMultipleHost() { + return multipleHost; + } + + @Override + public String getDatabaseId() { + return databaseId; + } + + @Override + public String getRealUrl() { + return realUrl; + } + + @Override + public String getUrl() { + return normalizedUrl; + } + + @Override + public ServiceType getType() { + return type; + } + + @Override + public ServiceType getExecuteQueryType() { + return executeQueryType; + } + + @Override + public String toString() { + return "DatabaseInfo{" + + "type=" + type + + ", executeQueryType=" + executeQueryType + + ", databaseId='" + databaseId + '\'' + + ", realUrl='" + realUrl + '\'' + + ", normalizedUrl='" + normalizedUrl + '\'' + + ", host=" + host + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParser.java index 87b26e1dc0f9..c253b6f6c2fc 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParser.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParser.java @@ -1,215 +1,108 @@ -package com.nhn.pinpoint.profiler.modifier.db; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.profiler.modifier.db.cubrid.CubridConnectionStringParser; -import com.nhn.pinpoint.profiler.modifier.db.mysql.MySqlConnectionStringParser; -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.Description; -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.KeyValue; -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleConnectionStringException; -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleNetConnectionDescriptorParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class JDBCUrlParser { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final ConcurrentMap cache = new ConcurrentHashMap(); - - - public DatabaseInfo parse(String url) { - final DatabaseInfo hit = cache.get(url); - if (hit != null) { - logger.debug("database url cache hit:{} {}", url, hit); - return hit; - } - - final DatabaseInfo databaseInfo = doParse(url); - final DatabaseInfo old = cache.putIfAbsent(url, databaseInfo); - if (old != null) { - return old; - } - return databaseInfo; - -// else if (url.indexOf("jdbc:oracle") >= 0) { -// maker.lower().after("jdbc:oracle:").after(':'); -// info.type = TYPE.ORACLE; -// String description = maker.after('@').value().trim(); -// -// if (description.startsWith("(")) { -// Matcher matcher = oracleRAC.matcher(description); -// -// if (matcher.matches()) { -// info.host = matcher.group(1); -// info.port = matcher.group(2); -// info.databaseId = matcher.group(3); -// } else { -// info.databaseId = "ParsingFailed[" + System.currentTimeMillis() + ']'; -// } -// } else { -// info.host = maker.before(':').value(); -// info.port = maker.next().after(':').before(':').value(); -// info.databaseId = maker.next().afterLast(':').value(); -// } -// } else if (url.indexOf("jdbc:sqlserver") >= 0) { -// maker.lower().after("jdbc:sqlserver:"); -// info.type = TYPE.MSSQL; -// info.host = maker.after("//").before(';').value(); -// info.port = maker.currentTraceClear().after("port=").before(';').value(); -// info.databaseId = maker.currentTraceClear().after("databasename=").before(';').value(); -// } else if (url.indexOf("jdbc:jtds:sqlserver") >= 0) { -// maker.lower().after("jdbc:jtds:sqlserver:"); -// info.type = TYPE.MSSQL; -// info.host = maker.after("//").beforeLast('/').beforeLast(':').value(); -// info.port = maker.next().after(':').beforeLast('/').value(); -// info.databaseId = maker.next().afterLast('/').before(';').value(); -// } else if (url.indexOf("jdbc:cubrid") >= 0) { -// maker.lower().after("jdbc:cubrid"); -// info.type = TYPE.CUBRID; -// info.host = maker.after(':').before(':').value(); -// info.port = maker.next().after(':').before(':').value(); -// info.databaseId = maker.next().after(':').before(':').value(); -// } -// if ("".equals(info.databaseId)) { -// info.databaseId = info.host; -// } - -// return info; -// return null; - } - - private DatabaseInfo doParse(String url) { - // jdbc 체크 - String lowCaseURL = url.toLowerCase().trim(); - if (!lowCaseURL.startsWith("jdbc:")) { - return createUnknownDataBase(url); - } - - if (driverTypeCheck(lowCaseURL, "mysql")) { - return parseMysql(url); - } - if (driverTypeCheck(lowCaseURL, "oracle")) { - return parseOracle(url); - } - if (driverTypeCheck(lowCaseURL, "cubrid")) { - return parseCubrid(url); - } - return createUnknownDataBase(url); - } - - private boolean driverTypeCheck(String lowCaseURL, String type) { - final int jdbcNextIndex = 5; - return lowCaseURL.startsWith(type, jdbcNextIndex); - } - - // rac url. -// jdbc:oracle:thin:@(Description=(LOAD_BALANCE=on)" + -// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + -// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))" + -// "(CONNECT_DATA=(SERVICE_NAME=service)))" -// -// thin driver url -// jdbc:oracle:thin:@hostname:port:SID -// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; -// 들여 쓰기를 통해 token을 보기 좋게 나눈경우. -// jdbc:oracle:thin: -// @( -// Description=(LOAD_BALANCE=on) -// ( -// ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521) -// ) -// ( -// ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521) -// ) -// ( -// CONNECT_DATA=(SERVICE_NAME=service) -// ) -// ) - - - private DatabaseInfo parseOracle(String url) { - StringMaker maker = new StringMaker(url); - maker.after("jdbc:oracle:").after(":"); - String description = maker.after('@').value().trim(); - if (description.startsWith("(")) { - return parseNetConnectionUrl(url); - } else { - return parseSimpleUrl(url, maker); - } - } - - private DatabaseInfo parseNetConnectionUrl(String url) { - try { - // oracle new URL : rac용 - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(url); - KeyValue keyValue = parser.parse(); - // TODO oci 드라이버 일경우의 추가 처리가 필요함. nhn말고 왠간한데는 oci를 더 많이 씀. -// parser.getDriverType(); - return createOracleDatabaseInfo(keyValue, url); - } catch (OracleConnectionStringException ex) { - logger.warn("OracleConnectionString parse error. url:{} Caused:", url, ex.getMessage(), ex); - - // 에러찍고 그냥 unknownDataBase 생성 - return createUnknownDataBase(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url); - } catch (Throwable ex) { - // 나중에 좀더 정교하게 exception을 던지게 되면 OracleConnectionStringException 만 잡는것으로 바꿔야 될듯하다. - logger.warn("OracleConnectionString parse error. url:{} Caused:", url, ex.getMessage(), ex); - // 에러찍고 그냥 unknownDataBase 생성 - return createUnknownDataBase(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url); - } - } - - private DefaultDatabaseInfo parseSimpleUrl(String url, StringMaker maker) { - // thin driver - // jdbc:oracle:thin:@hostname:port:SID - // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; -// jdbc:oracle:thin:@//hostname:port/serviceName - String host = maker.before(':').value(); - String port = maker.next().after(':').before(':', '/').value(); - String databaseId = maker.next().afterLast(':', '/').value(); - - List hostList = new ArrayList(1); - hostList.add(host + ":" + port); - return new DefaultDatabaseInfo(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url, url, hostList, databaseId); - } - - private DatabaseInfo createOracleDatabaseInfo(KeyValue keyValue, String url) { - - Description description = new Description(keyValue); - List jdbcHost = description.getJdbcHost(); - - return new DefaultDatabaseInfo(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url, url, jdbcHost, description.getDatabaseId()); - - } - - - public static DatabaseInfo createUnknownDataBase(String url) { - return createUnknownDataBase(ServiceType.UNKNOWN_DB, ServiceType.UNKNOWN_DB_EXECUTE_QUERY, url); - } - - public static DatabaseInfo createUnknownDataBase(ServiceType type, ServiceType executeQueryType, String url) { - List list = new ArrayList(); - list.add("error"); - return new DefaultDatabaseInfo(type, executeQueryType, url, url, list, "error"); - } - - - private DatabaseInfo parseMysql(String url) { - final ConnectionStringParser parser = new MySqlConnectionStringParser(); - return parser.parse(url); - } - - - - private DatabaseInfo parseCubrid(String url) { - final ConnectionStringParser parser = new CubridConnectionStringParser(); - return parser.parse(url); - } -} +package com.nhn.pinpoint.profiler.modifier.db; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.cubrid.CubridConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.jtds.JtdsConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.mysql.MySqlConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.oracle.OracleConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.Description; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.KeyValue; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleConnectionStringException; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleNetConnectionDescriptorParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class JDBCUrlParser { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final ConcurrentMap cache = new ConcurrentHashMap(); + + //http://www.petefreitag.com/articles/jdbc_urls/ + public DatabaseInfo parse(String url) { + final DatabaseInfo hit = cache.get(url); + if (hit != null) { + logger.debug("database url cache hit:{} {}", url, hit); + return hit; + } + + final DatabaseInfo databaseInfo = doParse(url); + final DatabaseInfo old = cache.putIfAbsent(url, databaseInfo); + if (old != null) { + return old; + } + return databaseInfo; + } + + private DatabaseInfo doParse(String url) { + // jdbc 체크 + String lowCaseURL = url.toLowerCase().trim(); + if (!lowCaseURL.startsWith("jdbc:")) { + return createUnknownDataBase(url); + } + + if (driverTypeCheck(lowCaseURL, "mysql")) { + return parseMysql(url); + } + if (driverTypeCheck(lowCaseURL, "oracle")) { + return parseOracle(url); + } + + if (driverTypeCheck(lowCaseURL, "jtds:sqlserver")) { + return parseJtds(url); + } + if (driverTypeCheck(lowCaseURL, "cubrid")) { + return parseCubrid(url); + } + return createUnknownDataBase(url); + } + + private boolean driverTypeCheck(String lowCaseURL, String type) { + final int jdbcNextIndex = 5; + return lowCaseURL.startsWith(type, jdbcNextIndex); + } + + + + private DatabaseInfo parseOracle(String url) { + OracleConnectionStringParser parser = new OracleConnectionStringParser(); + return parser.parse(url); + + } + + public static DatabaseInfo createUnknownDataBase(String url) { + return createUnknownDataBase(ServiceType.UNKNOWN_DB, ServiceType.UNKNOWN_DB_EXECUTE_QUERY, url); + } + + public static DatabaseInfo createUnknownDataBase(ServiceType type, ServiceType executeQueryType, String url) { + List list = new ArrayList(); + list.add("error"); + return new DefaultDatabaseInfo(type, executeQueryType, url, url, list, "error"); + } + + + private DatabaseInfo parseMysql(String url) { + final ConnectionStringParser parser = new MySqlConnectionStringParser(); + return parser.parse(url); + } + + private DatabaseInfo parseJtds(String url) { + final JtdsConnectionStringParser parser = new JtdsConnectionStringParser(); + return parser.parse(url); + + } + + + + private DatabaseInfo parseCubrid(String url) { + final ConnectionStringParser parser = new CubridConnectionStringParser(); + return parser.parse(url); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/StringMaker.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/StringMaker.java index da02ffb6298a..9657b79a0376 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/StringMaker.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/StringMaker.java @@ -1,358 +1,371 @@ -package com.nhn.pinpoint.profiler.modifier.db; - -/** - * @author emeroad - */ -public class StringMaker { - - /** - * The value. - */ - private String value; - - /** - * The indexing. - */ - private String indexing; - - /** - * The begin. - */ - private int begin; - - /** - * The end. - */ - private int end; - - /** - * Instantiates a new string maker. - * - * @param value the value - */ - public StringMaker(String value) { - this.value = value; - this.indexing = value; - this.end = value.length(); - } - - /** - * Instantiates a new string maker. - * - * @param value the value - * @param begin the begin - * @param end the end - */ - private StringMaker(String value, int begin, int end) { - this.value = value; - this.indexing = value; - this.begin = begin; - this.end = end; - } - - /** - * Lower. - * - * @return the string maker - */ - public StringMaker lower() { - indexing = indexing.toLowerCase(); - return this; - } - - /** - * Upper. - * - * @return the string maker - */ - public StringMaker upper() { - indexing = indexing.toUpperCase(); - return this; - } - - /** - * Reset. - * - * @return the string maker - */ - public StringMaker reset() { - indexing = value; - return this; - } - - /** - * After. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker after(char ch) { - int index = indexing.indexOf(ch, begin); - - if (index < 0 || index > end) { - return this; - } - - begin = index + 1 > end ? end : index + 1; - return this; - } - - /** - * After. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker after(String ch) { - int index = indexing.indexOf(ch, begin); - - if (index < 0 || index > end) { - return this; - } - - begin = index + ch.length() > end ? end : index + ch.length(); - return this; - } - - /** - * Before. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker before(char ch) { - int index = indexing.indexOf(ch, begin); - - if (index < 0 || index > end) { - return this; - } - - end = index < begin ? begin : index; - return this; - } - - public StringMaker before(char ch1, char ch2) { - int index = indexOf(ch1, ch2); -// int index = indexing.indexOf(ch1, begin); - - if (index < 0 || index > end) { - return this; - } - - end = index < begin ? begin : index; - return this; - } - - private int indexOf(char ch1, char ch2) { - for(int i = begin; i< indexing.length(); i++) { - final char c = indexing.charAt(i); - if (c == ch1 || c == ch2) { - return i; - } - } - return -1; - } - - /** - * Before. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker before(String ch) { - int index = indexing.indexOf(ch, begin); - - if (index < 0 || index > end) { - return this; - } - - end = index < begin ? begin : index; - return this; - } - - /** - * After last. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker afterLast(char ch) { - int index = indexing.lastIndexOf(ch, end); - - if (index < begin) { - return this; - } - - begin = index + 1 > end ? end : index + 1; - return this; - } - - public int getBeginIndex() { - return begin; - } - - public int getEndIndex() { - return end; - } - - - /** - * ch1이나 ch2중 하나가 발견될때까지 역으로 스캔 - * @param ch1 - * @param ch2 - * @return - */ - public StringMaker afterLast(char ch1, char ch2) { - int index = lastIndexOf(indexing, end, ch1, ch2); - if (index < begin) { - return this; - } - - begin = index + 1 > end ? end : index + 1; - return this; - } - - - - int lastIndexOf(String string, int end, char ch1, char ch2) { - int i = end; - for (; i >= begin; i--) { - final char c = string.charAt(i - 1); - if (ch1 == c || ch2 == c) { - return i-1; - } - } - // 찾지 못함.. - return -1; - } - - /** - * After last. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker afterLast(String ch) { - int index = indexing.lastIndexOf(ch, end); - - if (index < begin) { - return this; - } - - begin = index + ch.length() > end ? end : index + ch.length(); - return this; - } - - /** - * Before last. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker beforeLast(char ch) { - int index = indexing.lastIndexOf(ch, end); - - if (index < begin) { - return this; - } - - //end = index < begin ? begin : index; - //for Klocwork - - end = index; - return this; - } - - /** - * Before last. - * - * @param ch the ch - * @return the string maker - */ - public StringMaker beforeLast(String ch) { - int index = indexing.lastIndexOf(ch, end); - - if (index < begin) { - return this; - } - - //end = index < begin ? begin : index; - //for Klocwork - - end = index; - return this; - } - - /** - * Prev. - * - * @return the string maker - */ - public StringMaker prev() { - this.end = begin; - this.begin = 0; - return this; - } - - /** - * Next. - * - * @return the string maker - */ - public StringMaker next() { - this.begin = end; - this.end = indexing.length(); - return this; - } - - /** - * Clear. - * - * @return the string maker - */ - public StringMaker clear() { - begin = 0; - end = indexing.length(); - return this; - } - - /** - * Checks if is empty. - * - * @return true, if is empty - */ - public boolean isEmpty() { - return begin == end; - } - - /** - * Value. - * - * @return the string - */ - public String value() { - return value.substring(begin, end); - } - - /** - * Dulicate. - * - * @return the string maker - */ - public StringMaker duplicate() { - return new StringMaker(value, begin, end); - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - - /** - * To string. - * - * @return value() String - */ - public String toString() { - return value(); - } +package com.nhn.pinpoint.profiler.modifier.db; + +/** + * copy lucy 1.5 + */ +public class StringMaker { + + /** + * The value. + */ + private String value; + + /** + * The indexing. + */ + private String indexing; + + /** + * The begin. + */ + private int begin; + + /** + * The end. + */ + private int end; + + /** + * Instantiates a new string maker. + * + * @param value the value + */ + public StringMaker(String value) { + this.value = value; + this.indexing = value; + this.end = value.length(); + } + + /** + * Instantiates a new string maker. + * + * @param value the value + * @param begin the begin + * @param end the end + */ + private StringMaker(String value, int begin, int end) { + this.value = value; + this.indexing = value; + this.begin = begin; + this.end = end; + } + + /** + * Lower. + * + * @return the string maker + */ + public StringMaker lower() { + indexing = indexing.toLowerCase(); + return this; + } + + /** + * Upper. + * + * @return the string maker + */ + public StringMaker upper() { + indexing = indexing.toUpperCase(); + return this; + } + + /** + * Reset. + * + * @return the string maker + */ + public StringMaker reset() { + indexing = value; + return this; + } + + /** + * After. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker after(char ch) { + int index = indexing.indexOf(ch, begin); + + if (index < 0 || index > end) { + return this; + } + + begin = index + 1 > end ? end : index + 1; + return this; + } + + /** + * After. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker after(String ch) { + int index = indexing.indexOf(ch, begin); + + if (index < 0 || index > end) { + return this; + } + + begin = index + ch.length() > end ? end : index + ch.length(); + return this; + } + + /** + * Before. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker before(char ch) { + int index = indexing.indexOf(ch, begin); + + if (index < 0 || index > end) { + return this; + } + + end = index < begin ? begin : index; + return this; + } + + public StringMaker before(char ch1, char ch2) { + int index = indexOf(ch1, ch2); +// int index = indexing.indexOf(ch1, begin); + + if (index < 0 || index > end) { + return this; + } + + end = index < begin ? begin : index; + return this; + } + + private int indexOf(char ch1, char ch2) { + for(int i = begin; i< indexing.length(); i++) { + final char c = indexing.charAt(i); + if (c == ch1 || c == ch2) { + return i; + } + } + return -1; + } + + /** + * Before. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker before(String ch) { + int index = indexing.indexOf(ch, begin); + + if (index < 0 || index > end) { + return this; + } + + end = index < begin ? begin : index; + return this; + } + + /** + * After last. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker afterLast(char ch) { + int index = indexing.lastIndexOf(ch, end); + + if (index < begin) { + return this; + } + + begin = index + 1 > end ? end : index + 1; + return this; + } + + public int getBeginIndex() { + return begin; + } + + public int getEndIndex() { + return end; + } + + + /** + * ch1이나 ch2중 하나가 발견될때까지 역으로 스캔 + * @param ch1 + * @param ch2 + * @return + */ + public StringMaker afterLast(char ch1, char ch2) { + int index = lastIndexOf(indexing, end, ch1, ch2); + if (index < begin) { + return this; + } + + begin = index + 1 > end ? end : index + 1; + return this; + } + + + + int lastIndexOf(String string, int end, char ch1, char ch2) { + int i = end; + for (; i >= begin; i--) { + final char c = string.charAt(i - 1); + if (ch1 == c || ch2 == c) { + return i-1; + } + } + // 찾지 못함.. + return -1; + } + + /** + * After last. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker afterLast(String ch) { + int index = indexing.lastIndexOf(ch, end); + + if (index < begin) { + return this; + } + + begin = index + ch.length() > end ? end : index + ch.length(); + return this; + } + + /** + * Before last. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker beforeLast(char ch) { + int index = indexing.lastIndexOf(ch, end); + + if (index < begin) { + return this; + } + + //end = index < begin ? begin : index; + //for Klocwork + + end = index; + return this; + } + + public StringMaker beforeLast(char ch1, char ch2) { + int index = lastIndexOf(indexing, end, ch1, ch2); + if (index < begin) { + return this; + } + + //end = index < begin ? begin : index; + //for Klocwork + + end = index; + return this; + } + + /** + * Before last. + * + * @param ch the ch + * @return the string maker + */ + public StringMaker beforeLast(String ch) { + int index = indexing.lastIndexOf(ch, end); + + if (index < begin) { + return this; + } + + //end = index < begin ? begin : index; + //for Klocwork + + end = index; + return this; + } + + /** + * Prev. + * + * @return the string maker + */ + public StringMaker prev() { + this.end = begin; + this.begin = 0; + return this; + } + + /** + * Next. + * + * @return the string maker + */ + public StringMaker next() { + this.begin = end; + this.end = indexing.length(); + return this; + } + + /** + * Clear. + * + * @return the string maker + */ + public StringMaker clear() { + begin = 0; + end = indexing.length(); + return this; + } + + /** + * Checks if is empty. + * + * @return true, if is empty + */ + public boolean isEmpty() { + return begin == end; + } + + /** + * Value. + * + * @return the string + */ + public String value() { + return value.substring(begin, end); + } + + /** + * Dulicate. + * + * @return the string maker + */ + public StringMaker duplicate() { + return new StringMaker(value, begin, end); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + + /** + * To string. + * + * @return value() String + */ + public String toString() { + return value(); + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParser.java index 979330e540df..a756f931c460 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParser.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParser.java @@ -1,111 +1,111 @@ -package com.nhn.pinpoint.profiler.modifier.db.cubrid; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; -import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; -import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; -import com.nhn.pinpoint.profiler.modifier.db.StringMaker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author emeroad - */ -public class CubridConnectionStringParser implements ConnectionStringParser { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final String DEFAULT_HOSTNAME = "localhost"; - public static final int DEFAULT_PORT = 30000; - public static final String DEFAULT_USER = "public"; - public static final String DEFAULT_PASSWORD = ""; - - private static final String URL_PATTERN = "jdbc:cubrid(-oracle|-mysql)?:([a-zA-Z_0-9\\.-]*):([0-9]*):([^:]+):([^:]*):([^:]*):(\\?[a-zA-Z_0-9]+=[^&=?]+(&[a-zA-Z_0-9]+=[^&=?]+)*)?"; - private static final Pattern PATTERN = Pattern.compile(URL_PATTERN, Pattern.CASE_INSENSITIVE); - - @Override - public DatabaseInfo parse(String url) { - if (url == null) { - return JDBCUrlParser.createUnknownDataBase(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url); - } - - final Matcher matcher = PATTERN.matcher(url); - if (!matcher.find()) { - logger.warn("Cubrid connectionString parse fail. url:{}", url); - return JDBCUrlParser.createUnknownDataBase(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url); - } - - String host = matcher.group(2); - String portString = matcher.group(3); - String db = matcher.group(4); - String user = matcher.group(5); -// String pass = matcher.group(6); -// String prop = matcher.group(7); - - int port = DEFAULT_PORT; - -// String resolvedUrl; - - if (host == null || host.length() == 0) { - host = DEFAULT_HOSTNAME; - } - - if (portString == null || portString.length() == 0) { - port = DEFAULT_PORT; - } else { - try { - port = Integer.parseInt(portString); - } catch (NumberFormatException e) { - logger.warn("cubrid portString parsing fail. portString:{}, url:{}", portString, url); - } - } - - if (user == null) { - user = DEFAULT_USER; - } - -// if (pass == null) { -// pass = DEFAULT_PASSWORD; -// } - -// resolvedUrl = "jdbc:cubrid:" + host + ":" + port + ":" + db + ":" + user + ":********:"; - - StringMaker maker = new StringMaker(url); - String normalizedUrl = maker.clear().before('?').value(); - - List hostList = new ArrayList(1); - final String hostAndPort = host + ":" + portString; - hostList.add(hostAndPort); - - // alt host는 제외. - - return new DefaultDatabaseInfo(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url, normalizedUrl, hostList, db); - } - - - /* - private DatabaseInfo parseCubrid(String url) { - // jdbc:cubrid:10.101.57.233:30102:pinpoint::: - StringMaker maker = new StringMaker(url); - maker.after("jdbc:cubrid:"); - // 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯. - // mm db? 의 경우도 고려해야 될듯하다. - String host = maker.after("//").before('/').value(); - List hostList = new ArrayList(1); - hostList.add(host); - // String port = maker.next().after(':').before('/').value(); - - String databaseId = maker.next().afterLast('/').before('?').value(); - String normalizedUrl = maker.clear().before('?').value(); - - return new DatabaseInfo(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); - } - */ - -} +package com.nhn.pinpoint.profiler.modifier.db.cubrid; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; +import com.nhn.pinpoint.profiler.modifier.db.StringMaker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author emeroad + */ +public class CubridConnectionStringParser implements ConnectionStringParser { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final String DEFAULT_HOSTNAME = "localhost"; + public static final int DEFAULT_PORT = 30000; + public static final String DEFAULT_USER = "public"; + public static final String DEFAULT_PASSWORD = ""; + + private static final String URL_PATTERN = "jdbc:cubrid(-oracle|-mysql)?:([a-zA-Z_0-9\\.-]*):([0-9]*):([^:]+):([^:]*):([^:]*):(\\?[a-zA-Z_0-9]+=[^&=?]+(&[a-zA-Z_0-9]+=[^&=?]+)*)?"; + private static final Pattern PATTERN = Pattern.compile(URL_PATTERN, Pattern.CASE_INSENSITIVE); + + @Override + public DatabaseInfo parse(String url) { + if (url == null) { + return JDBCUrlParser.createUnknownDataBase(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url); + } + + final Matcher matcher = PATTERN.matcher(url); + if (!matcher.find()) { + logger.warn("Cubrid connectionString parse fail. url:{}", url); + return JDBCUrlParser.createUnknownDataBase(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url); + } + + String host = matcher.group(2); + String portString = matcher.group(3); + String db = matcher.group(4); + String user = matcher.group(5); +// String pass = matcher.group(6); +// String prop = matcher.group(7); + + int port = DEFAULT_PORT; + +// String resolvedUrl; + + if (host == null || host.length() == 0) { + host = DEFAULT_HOSTNAME; + } + + if (portString == null || portString.length() == 0) { + port = DEFAULT_PORT; + } else { + try { + port = Integer.parseInt(portString); + } catch (NumberFormatException e) { + logger.warn("cubrid portString parsing fail. portString:{}, url:{}", portString, url); + } + } + + if (user == null) { + user = DEFAULT_USER; + } + +// if (pass == null) { +// pass = DEFAULT_PASSWORD; +// } + +// resolvedUrl = "jdbc:cubrid:" + host + ":" + port + ":" + db + ":" + user + ":********:"; + + StringMaker maker = new StringMaker(url); + String normalizedUrl = maker.clear().before('?').value(); + + List hostList = new ArrayList(1); + final String hostAndPort = host + ":" + portString; + hostList.add(hostAndPort); + + // alt host는 제외. + + return new DefaultDatabaseInfo(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url, normalizedUrl, hostList, db); + } + + + /* + private DatabaseInfo parseCubrid(String url) { + // jdbc:cubrid:10.101.57.233:30102:pinpoint::: + StringMaker maker = new StringMaker(url); + maker.after("jdbc:cubrid:"); + // 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯. + // mm db? 의 경우도 고려해야 될듯하다. + String host = maker.after("//").before('/').value(); + List hostList = new ArrayList(1); + hostList.add(host); + // String port = maker.next().after(':').before('/').value(); + + String databaseId = maker.next().afterLast('/').before('?').value(); + String normalizedUrl = maker.clear().before('?').value(); + + return new DatabaseInfo(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); + } + */ + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridDriverModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridDriverModifier.java index 049fa06c9566..b2c3fd20bcb2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridDriverModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridDriverModifier.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.profiler.modifier.db.cubrid; - -import java.security.ProtectionDomain; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.db.interceptor.DriverConnectInterceptor; -import com.nhn.pinpoint.profiler.util.Scope; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CubridDriverModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public CubridDriverModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "cubrid/jdbc/driver/CUBRIDDriver"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass mysqlConnection = byteCodeInstrumentor.getClass(javassistClassName); - - final Scope scope = byteCodeInstrumentor.getScope(CubridScope.SCOPE_NAME); - DriverConnectInterceptor driverConnectInterceptor = new DriverConnectInterceptor(scope); - mysqlConnection.addInterceptor("connect", new String[]{"java.lang.String", "java.util.Properties"}, driverConnectInterceptor); - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return mysqlConnection.toBytecode(); - } catch (InstrumentException e) { - if (logger.isWarnEnabled()) { - logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); - } - return null; - } - } -} +package com.nhn.pinpoint.profiler.modifier.db.cubrid; + +import java.security.ProtectionDomain; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.DriverConnectInterceptor; +import com.nhn.pinpoint.profiler.util.Scope; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CubridDriverModifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public CubridDriverModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "cubrid/jdbc/driver/CUBRIDDriver"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass mysqlConnection = byteCodeInstrumentor.getClass(javassistClassName); + + final Scope scope = byteCodeInstrumentor.getScope(CubridScope.SCOPE_NAME); + DriverConnectInterceptor driverConnectInterceptor = new DriverConnectInterceptor(scope); + mysqlConnection.addInterceptor("connect", new String[]{"java.lang.String", "java.util.Properties"}, driverConnectInterceptor); + + if (this.logger.isInfoEnabled()) { + this.logger.info("{} class is converted.", javassistClassName); + } + + return mysqlConnection.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); + } + return null; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridResultSetModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridResultSetModifier.java index 3c0e9978aab4..addb7c1df013 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridResultSetModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridResultSetModifier.java @@ -4,8 +4,6 @@ import com.nhn.pinpoint.bootstrap.Agent; import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; import com.nhn.pinpoint.profiler.modifier.AbstractModifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,18 +27,6 @@ public byte[] modify(ClassLoader classLoader, String javassistClassName, Protect if (logger.isInfoEnabled()) { logger.info("Modifing. {}", javassistClassName); } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass resultSetClass = byteCodeInstrumentor.getClass(javassistClassName); - - // DO NOTHING - - return resultSetClass.toBytecode(); - } catch (InstrumentException e) { - if (logger.isWarnEnabled()) { - logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); - } - return null; - } + return null; } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtils.java index 56d676d8bed4..fcd9edacef4d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtils.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.util.StringUtils; - -/** - * @author emeroad - */ -public class BindValueUtils { - - private BindValueUtils() { - } - - public static String bindValueToString(String[] bindValueArray, int limit) { - if (bindValueArray == null) { - return ""; - } - final StringBuilder sb = new StringBuilder(32); - final int length = bindValueArray.length; - final int end = length - 1; - for (int i = 0; i < length; i++) { - if (sb.length() >= limit) { - // 드롭된 bindValue를 생략하는 메시지를 첨부하면 bindValue를 통해 바인딩 sql 생성하기가 힘든면이 있으나 없으면 생략인지 아닌지 알수가 없어 수정. - appendLength(sb, length); - break; - } - StringUtils.appendDrop(sb, bindValueArray[i], limit); - if (i < end) { - sb.append(", "); - } - - } - return sb.toString(); - } - - private static void appendLength(StringBuilder sb, int length) { - sb.append("...("); - sb.append(length); - sb.append(')'); - } - - public static String bindValueToString(String[] stringArray) { - return bindValueToString(stringArray, Integer.MAX_VALUE); - } -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.util.StringUtils; + +/** + * @author emeroad + */ +public class BindValueUtils { + + private BindValueUtils() { + } + + public static String bindValueToString(String[] bindValueArray, int limit) { + if (bindValueArray == null) { + return ""; + } + final StringBuilder sb = new StringBuilder(32); + final int length = bindValueArray.length; + final int end = length - 1; + for (int i = 0; i < length; i++) { + if (sb.length() >= limit) { + // 드롭된 bindValue를 생략하는 메시지를 첨부하면 bindValue를 통해 바인딩 sql 생성하기가 힘든면이 있으나 없으면 생략인지 아닌지 알수가 없어 수정. + appendLength(sb, length); + break; + } + StringUtils.appendDrop(sb, bindValueArray[i], limit); + if (i < end) { + sb.append(", "); + } + + } + return sb.toString(); + } + + private static void appendLength(StringBuilder sb, int length) { + sb.append("...("); + sb.append(length); + sb.append(')'); + } + + public static String bindValueToString(String[] stringArray) { + return bindValueToString(stringArray, Integer.MAX_VALUE); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/ConnectionCloseInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/ConnectionCloseInterceptor.java index e8a1ee0c5589..7cef94c04e5e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/ConnectionCloseInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/ConnectionCloseInterceptor.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -/** - * @author emeroad - */ -public class ConnectionCloseInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - // close의 경우 호출이 실패하더라도 데이터를 삭제해야함. - DatabaseInfoTraceValueUtils.__setTraceDatabaseInfo(target, null); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - } -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +/** + * @author emeroad + */ +public class ConnectionCloseInterceptor implements SimpleAroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + // close의 경우 호출이 실패하더라도 데이터를 삭제해야함. + DatabaseInfoTraceValueUtils.__setTraceDatabaseInfo(target, null); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceCloseInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceCloseInterceptor.java index 25e700e148ab..66a92d81a9c2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceCloseInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceCloseInterceptor.java @@ -1,45 +1,45 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * Datasource의 get을 추적해야 될것으로 예상됨. - * @author emeroad - */ -public class DataSourceCloseInterceptor extends SpanEventSimpleAroundInterceptor { - - - - public DataSourceCloseInterceptor() { - super(DataSourceCloseInterceptor.class); - } - -// @Override -// protected void prepareBeforeTrace(Object target, Object[] args) { -// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 push만 한다. -// scope.push(); -// } - - @Override - public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { - trace.markBeforeTime(); - } - -// @Override -// protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { -// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 pop만 한다. -// scope.pop(); -// } - - @Override - public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - trace.recordServiceType(ServiceType.DBCP); - trace.recordApi(getMethodDescriptor()); - trace.recordException(throwable); - - trace.markAfterTime(); - } -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * Datasource의 get을 추적해야 될것으로 예상됨. + * @author emeroad + */ +public class DataSourceCloseInterceptor extends SpanEventSimpleAroundInterceptor { + + + + public DataSourceCloseInterceptor() { + super(DataSourceCloseInterceptor.class); + } + +// @Override +// protected void prepareBeforeTrace(Object target, Object[] args) { +// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 push만 한다. +// scope.push(); +// } + + @Override + public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { + trace.markBeforeTime(); + } + +// @Override +// protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { +// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 pop만 한다. +// scope.pop(); +// } + + @Override + public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + trace.recordServiceType(ServiceType.DBCP); + trace.recordApi(getMethodDescriptor()); + trace.recordException(throwable); + + trace.markAfterTime(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceGetConnectionInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceGetConnectionInterceptor.java index b6f7462e8e89..345c9e98b756 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceGetConnectionInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DataSourceGetConnectionInterceptor.java @@ -1,54 +1,54 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.common.ServiceType; - -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * Datasource의 get을 추적해야 될것으로 예상됨. - * @author emeroad - */ -public class DataSourceGetConnectionInterceptor extends SpanEventSimpleAroundInterceptor { - -// private final DepthScope scope = JDBCScope.SCOPE; - - public DataSourceGetConnectionInterceptor() { - super(DataSourceGetConnectionInterceptor.class); - } - -// @Override -// protected void prepareBeforeTrace(Object target, Object[] args) { -// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 push만 한다. -// scope.push(); -// } - - @Override - public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { - trace.markBeforeTime(); - } - -// @Override -// protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { -// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 pop만 한다. -// scope.pop(); -// } - - @Override - public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - trace.recordServiceType(ServiceType.DBCP); - if (args == null) { -// args == null인 경우 parameter가 없는 getConnection() 호출시 - trace.recordApi(getMethodDescriptor()); - } else if(args.length == 2) { -// args[1]은 패스워드라서 뺀다. - trace.recordApi(getMethodDescriptor(), args[0], 0); - } - trace.recordException(throwable); - - trace.markAfterTime(); - } - - -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.common.ServiceType; + +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * Datasource의 get을 추적해야 될것으로 예상됨. + * @author emeroad + */ +public class DataSourceGetConnectionInterceptor extends SpanEventSimpleAroundInterceptor { + +// private final DepthScope scope = JDBCScope.SCOPE; + + public DataSourceGetConnectionInterceptor() { + super(DataSourceGetConnectionInterceptor.class); + } + +// @Override +// protected void prepareBeforeTrace(Object target, Object[] args) { +// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 push만 한다. +// scope.push(); +// } + + @Override + public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { + trace.markBeforeTime(); + } + +// @Override +// protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { +// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 pop만 한다. +// scope.pop(); +// } + + @Override + public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + trace.recordServiceType(ServiceType.DBCP); + if (args == null) { +// args == null인 경우 parameter가 없는 getConnection() 호출시 + trace.recordApi(getMethodDescriptor()); + } else if(args.length == 2) { +// args[1]은 패스워드라서 뺀다. + trace.recordApi(getMethodDescriptor(), args[0], 0); + } + trace.recordException(throwable); + + trace.markAfterTime(); + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DriverConnectInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DriverConnectInterceptor.java index 85942f6c9f35..2c95ec17eb16 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DriverConnectInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/DriverConnectInterceptor.java @@ -1,101 +1,101 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; -import com.nhn.pinpoint.profiler.util.Scope; - - -/** - * @author emeroad - */ -public class DriverConnectInterceptor extends SpanEventSimpleAroundInterceptor { - - private final Scope scope; - private final boolean recordConnection; - - - public DriverConnectInterceptor(Scope scope) { - this(true, scope); - } - - public DriverConnectInterceptor(boolean recordConnection, Scope scope) { - super(DriverConnectInterceptor.class); - if (scope == null) { - throw new NullPointerException("scope must not be null"); - } - // mysql loadbalance 전용옵션 실제 destination은 하위의 구현체에서 레코딩한다. - this.recordConnection = recordConnection; - this.scope = scope; - } - - @Override - protected void logBeforeInterceptor(Object target, Object[] args) { - // parameter에 암호가 포함되어 있음 로깅하면 안됨. - logger.beforeInterceptor(target, null); - } - - @Override - protected void prepareBeforeTrace(Object target, Object[] args) { - scope.push(); - } - - @Override - protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - trace.markBeforeTime(); - } - - - @Override - protected void logAfterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { - logger.afterInterceptor(target, null, result, throwable); - } - - @Override - protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { - // 여기서는 trace context인지 아닌지 확인하면 안된다. trace 대상 thread가 아닌곳에서 connection이 생성될수 있음. - scope.pop(); - - final boolean success = InterceptorUtils.isSuccess(throwable); - // 여기서는 trace context인지 아닌지 확인하면 안된다. trace 대상 thread가 아닌곳에서 connection이 생성될수 있음. - final String driverUrl = (String) args[0]; - DatabaseInfo databaseInfo = createDatabaseInfo(driverUrl); - if (success) { - if (recordConnection) { - DatabaseInfoTraceValueUtils.__setTraceDatabaseInfo(result, databaseInfo); - } - } - } - - @Override - protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - - if (recordConnection) { - final DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(result, UnKnownDatabaseInfo.INSTANCE); - // database connect도 매우 무거운 액션이므로 카운트로 친다. - trace.recordServiceType(databaseInfo.getExecuteQueryType()); - trace.recordEndPoint(databaseInfo.getMultipleHost()); - trace.recordDestinationId(databaseInfo.getDatabaseId()); - } - final String driverUrl = (String) args[0]; - // 여기서 databaseInfo.getRealUrl을 하면 위험하다. loadbalance connection일때 원본 url이 아닌 url이 오게 되어 있음. - trace.recordApiCachedString(getMethodDescriptor(), driverUrl, 0); - - trace.recordException(throwable); - trace.markAfterTime(); - } - - private DatabaseInfo createDatabaseInfo(String url) { - if (url == null) { - return UnKnownDatabaseInfo.INSTANCE; - } - final DatabaseInfo databaseInfo = getTraceContext().parseJdbcUrl(url); - if (isDebug) { - logger.debug("parse DatabaseInfo:{}", databaseInfo); - } - return databaseInfo; - } - -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; +import com.nhn.pinpoint.profiler.util.Scope; + + +/** + * @author emeroad + */ +public class DriverConnectInterceptor extends SpanEventSimpleAroundInterceptor { + + private final Scope scope; + private final boolean recordConnection; + + + public DriverConnectInterceptor(Scope scope) { + this(true, scope); + } + + public DriverConnectInterceptor(boolean recordConnection, Scope scope) { + super(DriverConnectInterceptor.class); + if (scope == null) { + throw new NullPointerException("scope must not be null"); + } + // mysql loadbalance 전용옵션 실제 destination은 하위의 구현체에서 레코딩한다. + this.recordConnection = recordConnection; + this.scope = scope; + } + + @Override + protected void logBeforeInterceptor(Object target, Object[] args) { + // parameter에 암호가 포함되어 있음 로깅하면 안됨. + logger.beforeInterceptor(target, null); + } + + @Override + protected void prepareBeforeTrace(Object target, Object[] args) { + scope.push(); + } + + @Override + protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + trace.markBeforeTime(); + } + + + @Override + protected void logAfterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { + logger.afterInterceptor(target, null, result, throwable); + } + + @Override + protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { + // 여기서는 trace context인지 아닌지 확인하면 안된다. trace 대상 thread가 아닌곳에서 connection이 생성될수 있음. + scope.pop(); + + final boolean success = InterceptorUtils.isSuccess(throwable); + // 여기서는 trace context인지 아닌지 확인하면 안된다. trace 대상 thread가 아닌곳에서 connection이 생성될수 있음. + final String driverUrl = (String) args[0]; + DatabaseInfo databaseInfo = createDatabaseInfo(driverUrl); + if (success) { + if (recordConnection) { + DatabaseInfoTraceValueUtils.__setTraceDatabaseInfo(result, databaseInfo); + } + } + } + + @Override + protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + + if (recordConnection) { + final DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(result, UnKnownDatabaseInfo.INSTANCE); + // database connect도 매우 무거운 액션이므로 카운트로 친다. + trace.recordServiceType(databaseInfo.getExecuteQueryType()); + trace.recordEndPoint(databaseInfo.getMultipleHost()); + trace.recordDestinationId(databaseInfo.getDatabaseId()); + } + final String driverUrl = (String) args[0]; + // 여기서 databaseInfo.getRealUrl을 하면 위험하다. loadbalance connection일때 원본 url이 아닌 url이 오게 되어 있음. + trace.recordApiCachedString(getMethodDescriptor(), driverUrl, 0); + + trace.recordException(throwable); + trace.markAfterTime(); + } + + private DatabaseInfo createDatabaseInfo(String url) { + if (url == null) { + return UnKnownDatabaseInfo.INSTANCE; + } + final DatabaseInfo databaseInfo = getTraceContext().parseJdbcUrl(url); + if (isDebug) { + logger.debug("parse DatabaseInfo:{}", databaseInfo); + } + return databaseInfo; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/JDBCScope.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/JDBCScope.java deleted file mode 100644 index ed91c213540c..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/JDBCScope.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * @author emeroad - */ -@Deprecated -public class JDBCScope { - public static final DepthScope SCOPE = new DepthScope("JDBCScope"); -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementBindVariableInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementBindVariableInterceptor.java index 5e55fa6ea382..4cda1f25fcda 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementBindVariableInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementBindVariableInterceptor.java @@ -1,66 +1,66 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.NumberUtils; -import com.nhn.pinpoint.profiler.util.bindvalue.BindValueConverter; - -import java.util.Map; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -/** - * @author emeroad - */ -public class PreparedStatementBindVariableInterceptor implements StaticAroundInterceptor, TraceContextSupport { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private TraceContext traceContext; - - @Override - public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { - } - - @Override - public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - - if (isDebug) { - logger.afterInterceptor(target, className, methodName, parameterDescription, args, result, throwable); - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - Map bindList = null; - if (target instanceof BindValueTraceValue) { - bindList = ((BindValueTraceValue)target).__getTraceBindValue(); - } - if (bindList == null) { - if (logger.isWarnEnabled()) { - logger.warn("bindValue is null"); - } - return; - } - Integer index = NumberUtils.toInteger(args[0]); - if (index == null) { - // 어딘가 잘못됨. - return; - } - String value = BindValueConverter.convert(methodName, args); - bindList.put(index, value); - - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.NumberUtils; +import com.nhn.pinpoint.profiler.util.bindvalue.BindValueConverter; + +import java.util.Map; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +/** + * @author emeroad + */ +public class PreparedStatementBindVariableInterceptor implements StaticAroundInterceptor, TraceContextSupport { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private TraceContext traceContext; + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + + if (isDebug) { + logger.afterInterceptor(target, className, methodName, parameterDescription, args, result, throwable); + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + Map bindList = null; + if (target instanceof BindValueTraceValue) { + bindList = ((BindValueTraceValue)target).__getTraceBindValue(); + } + if (bindList == null) { + if (logger.isWarnEnabled()) { + logger.warn("bindValue is null"); + } + return; + } + Integer index = NumberUtils.toInteger(args[0]); + if (index == null) { + // 어딘가 잘못됨. + return; + } + String value = BindValueConverter.convert(methodName, args); + bindList.put(index, value); + + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java index bbd7187cbd3f..6b4e9515ad15 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java @@ -1,74 +1,74 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue; -import com.nhn.pinpoint.common.util.ParsingResult; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; - -/** - * @author emeroad - */ -public class PreparedStatementCreateInterceptor extends SpanEventSimpleAroundInterceptor { - - - public PreparedStatementCreateInterceptor() { - super(PreparedStatementCreateInterceptor.class); - } - - @Override - public void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - trace.markBeforeTime(); - - final DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); - trace.recordServiceType(databaseInfo.getType()); - trace.recordEndPoint(databaseInfo.getMultipleHost()); - trace.recordDestinationId(databaseInfo.getDatabaseId()); - } - - @Override - protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { - final boolean success = InterceptorUtils.isSuccess(throwable); - if (success) { - if (target instanceof DatabaseInfoTraceValue) { - // preparedStatement의 생성이 성공하였을 경우만 PreparedStatement에 databaseInfo를 세팅해야 한다. - DatabaseInfo databaseInfo = ((DatabaseInfoTraceValue) target).__getTraceDatabaseInfo(); - if (databaseInfo != null) { - if (result instanceof DatabaseInfoTraceValue) { - ((DatabaseInfoTraceValue) result).__setTraceDatabaseInfo(databaseInfo); - } - } - } - if (result instanceof ParsingResultTraceValue) { - // 1. traceContext를 체크하면 안됨. traceContext에서 즉 같은 thread에서 prearedStatement에서 안만들수도 있음. - // 2. sampling 동작이 동작할 경우 preparedStatement를 create하는 thread가 trace 대상이 아닐수 있음. 먼제 sql을 저장해야 한다. - String sql = (String) args[0]; - ParsingResult parsingResult = getTraceContext().parseSql(sql); - if (parsingResult != null) { - ((ParsingResultTraceValue)result).__setTraceParsingResult(parsingResult); - } else { - if (logger.isErrorEnabled()) { - logger.error("sqlParsing fail. parsingResult is null sql:{}", sql); - } - } - } - } - } - - @Override - public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - - ParsingResult parsingResult = ((ParsingResultTraceValue) result).__getTraceParsingResult(); - trace.recordSqlParsingResult(parsingResult); - trace.recordException(throwable); - trace.recordApi(getMethodDescriptor()); - - trace.markAfterTime(); - } - - -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue; +import com.nhn.pinpoint.common.util.ParsingResult; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; + +/** + * @author emeroad + */ +public class PreparedStatementCreateInterceptor extends SpanEventSimpleAroundInterceptor { + + + public PreparedStatementCreateInterceptor() { + super(PreparedStatementCreateInterceptor.class); + } + + @Override + public void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + trace.markBeforeTime(); + + final DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); + trace.recordServiceType(databaseInfo.getType()); + trace.recordEndPoint(databaseInfo.getMultipleHost()); + trace.recordDestinationId(databaseInfo.getDatabaseId()); + } + + @Override + protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { + final boolean success = InterceptorUtils.isSuccess(throwable); + if (success) { + if (target instanceof DatabaseInfoTraceValue) { + // preparedStatement의 생성이 성공하였을 경우만 PreparedStatement에 databaseInfo를 세팅해야 한다. + DatabaseInfo databaseInfo = ((DatabaseInfoTraceValue) target).__getTraceDatabaseInfo(); + if (databaseInfo != null) { + if (result instanceof DatabaseInfoTraceValue) { + ((DatabaseInfoTraceValue) result).__setTraceDatabaseInfo(databaseInfo); + } + } + } + if (result instanceof ParsingResultTraceValue) { + // 1. traceContext를 체크하면 안됨. traceContext에서 즉 같은 thread에서 prearedStatement에서 안만들수도 있음. + // 2. sampling 동작이 동작할 경우 preparedStatement를 create하는 thread가 trace 대상이 아닐수 있음. 먼제 sql을 저장해야 한다. + String sql = (String) args[0]; + ParsingResult parsingResult = getTraceContext().parseSql(sql); + if (parsingResult != null) { + ((ParsingResultTraceValue)result).__setTraceParsingResult(parsingResult); + } else { + if (logger.isErrorEnabled()) { + logger.error("sqlParsing fail. parsingResult is null sql:{}", sql); + } + } + } + } + } + + @Override + public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + + ParsingResult parsingResult = ((ParsingResultTraceValue) result).__getTraceParsingResult(); + trace.recordSqlParsingResult(parsingResult); + trace.recordException(throwable); + trace.recordApi(getMethodDescriptor()); + + trace.markAfterTime(); + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java index 54b044d55389..6c58e067c0cf 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java @@ -1,138 +1,138 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import java.util.HashMap; -import java.util.Map; - -import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; -import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.common.util.ParsingResult; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; - -/** - * @author emeroad - */ -public class PreparedStatementExecuteQueryInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { - - private static final int DEFAULT_BIND_VALUE_LENGTH = 1024; - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private MethodDescriptor descriptor; - private TraceContext traceContext; - private int maxSqlBindValueLength = DEFAULT_BIND_VALUE_LENGTH; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - trace.traceBlockBegin(); - trace.markBeforeTime(); - try { - DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); - trace.recordServiceType(databaseInfo.getExecuteQueryType()); - - trace.recordEndPoint(databaseInfo.getMultipleHost()); - trace.recordDestinationId(databaseInfo.getDatabaseId()); - - ParsingResult parsingResult = null; - if (target instanceof ParsingResultTraceValue) { - parsingResult = ((ParsingResultTraceValue) target).__getTraceParsingResult(); - } - Map bindValue = null; - if (target instanceof BindValueTraceValue) { - bindValue = ((BindValueTraceValue)target).__getTraceBindValue(); - } - if (bindValue != null) { - String bindString = toBindVariable(bindValue); - trace.recordSqlParsingResult(parsingResult, bindString); - } else { - trace.recordSqlParsingResult(parsingResult); - } - - trace.recordApi(descriptor); -// trace.recordApi(apiId); - // clean 타이밍을 변경해야 될듯 하다. - // clearParameters api가 따로 있으나, 구지 캡쳐 하지 않아도 될듯함.시간남으면 하면 좋기는 함. - // ibatis 등에서 확인해봐도 cleanParameters 의 경우 대부분의 경우 일부러 호출하지 않음. - clean(target); - - - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - - } - - private void clean(Object target) { - if (target instanceof BindValueTraceValue) { - ((BindValueTraceValue) target).__setTraceBindValue(new HashMap()); - } - } - - private String toBindVariable(Map bindValue) { - final String[] temp = new String[bindValue.size()]; - for (Map.Entry entry : bindValue.entrySet()) { - Integer key = entry.getKey() - 1; - if (temp.length < key) { - continue; - } - temp[key] = entry.getValue(); - } - - return BindValueUtils.bindValueToString(temp, maxSqlBindValueLength); - - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - - try { - // TODO 일단 테스트로 실패일경우 종료 아닐경우 resultset fetch까지 계산. fetch count는 옵션으로 빼는게 좋을듯. - trace.recordException(throwable); - trace.markAfterTime(); - } finally { - trace.traceBlockEnd(); - } - } - - @Override - public void setMethodDescriptor(MethodDescriptor descriptor) { - this.descriptor = descriptor; - traceContext.cacheApi(descriptor); - } - - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - this.maxSqlBindValueLength = traceContext.getProfilerConfig().getJdbcMaxSqlBindValueSize(); - } -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import java.util.HashMap; +import java.util.Map; + +import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport; +import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.common.util.ParsingResult; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; + +/** + * @author emeroad + */ +public class PreparedStatementExecuteQueryInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { + + private static final int DEFAULT_BIND_VALUE_LENGTH = 1024; + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private MethodDescriptor descriptor; + private TraceContext traceContext; + private int maxSqlBindValueLength = DEFAULT_BIND_VALUE_LENGTH; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + trace.traceBlockBegin(); + trace.markBeforeTime(); + try { + DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); + trace.recordServiceType(databaseInfo.getExecuteQueryType()); + + trace.recordEndPoint(databaseInfo.getMultipleHost()); + trace.recordDestinationId(databaseInfo.getDatabaseId()); + + ParsingResult parsingResult = null; + if (target instanceof ParsingResultTraceValue) { + parsingResult = ((ParsingResultTraceValue) target).__getTraceParsingResult(); + } + Map bindValue = null; + if (target instanceof BindValueTraceValue) { + bindValue = ((BindValueTraceValue)target).__getTraceBindValue(); + } + if (bindValue != null) { + String bindString = toBindVariable(bindValue); + trace.recordSqlParsingResult(parsingResult, bindString); + } else { + trace.recordSqlParsingResult(parsingResult); + } + + trace.recordApi(descriptor); +// trace.recordApi(apiId); + // clean 타이밍을 변경해야 될듯 하다. + // clearParameters api가 따로 있으나, 구지 캡쳐 하지 않아도 될듯함.시간남으면 하면 좋기는 함. + // ibatis 등에서 확인해봐도 cleanParameters 의 경우 대부분의 경우 일부러 호출하지 않음. + clean(target); + + + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn(e.getMessage(), e); + } + } + + } + + private void clean(Object target) { + if (target instanceof BindValueTraceValue) { + ((BindValueTraceValue) target).__setTraceBindValue(new HashMap()); + } + } + + private String toBindVariable(Map bindValue) { + final String[] temp = new String[bindValue.size()]; + for (Map.Entry entry : bindValue.entrySet()) { + Integer key = entry.getKey() - 1; + if (temp.length < key) { + continue; + } + temp[key] = entry.getValue(); + } + + return BindValueUtils.bindValueToString(temp, maxSqlBindValueLength); + + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + try { + // TODO 일단 테스트로 실패일경우 종료 아닐경우 resultset fetch까지 계산. fetch count는 옵션으로 빼는게 좋을듯. + trace.recordException(throwable); + trace.markAfterTime(); + } finally { + trace.traceBlockEnd(); + } + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + traceContext.cacheApi(descriptor); + } + + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + this.maxSqlBindValueLength = traceContext.getProfilerConfig().getJdbcMaxSqlBindValueSize(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/StatementCreateInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/StatementCreateInterceptor.java index 292bc157439b..d1d86aab9ec6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/StatementCreateInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/StatementCreateInterceptor.java @@ -1,56 +1,56 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; - -import java.sql.Connection; - -/** - * @author emeroad - */ -public class StatementCreateInterceptor implements SimpleAroundInterceptor, TraceContextSupport { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private TraceContext traceContext; - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - - if (InterceptorUtils.isThrowable(throwable)) { - return; - } - Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - if (target instanceof Connection) { - final DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); - DatabaseInfoTraceValueUtils.__setTraceDatabaseInfo(result, databaseInfo); - } - } - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; + +import java.sql.Connection; + +/** + * @author emeroad + */ +public class StatementCreateInterceptor implements SimpleAroundInterceptor, TraceContextSupport { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private TraceContext traceContext; + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + + if (InterceptorUtils.isThrowable(throwable)) { + return; + } + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + if (target instanceof Connection) { + final DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); + DatabaseInfoTraceValueUtils.__setTraceDatabaseInfo(result, databaseInfo); + } + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionCommitInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionCommitInterceptor.java index f930c4d4f2e2..cc8265b01a3a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionCommitInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionCommitInterceptor.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; - -/** - * @author emeroad - */ -public class TransactionCommitInterceptor extends SpanEventSimpleAroundInterceptor { - - - public TransactionCommitInterceptor() { - super(TransactionCommitInterceptor.class); - } - - @Override - protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - trace.markBeforeTime(); - } - - - @Override - public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); - - trace.recordServiceType(databaseInfo.getType()); - trace.recordEndPoint(databaseInfo.getMultipleHost()); - trace.recordDestinationId(databaseInfo.getDatabaseId()); - - trace.recordApi(getMethodDescriptor()); - trace.recordException(throwable); - - trace.markAfterTime(); - } -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; + +/** + * @author emeroad + */ +public class TransactionCommitInterceptor extends SpanEventSimpleAroundInterceptor { + + + public TransactionCommitInterceptor() { + super(TransactionCommitInterceptor.class); + } + + @Override + protected void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + trace.markBeforeTime(); + } + + + @Override + public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); + + trace.recordServiceType(databaseInfo.getType()); + trace.recordEndPoint(databaseInfo.getMultipleHost()); + trace.recordDestinationId(databaseInfo.getDatabaseId()); + + trace.recordApi(getMethodDescriptor()); + trace.recordException(throwable); + + trace.markAfterTime(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionRollbackInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionRollbackInterceptor.java index 97d36512d682..3408bbb947f0 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionRollbackInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionRollbackInterceptor.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; - -/** - * @author emeroad - */ -public class TransactionRollbackInterceptor extends SpanEventSimpleAroundInterceptor { - - - public TransactionRollbackInterceptor() { - super(TransactionRollbackInterceptor.class); - } - - - @Override - public void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - trace.markBeforeTime(); - } - - - @Override - public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - - DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); - - trace.recordServiceType(databaseInfo.getType()); - trace.recordEndPoint(databaseInfo.getMultipleHost()); - trace.recordDestinationId(databaseInfo.getDatabaseId()); - - - trace.recordApi(getMethodDescriptor()); -// boolean success = InterceptorUtils.isSuccess(result); -// if (success) { -// trace.recordAttribute("Transaction", "rollback"); -// } else { -// trace.recordAttribute("Transaction", "rollback fail"); -// } - trace.recordException(throwable); - trace.markAfterTime(); - } - -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; + +/** + * @author emeroad + */ +public class TransactionRollbackInterceptor extends SpanEventSimpleAroundInterceptor { + + + public TransactionRollbackInterceptor() { + super(TransactionRollbackInterceptor.class); + } + + + @Override + public void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + trace.markBeforeTime(); + } + + + @Override + public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + + DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); + + trace.recordServiceType(databaseInfo.getType()); + trace.recordEndPoint(databaseInfo.getMultipleHost()); + trace.recordDestinationId(databaseInfo.getDatabaseId()); + + + trace.recordApi(getMethodDescriptor()); +// boolean success = InterceptorUtils.isSuccess(result); +// if (success) { +// trace.recordAttribute("Transaction", "rollback"); +// } else { +// trace.recordAttribute("Transaction", "rollback fail"); +// } + trace.recordException(throwable); + trace.markAfterTime(); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionSetAutoCommitInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionSetAutoCommitInterceptor.java index 40aa50493bf2..3d074c4cee3c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionSetAutoCommitInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/TransactionSetAutoCommitInterceptor.java @@ -1,40 +1,40 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; - -/** - * @author emeroad - */ -public class TransactionSetAutoCommitInterceptor extends SpanEventSimpleAroundInterceptor { - - - public TransactionSetAutoCommitInterceptor() { - super(TransactionSetAutoCommitInterceptor.class); - } - - - @Override - public void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { - trace.markBeforeTime(); - } - - @Override - protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); - - trace.recordServiceType(databaseInfo.getType()); - trace.recordEndPoint(databaseInfo.getMultipleHost()); - trace.recordDestinationId(databaseInfo.getDatabaseId()); - - - trace.recordApi(getMethodDescriptor(), args); - trace.recordException(throwable); - - trace.markAfterTime(); - } - -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValueUtils; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; + +/** + * @author emeroad + */ +public class TransactionSetAutoCommitInterceptor extends SpanEventSimpleAroundInterceptor { + + + public TransactionSetAutoCommitInterceptor() { + super(TransactionSetAutoCommitInterceptor.class); + } + + + @Override + public void doInBeforeTrace(RecordableTrace trace, Object target, Object[] args) { + trace.markBeforeTime(); + } + + @Override + protected void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(target, UnKnownDatabaseInfo.INSTANCE); + + trace.recordServiceType(databaseInfo.getType()); + trace.recordEndPoint(databaseInfo.getMultipleHost()); + trace.recordDestinationId(databaseInfo.getDatabaseId()); + + + trace.recordApi(getMethodDescriptor(), args); + trace.recordException(throwable); + + trace.markAfterTime(); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/UnKnownDatabaseInfo.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/UnKnownDatabaseInfo.java index d2ce84aedf5d..422d9ce2b931 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/UnKnownDatabaseInfo.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/UnKnownDatabaseInfo.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public class UnKnownDatabaseInfo { - public static final DatabaseInfo INSTANCE; - - static{ - final List urls = new ArrayList(); - urls.add("unknown"); - INSTANCE = new DefaultDatabaseInfo(ServiceType.UNKNOWN_DB, ServiceType.UNKNOWN_DB_EXECUTE_QUERY, "unknown", "unknown", urls, "unknown"); - } -} +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class UnKnownDatabaseInfo { + public static final DatabaseInfo INSTANCE; + + static{ + final List urls = new ArrayList(); + urls.add("unknown"); + INSTANCE = new DefaultDatabaseInfo(ServiceType.UNKNOWN_DB, ServiceType.UNKNOWN_DB_EXECUTE_QUERY, "unknown", "unknown", urls, "unknown"); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/Jdbc2ConnectionModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/Jdbc2ConnectionModifier.java new file mode 100644 index 000000000000..213516cda0d0 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/Jdbc2ConnectionModifier.java @@ -0,0 +1,19 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; + +/** + * 1.2.x -> jdk 1.5 + * @author emeroad + */ +public class Jdbc2ConnectionModifier extends JtdsConnectionModifier { + + public Jdbc2ConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "net/sourceforge/jtds/jdbc/ConnectionJDBC2"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/Jdbc4_1ConnectionModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/Jdbc4_1ConnectionModifier.java new file mode 100644 index 000000000000..d2e195e6b842 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/Jdbc4_1ConnectionModifier.java @@ -0,0 +1,19 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; + +/** + * 1.3.x -> jdk 1.7 + * @author emeroad + */ +public class Jdbc4_1ConnectionModifier extends JtdsConnectionModifier { + + public Jdbc4_1ConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "net/sourceforge/jtds/jdbc/JtdsConnection"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionModifier.java new file mode 100644 index 000000000000..4dc7c7fdf4ba --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionModifier.java @@ -0,0 +1,102 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.Agent; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.ProtectionDomain; + +public abstract class JtdsConnectionModifier extends AbstractModifier { + + private static final String SCOPE_NAME = JtdsScope.SCOPE_NAME; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public JtdsConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass jtdsConnection = byteCodeInstrumentor.getClass(javassistClassName); + + + jtdsConnection.addTraceValue(DatabaseInfoTraceValue.class); + + + Interceptor closeConnection = new ConnectionCloseInterceptor(); + jtdsConnection.addScopeInterceptor("close", null, closeConnection, SCOPE_NAME); + + + Interceptor statementCreateInterceptor1 = new StatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("createStatement", null, statementCreateInterceptor1, SCOPE_NAME); + + Interceptor statementCreateInterceptor2 = new StatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("createStatement", new String[]{"int", "int"}, statementCreateInterceptor2, SCOPE_NAME); + + Interceptor statementCreateInterceptor3 = new StatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("createStatement", new String[]{"int", "int", "int"}, statementCreateInterceptor3, SCOPE_NAME); + + + Interceptor preparedStatementCreateInterceptor1 = new PreparedStatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String"}, preparedStatementCreateInterceptor1, SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor2 = new PreparedStatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int"}, preparedStatementCreateInterceptor2, SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor3 = new PreparedStatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int[]"}, preparedStatementCreateInterceptor3, SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor4 = new PreparedStatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "java.lang.String[]"}, preparedStatementCreateInterceptor4, SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor5 = new PreparedStatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int", "int"}, preparedStatementCreateInterceptor5, SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor6 = new PreparedStatementCreateInterceptor(); + jtdsConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int", "int", "int"}, preparedStatementCreateInterceptor6, SCOPE_NAME); + + final ProfilerConfig profilerConfig = agent.getProfilerConfig(); + if (profilerConfig.isJdbcProfileJtdsSetAutoCommit()) { + Interceptor setAutocommit = new TransactionSetAutoCommitInterceptor(); + jtdsConnection.addScopeInterceptor("setAutoCommit", new String[]{"boolean"}, setAutocommit, SCOPE_NAME); + } + if (profilerConfig.isJdbcProfileJtdsCommit()) { + Interceptor commit = new TransactionCommitInterceptor(); + jtdsConnection.addScopeInterceptor("commit", null, commit, SCOPE_NAME); + } + if (profilerConfig.isJdbcProfileJtdsRollback()) { + Interceptor rollback = new TransactionRollbackInterceptor(); + jtdsConnection.addScopeInterceptor("rollback", null, rollback, SCOPE_NAME); + } + + if (this.logger.isInfoEnabled()) { + this.logger.info("{} class is converted.", javassistClassName); + } + + return jtdsConnection.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); + } + return null; + } + } + + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionStringParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionStringParser.java new file mode 100644 index 000000000000..423d8c7c091f --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionStringParser.java @@ -0,0 +1,62 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; +import com.nhn.pinpoint.profiler.modifier.db.StringMaker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class JtdsConnectionStringParser implements ConnectionStringParser { + + public static final int DEFAULT_PORT = 1433; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public DatabaseInfo parse(String url) { + if (url == null) { + return JDBCUrlParser.createUnknownDataBase(ServiceType.MSSQL, ServiceType.MSSQL_EXECUTE_QUERY, url); + } + +// jdbc:jtds:sqlserver://10.xx.xx.xx:1433;DatabaseName=CAFECHAT;sendStringParametersAsUnicode=false;useLOBs=false;loginTimeout=3 +// jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] +// jdbc:jtds:sqlserver://server/db;user=userName;password=password + StringMaker maker = new StringMaker(url); + + maker.lower().after("jdbc:jtds:sqlserver:"); + + StringMaker before = maker.after("//").before(';'); + final String hostAndPortAndDataBaseString = before.value(); + String databaseId = ""; + String hostAndPortString = ""; + final int databaseIdIndex = hostAndPortAndDataBaseString.indexOf('/'); + if (databaseIdIndex != -1) { + hostAndPortString = hostAndPortAndDataBaseString.substring(0, databaseIdIndex); + databaseId = hostAndPortAndDataBaseString.substring(databaseIdIndex+1, hostAndPortAndDataBaseString.length()); + } else { + hostAndPortString = hostAndPortAndDataBaseString; + } + + List hostList = new ArrayList(1); + hostList.add(hostAndPortString); + // option properties search + if (databaseId.isEmpty()) { + databaseId = maker.next().after("databasename=").before(';').value(); + } + + String normalizedUrl = maker.clear().before(";").value(); + + return new DefaultDatabaseInfo(ServiceType.MSSQL, ServiceType.MSSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsDriverModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsDriverModifier.java new file mode 100644 index 000000000000..898237306044 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsDriverModifier.java @@ -0,0 +1,58 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.DriverConnectInterceptor; +import com.nhn.pinpoint.profiler.util.Scope; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.ProtectionDomain; + +/** + * @author emeroad + */ +public class JtdsDriverModifier extends AbstractModifier { + +// oracle.jdbc.driver + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public JtdsDriverModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "net/sourceforge/jtds/jdbc/Driver"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass jtdsDriver = byteCodeInstrumentor.getClass(javassistClassName); + + final Scope scope = byteCodeInstrumentor.getScope(JtdsScope.SCOPE_NAME); + Interceptor createConnection = new DriverConnectInterceptor(scope); + String[] params = new String[]{ "java.lang.String", "java.util.Properties" }; + jtdsDriver.addInterceptor("connect", params, createConnection); + + if (logger.isInfoEnabled()) { + logger.info("{} class is converted.", javassistClassName); + } + + return jtdsDriver.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn(this.getClass().getSimpleName() + " modify fail. Cause:" + e.getMessage(), e); + } + return null; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsPreparedStatementModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsPreparedStatementModifier.java new file mode 100644 index 000000000000..66917ca0ae3e --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsPreparedStatementModifier.java @@ -0,0 +1,100 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue; +import com.nhn.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.interceptor.bci.NotFoundInstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.PreparedStatementBindVariableInterceptor; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.PreparedStatementExecuteQueryInterceptor; +import com.nhn.pinpoint.profiler.util.JavaAssistUtils; +import com.nhn.pinpoint.profiler.util.PreparedStatementUtils; +import com.nhn.pinpoint.profiler.util.Scope; + + +import java.lang.reflect.Method; +import java.security.ProtectionDomain; +import java.util.Arrays; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JtdsPreparedStatementModifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public JtdsPreparedStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "net/sourceforge/jtds/jdbc/JtdsPreparedStatement"; + } + + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass preparedStatementClass = byteCodeInstrumentor.getClass(javassistClassName); + + Interceptor executeInterceptor = new PreparedStatementExecuteQueryInterceptor(); + preparedStatementClass.addScopeInterceptor("execute", null, executeInterceptor, JtdsScope.SCOPE_NAME); + + Interceptor executeQueryInterceptor = new PreparedStatementExecuteQueryInterceptor(); + preparedStatementClass.addScopeInterceptor("executeQuery", null, executeQueryInterceptor, JtdsScope.SCOPE_NAME); + + Interceptor executeUpdateInterceptor = new PreparedStatementExecuteQueryInterceptor(); + preparedStatementClass.addScopeInterceptor("executeUpdate", null, executeUpdateInterceptor, JtdsScope.SCOPE_NAME); + + preparedStatementClass.addTraceValue(DatabaseInfoTraceValue.class); + preparedStatementClass.addTraceValue(ParsingResultTraceValue.class); + preparedStatementClass.addTraceValue(BindValueTraceValue.class, "new java.util.HashMap();"); + + bindVariableIntercept(preparedStatementClass, classLoader, protectedDomain); + + return preparedStatementClass.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); + } + return null; + } + } + + private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException { + List bindMethod = PreparedStatementUtils.findBindVariableSetMethod(); + final Scope scope = byteCodeInstrumentor.getScope(JtdsScope.SCOPE_NAME); + Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope); + int interceptorId = -1; + for (Method method : bindMethod) { + String methodName = method.getName(); + String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes()); + try { + if (interceptorId == -1) { + interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor); + } else { + preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId); + } + } catch (NotFoundInstrumentException e) { + // bind variable setter메소드를 못찾을 경우는 그냥 경고만 표시, 에러 아님. + if (logger.isDebugEnabled()) { + logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage()); + } + } + } + } + + + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLResultSetModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsResultSetModifier.java similarity index 50% rename from profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLResultSetModifier.java rename to profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsResultSetModifier.java index 00451a75e5ef..355e27d72584 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLResultSetModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsResultSetModifier.java @@ -1,4 +1,4 @@ -package com.nhn.pinpoint.profiler.modifier.db.mssql; +package com.nhn.pinpoint.profiler.modifier.db.jtds; import com.nhn.pinpoint.bootstrap.Agent; import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; @@ -10,11 +10,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class MSSQLResultSetModifier extends AbstractModifier { +public class JtdsResultSetModifier extends AbstractModifier { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public MSSQLResultSetModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + public JtdsResultSetModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { super(byteCodeInstrumentor, agent); } @@ -26,26 +26,11 @@ public byte[] modify(ClassLoader classLoader, String javassistClassName, Protect if (logger.isInfoEnabled()) { logger.info("Modifing. {}", javassistClassName); } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - return changeMethod(javassistClassName, classFileBuffer); - } - - private byte[] changeMethod(String javassistClassName, byte[] classfileBuffer) { - try { - CtClass cc = null; - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - return null; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } return null; } + + } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsScope.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsScope.java new file mode 100644 index 000000000000..43a96ac96169 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsScope.java @@ -0,0 +1,8 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +/** + * @author emeroad + */ +public final class JtdsScope { + public static final String SCOPE_NAME = "Jtds"; +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsStatementModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsStatementModifier.java new file mode 100644 index 000000000000..45a466c384fb --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsStatementModifier.java @@ -0,0 +1,65 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.StatementExecuteQueryInterceptor; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.StatementExecuteUpdateInterceptor; + +import java.security.ProtectionDomain; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JtdsStatementModifier extends AbstractModifier { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public JtdsStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "net/sourceforge/jtds/jdbc/JtdsStatement"; + } + + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + + byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + + try { + InstrumentClass statementClass = byteCodeInstrumentor.getClass(javassistClassName); + Interceptor executeQuery = new StatementExecuteQueryInterceptor(); + statementClass.addScopeInterceptor("executeQuery", new String[]{"java.lang.String"}, executeQuery, JtdsScope.SCOPE_NAME); + + Interceptor executeUpdateInterceptor1 = new StatementExecuteUpdateInterceptor(); + statementClass.addScopeInterceptor("executeUpdate", new String[]{"java.lang.String"}, executeUpdateInterceptor1, JtdsScope.SCOPE_NAME); + + + Interceptor executeUpdateInterceptor2 = new StatementExecuteUpdateInterceptor(); + statementClass.addScopeInterceptor("executeUpdate", new String[]{"java.lang.String", "int"}, executeUpdateInterceptor2, JtdsScope.SCOPE_NAME); + + Interceptor executeInterceptor1 = new StatementExecuteUpdateInterceptor(); + statementClass.addScopeInterceptor("execute", new String[]{"java.lang.String"}, executeInterceptor1, JtdsScope.SCOPE_NAME); + + Interceptor executeInterceptor2 = new StatementExecuteUpdateInterceptor(); + statementClass.addScopeInterceptor("execute", new String[]{"java.lang.String", "int"}, executeInterceptor2, JtdsScope.SCOPE_NAME); + + statementClass.addTraceValue(DatabaseInfoTraceValue.class); + return statementClass.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); + } + return null; + } + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLConnectionModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLConnectionModifier.java deleted file mode 100644 index 3f38db093454..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLConnectionModifier.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.db.mssql; - -import com.nhn.pinpoint.bootstrap.Agent; - -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import javassist.CtClass; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.security.ProtectionDomain; - -public class MSSQLConnectionModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public MSSQLConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "net/sourceforge/jtds/jdbc/ConnectionJDBC2"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - return changeMethods(javassistClassName, classFileBuffer); - } - - private byte[] changeMethods(String javassistClassName, byte[] classfileBuffer) { - try { - CtClass cc = null; - - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return null; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - return null; - } - - -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLPreparedStatementModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLPreparedStatementModifier.java deleted file mode 100644 index d2f4db1dfd7e..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLPreparedStatementModifier.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.db.mssql; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import javassist.CtClass; - - -import java.security.ProtectionDomain; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MSSQLPreparedStatementModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public MSSQLPreparedStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "net/sourceforge/jtds/jdbc/JtdsPreparedStatement"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - return changeMethod(javassistClassName, classFileBuffer); - } - - private byte[] changeMethod(String javassistClassName, byte[] classfileBuffer) { - try { - CtClass cc = null; - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return null; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - return null; - } - - - - -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLStatementModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLStatementModifier.java deleted file mode 100644 index 538bbc9ff97a..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mssql/MSSQLStatementModifier.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.db.mssql; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import javassist.CtClass; - -import java.security.ProtectionDomain; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MSSQLStatementModifier extends AbstractModifier { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public MSSQLStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "net/sourceforge/jtds/jdbc/JtdsStatement"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - return changeMethod(javassistClassName, classFileBuffer); - } - - private byte[] changeMethod(String javassistClassName, byte[] classfileBuffer) { - try { - CtClass cc = null; - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return null; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - return null; - } - -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionModifier.java index f33fe0f28f0b..d1023394d9c6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionModifier.java @@ -1,119 +1,119 @@ -package com.nhn.pinpoint.profiler.modifier.db.mysql; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.db.interceptor.*; -import com.nhn.pinpoint.profiler.modifier.db.mysql.interceptor.MySQLConnectionCreateInterceptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.security.ProtectionDomain; - -/** - * @author emeroad - */ -public class MySQLConnectionModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public MySQLConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - // mysql의 과거버전의 경우 Connection class에 직접 구현이 되어있다. - return "com/mysql/jdbc/Connection"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass mysqlConnection = byteCodeInstrumentor.getClass(javassistClassName); - if (mysqlConnection.isInterface()) { - // 최신버전의 mysql dirver를 사용했을 경우의 호환성 작업. - return null; - } - - - mysqlConnection.addTraceValue(DatabaseInfoTraceValue.class); - - // 해당 Interceptor를 공통클래스 만들경우 system에 로드해야 된다. -// Interceptor createConnection = new ConnectionCreateInterceptor(); -// String[] params = new String[] { -// "java.lang.String", "int", "java.util.Properties", "java.lang.String", "java.lang.String" -// }; -// mysqlConnection.addInterceptor("getInstance", params, createConnection); - Interceptor connectionUrlBindInterceptor = new MySQLConnectionCreateInterceptor(); - mysqlConnection.addConstructorInterceptor(new String[]{"java.lang.String", "int", - "java.util.Properties", "java.lang.String", "java.lang.String" }, connectionUrlBindInterceptor); - - - Interceptor closeConnection = new ConnectionCloseInterceptor(); - mysqlConnection.addScopeInterceptor("close", null, closeConnection, MYSQLScope.SCOPE_NAME); - - Interceptor statementCreateInterceptor1 = new StatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("createStatement", null, statementCreateInterceptor1, MYSQLScope.SCOPE_NAME); - - Interceptor statementCreateInterceptor2 = new StatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("createStatement", new String[]{"int", "int"}, statementCreateInterceptor2, MYSQLScope.SCOPE_NAME); - - Interceptor statementCreateInterceptor3 = new StatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("createStatement", new String[]{"int", "int", "int"}, statementCreateInterceptor3, MYSQLScope.SCOPE_NAME); - - - Interceptor preparedStatementCreateInterceptor1 = new PreparedStatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String"}, preparedStatementCreateInterceptor1, MYSQLScope.SCOPE_NAME); - - Interceptor preparedStatementCreateInterceptor2 = new PreparedStatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int"}, preparedStatementCreateInterceptor2, MYSQLScope.SCOPE_NAME); - - Interceptor preparedStatementCreateInterceptor3 = new PreparedStatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int[]"}, preparedStatementCreateInterceptor3, MYSQLScope.SCOPE_NAME); - - Interceptor preparedStatementCreateInterceptor4 = new PreparedStatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "java.lang.String[]"}, preparedStatementCreateInterceptor4, MYSQLScope.SCOPE_NAME); - - Interceptor preparedStatementCreateInterceptor5 = new PreparedStatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int", "int"}, preparedStatementCreateInterceptor5, MYSQLScope.SCOPE_NAME); - - Interceptor preparedStatementCreateInterceptor6 = new PreparedStatementCreateInterceptor(); - mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int", "int", "int"}, preparedStatementCreateInterceptor6, MYSQLScope.SCOPE_NAME); - - - final ProfilerConfig profilerConfig = agent.getProfilerConfig(); - if (profilerConfig.isJdbcProfileMySqlSetAutoCommit()) { - Interceptor setAutocommit = new TransactionSetAutoCommitInterceptor(); - mysqlConnection.addScopeInterceptor("setAutoCommit", new String[]{"boolean"}, setAutocommit, MYSQLScope.SCOPE_NAME); - } - if (profilerConfig.isJdbcProfileMySqlCommit()) { - Interceptor commit = new TransactionCommitInterceptor(); - mysqlConnection.addScopeInterceptor("commit", null, commit, MYSQLScope.SCOPE_NAME); - } - if (profilerConfig.isJdbcProfileMySqlRollback()) { - Interceptor rollback = new TransactionRollbackInterceptor(); - mysqlConnection.addScopeInterceptor("rollback", null, rollback, MYSQLScope.SCOPE_NAME); - } - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return mysqlConnection.toBytecode(); - } catch (InstrumentException e) { - if (logger.isWarnEnabled()) { - logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); - } - return null; - } - } -} - +package com.nhn.pinpoint.profiler.modifier.db.mysql; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.*; +import com.nhn.pinpoint.profiler.modifier.db.mysql.interceptor.MySQLConnectionCreateInterceptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.ProtectionDomain; + +/** + * @author emeroad + */ +public class MySQLConnectionModifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public MySQLConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + // mysql의 과거버전의 경우 Connection class에 직접 구현이 되어있다. + return "com/mysql/jdbc/Connection"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass mysqlConnection = byteCodeInstrumentor.getClass(javassistClassName); + if (mysqlConnection.isInterface()) { + // 최신버전의 mysql dirver를 사용했을 경우의 호환성 작업. + return null; + } + + + mysqlConnection.addTraceValue(DatabaseInfoTraceValue.class); + + // 해당 Interceptor를 공통클래스 만들경우 system에 로드해야 된다. +// Interceptor createConnection = new ConnectionCreateInterceptor(); +// String[] params = new String[] { +// "java.lang.String", "int", "java.util.Properties", "java.lang.String", "java.lang.String" +// }; +// mysqlConnection.addInterceptor("getInstance", params, createConnection); + Interceptor connectionUrlBindInterceptor = new MySQLConnectionCreateInterceptor(); + mysqlConnection.addConstructorInterceptor(new String[]{"java.lang.String", "int", + "java.util.Properties", "java.lang.String", "java.lang.String" }, connectionUrlBindInterceptor); + + + Interceptor closeConnection = new ConnectionCloseInterceptor(); + mysqlConnection.addScopeInterceptor("close", null, closeConnection, MYSQLScope.SCOPE_NAME); + + Interceptor statementCreateInterceptor1 = new StatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("createStatement", null, statementCreateInterceptor1, MYSQLScope.SCOPE_NAME); + + Interceptor statementCreateInterceptor2 = new StatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("createStatement", new String[]{"int", "int"}, statementCreateInterceptor2, MYSQLScope.SCOPE_NAME); + + Interceptor statementCreateInterceptor3 = new StatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("createStatement", new String[]{"int", "int", "int"}, statementCreateInterceptor3, MYSQLScope.SCOPE_NAME); + + + Interceptor preparedStatementCreateInterceptor1 = new PreparedStatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String"}, preparedStatementCreateInterceptor1, MYSQLScope.SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor2 = new PreparedStatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int"}, preparedStatementCreateInterceptor2, MYSQLScope.SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor3 = new PreparedStatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int[]"}, preparedStatementCreateInterceptor3, MYSQLScope.SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor4 = new PreparedStatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "java.lang.String[]"}, preparedStatementCreateInterceptor4, MYSQLScope.SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor5 = new PreparedStatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int", "int"}, preparedStatementCreateInterceptor5, MYSQLScope.SCOPE_NAME); + + Interceptor preparedStatementCreateInterceptor6 = new PreparedStatementCreateInterceptor(); + mysqlConnection.addScopeInterceptor("prepareStatement", new String[]{"java.lang.String", "int", "int", "int"}, preparedStatementCreateInterceptor6, MYSQLScope.SCOPE_NAME); + + + final ProfilerConfig profilerConfig = agent.getProfilerConfig(); + if (profilerConfig.isJdbcProfileMySqlSetAutoCommit()) { + Interceptor setAutocommit = new TransactionSetAutoCommitInterceptor(); + mysqlConnection.addScopeInterceptor("setAutoCommit", new String[]{"boolean"}, setAutocommit, MYSQLScope.SCOPE_NAME); + } + if (profilerConfig.isJdbcProfileMySqlCommit()) { + Interceptor commit = new TransactionCommitInterceptor(); + mysqlConnection.addScopeInterceptor("commit", null, commit, MYSQLScope.SCOPE_NAME); + } + if (profilerConfig.isJdbcProfileMySqlRollback()) { + Interceptor rollback = new TransactionRollbackInterceptor(); + mysqlConnection.addScopeInterceptor("rollback", null, rollback, MYSQLScope.SCOPE_NAME); + } + + if (this.logger.isInfoEnabled()) { + this.logger.info("{} class is converted.", javassistClassName); + } + + return mysqlConnection.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); + } + return null; + } + } +} + diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLNonRegisteringDriverModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLNonRegisteringDriverModifier.java index 0aded1c19792..17cd2a3c78f4 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLNonRegisteringDriverModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLNonRegisteringDriverModifier.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.profiler.modifier.db.mysql; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; - -import java.security.ProtectionDomain; - -import com.nhn.pinpoint.profiler.modifier.db.interceptor.DriverConnectInterceptor; -import com.nhn.pinpoint.profiler.util.Scope; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class MySQLNonRegisteringDriverModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public MySQLNonRegisteringDriverModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "com/mysql/jdbc/NonRegisteringDriver"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass mysqlConnection = byteCodeInstrumentor.getClass(javassistClassName); - - final Scope scope = byteCodeInstrumentor.getScope(MYSQLScope.SCOPE_NAME); - Interceptor createConnection = new DriverConnectInterceptor(false, scope); - String[] params = new String[]{ - "java.lang.String", "java.util.Properties" - }; -// Driver에서는 scopeInterceptor를 걸면안된다. trace thread가 아닌곳에서 connection이 생성될수 있다. - mysqlConnection.addInterceptor("connect", params, createConnection); - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return mysqlConnection.toBytecode(); - } catch (InstrumentException e) { - if (logger.isWarnEnabled()) { - logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); - } - return null; - } - } -} +package com.nhn.pinpoint.profiler.modifier.db.mysql; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; + +import java.security.ProtectionDomain; + +import com.nhn.pinpoint.profiler.modifier.db.interceptor.DriverConnectInterceptor; +import com.nhn.pinpoint.profiler.util.Scope; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class MySQLNonRegisteringDriverModifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public MySQLNonRegisteringDriverModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "com/mysql/jdbc/NonRegisteringDriver"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass mysqlConnection = byteCodeInstrumentor.getClass(javassistClassName); + + final Scope scope = byteCodeInstrumentor.getScope(MYSQLScope.SCOPE_NAME); + Interceptor createConnection = new DriverConnectInterceptor(false, scope); + String[] params = new String[]{ + "java.lang.String", "java.util.Properties" + }; +// Driver에서는 scopeInterceptor를 걸면안된다. trace thread가 아닌곳에서 connection이 생성될수 있다. + mysqlConnection.addInterceptor("connect", params, createConnection); + + if (this.logger.isInfoEnabled()) { + this.logger.info("{} class is converted.", javassistClassName); + } + + return mysqlConnection.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); + } + return null; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLPreparedStatementJDBC4Modifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLPreparedStatementJDBC4Modifier.java index 981a545d6c5a..9c0c8d629920 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLPreparedStatementJDBC4Modifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLPreparedStatementJDBC4Modifier.java @@ -1,81 +1,81 @@ -package com.nhn.pinpoint.profiler.modifier.db.mysql; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor; -import com.nhn.pinpoint.profiler.interceptor.bci.*; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.db.interceptor.PreparedStatementBindVariableInterceptor; -import com.nhn.pinpoint.profiler.util.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.Method; -import java.security.ProtectionDomain; -import java.util.Arrays; -import java.util.List; - -/** - * @author emeroad - */ -public class MySQLPreparedStatementJDBC4Modifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public MySQLPreparedStatementJDBC4Modifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "com/mysql/jdbc/JDBC4PreparedStatement"; - } - - @Override - public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. " + className); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, className); - try { - InstrumentClass preparedStatement = byteCodeInstrumentor.getClass(className); - - bindVariableIntercept(preparedStatement, classLoader, protectedDomain); - - return preparedStatement.toBytecode(); - } catch (InstrumentException e) { - if (logger.isWarnEnabled()) { - logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); - } - return null; - } - } - - private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException { - // TODO 문자열에 추가로 파라미터 type을 넣어야 될거 같음. - // jdbc 드라이버 마다 구현api가 약간식 차이가 있는데 파라미터 타입이 없을경우, api 판별에 한계가 있음. - BindVariableFilter exclude = new IncludeBindVariableFilter(new String[]{"setRowId", "setNClob", "setSQLXML"}); - List bindMethod = PreparedStatementUtils.findBindVariableSetMethod(exclude); - // TODO 해당 로직 공통화 필요? - // bci 쪽에 multi api 스펙에 대한 자동으로 인터셉터를 n개 걸어주는 api가 더 좋지 않을까한다. - final Scope scope = byteCodeInstrumentor.getScope(MYSQLScope.SCOPE_NAME); - Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope); - int interceptorId = -1; - for (Method method : bindMethod) { - String methodName = method.getName(); - String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes()); - try { - if (interceptorId == -1) { - interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor, Type.after); - } else { - preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId, Type.after); - } - } catch (NotFoundInstrumentException e) { - // bind variable setter메소드를 못찾을 경우는 그냥 경고만 표시, 에러 아님. - // stack trace는 일부러 안찍음. - if (logger.isDebugEnabled()) { - logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage()); - } - } - } - } -} +package com.nhn.pinpoint.profiler.modifier.db.mysql; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor; +import com.nhn.pinpoint.profiler.interceptor.bci.*; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.PreparedStatementBindVariableInterceptor; +import com.nhn.pinpoint.profiler.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; +import java.security.ProtectionDomain; +import java.util.Arrays; +import java.util.List; + +/** + * @author emeroad + */ +public class MySQLPreparedStatementJDBC4Modifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public MySQLPreparedStatementJDBC4Modifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "com/mysql/jdbc/JDBC4PreparedStatement"; + } + + @Override + public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. " + className); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, className); + try { + InstrumentClass preparedStatement = byteCodeInstrumentor.getClass(className); + + bindVariableIntercept(preparedStatement, classLoader, protectedDomain); + + return preparedStatement.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e); + } + return null; + } + } + + private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException { + // TODO 문자열에 추가로 파라미터 type을 넣어야 될거 같음. + // jdbc 드라이버 마다 구현api가 약간식 차이가 있는데 파라미터 타입이 없을경우, api 판별에 한계가 있음. + BindVariableFilter exclude = new IncludeBindVariableFilter(new String[]{"setRowId", "setNClob", "setSQLXML"}); + List bindMethod = PreparedStatementUtils.findBindVariableSetMethod(exclude); + // TODO 해당 로직 공통화 필요? + // bci 쪽에 multi api 스펙에 대한 자동으로 인터셉터를 n개 걸어주는 api가 더 좋지 않을까한다. + final Scope scope = byteCodeInstrumentor.getScope(MYSQLScope.SCOPE_NAME); + Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope); + int interceptorId = -1; + for (Method method : bindMethod) { + String methodName = method.getName(); + String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes()); + try { + if (interceptorId == -1) { + interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor, Type.after); + } else { + preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId, Type.after); + } + } catch (NotFoundInstrumentException e) { + // bind variable setter메소드를 못찾을 경우는 그냥 경고만 표시, 에러 아님. + // stack trace는 일부러 안찍음. + if (logger.isDebugEnabled()) { + logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage()); + } + } + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLResultSetModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLResultSetModifier.java index 1ad01a822114..5a0e71687d3e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLResultSetModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLResultSetModifier.java @@ -28,25 +28,8 @@ public byte[] modify(ClassLoader classLoader, String javassistClassName, Protect if (logger.isInfoEnabled()) { logger.info("Modifing. {}", javassistClassName); } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - return changeMethod(javassistClassName, classFileBuffer); - } - - private byte[] changeMethod(String javassistClassName, byte[] classfileBuffer) { - try { - - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return null; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } return null; } + } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySqlConnectionStringParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySqlConnectionStringParser.java index ec7a11081f91..713fb91f7076 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySqlConnectionStringParser.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySqlConnectionStringParser.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.profiler.modifier.db.mysql; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; -import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; -import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; -import com.nhn.pinpoint.profiler.modifier.db.StringMaker; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -/** - * @author emeroad - */ -public class MySqlConnectionStringParser implements ConnectionStringParser { - - // jdbc:mysql:loadbalance://10.25.149.62:3306,10.25.149.61:3306/MySQL?characterEncoding=UTF-8 - private static final String JDBC_MYSQL_LOADBALANCE = "jdbc:mysql:loadbalance:"; - - @Override - public DatabaseInfo parse(String url) { - if (url == null) { - return JDBCUrlParser.createUnknownDataBase(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, url); - } - - if (isLoadbalanceUrl(url)) { - return parseLoadbalancedUrl(url); - } - return parseNormal(url); - } - - private DatabaseInfo parseLoadbalancedUrl(String url) { - // jdbc:mysql://10.98.133.22:3306/test_lucy_db - StringMaker maker = new StringMaker(url); - maker.after("jdbc:mysql:"); - // 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯. - // mm db? 의 경우도 고려해야 될듯하다. - String host = maker.after("//").before('/').value(); - - // regex cache코드 삭제. 자주 호출되는 api가 아니라 메모리에 안가지고있는게 좋을듯함하다. - String[] parsedHost = host.split(","); - List hostList = Arrays.asList(parsedHost); - - - String databaseId = maker.next().afterLast('/').before('?').value(); - String normalizedUrl = maker.clear().before('?').value(); - return new DefaultDatabaseInfo(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); - } - - private boolean isLoadbalanceUrl(String url) { - return url.regionMatches(true, 0, JDBC_MYSQL_LOADBALANCE, 0, JDBC_MYSQL_LOADBALANCE.length()); - } - - private DatabaseInfo parseNormal(String url) { - // jdbc:mysql://10.98.133.22:3306/test_lucy_db - StringMaker maker = new StringMaker(url); - maker.after("jdbc:mysql:"); - // 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯. - // mm db? 의 경우도 고려해야 될듯하다. - String host = maker.after("//").before('/').value(); - List hostList = new ArrayList(1); - hostList.add(host); - // String port = maker.next().after(':').before('/').value(); - - String databaseId = maker.next().afterLast('/').before('?').value(); - String normalizedUrl = maker.clear().before('?').value(); - return new DefaultDatabaseInfo(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); - } -} +package com.nhn.pinpoint.profiler.modifier.db.mysql; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; +import com.nhn.pinpoint.profiler.modifier.db.StringMaker; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @author emeroad + */ +public class MySqlConnectionStringParser implements ConnectionStringParser { + + // jdbc:mysql:loadbalance://10.25.149.62:3306,10.25.149.61:3306/MySQL?characterEncoding=UTF-8 + private static final String JDBC_MYSQL_LOADBALANCE = "jdbc:mysql:loadbalance:"; + + @Override + public DatabaseInfo parse(String url) { + if (url == null) { + return JDBCUrlParser.createUnknownDataBase(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, url); + } + + if (isLoadbalanceUrl(url)) { + return parseLoadbalancedUrl(url); + } + return parseNormal(url); + } + + private DatabaseInfo parseLoadbalancedUrl(String url) { + // jdbc:mysql://10.98.133.22:3306/test_lucy_db + StringMaker maker = new StringMaker(url); + maker.after("jdbc:mysql:"); + // 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯. + // mm db? 의 경우도 고려해야 될듯하다. + String host = maker.after("//").before('/').value(); + + // regex cache코드 삭제. 자주 호출되는 api가 아니라 메모리에 안가지고있는게 좋을듯함하다. + String[] parsedHost = host.split(","); + List hostList = Arrays.asList(parsedHost); + + + String databaseId = maker.next().afterLast('/').before('?').value(); + String normalizedUrl = maker.clear().before('?').value(); + return new DefaultDatabaseInfo(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); + } + + private boolean isLoadbalanceUrl(String url) { + return url.regionMatches(true, 0, JDBC_MYSQL_LOADBALANCE, 0, JDBC_MYSQL_LOADBALANCE.length()); + } + + private DatabaseInfo parseNormal(String url) { + // jdbc:mysql://10.98.133.22:3306/test_lucy_db + StringMaker maker = new StringMaker(url); + maker.after("jdbc:mysql:"); + // 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯. + // mm db? 의 경우도 고려해야 될듯하다. + String host = maker.after("//").before('/').value(); + List hostList = new ArrayList(1); + hostList.add(host); + // String port = maker.next().after(':').before('/').value(); + + String databaseId = maker.next().afterLast('/').before('?').value(); + String normalizedUrl = maker.clear().before('?').value(); + return new DefaultDatabaseInfo(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/interceptor/MySQLConnectionCreateInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/interceptor/MySQLConnectionCreateInterceptor.java index bdcb02bab8f2..5ef9fc3c379d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/interceptor/MySQLConnectionCreateInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/interceptor/MySQLConnectionCreateInterceptor.java @@ -1,89 +1,89 @@ -package com.nhn.pinpoint.profiler.modifier.db.mysql.interceptor; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; -import com.nhn.pinpoint.bootstrap.logging.PLogger; - -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; -import com.nhn.pinpoint.common.ServiceType; - -/** - * @author emeroad - */ -public class MySQLConnectionCreateInterceptor implements SimpleAroundInterceptor, TraceContextSupport { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private TraceContext traceContext; - - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - if (args == null || args.length != 5) { - return; - } - - final String hostToConnectTo = getString(args[0]); - final Integer portToConnectTo = getInteger(args[1]); - final String databaseId = getString(args[3]); - // loadbalance 일경우 변형된 connectUrl이 온다. -// final String url = getString(args[4]); - DatabaseInfo databaseInfo = null; - if (hostToConnectTo != null && portToConnectTo != null && databaseId != null) { - // 여기의 url은 직접 사용하면 위험하다. - databaseInfo = traceContext.createDatabaseInfo(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, hostToConnectTo, portToConnectTo, databaseId); - if (InterceptorUtils.isSuccess(throwable)) { - // connection이 정상 성공일때만 set해야 한다. - if (target instanceof DatabaseInfoTraceValue) { - ((DatabaseInfoTraceValue)target).__setTraceDatabaseInfo(databaseInfo); - } - } - } - - final Trace trace = traceContext.currentTraceObject(); - if (trace == null) { - return; - } - // 상위에서 레코딩 중일 경우반드시한다. - if (databaseInfo != null) { - trace.recordServiceType(databaseInfo.getExecuteQueryType()); - trace.recordEndPoint(databaseInfo.getMultipleHost()); - trace.recordDestinationId(databaseInfo.getDatabaseId()); - } - - } - - private String getString(Object value) { - if (value instanceof String) { - return (String) value; - } - return null; - } - - private Integer getInteger(Object value) { - if (value instanceof Integer) { - return (Integer) value; - } - return null; - } - - @Override - public void before(Object target, Object[] args) { - - } - - - @Override - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - -} +package com.nhn.pinpoint.profiler.modifier.db.mysql.interceptor; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.bootstrap.logging.PLogger; + +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.bootstrap.util.InterceptorUtils; +import com.nhn.pinpoint.common.ServiceType; + +/** + * @author emeroad + */ +public class MySQLConnectionCreateInterceptor implements SimpleAroundInterceptor, TraceContextSupport { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private TraceContext traceContext; + + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + if (args == null || args.length != 5) { + return; + } + + final String hostToConnectTo = getString(args[0]); + final Integer portToConnectTo = getInteger(args[1]); + final String databaseId = getString(args[3]); + // loadbalance 일경우 변형된 connectUrl이 온다. +// final String url = getString(args[4]); + DatabaseInfo databaseInfo = null; + if (hostToConnectTo != null && portToConnectTo != null && databaseId != null) { + // 여기의 url은 직접 사용하면 위험하다. + databaseInfo = traceContext.createDatabaseInfo(ServiceType.MYSQL, ServiceType.MYSQL_EXECUTE_QUERY, hostToConnectTo, portToConnectTo, databaseId); + if (InterceptorUtils.isSuccess(throwable)) { + // connection이 정상 성공일때만 set해야 한다. + if (target instanceof DatabaseInfoTraceValue) { + ((DatabaseInfoTraceValue)target).__setTraceDatabaseInfo(databaseInfo); + } + } + } + + final Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + // 상위에서 레코딩 중일 경우반드시한다. + if (databaseInfo != null) { + trace.recordServiceType(databaseInfo.getExecuteQueryType()); + trace.recordEndPoint(databaseInfo.getMultipleHost()); + trace.recordDestinationId(databaseInfo.getDatabaseId()); + } + + } + + private String getString(Object value) { + if (value instanceof String) { + return (String) value; + } + return null; + } + + private Integer getInteger(Object value) { + if (value instanceof Integer) { + return (Integer) value; + } + return null; + } + + @Override + public void before(Object target, Object[] args) { + + } + + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleConnectionStringParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleConnectionStringParser.java new file mode 100644 index 000000000000..2c934f12dc73 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleConnectionStringParser.java @@ -0,0 +1,105 @@ +package com.nhn.pinpoint.profiler.modifier.db.oracle; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; +import com.nhn.pinpoint.profiler.modifier.db.DefaultDatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.JDBCUrlParser; +import com.nhn.pinpoint.profiler.modifier.db.StringMaker; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.Description; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.KeyValue; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleConnectionStringException; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleNetConnectionDescriptorParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class OracleConnectionStringParser implements ConnectionStringParser { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public DatabaseInfo parse(String url) { + StringMaker maker = new StringMaker(url); + maker.after("jdbc:oracle:").after(":"); + String description = maker.after('@').value().trim(); + if (description.startsWith("(")) { + return parseNetConnectionUrl(url); + } else { + return parseSimpleUrl(url, maker); + } + } + + + // rac url. +// jdbc:oracle:thin:@(Description=(LOAD_BALANCE=on)" + +// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + +// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))" + +// "(CONNECT_DATA=(SERVICE_NAME=service)))" +// +// thin driver url +// jdbc:oracle:thin:@hostname:port:SID +// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; +// 들여 쓰기를 통해 token을 보기 좋게 나눈경우. +// jdbc:oracle:thin: +// @( +// Description=(LOAD_BALANCE=on) +// ( +// ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521) +// ) +// ( +// ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521) +// ) +// ( +// CONNECT_DATA=(SERVICE_NAME=service) +// ) +// ) + private DatabaseInfo parseNetConnectionUrl(String url) { + try { + // oracle new URL : rac용 + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(url); + KeyValue keyValue = parser.parse(); + // TODO oci 드라이버 일경우의 추가 처리가 필요함. nhn말고 왠간한데는 oci를 더 많이 씀. +// parser.getDriverType(); + return createOracleDatabaseInfo(keyValue, url); + } catch (OracleConnectionStringException ex) { + logger.warn("OracleConnectionString parse error. url:{} Caused:", url, ex.getMessage(), ex); + + // 에러찍고 그냥 unknownDataBase 생성 + return JDBCUrlParser.createUnknownDataBase(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url); + } catch (Throwable ex) { + // 나중에 좀더 정교하게 exception을 던지게 되면 OracleConnectionStringException 만 잡는것으로 바꿔야 될듯하다. + logger.warn("OracleConnectionString parse error. url:{} Caused:", url, ex.getMessage(), ex); + // 에러찍고 그냥 unknownDataBase 생성 + return JDBCUrlParser.createUnknownDataBase(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url); + } + } + + private DefaultDatabaseInfo parseSimpleUrl(String url, StringMaker maker) { + // thin driver + // jdbc:oracle:thin:@hostname:port:SID + // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; +// jdbc:oracle:thin:@//hostname:port/serviceName + String host = maker.before(':').value(); + String port = maker.next().after(':').before(':', '/').value(); + String databaseId = maker.next().afterLast(':', '/').value(); + + List hostList = new ArrayList(1); + hostList.add(host + ":" + port); + return new DefaultDatabaseInfo(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url, url, hostList, databaseId); + } + + private DatabaseInfo createOracleDatabaseInfo(KeyValue keyValue, String url) { + + Description description = new Description(keyValue); + List jdbcHost = description.getJdbcHost(); + + return new DefaultDatabaseInfo(ServiceType.ORACLE, ServiceType.ORACLE_EXECUTE_QUERY, url, url, jdbcHost, description.getDatabaseId()); + + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleDriverModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleDriverModifier.java index d30fbe75e7d2..c9c56d3df32b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleDriverModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleDriverModifier.java @@ -1,58 +1,58 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.db.interceptor.DriverConnectInterceptor; -import com.nhn.pinpoint.profiler.util.Scope; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.security.ProtectionDomain; - -/** - * @author emeroad - */ -public class OracleDriverModifier extends AbstractModifier { - -// oracle.jdbc.driver - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public OracleDriverModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "oracle/jdbc/driver/OracleDriver"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass oracleDriver = byteCodeInstrumentor.getClass(javassistClassName); - - final Scope scope = byteCodeInstrumentor.getScope(OracleScope.SCOPE_NAME); - Interceptor createConnection = new DriverConnectInterceptor(scope); - String[] params = new String[]{ "java.lang.String", "java.util.Properties" }; - oracleDriver.addInterceptor("connect", params, createConnection); - - if (logger.isInfoEnabled()) { - logger.info("{} class is converted.", javassistClassName); - } - - return oracleDriver.toBytecode(); - } catch (InstrumentException e) { - if (logger.isWarnEnabled()) { - logger.warn(this.getClass().getSimpleName() + " modify fail. Cause:" + e.getMessage(), e); - } - return null; - } - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.DriverConnectInterceptor; +import com.nhn.pinpoint.profiler.util.Scope; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.ProtectionDomain; + +/** + * @author emeroad + */ +public class OracleDriverModifier extends AbstractModifier { + +// oracle.jdbc.driver + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public OracleDriverModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "oracle/jdbc/driver/OracleDriver"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifing. {}", javassistClassName); + } + this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass oracleDriver = byteCodeInstrumentor.getClass(javassistClassName); + + final Scope scope = byteCodeInstrumentor.getScope(OracleScope.SCOPE_NAME); + Interceptor createConnection = new DriverConnectInterceptor(scope); + String[] params = new String[]{ "java.lang.String", "java.util.Properties" }; + oracleDriver.addInterceptor("connect", params, createConnection); + + if (logger.isInfoEnabled()) { + logger.info("{} class is converted.", javassistClassName); + } + + return oracleDriver.toBytecode(); + } catch (InstrumentException e) { + if (logger.isWarnEnabled()) { + logger.warn(this.getClass().getSimpleName() + " modify fail. Cause:" + e.getMessage(), e); + } + return null; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleResultSetModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleResultSetModifier.java index a801eb25db44..a0bb37110d72 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleResultSetModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/OracleResultSetModifier.java @@ -30,27 +30,10 @@ public byte[] modify(ClassLoader classLoader, String javassistClassName, Protect if (logger.isInfoEnabled()) { logger.info("Modifing. {}", javassistClassName); } - this.byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - return changeMethod(javassistClassName, classFileBuffer); + return null; } - private byte[] changeMethod(String javassistClassName, byte[] classfileBuffer) { - try { - CtClass cc = null; - - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - return null; - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - return null; - } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Address.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Address.java index 6b3474ddcaf8..08a60f6930c0 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Address.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Address.java @@ -1,76 +1,76 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -/** - * @author emeroad - */ -public class Address { - - private String protocol; - - private String host; - - private String port; - - public Address(String protocol, String host, String port) { - this.protocol = protocol; - this.host = host; - this.port = port; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public String getPort() { - return port; - } - - public void setPort(String port) { - this.port = port; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Address address = (Address) o; - - if (host != null ? !host.equals(address.host) : address.host != null) return false; - if (port != null ? !port.equals(address.port) : address.port != null) return false; - if (protocol != null ? !protocol.equals(address.protocol) : address.protocol != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = protocol != null ? protocol.hashCode() : 0; - result = 31 * result + (host != null ? host.hashCode() : 0); - result = 31 * result + (port != null ? port.hashCode() : 0); - return result; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("Address"); - sb.append("{protocol='").append(protocol).append('\''); - sb.append(", host='").append(host).append('\''); - sb.append(", port='").append(port).append('\''); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +/** + * @author emeroad + */ +public class Address { + + private String protocol; + + private String host; + + private String port; + + public Address(String protocol, String host, String port) { + this.protocol = protocol; + this.host = host; + this.port = port; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Address address = (Address) o; + + if (host != null ? !host.equals(address.host) : address.host != null) return false; + if (port != null ? !port.equals(address.port) : address.port != null) return false; + if (protocol != null ? !protocol.equals(address.protocol) : address.protocol != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = protocol != null ? protocol.hashCode() : 0; + result = 31 * result + (host != null ? host.hashCode() : 0); + result = 31 * result + (port != null ? port.hashCode() : 0); + return result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("Address"); + sb.append("{protocol='").append(protocol).append('\''); + sb.append(", host='").append(host).append('\''); + sb.append(", port='").append(port).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Description.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Description.java index da23f06b59e1..51d27f67fa0e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Description.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Description.java @@ -1,149 +1,149 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public class Description { - - private String serviceName; - private String sid; - private ArrayList
addressList = new ArrayList
(); - - public Description() { - } - - public Description(KeyValue keyValue) { - if (keyValue == null) { - throw new NullPointerException("keyValue"); - } - mapping(keyValue); - } - - - - private void mapping(KeyValue keyValue) { - if (!compare("description", keyValue)) { - throw new OracleConnectionStringException("description node not found"); - } - - for (KeyValue kv : keyValue.getKeyValueList()) { - if (compare("address", kv)) { - String host = null; - String port = null; - String protocol = null; - for (KeyValue address : kv.getKeyValueList()) { - if (compare("host", address)) { - host = address.getValue(); - } else if (compare("port", address)) { - port = address.getValue(); - } else if(compare("protocol", address)) { - protocol = address.getValue(); - } - } - this.addAddress(protocol, host, port); - } else if(compare("connect_data", kv)) { - for (KeyValue connectData : kv.getKeyValueList()) { - if (compare("service_name", connectData)) { - this.serviceName = connectData.getValue(); - } else if(compare("sid", connectData)) { - // sid도 호환을 위해서 봐야 한다. - this.sid = connectData.getValue(); - } - } - } - } - } - - private boolean compare(String value, KeyValue kv) { - if (kv == null) { - return false; - } - return value.equals(kv.getKey()); - } - - public String getServiceName() { - return serviceName; - } - - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getSid() { - return sid; - } - - public void setSid(String sid) { - this.sid = sid; - } - - public List getJdbcHost() { - List hostList = new ArrayList(); - for(Address address : addressList) { - String host = address.getHost(); - String port = address.getPort(); - if(port == null) { - // default port를 세팅한다. - port = "1521"; - } - hostList.add(host + ":" + port); - } - return hostList; - } - - public String getDatabaseId() { - // 전체 집합에 해당하는 servcieName 먼저 검색 - String serviceName = getServiceName(); - if(serviceName != null) { - return serviceName; - } - // serviceName이 없으면 대안으로 sid 사용. - String sid = getSid(); - if (sid != null) { - return sid; - } - return "oracleDatabaseId not found"; - } - - - public void addAddress(String protocol, String host, String port) { - this.addressList.add(new Address(protocol, host, port)); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Description that = (Description) o; - - if (addressList != null ? !addressList.equals(that.addressList) : that.addressList != null) return false; - if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) return false; - if (sid != null ? !sid.equals(that.sid) : that.sid != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = serviceName != null ? serviceName.hashCode() : 0; - result = 31 * result + (sid != null ? sid.hashCode() : 0); - result = 31 * result + (addressList != null ? addressList.hashCode() : 0); - return result; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("Description"); - sb.append("{serviceName='").append(serviceName).append('\''); - sb.append(", sid='").append(sid).append('\''); - sb.append(", addressList=").append(addressList); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class Description { + + private String serviceName; + private String sid; + private ArrayList
addressList = new ArrayList
(); + + public Description() { + } + + public Description(KeyValue keyValue) { + if (keyValue == null) { + throw new NullPointerException("keyValue"); + } + mapping(keyValue); + } + + + + private void mapping(KeyValue keyValue) { + if (!compare("description", keyValue)) { + throw new OracleConnectionStringException("description node not found"); + } + + for (KeyValue kv : keyValue.getKeyValueList()) { + if (compare("address", kv)) { + String host = null; + String port = null; + String protocol = null; + for (KeyValue address : kv.getKeyValueList()) { + if (compare("host", address)) { + host = address.getValue(); + } else if (compare("port", address)) { + port = address.getValue(); + } else if(compare("protocol", address)) { + protocol = address.getValue(); + } + } + this.addAddress(protocol, host, port); + } else if(compare("connect_data", kv)) { + for (KeyValue connectData : kv.getKeyValueList()) { + if (compare("service_name", connectData)) { + this.serviceName = connectData.getValue(); + } else if(compare("sid", connectData)) { + // sid도 호환을 위해서 봐야 한다. + this.sid = connectData.getValue(); + } + } + } + } + } + + private boolean compare(String value, KeyValue kv) { + if (kv == null) { + return false; + } + return value.equals(kv.getKey()); + } + + public String getServiceName() { + return serviceName; + } + + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + + public List getJdbcHost() { + List hostList = new ArrayList(); + for(Address address : addressList) { + String host = address.getHost(); + String port = address.getPort(); + if(port == null) { + // default port를 세팅한다. + port = "1521"; + } + hostList.add(host + ":" + port); + } + return hostList; + } + + public String getDatabaseId() { + // 전체 집합에 해당하는 servcieName 먼저 검색 + String serviceName = getServiceName(); + if(serviceName != null) { + return serviceName; + } + // serviceName이 없으면 대안으로 sid 사용. + String sid = getSid(); + if (sid != null) { + return sid; + } + return "oracleDatabaseId not found"; + } + + + public void addAddress(String protocol, String host, String port) { + this.addressList.add(new Address(protocol, host, port)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Description that = (Description) o; + + if (addressList != null ? !addressList.equals(that.addressList) : that.addressList != null) return false; + if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) return false; + if (sid != null ? !sid.equals(that.sid) : that.sid != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = serviceName != null ? serviceName.hashCode() : 0; + result = 31 * result + (sid != null ? sid.hashCode() : 0); + result = 31 * result + (addressList != null ? addressList.hashCode() : 0); + return result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("Description"); + sb.append("{serviceName='").append(serviceName).append('\''); + sb.append(", sid='").append(sid).append('\''); + sb.append(", addressList=").append(addressList); + sb.append('}'); + return sb.toString(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/DriverType.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/DriverType.java index 9e98b2d045a8..b399a585edb4 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/DriverType.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/DriverType.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -/** - * @author emeroad - */ -public enum DriverType { - THIN, OCI -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +/** + * @author emeroad + */ +public enum DriverType { + THIN, OCI +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/KeyValue.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/KeyValue.java index eeb75ee7b087..363d894b4bff 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/KeyValue.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/KeyValue.java @@ -1,82 +1,82 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * @author emeroad - */ -public class KeyValue { - - public String key; - public String value; - public List keyValueList; - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public List getKeyValueList() { - if (keyValueList == null) { - return Collections.emptyList(); - } - return keyValueList; - } - - public void addKeyValueList(KeyValue keyValue) { - if (keyValueList == null) { - keyValueList = new ArrayList(); - } - this.keyValueList.add(keyValue); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("{key='").append(key).append('\''); - if (value != null) { - sb.append(", value='").append(value).append('\''); - } - if (keyValueList != null) { - sb.append(", keyValueList=").append(keyValueList); - } - sb.append('}'); - return sb.toString(); - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - KeyValue keyValue = (KeyValue) o; - - if (key != null ? !key.equals(keyValue.key) : keyValue.key != null) return false; - if (keyValueList != null ? !keyValueList.equals(keyValue.keyValueList) : keyValue.keyValueList != null) return false; - if (value != null ? !value.equals(keyValue.value) : keyValue.value != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = key != null ? key.hashCode() : 0; - result = 31 * result + (value != null ? value.hashCode() : 0); - result = 31 * result + (keyValueList != null ? keyValueList.hashCode() : 0); - return result; - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author emeroad + */ +public class KeyValue { + + public String key; + public String value; + public List keyValueList; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public List getKeyValueList() { + if (keyValueList == null) { + return Collections.emptyList(); + } + return keyValueList; + } + + public void addKeyValueList(KeyValue keyValue) { + if (keyValueList == null) { + keyValueList = new ArrayList(); + } + this.keyValueList.add(keyValue); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("{key='").append(key).append('\''); + if (value != null) { + sb.append(", value='").append(value).append('\''); + } + if (keyValueList != null) { + sb.append(", keyValueList=").append(keyValueList); + } + sb.append('}'); + return sb.toString(); + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + KeyValue keyValue = (KeyValue) o; + + if (key != null ? !key.equals(keyValue.key) : keyValue.key != null) return false; + if (keyValueList != null ? !keyValueList.equals(keyValue.keyValueList) : keyValue.keyValueList != null) return false; + if (value != null ? !value.equals(keyValue.value) : keyValue.value != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = key != null ? key.hashCode() : 0; + result = 31 * result + (value != null ? value.hashCode() : 0); + result = 31 * result + (keyValueList != null ? keyValueList.hashCode() : 0); + return result; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleConnectionStringException.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleConnectionStringException.java index 005743efc528..a3f79889d005 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleConnectionStringException.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleConnectionStringException.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -import com.nhn.pinpoint.exception.PinpointException; - -/** - * @author emeroad - */ -public class OracleConnectionStringException extends PinpointException { - - public OracleConnectionStringException() { - } - - public OracleConnectionStringException(String message) { - super(message); - } - - public OracleConnectionStringException(String message, Throwable cause) { - super(message, cause); - } - - public OracleConnectionStringException(Throwable cause) { - super(cause); - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +import com.nhn.pinpoint.exception.PinpointException; + +/** + * @author emeroad + */ +public class OracleConnectionStringException extends PinpointException { + + public OracleConnectionStringException() { + } + + public OracleConnectionStringException(String message) { + super(message); + } + + public OracleConnectionStringException(String message, Throwable cause) { + super(message, cause); + } + + public OracleConnectionStringException(Throwable cause) { + super(cause); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParser.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParser.java index 5864d1f30a73..c62ad2c29281 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParser.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParser.java @@ -1,134 +1,134 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -/** - * @author emeroad - */ -public class OracleNetConnectionDescriptorParser { - - private static String THIN = "jdbc:oracle:thin"; - private static String OCI = "jdbc:oracle:oci"; - - private String url; - private String normalizedUrl; - - private DriverType driverType; - - private OracleNetConnectionDescriptorTokenizer tokenizer; - - public OracleNetConnectionDescriptorParser(String url) { - this.url = url; - this.normalizedUrl = url.toLowerCase(); - this.tokenizer = new OracleNetConnectionDescriptorTokenizer(normalizedUrl); - } - - public KeyValue parse() { - // 드라이버 스펙을 좀더 확인하려면 아래 참조. 10g 용이므로 11g도 거의 커버 될듯. - // http://docs.oracle.com/cd/B14117_01/java.101/b10979/urls.htm - - int position; - if (normalizedUrl.startsWith(THIN)) { - position = nextPosition(THIN); - driverType = DriverType.THIN; - } else if(normalizedUrl.startsWith(OCI)) { - position = nextPosition(OCI); - driverType = DriverType.OCI; - } else { - // 파싱할 대상이 아님 - throw new IllegalArgumentException("invalid oracle jdbc url. expected token:(" + THIN + " or " + OCI + ") url:" + url); - } - - // thin 문자열 스킵 - this.tokenizer.setPosition(position); - // token으로 분리. - this.tokenizer.parse(); - // 구분분석. - KeyValue keyValue = parseKeyValue(); - - checkEof(); - - return keyValue; - } - - private void checkEof() { - Token eof = this.tokenizer.nextToken(); - if (eof == null) { - throw new OracleConnectionStringException("parsing error. expected token:'EOF' token:null"); - } - if (eof != OracleNetConnectionDescriptorTokenizer.TOKEN_EOF_OBJECT) { - throw new OracleConnectionStringException("parsing error. expected token:'EOF' token:" + eof); - } - } - - public DriverType getDriverType() { - return driverType; - } - - private int nextPosition(String driverUrl) { - final int thinLength = driverUrl.length(); - if (normalizedUrl.startsWith(":@", thinLength)) { - return thinLength + 2; - } else if(normalizedUrl.startsWith("@", thinLength)) { - return thinLength + 1; - } else { - throw new OracleConnectionStringException("invalid oracle jdbc url:" + driverUrl); - } - } - - private KeyValue parseKeyValue() { - - // start - this.tokenizer.checkStartToken(); - - KeyValue keyValue = new KeyValue(); - // key - Token literalToken = this.tokenizer.getLiteralToken(); - keyValue.setKey(literalToken.getToken()); - - // = - this.tokenizer.checkEqualToken(); - - // value 비교 reduce - boolean nonTerminalValue = false; - while(true) { - final Token token = this.tokenizer.lookAheadToken(); - if (token == null) { - // EOF하고는 다른 비정상적 종료인것으로 판단됨. - throw new OracleConnectionStringException("Syntax error. lookAheadToken is null"); - } - if (token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_KEY_START) { - nonTerminalValue = true; - KeyValue child = parseKeyValue(); - keyValue.addKeyValueList(child); - - // 다음 토큰을 더 까보고 )면 value 완성으로 종료. - Token endCheck = this.tokenizer.lookAheadToken(); - if (endCheck == OracleNetConnectionDescriptorTokenizer.TOKEN_KEY_END_OBJECT) { - this.tokenizer.nextPosition(); - return keyValue; - } - } else if(token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_LITERAL) { - if (nonTerminalValue) { - throw new OracleConnectionStringException("Syntax error. expected token:'(' or ')' :" + token.getToken()); - } - // lookahead로 봤으므로 토큰 버림. - this.tokenizer.nextPosition(); - - keyValue.setValue(token.getToken()); - this.tokenizer.checkEndToken(); - return keyValue; - } else if(token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_KEY_END){ - this.tokenizer.nextPosition(); - // 빈칸이면 가능할듯 한데 뭔가 예외를 둬야 될듯하다. - // empty value가 가능한가?? - return keyValue; - } else { - // START, END, LITERAL 을 다 체크하므로 불가능한거 같긴한데. - // 향후 추가 토큰이 발생하면 에러 발생이 가능함. - // 문법이 잘못됬을 경우 EOF가 오거나 할 수있음. - throw new OracleConnectionStringException("Syntax error. " + token.getToken()); - } - } - - } - -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +/** + * @author emeroad + */ +public class OracleNetConnectionDescriptorParser { + + private static String THIN = "jdbc:oracle:thin"; + private static String OCI = "jdbc:oracle:oci"; + + private String url; + private String normalizedUrl; + + private DriverType driverType; + + private OracleNetConnectionDescriptorTokenizer tokenizer; + + public OracleNetConnectionDescriptorParser(String url) { + this.url = url; + this.normalizedUrl = url.toLowerCase(); + this.tokenizer = new OracleNetConnectionDescriptorTokenizer(normalizedUrl); + } + + public KeyValue parse() { + // 드라이버 스펙을 좀더 확인하려면 아래 참조. 10g 용이므로 11g도 거의 커버 될듯. + // http://docs.oracle.com/cd/B14117_01/java.101/b10979/urls.htm + + int position; + if (normalizedUrl.startsWith(THIN)) { + position = nextPosition(THIN); + driverType = DriverType.THIN; + } else if(normalizedUrl.startsWith(OCI)) { + position = nextPosition(OCI); + driverType = DriverType.OCI; + } else { + // 파싱할 대상이 아님 + throw new IllegalArgumentException("invalid oracle jdbc url. expected token:(" + THIN + " or " + OCI + ") url:" + url); + } + + // thin 문자열 스킵 + this.tokenizer.setPosition(position); + // token으로 분리. + this.tokenizer.parse(); + // 구분분석. + KeyValue keyValue = parseKeyValue(); + + checkEof(); + + return keyValue; + } + + private void checkEof() { + Token eof = this.tokenizer.nextToken(); + if (eof == null) { + throw new OracleConnectionStringException("parsing error. expected token:'EOF' token:null"); + } + if (eof != OracleNetConnectionDescriptorTokenizer.TOKEN_EOF_OBJECT) { + throw new OracleConnectionStringException("parsing error. expected token:'EOF' token:" + eof); + } + } + + public DriverType getDriverType() { + return driverType; + } + + private int nextPosition(String driverUrl) { + final int thinLength = driverUrl.length(); + if (normalizedUrl.startsWith(":@", thinLength)) { + return thinLength + 2; + } else if(normalizedUrl.startsWith("@", thinLength)) { + return thinLength + 1; + } else { + throw new OracleConnectionStringException("invalid oracle jdbc url:" + driverUrl); + } + } + + private KeyValue parseKeyValue() { + + // start + this.tokenizer.checkStartToken(); + + KeyValue keyValue = new KeyValue(); + // key + Token literalToken = this.tokenizer.getLiteralToken(); + keyValue.setKey(literalToken.getToken()); + + // = + this.tokenizer.checkEqualToken(); + + // value 비교 reduce + boolean nonTerminalValue = false; + while(true) { + final Token token = this.tokenizer.lookAheadToken(); + if (token == null) { + // EOF하고는 다른 비정상적 종료인것으로 판단됨. + throw new OracleConnectionStringException("Syntax error. lookAheadToken is null"); + } + if (token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_KEY_START) { + nonTerminalValue = true; + KeyValue child = parseKeyValue(); + keyValue.addKeyValueList(child); + + // 다음 토큰을 더 까보고 )면 value 완성으로 종료. + Token endCheck = this.tokenizer.lookAheadToken(); + if (endCheck == OracleNetConnectionDescriptorTokenizer.TOKEN_KEY_END_OBJECT) { + this.tokenizer.nextPosition(); + return keyValue; + } + } else if(token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_LITERAL) { + if (nonTerminalValue) { + throw new OracleConnectionStringException("Syntax error. expected token:'(' or ')' :" + token.getToken()); + } + // lookahead로 봤으므로 토큰 버림. + this.tokenizer.nextPosition(); + + keyValue.setValue(token.getToken()); + this.tokenizer.checkEndToken(); + return keyValue; + } else if(token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_KEY_END){ + this.tokenizer.nextPosition(); + // 빈칸이면 가능할듯 한데 뭔가 예외를 둬야 될듯하다. + // empty value가 가능한가?? + return keyValue; + } else { + // START, END, LITERAL 을 다 체크하므로 불가능한거 같긴한데. + // 향후 추가 토큰이 발생하면 에러 발생이 가능함. + // 문법이 잘못됬을 경우 EOF가 오거나 할 수있음. + throw new OracleConnectionStringException("Syntax error. " + token.getToken()); + } + } + + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizer.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizer.java index 315d4acfa823..059dd9fc8f92 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizer.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizer.java @@ -1,228 +1,228 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public class OracleNetConnectionDescriptorTokenizer { - - public static final char TOKEN_EQUAL = '='; - public static final char TOKEN_KEY_START = '('; - public static final char TOKEN_KEY_END = ')'; - -// 사실 아래 토큰이 더 있음 추후 이슈 발생시 추가로 구현이 필요함. -// 현재는 그냥 지원하지 않는다고 에러나 발생시키자. - private static final char TOKEN_COMMA = ','; - private static final char TOKEN_BKSLASH = '\\'; - private static final char TOKEN_DQUOTE = '"'; - private static final char TOKEN_SQUOTE = '\''; - - public static final int TYPE_KEY_START = 0; - public static final Token TOKEN_KEY_START_OBJECT = new Token(String.valueOf(TOKEN_KEY_START), TYPE_KEY_START); - - public static final int TYPE_KEY_END = 1; - public static final Token TOKEN_KEY_END_OBJECT = new Token(String.valueOf(TOKEN_KEY_END), TYPE_KEY_END); - - public static final int TYPE_EQUAL = 2; - public static final Token TOKEN_EQUAL_OBJECT = new Token(String.valueOf(TOKEN_EQUAL), TYPE_EQUAL); - - public static final int TYPE_LITERAL = 3; - - public static final int TYPE_EOF = -1; - public static final Token TOKEN_EOF_OBJECT = new Token("EOF", TYPE_EOF); - - private final List tokenList = new ArrayList(); - private int tokenPosition = 0; - - private final String connectionString; - private int position = 0; - - public OracleNetConnectionDescriptorTokenizer(String connectionString) { - if (connectionString == null) { - throw new NullPointerException("connectionString"); - } - this.connectionString = connectionString; - } - - public void parse() { - final int length = connectionString.length(); - - for (; position < length; position++) { - final char ch = connectionString.charAt(position); - if (isWhiteSpace(ch)) { - continue; - } - - switch (ch) { - case TOKEN_KEY_START: - this.tokenList.add(TOKEN_KEY_START_OBJECT); - break; - case TOKEN_EQUAL: - this.tokenList.add(TOKEN_EQUAL_OBJECT); - break; - case TOKEN_KEY_END: - this.tokenList.add(TOKEN_KEY_END_OBJECT); - break; - case TOKEN_COMMA: - case TOKEN_BKSLASH: - case TOKEN_DQUOTE: - case TOKEN_SQUOTE: - // TODO 위 4개 토큰에 대해서 추가 구현이 필요함. - // 사내에서는 안쓰고 어떻게 구문이 완성되는건지 모르니 일단 skip하자. - throw new OracleConnectionStringException("unsupported token:" + ch); - default: - String literal = parseLiteral(); - addToken(literal, TYPE_LITERAL); - } - } - this.tokenList.add(TOKEN_EOF_OBJECT); - } - - String parseLiteral() { - // literal 의 왼쪽 빈칸을 감는다. - int start = trimLeft(); - - for (position = start; position < connectionString.length(); position++) { - final char ch = connectionString.charAt(position); - switch (ch) { - case TOKEN_EQUAL: - case TOKEN_KEY_START: - case TOKEN_KEY_END: - // literal 의 오른쪽 빈칸을 감는다. - int end = trimRight(position); - // 마지막 토큰을 본것은 다시 리셋해야 되므로 pos를 역으로 치환. - position--; - return connectionString.substring(start, end); - default: - } - } - // 문자열끝까지 옴. - int end = trimRight(position); - return connectionString.substring(start, end); - } - - int trimRight(int index) { - int end = index; - for (; end > 0 ; end--) { - final char ch = connectionString.charAt(end-1); - if (!isWhiteSpace(ch)) { - return end; - } - } - return end; - } - - int trimLeft() { - final int length = connectionString.length(); - int start = position; - for (; start < length; start++) { - final char ch = connectionString.charAt(start); - if (!isWhiteSpace(ch)) { - return start; - } - } - return start; - } - - private void addToken(String tokenString, int type) { - Token token = new Token(tokenString, type); - this.tokenList.add(token); - } - - - private boolean isWhiteSpace(char ch) { - return (ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r'); - } - - - public Token nextToken() { - if (tokenList.size() <= tokenPosition) { - return null; - } - Token token = tokenList.get(tokenPosition); - tokenPosition++; - return token; - } - - public void nextPosition() { - if (tokenList.size() <= tokenPosition) { - return; - } - tokenPosition++; - } - - public Token lookAheadToken() { - if (tokenList.size() <= tokenPosition) { - return null; - } - return tokenList.get(tokenPosition); - } - - public void setPosition(int position) { - this.position = position; - } - - public void checkStartToken() { - Token token = this.nextToken(); - if (token == null) { - throw new OracleConnectionStringException("parse error. token is null"); - } - // 객체를 재활용한므로 == 해도됨 - if (!(token == TOKEN_KEY_START_OBJECT)) { - throw new OracleConnectionStringException("syntax error. Expected token='(' :" + token.getToken()); - } - } - - public void checkEqualToken() { - Token token = this.nextToken(); - if (token == null) { - throw new OracleConnectionStringException("parse error. token is null. Expected token='='"); - } - // 객체를 재활용한므로 == 해도됨 - if (!(token == TOKEN_EQUAL_OBJECT)) { - throw new OracleConnectionStringException("Syntax error. Expected token='=' :" + token.getToken()); - } - return ; - } - - public void checkEndToken() { - Token token = this.nextToken(); - if (token == null) { - throw new OracleConnectionStringException("parse error. token is null. Expected token=')"); - } - // 객체를 재활용한므로 == 해도됨 - if (!(token == TOKEN_KEY_END_OBJECT)) { - throw new OracleConnectionStringException("Syntax error. Expected token=')' :" + token.getToken()); - } - return; - } - - public Token getLiteralToken() { - Token token = this.nextToken(); - if (token == null) { - throw new OracleConnectionStringException("parse error. token is null. Expected token='LITERAL'"); - } - // 객체를 재활용한므로 == 해도됨 - if (!(token.getType() == TYPE_LITERAL)) { - throw new OracleConnectionStringException("Syntax error. Expected token='LITERAL'' :" + token.getToken()); - } - return token; - } - - public Token getLiteralToken(String expectedValue) { - Token token = this.nextToken(); - if (token == null) { - throw new OracleConnectionStringException("parse error. token is null. Expected token='LITERAL'"); - } - // 객체를 재활용한므로 == 해도됨 - if (!(token.getType() == TYPE_LITERAL)) { - throw new OracleConnectionStringException("Syntax error. Expected token='LITERAL' :" + token.getToken()); - } - if (!expectedValue.equals(token.getToken())) { - throw new OracleConnectionStringException("Syntax error. Expected token=" + expectedValue + "' :" + token.getToken()); - } - return token; - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class OracleNetConnectionDescriptorTokenizer { + + public static final char TOKEN_EQUAL = '='; + public static final char TOKEN_KEY_START = '('; + public static final char TOKEN_KEY_END = ')'; + +// 사실 아래 토큰이 더 있음 추후 이슈 발생시 추가로 구현이 필요함. +// 현재는 그냥 지원하지 않는다고 에러나 발생시키자. + private static final char TOKEN_COMMA = ','; + private static final char TOKEN_BKSLASH = '\\'; + private static final char TOKEN_DQUOTE = '"'; + private static final char TOKEN_SQUOTE = '\''; + + public static final int TYPE_KEY_START = 0; + public static final Token TOKEN_KEY_START_OBJECT = new Token(String.valueOf(TOKEN_KEY_START), TYPE_KEY_START); + + public static final int TYPE_KEY_END = 1; + public static final Token TOKEN_KEY_END_OBJECT = new Token(String.valueOf(TOKEN_KEY_END), TYPE_KEY_END); + + public static final int TYPE_EQUAL = 2; + public static final Token TOKEN_EQUAL_OBJECT = new Token(String.valueOf(TOKEN_EQUAL), TYPE_EQUAL); + + public static final int TYPE_LITERAL = 3; + + public static final int TYPE_EOF = -1; + public static final Token TOKEN_EOF_OBJECT = new Token("EOF", TYPE_EOF); + + private final List tokenList = new ArrayList(); + private int tokenPosition = 0; + + private final String connectionString; + private int position = 0; + + public OracleNetConnectionDescriptorTokenizer(String connectionString) { + if (connectionString == null) { + throw new NullPointerException("connectionString"); + } + this.connectionString = connectionString; + } + + public void parse() { + final int length = connectionString.length(); + + for (; position < length; position++) { + final char ch = connectionString.charAt(position); + if (isWhiteSpace(ch)) { + continue; + } + + switch (ch) { + case TOKEN_KEY_START: + this.tokenList.add(TOKEN_KEY_START_OBJECT); + break; + case TOKEN_EQUAL: + this.tokenList.add(TOKEN_EQUAL_OBJECT); + break; + case TOKEN_KEY_END: + this.tokenList.add(TOKEN_KEY_END_OBJECT); + break; + case TOKEN_COMMA: + case TOKEN_BKSLASH: + case TOKEN_DQUOTE: + case TOKEN_SQUOTE: + // TODO 위 4개 토큰에 대해서 추가 구현이 필요함. + // 사내에서는 안쓰고 어떻게 구문이 완성되는건지 모르니 일단 skip하자. + throw new OracleConnectionStringException("unsupported token:" + ch); + default: + String literal = parseLiteral(); + addToken(literal, TYPE_LITERAL); + } + } + this.tokenList.add(TOKEN_EOF_OBJECT); + } + + String parseLiteral() { + // literal 의 왼쪽 빈칸을 감는다. + int start = trimLeft(); + + for (position = start; position < connectionString.length(); position++) { + final char ch = connectionString.charAt(position); + switch (ch) { + case TOKEN_EQUAL: + case TOKEN_KEY_START: + case TOKEN_KEY_END: + // literal 의 오른쪽 빈칸을 감는다. + int end = trimRight(position); + // 마지막 토큰을 본것은 다시 리셋해야 되므로 pos를 역으로 치환. + position--; + return connectionString.substring(start, end); + default: + } + } + // 문자열끝까지 옴. + int end = trimRight(position); + return connectionString.substring(start, end); + } + + int trimRight(int index) { + int end = index; + for (; end > 0 ; end--) { + final char ch = connectionString.charAt(end-1); + if (!isWhiteSpace(ch)) { + return end; + } + } + return end; + } + + int trimLeft() { + final int length = connectionString.length(); + int start = position; + for (; start < length; start++) { + final char ch = connectionString.charAt(start); + if (!isWhiteSpace(ch)) { + return start; + } + } + return start; + } + + private void addToken(String tokenString, int type) { + Token token = new Token(tokenString, type); + this.tokenList.add(token); + } + + + private boolean isWhiteSpace(char ch) { + return (ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r'); + } + + + public Token nextToken() { + if (tokenList.size() <= tokenPosition) { + return null; + } + Token token = tokenList.get(tokenPosition); + tokenPosition++; + return token; + } + + public void nextPosition() { + if (tokenList.size() <= tokenPosition) { + return; + } + tokenPosition++; + } + + public Token lookAheadToken() { + if (tokenList.size() <= tokenPosition) { + return null; + } + return tokenList.get(tokenPosition); + } + + public void setPosition(int position) { + this.position = position; + } + + public void checkStartToken() { + Token token = this.nextToken(); + if (token == null) { + throw new OracleConnectionStringException("parse error. token is null"); + } + // 객체를 재활용한므로 == 해도됨 + if (!(token == TOKEN_KEY_START_OBJECT)) { + throw new OracleConnectionStringException("syntax error. Expected token='(' :" + token.getToken()); + } + } + + public void checkEqualToken() { + Token token = this.nextToken(); + if (token == null) { + throw new OracleConnectionStringException("parse error. token is null. Expected token='='"); + } + // 객체를 재활용한므로 == 해도됨 + if (!(token == TOKEN_EQUAL_OBJECT)) { + throw new OracleConnectionStringException("Syntax error. Expected token='=' :" + token.getToken()); + } + return ; + } + + public void checkEndToken() { + Token token = this.nextToken(); + if (token == null) { + throw new OracleConnectionStringException("parse error. token is null. Expected token=')"); + } + // 객체를 재활용한므로 == 해도됨 + if (!(token == TOKEN_KEY_END_OBJECT)) { + throw new OracleConnectionStringException("Syntax error. Expected token=')' :" + token.getToken()); + } + return; + } + + public Token getLiteralToken() { + Token token = this.nextToken(); + if (token == null) { + throw new OracleConnectionStringException("parse error. token is null. Expected token='LITERAL'"); + } + // 객체를 재활용한므로 == 해도됨 + if (!(token.getType() == TYPE_LITERAL)) { + throw new OracleConnectionStringException("Syntax error. Expected token='LITERAL'' :" + token.getToken()); + } + return token; + } + + public Token getLiteralToken(String expectedValue) { + Token token = this.nextToken(); + if (token == null) { + throw new OracleConnectionStringException("parse error. token is null. Expected token='LITERAL'"); + } + // 객체를 재활용한므로 == 해도됨 + if (!(token.getType() == TYPE_LITERAL)) { + throw new OracleConnectionStringException("Syntax error. Expected token='LITERAL' :" + token.getToken()); + } + if (!expectedValue.equals(token.getToken())) { + throw new OracleConnectionStringException("Syntax error. Expected token=" + expectedValue + "' :" + token.getToken()); + } + return token; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Token.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Token.java index 69666035449a..6f47ad6d5bd1 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Token.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/Token.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -/** - * @author emeroad - */ -public class Token { - - private String token; - private int type; - - public Token(String token, int type) { - this.token = token; - this.type = type; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("Token"); - sb.append("{token='").append(token).append('\''); - sb.append(", type=").append(type); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +/** + * @author emeroad + */ +public class Token { + + private String token; + private int type; + + public Token(String token, int type) { + this.token = token; + this.type = type; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("Token"); + sb.append("{token='").append(token).append('\''); + sb.append(", type=").append(type); + sb.append('}'); + return sb.toString(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/method/EmptyMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/method/EmptyMethodFilter.java index af19df328236..a287cc6ed93e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/method/EmptyMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/method/EmptyMethodFilter.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.profiler.modifier.method; - -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import javassist.CtMethod; - -/** - * @author emeroad - */ -public class EmptyMethodFilter implements MethodFilter { - public static final MethodFilter FILTER = new EmptyMethodFilter(); - - @Override - public boolean filter(CtMethod ctMethod) { - return ctMethod.isEmpty(); - } -} +package com.nhn.pinpoint.profiler.modifier.method; + +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import javassist.CtMethod; + +/** + * @author emeroad + */ +public class EmptyMethodFilter implements MethodFilter { + public static final MethodFilter FILTER = new EmptyMethodFilter(); + + @Override + public boolean filter(CtMethod ctMethod) { + return ctMethod.isEmpty(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/SqlMapOperationInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/SqlMapOperationInterceptor.java index 2acf909793ee..a257baf4516a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/SqlMapOperationInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/SqlMapOperationInterceptor.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.profiler.modifier.orm; - -import com.nhn.pinpoint.bootstrap.context.RecordableTrace; -import com.nhn.pinpoint.bootstrap.interceptor.*; -import com.nhn.pinpoint.common.ServiceType; - -/** - * @author Hyun Jeong - * @author netspider - */ -public abstract class SqlMapOperationInterceptor extends SpanEventSimpleAroundInterceptor { - - private final ServiceType serviceType; - - public SqlMapOperationInterceptor(ServiceType serviceType, Class childClazz) { - super(childClazz); - this.serviceType = serviceType; - } - - @Override - public final void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { - trace.markBeforeTime(); - } - - @Override - public final void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { - trace.recordServiceType(this.serviceType); - trace.recordException(throwable); - if (args != null && args.length > 0) { - trace.recordApiCachedString(getMethodDescriptor(), (String)args[0], 0); - } else { - trace.recordApi(getMethodDescriptor()); - } - trace.markAfterTime(); - } - -} +package com.nhn.pinpoint.profiler.modifier.orm; + +import com.nhn.pinpoint.bootstrap.context.RecordableTrace; +import com.nhn.pinpoint.bootstrap.interceptor.*; +import com.nhn.pinpoint.common.ServiceType; + +/** + * @author Hyun Jeong + * @author netspider + */ +public abstract class SqlMapOperationInterceptor extends SpanEventSimpleAroundInterceptor { + + private final ServiceType serviceType; + + public SqlMapOperationInterceptor(ServiceType serviceType, Class childClazz) { + super(childClazz); + this.serviceType = serviceType; + } + + @Override + public final void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) { + trace.markBeforeTime(); + } + + @Override + public final void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) { + trace.recordServiceType(this.serviceType); + trace.recordException(throwable); + if (args != null && args.length > 0) { + trace.recordApiCachedString(getMethodDescriptor(), (String)args[0], 0); + } else { + trace.recordApi(getMethodDescriptor()); + } + trace.markAfterTime(); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/IbatisClientModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/IbatisClientModifier.java index 1a0b580a0345..d29cb92fee4d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/IbatisClientModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/IbatisClientModifier.java @@ -1,59 +1,59 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis; - -import java.security.ProtectionDomain; -import java.util.List; - -import org.slf4j.Logger; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.Method; -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisSqlMapOperationInterceptor; -import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisScope; -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * Base class for modifying iBatis client classes - * - * @author Hyun Jeong - */ -public abstract class IbatisClientModifier extends AbstractModifier { - - private static final ServiceType serviceType = ServiceType.IBATIS; - private static final DepthScope scope = IbatisScope.SCOPE; - - protected Logger logger; - - protected abstract MethodFilter getIbatisApiMethodFilter(); - - public IbatisClientModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - @Override - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifying. {}", javassistClassName); - } - byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass ibatisClientImpl = byteCodeInstrumentor.getClass(javassistClassName); - List declaredMethods = ibatisClientImpl.getDeclaredMethods(getIbatisApiMethodFilter()); - - for (Method method : declaredMethods) { - Interceptor ibatisApiInterceptor = new IbatisSqlMapOperationInterceptor(serviceType); - ibatisClientImpl.addScopeInterceptor(method.getMethodName(), method.getMethodParams(), ibatisApiInterceptor, scope); - } - - return ibatisClientImpl.toBytecode(); - } catch (Throwable e) { - this.logger.warn("{} modifier error. Cause:{}", javassistClassName, e.getMessage(), e); - return null; - } - } -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis; + +import java.security.ProtectionDomain; +import java.util.List; + +import org.slf4j.Logger; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.Method; +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisSqlMapOperationInterceptor; +import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisScope; +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * Base class for modifying iBatis client classes + * + * @author Hyun Jeong + */ +public abstract class IbatisClientModifier extends AbstractModifier { + + private static final ServiceType serviceType = ServiceType.IBATIS; + private static final DepthScope scope = IbatisScope.SCOPE; + + protected Logger logger; + + protected abstract MethodFilter getIbatisApiMethodFilter(); + + public IbatisClientModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + @Override + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifying. {}", javassistClassName); + } + byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass ibatisClientImpl = byteCodeInstrumentor.getClass(javassistClassName); + List declaredMethods = ibatisClientImpl.getDeclaredMethods(getIbatisApiMethodFilter()); + + for (Method method : declaredMethods) { + Interceptor ibatisApiInterceptor = new IbatisSqlMapOperationInterceptor(serviceType); + ibatisClientImpl.addScopeInterceptor(method.getMethodName(), method.getMethodParams(), ibatisApiInterceptor, scope); + } + + return ibatisClientImpl.toBytecode(); + } catch (Throwable e) { + this.logger.warn("{} modifier error. Cause:{}", javassistClassName, e.getMessage(), e); + return null; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifier.java index 53d321db0979..f97247ea2e0f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifier.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter.SqlMapClientMethodFilter; - -/** - * iBatis SqlMapClientImpl Modifier - *

- * Hooks onto com.ibatis.sqlmap.engine.SqlMapClientImpl - *

- * - * @author Hyun Jeong - */ -public final class SqlMapClientImplModifier extends IbatisClientModifier { - - private static final MethodFilter sqlMapClientMethodFilter = new SqlMapClientMethodFilter(); - - public static final String TARGET_CLASS_NAME = "com/ibatis/sqlmap/engine/impl/SqlMapClientImpl"; - - public SqlMapClientImplModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return TARGET_CLASS_NAME; - } - - - @Override - protected MethodFilter getIbatisApiMethodFilter() { - return sqlMapClientMethodFilter; - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter.SqlMapClientMethodFilter; + +/** + * iBatis SqlMapClientImpl Modifier + *

+ * Hooks onto com.ibatis.sqlmap.engine.SqlMapClientImpl + *

+ * + * @author Hyun Jeong + */ +public final class SqlMapClientImplModifier extends IbatisClientModifier { + + private static final MethodFilter sqlMapClientMethodFilter = new SqlMapClientMethodFilter(); + + public static final String TARGET_CLASS_NAME = "com/ibatis/sqlmap/engine/impl/SqlMapClientImpl"; + + public SqlMapClientImplModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return TARGET_CLASS_NAME; + } + + + @Override + protected MethodFilter getIbatisApiMethodFilter() { + return sqlMapClientMethodFilter; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifier.java index 88432dcdb387..6d631958b102 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifier.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter.SqlMapSessionMethodFilter; - -/** - * iBatis SqlMapSessionImpl Modifier - *

- * Hooks onto com.ibatis.sqlmap.engine.SqlMapSessionImpl - *

- * - * @author Hyun Jeong - */ -public final class SqlMapSessionImplModifier extends IbatisClientModifier { - - private static final MethodFilter sqlMapSessionMethodFilter = new SqlMapSessionMethodFilter(); - - public static final String TARGET_CLASS_NAME = "com/ibatis/sqlmap/engine/impl/SqlMapSessionImpl"; - - public SqlMapSessionImplModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return TARGET_CLASS_NAME; - } - - - @Override - protected MethodFilter getIbatisApiMethodFilter() { - return sqlMapSessionMethodFilter; - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter.SqlMapSessionMethodFilter; + +/** + * iBatis SqlMapSessionImpl Modifier + *

+ * Hooks onto com.ibatis.sqlmap.engine.SqlMapSessionImpl + *

+ * + * @author Hyun Jeong + */ +public final class SqlMapSessionImplModifier extends IbatisClientModifier { + + private static final MethodFilter sqlMapSessionMethodFilter = new SqlMapSessionMethodFilter(); + + public static final String TARGET_CLASS_NAME = "com/ibatis/sqlmap/engine/impl/SqlMapSessionImpl"; + + public SqlMapSessionImplModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return TARGET_CLASS_NAME; + } + + + @Override + protected MethodFilter getIbatisApiMethodFilter() { + return sqlMapSessionMethodFilter; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisInterfaceApi.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisInterfaceApi.java index a197579d341b..18579da91544 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisInterfaceApi.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisInterfaceApi.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; - -/** - * @author Hyun Jeong - */ -public final class IbatisInterfaceApi { - - private IbatisInterfaceApi() {} - - private static final String[] sqlMapExecutorApis = { - "insert", - "delete", - "update", - "queryForList", - "queryForMap", - "queryForObject", - "queryForPaginatedList", - "queryForRowHandler" - }; -// private static final String[] sqlMapTransactionManagerApis = { -// "startTransaction", -// "endTransaction", -// "commitTransaction", -// "getDataSource", -// "getUserConnection", -// "getCurrentConnection", -// }; -// static final String[] sqlMapSessionApis = ArrayUtils.addAll( -// ArrayUtils.addAll(sqlMapExecutorApis, sqlMapTransactionManagerApis), -// "close" -// ); - static final String[] sqlMapSessionApis = sqlMapExecutorApis; -// static final String[] sqlMapClientApis = ArrayUtils.addAll( -// sqlMapExecutorApis, -// sqlMapTransactionManagerApis -// ); - static final String[] sqlMapClientApis = sqlMapExecutorApis; - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; + +/** + * @author Hyun Jeong + */ +public final class IbatisInterfaceApi { + + private IbatisInterfaceApi() {} + + private static final String[] sqlMapExecutorApis = { + "insert", + "delete", + "update", + "queryForList", + "queryForMap", + "queryForObject", + "queryForPaginatedList", + "queryForRowHandler" + }; +// private static final String[] sqlMapTransactionManagerApis = { +// "startTransaction", +// "endTransaction", +// "commitTransaction", +// "getDataSource", +// "getUserConnection", +// "getCurrentConnection", +// }; +// static final String[] sqlMapSessionApis = ArrayUtils.addAll( +// ArrayUtils.addAll(sqlMapExecutorApis, sqlMapTransactionManagerApis), +// "close" +// ); + static final String[] sqlMapSessionApis = sqlMapExecutorApis; +// static final String[] sqlMapClientApis = ArrayUtils.addAll( +// sqlMapExecutorApis, +// sqlMapTransactionManagerApis +// ); + static final String[] sqlMapClientApis = sqlMapExecutorApis; + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisMethodFilter.java index 9313341d5cd3..ce2cf42a7a1f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/IbatisMethodFilter.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; - -import java.lang.reflect.Modifier; - -import javassist.CtClass; -import javassist.CtMethod; -import javassist.NotFoundException; - -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; - -/** - * @author Hyun Jeong - */ -public abstract class IbatisMethodFilter implements MethodFilter { - - private static final boolean TRACK = false; - private static final boolean DO_NOT_TRACK = true; - - protected abstract boolean shouldTrackMethod(String methodName); - - @Override - public boolean filter(CtMethod ctMethod) { - final int modifiers = ctMethod.getModifiers(); - if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - return DO_NOT_TRACK; - } - return filterApiForTracking(ctMethod); - } - - private boolean filterApiForTracking(CtMethod ctMethod) { - if (!shouldTrackMethod(ctMethod.getName())) { - return DO_NOT_TRACK; - } - try { - final int parameterIndexToMatch = 0; // 0-based index - CtClass[] parameterTypes = ctMethod.getParameterTypes(); - if (parameterTypes != null && parameterTypes.length > 0) { - return parameterTypeMatches(parameterTypes, parameterIndexToMatch, String.class); - } else { - return TRACK; - } - } catch (NotFoundException e) { - return DO_NOT_TRACK; - } - } - - private boolean parameterTypeMatches(final CtClass[] parameterTypes, final int parameterIndex, final Class parameterType) { - if (parameterTypes == null || parameterTypes.length <= parameterIndex) { - return DO_NOT_TRACK; - } - if (parameterType.getName().equals(parameterTypes[parameterIndex].getName())) { - return TRACK; - } - return DO_NOT_TRACK; - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; + +import java.lang.reflect.Modifier; + +import javassist.CtClass; +import javassist.CtMethod; +import javassist.NotFoundException; + +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; + +/** + * @author Hyun Jeong + */ +public abstract class IbatisMethodFilter implements MethodFilter { + + private static final boolean TRACK = false; + private static final boolean DO_NOT_TRACK = true; + + protected abstract boolean shouldTrackMethod(String methodName); + + @Override + public boolean filter(CtMethod ctMethod) { + final int modifiers = ctMethod.getModifiers(); + if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return DO_NOT_TRACK; + } + return filterApiForTracking(ctMethod); + } + + private boolean filterApiForTracking(CtMethod ctMethod) { + if (!shouldTrackMethod(ctMethod.getName())) { + return DO_NOT_TRACK; + } + try { + final int parameterIndexToMatch = 0; // 0-based index + CtClass[] parameterTypes = ctMethod.getParameterTypes(); + if (parameterTypes != null && parameterTypes.length > 0) { + return parameterTypeMatches(parameterTypes, parameterIndexToMatch, String.class); + } else { + return TRACK; + } + } catch (NotFoundException e) { + return DO_NOT_TRACK; + } + } + + private boolean parameterTypeMatches(final CtClass[] parameterTypes, final int parameterIndex, final Class parameterType) { + if (parameterTypes == null || parameterTypes.length <= parameterIndex) { + return DO_NOT_TRACK; + } + if (parameterType.getName().equals(parameterTypes[parameterIndex].getName())) { + return TRACK; + } + return DO_NOT_TRACK; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapClientMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapClientMethodFilter.java index 8c006732def8..f99a890dba1f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapClientMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapClientMethodFilter.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * @author Hyun Jeong - */ -public class SqlMapClientMethodFilter extends IbatisMethodFilter { - - private static final Set WHITE_LIST_API = createWhiteListApi(); - - private static Set createWhiteListApi() { - return new HashSet(Arrays.asList(IbatisInterfaceApi.sqlMapClientApis)); - } - - protected final boolean shouldTrackMethod(String methodName) { - return WHITE_LIST_API.contains(methodName); - } -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Hyun Jeong + */ +public class SqlMapClientMethodFilter extends IbatisMethodFilter { + + private static final Set WHITE_LIST_API = createWhiteListApi(); + + private static Set createWhiteListApi() { + return new HashSet(Arrays.asList(IbatisInterfaceApi.sqlMapClientApis)); + } + + protected final boolean shouldTrackMethod(String methodName) { + return WHITE_LIST_API.contains(methodName); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapSessionMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapSessionMethodFilter.java index 38144592cf86..58d52174fd24 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapSessionMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/filter/SqlMapSessionMethodFilter.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * @author Hyun Jeong - */ -public class SqlMapSessionMethodFilter extends IbatisMethodFilter { - - private static final Set WHITE_LIST_API = createWhiteListApi(); - - private static Set createWhiteListApi() { - return new HashSet(Arrays.asList(IbatisInterfaceApi.sqlMapSessionApis)); - } - - @Override - protected boolean shouldTrackMethod(String methodName) { - return WHITE_LIST_API.contains(methodName); - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Hyun Jeong + */ +public class SqlMapSessionMethodFilter extends IbatisMethodFilter { + + private static final Set WHITE_LIST_API = createWhiteListApi(); + + private static Set createWhiteListApi() { + return new HashSet(Arrays.asList(IbatisInterfaceApi.sqlMapSessionApis)); + } + + @Override + protected boolean shouldTrackMethod(String methodName) { + return WHITE_LIST_API.contains(methodName); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisScope.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisScope.java index fceb5d6f5aa6..a0fc8c2ce824 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisScope.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisScope.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor; - -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * @author Hyun Jeong - */ -public class IbatisScope { - public static final DepthScope SCOPE = new DepthScope("iBatisScope"); - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor; + +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * @author Hyun Jeong + */ +public class IbatisScope { + public static final DepthScope SCOPE = new DepthScope("iBatisScope"); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisSqlMapOperationInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisSqlMapOperationInterceptor.java index 17d0ddc15779..3d2e7452a42a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisSqlMapOperationInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/interceptor/IbatisSqlMapOperationInterceptor.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.modifier.orm.SqlMapOperationInterceptor; - -/** - * @author Hyun Jeong - * @author netspider - */ -public class IbatisSqlMapOperationInterceptor extends SqlMapOperationInterceptor { - - public IbatisSqlMapOperationInterceptor(ServiceType serviceType) { - super(serviceType, IbatisSqlMapOperationInterceptor.class); - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.modifier.orm.SqlMapOperationInterceptor; + +/** + * @author Hyun Jeong + * @author netspider + */ +public class IbatisSqlMapOperationInterceptor extends SqlMapOperationInterceptor { + + public IbatisSqlMapOperationInterceptor(ServiceType serviceType) { + super(serviceType, IbatisSqlMapOperationInterceptor.class); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifier.java index a08b1f466513..638936d2212e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifier.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis; - -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; - -/** - * @author Hyun Jeong - */ -public class DefaultSqlSessionModifier extends MyBatisClientModifier { - - public static final String TARGET_CLASS_NAME = "org/apache/ibatis/session/defaults/DefaultSqlSession"; - - public DefaultSqlSessionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return TARGET_CLASS_NAME; - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis; + +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; + +/** + * @author Hyun Jeong + */ +public class DefaultSqlSessionModifier extends MyBatisClientModifier { + + public static final String TARGET_CLASS_NAME = "org/apache/ibatis/session/defaults/DefaultSqlSession"; + + public DefaultSqlSessionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return TARGET_CLASS_NAME; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifier.java index ada45811754d..613e5bc34a4e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifier.java @@ -1,62 +1,62 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis; - -import java.security.ProtectionDomain; -import java.util.List; - -import org.slf4j.Logger; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.Method; -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.orm.mybatis.filter.SqlSessionMethodFilter; -import com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor.MyBatisScope; -import com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor.MyBatisSqlMapOperationInterceptor; -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * @author Hyun Jeong - */ -public abstract class MyBatisClientModifier extends AbstractModifier { - - private static final ServiceType serviceType = ServiceType.MYBATIS; - private static final DepthScope scope = MyBatisScope.SCOPE; - private static final MethodFilter sqlSessionMethodFilter = new SqlSessionMethodFilter(); - protected Logger logger; - - - protected MethodFilter getSqlSessionMethodFilter() { - return sqlSessionMethodFilter; - } - - public MyBatisClientModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - @Override - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifying. {}", javassistClassName); - } - byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass myBatisClientImpl = byteCodeInstrumentor.getClass(javassistClassName); - List declaredMethods = myBatisClientImpl.getDeclaredMethods(getSqlSessionMethodFilter()); - for (Method method : declaredMethods) { - Interceptor sqlSessionInterceptor = new MyBatisSqlMapOperationInterceptor(serviceType); - myBatisClientImpl.addScopeInterceptor(method.getMethodName(), method.getMethodParams(), sqlSessionInterceptor, scope); - } - - return myBatisClientImpl.toBytecode(); - } catch (Throwable e) { - logger.warn("{} modifier error. Cause:{}", javassistClassName, e.getMessage(), e); - return null; - } - } - - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis; + +import java.security.ProtectionDomain; +import java.util.List; + +import org.slf4j.Logger; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.Method; +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.orm.mybatis.filter.SqlSessionMethodFilter; +import com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor.MyBatisScope; +import com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor.MyBatisSqlMapOperationInterceptor; +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * @author Hyun Jeong + */ +public abstract class MyBatisClientModifier extends AbstractModifier { + + private static final ServiceType serviceType = ServiceType.MYBATIS; + private static final DepthScope scope = MyBatisScope.SCOPE; + private static final MethodFilter sqlSessionMethodFilter = new SqlSessionMethodFilter(); + protected Logger logger; + + + protected MethodFilter getSqlSessionMethodFilter() { + return sqlSessionMethodFilter; + } + + public MyBatisClientModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + @Override + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifying. {}", javassistClassName); + } + byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass myBatisClientImpl = byteCodeInstrumentor.getClass(javassistClassName); + List declaredMethods = myBatisClientImpl.getDeclaredMethods(getSqlSessionMethodFilter()); + for (Method method : declaredMethods) { + Interceptor sqlSessionInterceptor = new MyBatisSqlMapOperationInterceptor(serviceType); + myBatisClientImpl.addScopeInterceptor(method.getMethodName(), method.getMethodParams(), sqlSessionInterceptor, scope); + } + + return myBatisClientImpl.toBytecode(); + } catch (Throwable e) { + logger.warn("{} modifier error. Cause:{}", javassistClassName, e.getMessage(), e); + return null; + } + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifier.java index cc87e1c1d837..5d535f6da968 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifier.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; - -/** - * @author Hyun Jeong - */ -public class SqlSessionTemplateModifier extends MyBatisClientModifier { - - public static final String TARGET_CLASS_NAME = "org/mybatis/spring/SqlSessionTemplate"; - - public SqlSessionTemplateModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - this.logger = LoggerFactory.getLogger(this.getClass()); - } - - @Override - public String getTargetClass() { - return TARGET_CLASS_NAME; - } - - - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; + +/** + * @author Hyun Jeong + */ +public class SqlSessionTemplateModifier extends MyBatisClientModifier { + + public static final String TARGET_CLASS_NAME = "org/mybatis/spring/SqlSessionTemplate"; + + public SqlSessionTemplateModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + this.logger = LoggerFactory.getLogger(this.getClass()); + } + + @Override + public String getTargetClass() { + return TARGET_CLASS_NAME; + } + + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/filter/SqlSessionMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/filter/SqlSessionMethodFilter.java index fc2c7e7e0afe..e2f37588f431 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/filter/SqlSessionMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/filter/SqlSessionMethodFilter.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis.filter; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import javassist.CtMethod; - -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; - -/** - * @author Hyun Jeong - */ -public class SqlSessionMethodFilter implements MethodFilter { - - private static final boolean TRACK = false; - private static final boolean DO_NOT_TRACK = true; - - private static final Set WHITE_LIST_API = createWhiteListApi(); - - private static Set createWhiteListApi() { - return new HashSet(Arrays.asList( - "selectOne", - "selectList", - "selectMap", - "select", - "insert", - "update", - "delete" -// "commit", -// "rollback", -// "flushStatements", -// "close", -// "getConfiguration", -// "getMapper", -// "getConnection" - )); - } - - @Override - public boolean filter(CtMethod ctMethod) { - if (WHITE_LIST_API.contains(ctMethod.getName())) { - return TRACK; - } - return DO_NOT_TRACK; - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis.filter; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import javassist.CtMethod; + +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; + +/** + * @author Hyun Jeong + */ +public class SqlSessionMethodFilter implements MethodFilter { + + private static final boolean TRACK = false; + private static final boolean DO_NOT_TRACK = true; + + private static final Set WHITE_LIST_API = createWhiteListApi(); + + private static Set createWhiteListApi() { + return new HashSet(Arrays.asList( + "selectOne", + "selectList", + "selectMap", + "select", + "insert", + "update", + "delete" +// "commit", +// "rollback", +// "flushStatements", +// "close", +// "getConfiguration", +// "getMapper", +// "getConnection" + )); + } + + @Override + public boolean filter(CtMethod ctMethod) { + if (WHITE_LIST_API.contains(ctMethod.getName())) { + return TRACK; + } + return DO_NOT_TRACK; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisScope.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisScope.java index 792ca3b8e509..64d42aa66e73 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisScope.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisScope.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor; - -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * @author Hyun Jeong - */ -public class MyBatisScope { - public static final DepthScope SCOPE = new DepthScope("myBatisScope"); - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor; + +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * @author Hyun Jeong + */ +public class MyBatisScope { + public static final DepthScope SCOPE = new DepthScope("myBatisScope"); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisSqlMapOperationInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisSqlMapOperationInterceptor.java index 8539993b4a0e..d2347818aab4 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisSqlMapOperationInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/interceptor/MyBatisSqlMapOperationInterceptor.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.modifier.orm.SqlMapOperationInterceptor; - -/** - * @author Hyun Jeong - * @author netspider - */ -public class MyBatisSqlMapOperationInterceptor extends SqlMapOperationInterceptor { - - public MyBatisSqlMapOperationInterceptor(ServiceType serviceType) { - super(serviceType, MyBatisSqlMapOperationInterceptor.class); - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis.interceptor; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.modifier.orm.SqlMapOperationInterceptor; + +/** + * @author Hyun Jeong + * @author netspider + */ +public class MyBatisSqlMapOperationInterceptor extends SqlMapOperationInterceptor { + + public MyBatisSqlMapOperationInterceptor(ServiceType serviceType) { + super(serviceType, MyBatisSqlMapOperationInterceptor.class); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/spring/orm/ibatis/SqlMapClientTemplateModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/spring/orm/ibatis/SqlMapClientTemplateModifier.java index 28439ae1da54..a1a63c51e418 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/spring/orm/ibatis/SqlMapClientTemplateModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/spring/orm/ibatis/SqlMapClientTemplateModifier.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.profiler.modifier.spring.orm.ibatis; - -import java.security.ProtectionDomain; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.Method; -import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter.SqlMapClientMethodFilter; -import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisScope; -import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisSqlMapOperationInterceptor; -import com.nhn.pinpoint.profiler.util.DepthScope; - -/** - * SqlMapClientTemplate Modifier - *

- * Hooks onto org.springframework.orm.ibatis.SqlMapClientTemplate - *

- * - * @author Hyun Jeong - * @see com.ibatis.sqlmap.client.SqlMapExecutor - */ -public final class SqlMapClientTemplateModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private static final ServiceType serviceType = ServiceType.SPRING_ORM_IBATIS; - private static final DepthScope scope = IbatisScope.SCOPE; - private static final MethodFilter sqlMapClientMethodFilter = new SqlMapClientMethodFilter(); - - public static final String TARGET_CLASS_NAME = "org/springframework/orm/ibatis/SqlMapClientTemplate"; - - public SqlMapClientTemplateModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - @Override - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (this.logger.isInfoEnabled()) { - this.logger.info("Modifying. {}", javassistClassName); - } - byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - try { - InstrumentClass sqlMapClientTemplate = byteCodeInstrumentor.getClass(javassistClassName); - List declaredMethods = sqlMapClientTemplate.getDeclaredMethods(sqlMapClientMethodFilter); - - for (Method method : declaredMethods) { - Interceptor sqlMapClientTemplateInterceptor = new IbatisSqlMapOperationInterceptor(serviceType); - sqlMapClientTemplate.addScopeInterceptor(method.getMethodName(), method.getMethodParams(), sqlMapClientTemplateInterceptor, scope); - } - - return sqlMapClientTemplate.toBytecode(); - } catch (Throwable e) { - this.logger.warn("{} modifier error. Cause:{}", javassistClassName, e.getMessage(), e); - return null; - } - } - - @Override - public String getTargetClass() { - return TARGET_CLASS_NAME; - } - -} +package com.nhn.pinpoint.profiler.modifier.spring.orm.ibatis; + +import java.security.ProtectionDomain; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.interceptor.bci.Method; +import com.nhn.pinpoint.profiler.interceptor.bci.MethodFilter; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.orm.ibatis.filter.SqlMapClientMethodFilter; +import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisScope; +import com.nhn.pinpoint.profiler.modifier.orm.ibatis.interceptor.IbatisSqlMapOperationInterceptor; +import com.nhn.pinpoint.profiler.util.DepthScope; + +/** + * SqlMapClientTemplate Modifier + *

+ * Hooks onto org.springframework.orm.ibatis.SqlMapClientTemplate + *

+ * + * @author Hyun Jeong + * @see com.ibatis.sqlmap.client.SqlMapExecutor + */ +public final class SqlMapClientTemplateModifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final ServiceType serviceType = ServiceType.SPRING_ORM_IBATIS; + private static final DepthScope scope = IbatisScope.SCOPE; + private static final MethodFilter sqlMapClientMethodFilter = new SqlMapClientMethodFilter(); + + public static final String TARGET_CLASS_NAME = "org/springframework/orm/ibatis/SqlMapClientTemplate"; + + public SqlMapClientTemplateModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + @Override + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (this.logger.isInfoEnabled()) { + this.logger.info("Modifying. {}", javassistClassName); + } + byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass sqlMapClientTemplate = byteCodeInstrumentor.getClass(javassistClassName); + List declaredMethods = sqlMapClientTemplate.getDeclaredMethods(sqlMapClientMethodFilter); + + for (Method method : declaredMethods) { + Interceptor sqlMapClientTemplateInterceptor = new IbatisSqlMapOperationInterceptor(serviceType); + sqlMapClientTemplate.addScopeInterceptor(method.getMethodName(), method.getMethodParams(), sqlMapClientTemplateInterceptor, scope); + } + + return sqlMapClientTemplate.toBytecode(); + } catch (Throwable e) { + this.logger.warn("{} modifier error. Cause:{}", javassistClassName, e.getMessage(), e); + return null; + } + } + + @Override + public String getTargetClass() { + return TARGET_CLASS_NAME; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/CatalinaModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/CatalinaModifier.java deleted file mode 100644 index 5490bb671424..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/CatalinaModifier.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat; - -import java.security.ProtectionDomain; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.CatalinaAwaitInterceptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Tomcat startup정보를 Pinpoint서버로 전송하는 코드를 호출하기위한 modifier - * - * @author netspider - */ -public class CatalinaModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public CatalinaModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "org/apache/catalina/startup/Catalina"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - return changeMethod(javassistClassName, classFileBuffer); - } - - public byte[] changeMethod(String javassistClassName, byte[] classfileBuffer) { - try { - /** - * Tomcat startup완료되면 Catalina.await()을 호출하고 stop되기를 기다린다. 이 때 - * await하기 전에 서버가 시작되면서 수집된 WAS정보를 Pinpoint 서버로 전송한다. - */ - InstrumentClass aClass = this.byteCodeInstrumentor.getClass(javassistClassName); - - CatalinaAwaitInterceptor catalinaAwaitInterceptor = new CatalinaAwaitInterceptor(agent); - aClass.addInterceptor("await", null, catalinaAwaitInterceptor); - -// // Tomcat 7 -// if (aClass.hasDeclaredMethod("start", null) && aClass.hasDeclaredMethod("stop", null)) { -// LifeCycleEventListener lifeCycleEventListener = new LifeCycleEventListener(agent); -// aClass.addInterceptor("start", null, new CatalinaStartInterceptor(lifeCycleEventListener)); -// aClass.addInterceptor("stop", null, new CatalinaStopInterceptor(lifeCycleEventListener)); -// } - - if (this.logger.isInfoEnabled()) { - this.logger.info("{} class is converted.", javassistClassName); - } - - return aClass.toBytecode(); - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn(e.getMessage(), e); - } - } - return null; - } -} \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/StandardServiceModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/StandardServiceModifier.java new file mode 100644 index 000000000000..ac82a7865688 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/StandardServiceModifier.java @@ -0,0 +1,72 @@ +package com.nhn.pinpoint.profiler.modifier.tomcat; + +import java.security.ProtectionDomain; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.profiler.LifeCycleEventListener; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; +import com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.StandardServiceStartInterceptor; +import com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.StandardServiceStopInterceptor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author cowboy93, netspider + * @author hyungil.jeong + */ +public class StandardServiceModifier extends AbstractModifier { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public StandardServiceModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "org/apache/catalina/core/StandardService"; + } + + @Override + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isInfoEnabled()) { + logger.info("Modifying. {}", javassistClassName); + } +// byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + + try { + InstrumentClass standardService = byteCodeInstrumentor.getClass(javassistClassName); + + LifeCycleEventListener lifeCycleEventListener = new LifeCycleEventListener(agent); + Interceptor standardServiceStartInterceptor = new StandardServiceStartInterceptor(lifeCycleEventListener); + Interceptor standardServiceStopInterceptor = new StandardServiceStopInterceptor(lifeCycleEventListener); + + boolean isHooked = false; + // Tomcat 6 - org.apache.catalina.core.StandardService.start(), stop() + if (isHooked = (standardService.hasDeclaredMethod("start", null) && standardService.hasDeclaredMethod("stop", null))) { + standardService.addInterceptor("start", null, standardServiceStartInterceptor); + standardService.addInterceptor("stop", null, standardServiceStopInterceptor); + } + // Tomcat 7, 8 - org.apache.catalina.core.StandardService.startInternal(), stopInternal() + else if (isHooked = (standardService.hasDeclaredMethod("startInternal", null) && standardService.hasDeclaredMethod("stopInternal", null))) { + standardService.addInterceptor("startInternal", null, standardServiceStartInterceptor); + standardService.addInterceptor("stopInternal", null, standardServiceStopInterceptor); + } + + if (isHooked) { + logger.info("{} class is converted.", javassistClassName); + } else { + logger.warn("{} class not converted - start() or startInternal() method not found.", javassistClassName); + } + return standardService.toBytecode(); + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn("modify fail. Cause:" + e.getMessage(), e); + } + } + return null; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/TomcatStandardServiceModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/TomcatStandardServiceModifier.java deleted file mode 100644 index 800f398bf954..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/TomcatStandardServiceModifier.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat; - -import java.security.ProtectionDomain; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.profiler.LifeCycleEventListener; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentClass; -import com.nhn.pinpoint.profiler.interceptor.bci.InstrumentException; -import com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.StandardServiceStartInterceptor; -import com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.StandardServiceStopInterceptor; - -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * When org.apache.catalina.core.StandardService class is loaded in ClassLoader, - * this class modifies methods. - * - * @author cowboy93, netspider - */ -public class TomcatStandardServiceModifier extends AbstractModifier { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - - public TomcatStandardServiceModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - public String getTargetClass() { - return "org/apache/catalina/core/StandardService"; - } - - public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - if (logger.isInfoEnabled()) { - logger.info("Modifing. {}", javassistClassName); - } - byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); - - try { - InstrumentClass standardService = byteCodeInstrumentor.getClass(javassistClassName); - - LifeCycleEventListener lifeCycleEventListener = new LifeCycleEventListener(agent); - - // Tomcat 6 - if (standardService.hasDeclaredMethod("start", null) && standardService.hasDeclaredMethod("stop", null)) { - standardService.addInterceptor("start", null, new StandardServiceStartInterceptor(lifeCycleEventListener)); - standardService.addInterceptor("stop", null, new StandardServiceStopInterceptor(lifeCycleEventListener)); - } - // Tomcat 7 - else if (standardService.hasDeclaredMethod("startInternal", null) && standardService.hasDeclaredMethod("stopInternal", null)) { - standardService.addInterceptor("startInternal", null, new StandardServiceStartInterceptor(lifeCycleEventListener)); - standardService.addInterceptor("stopInternal", null, new StandardServiceStopInterceptor(lifeCycleEventListener)); - } - - return standardService.toBytecode(); - } catch (InstrumentException e) { - logger.warn("modify fail. Cause:" + e.getMessage(), e); - return null; - } - } -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaAwaitInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaAwaitInterceptor.java deleted file mode 100644 index 0f1a01a18fc1..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaAwaitInterceptor.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -import com.nhn.pinpoint.bootstrap.Agent; - -/** - * @author emeroad - */ -public class CatalinaAwaitInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private Agent agent; - - public CatalinaAwaitInterceptor(Agent agent) { - if (agent == null) { - throw new IllegalArgumentException("agent must not be null"); - } - this.agent = agent; - } - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - agent.started(); - // agent.sendStartupInfo(); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - - } -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaStartInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaStartInterceptor.java deleted file mode 100644 index 0bb410daf060..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaStartInterceptor.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -import com.nhn.pinpoint.profiler.LifeCycleEventListener; - -/** - * @author emeroad - */ -public class CatalinaStartInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private LifeCycleEventListener lifeCycleEventListener; - - public CatalinaStartInterceptor(LifeCycleEventListener lifeCycleEventListener) { - this.lifeCycleEventListener = lifeCycleEventListener; - } - - @Override - public void before(Object target, Object[] args) { - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - // if (!InterceptorUtils.isSuccess(result)) { - // return; - // } - lifeCycleEventListener.start(); - } -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaStopInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaStopInterceptor.java deleted file mode 100644 index 18ca29499a5c..000000000000 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/CatalinaStopInterceptor.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.profiler.util.StackTraceUtil; - -import com.nhn.pinpoint.profiler.LifeCycleEventListener; - -/** - * @author emeroad - */ -public class CatalinaStopInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private LifeCycleEventListener lifeCycleEventListener; - - public CatalinaStopInterceptor(LifeCycleEventListener lifeCycleEventListener) { - this.lifeCycleEventListener = lifeCycleEventListener; - } - - @Override - public void before(Object target, Object[] args) { - System.out.println("TOMCAT-STOP"); - StackTraceUtil.printCurrentStackTrace(); - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - // TODO 시작이 실패했을때 stop이 불러 지는가? - // if (!InterceptorUtils.isSuccess(result)) { - // return; - // } - lifeCycleEventListener.stop(); - } -} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/ConnectorInitializeInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/ConnectorInitializeInterceptor.java index b0dc5a0a66fd..4252937f06a3 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/ConnectorInitializeInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/ConnectorInitializeInterceptor.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import org.apache.catalina.connector.Connector; - -/** - * @author emeroad - */ -public class ConnectorInitializeInterceptor implements SimpleAroundInterceptor, TargetClassLoader { - - private PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private Agent agent; - - public ConnectorInitializeInterceptor(Agent agent) { - if (agent == null) { - throw new NullPointerException("agent must not be null"); - } - this.agent = agent; - } - - @Override - public void before(Object target, Object[] args) { - - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - Connector connector = (Connector) target; - agent.addConnector(connector.getProtocol(), connector.getPort()); - - } -} +package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import org.apache.catalina.connector.Connector; + +/** + * @author emeroad + */ +public class ConnectorInitializeInterceptor implements SimpleAroundInterceptor, TargetClassLoader { + + private PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private Agent agent; + + public ConnectorInitializeInterceptor(Agent agent) { + if (agent == null) { + throw new NullPointerException("agent must not be null"); + } + this.agent = agent; + } + + @Override + public void before(Object target, Object[] args) { + + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + Connector connector = (Connector) target; + agent.addConnector(connector.getProtocol(), connector.getPort()); + + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStartInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStartInterceptor.java index 7f0b20d83570..f328f23f3c5f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStartInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStartInterceptor.java @@ -1,38 +1,38 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -import com.nhn.pinpoint.profiler.LifeCycleEventListener; - -/** - * @author emeroad - */ -public class StandardServiceStartInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private LifeCycleEventListener lifeCycleEventListener; - - public StandardServiceStartInterceptor(LifeCycleEventListener lifeCycleEventListener) { - this.lifeCycleEventListener = lifeCycleEventListener; - } - - @Override - public void before(Object target, Object[] args) { - - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - // if (!InterceptorUtils.isSuccess(result)) { - // return; - // } - lifeCycleEventListener.start(); - } -} +package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; + +import com.nhn.pinpoint.profiler.LifeCycleEventListener; + +/** + * @author emeroad + */ +public class StandardServiceStartInterceptor implements SimpleAroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private LifeCycleEventListener lifeCycleEventListener; + + public StandardServiceStartInterceptor(LifeCycleEventListener lifeCycleEventListener) { + this.lifeCycleEventListener = lifeCycleEventListener; + } + + @Override + public void before(Object target, Object[] args) { + + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + // if (!InterceptorUtils.isSuccess(result)) { + // return; + // } + lifeCycleEventListener.start(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStopInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStopInterceptor.java index 3fe7618ed84c..b760b54cd129 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStopInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/tomcat/interceptor/StandardServiceStopInterceptor.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; -import com.nhn.pinpoint.bootstrap.logging.PLogger; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; - -import com.nhn.pinpoint.profiler.LifeCycleEventListener; - -/** - * @author emeroad - */ -public class StandardServiceStopInterceptor implements SimpleAroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - private LifeCycleEventListener lifeCycleEventListener; - - public StandardServiceStopInterceptor(LifeCycleEventListener lifeCycleEventListener) { - this.lifeCycleEventListener = lifeCycleEventListener; - } - - @Override - public void before(Object target, Object[] args) { - - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - if (isDebug) { - logger.afterInterceptor(target, args, result, throwable); - } - // TODO 시작이 실패했을때 stop이 불러 지는가? - // if (!InterceptorUtils.isSuccess(result)) { - // return; - // } - lifeCycleEventListener.stop(); - } -} +package com.nhn.pinpoint.profiler.modifier.tomcat.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor; +import com.nhn.pinpoint.bootstrap.logging.PLogger; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; + +import com.nhn.pinpoint.profiler.LifeCycleEventListener; + +/** + * @author emeroad + */ +public class StandardServiceStopInterceptor implements SimpleAroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private LifeCycleEventListener lifeCycleEventListener; + + public StandardServiceStopInterceptor(LifeCycleEventListener lifeCycleEventListener) { + this.lifeCycleEventListener = lifeCycleEventListener; + } + + @Override + public void before(Object target, Object[] args) { + + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + // TODO 시작이 실패했을때 stop이 불러 지는가? + // if (!InterceptorUtils.isSuccess(result)) { + // return; + // } + lifeCycleEventListener.stop(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadCollector.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadCollector.java index 84bf2d5c3f9b..c25e9975eede 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadCollector.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadCollector.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.cpu; - -import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.*; - -import java.util.Map; - -import com.codahale.metrics.Gauge; -import com.codahale.metrics.Metric; -import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues; -import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.CpuLoadMetricSet; -import com.nhn.pinpoint.thrift.dto.TCpuLoad; - -/** - * @author hyungil.jeong - */ -public class CpuLoadCollector { - - private final Gauge jvmCpuLoadGauge; - private final Gauge systemCpuLoadGauge; - - @SuppressWarnings("unchecked") - public CpuLoadCollector(CpuLoadMetricSet cpuLoadMetricSet) { - if (cpuLoadMetricSet == null) { - throw new NullPointerException("cpuLoadMetricSet must not be null"); - } - Map metrics = cpuLoadMetricSet.getMetrics(); - this.jvmCpuLoadGauge = (Gauge)MetricMonitorValues.getMetric(metrics, CPU_LOAD_JVM, DOUBLE_ZERO); - this.systemCpuLoadGauge = (Gauge)MetricMonitorValues.getMetric(metrics, CPU_LOAD_SYSTEM, DOUBLE_ZERO); - } - - public TCpuLoad collectCpuLoad() { - Double jvmCpuLoad = this.jvmCpuLoadGauge.getValue(); - Double systemCpuLoad = this.systemCpuLoadGauge.getValue(); - if (notCollected(jvmCpuLoad) && notCollected(systemCpuLoad)) { - return null; - } - TCpuLoad cpuLoad = new TCpuLoad(); - if (!notCollected(jvmCpuLoad)) { - cpuLoad.setJvmCpuLoad(jvmCpuLoad); - } - if (!notCollected(systemCpuLoad)) { - cpuLoad.setSystemCpuLoad(systemCpuLoad); - } - return cpuLoad; - } - - private boolean notCollected(double cpuLoad) { - return cpuLoad < 0; - } -} +package com.nhn.pinpoint.profiler.monitor.codahale.cpu; + +import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.*; + +import java.util.Map; + +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Metric; +import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues; +import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.CpuLoadMetricSet; +import com.nhn.pinpoint.thrift.dto.TCpuLoad; + +/** + * @author hyungil.jeong + */ +public class CpuLoadCollector { + + private final Gauge jvmCpuLoadGauge; + private final Gauge systemCpuLoadGauge; + + @SuppressWarnings("unchecked") + public CpuLoadCollector(CpuLoadMetricSet cpuLoadMetricSet) { + if (cpuLoadMetricSet == null) { + throw new NullPointerException("cpuLoadMetricSet must not be null"); + } + Map metrics = cpuLoadMetricSet.getMetrics(); + this.jvmCpuLoadGauge = (Gauge)MetricMonitorValues.getMetric(metrics, CPU_LOAD_JVM, DOUBLE_ZERO); + this.systemCpuLoadGauge = (Gauge)MetricMonitorValues.getMetric(metrics, CPU_LOAD_SYSTEM, DOUBLE_ZERO); + } + + public TCpuLoad collectCpuLoad() { + Double jvmCpuLoad = this.jvmCpuLoadGauge.getValue(); + Double systemCpuLoad = this.systemCpuLoadGauge.getValue(); + if (notCollected(jvmCpuLoad) && notCollected(systemCpuLoad)) { + return null; + } + TCpuLoad cpuLoad = new TCpuLoad(); + if (!notCollected(jvmCpuLoad)) { + cpuLoad.setJvmCpuLoad(jvmCpuLoad); + } + if (!notCollected(systemCpuLoad)) { + cpuLoad.setSystemCpuLoad(systemCpuLoad); + } + return cpuLoad; + } + + private boolean notCollected(double cpuLoad) { + return cpuLoad < 0; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadMetricSetSelector.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadMetricSetSelector.java index 0a7bdfc89353..a7831271c3b7 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadMetricSetSelector.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/CpuLoadMetricSetSelector.java @@ -1,62 +1,62 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.cpu; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.common.JvmVersion; -import com.nhn.pinpoint.common.util.JvmUtils; -import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.CpuLoadMetricSet; -import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.DefaultCpuLoadMetricSet; -import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.EmptyCpuLoadMetricSet; - -/** - * @author hyungil.jeong - */ -public class CpuLoadMetricSetSelector { - - private static final Logger LOGGER = LoggerFactory.getLogger(CpuLoadMetricSetSelector.class); - - private static final String OPTIONAL_CPU_LOAD_METRIC_SET_CLASSPATH = "com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.EnhancedCpuLoadMetricSet"; - - private CpuLoadMetricSetSelector() { - throw new IllegalAccessError(); - } - - public static CpuLoadMetricSet getCpuLoadMetricSet() { - if (canLoadOptionalPackage()) { - CpuLoadMetricSet optionalPackage = loadOptionalPackage(); - if (optionalPackage != null) { - return optionalPackage; - } - } - if (canLoadDefault()) { - return new DefaultCpuLoadMetricSet(); - } else { - return new EmptyCpuLoadMetricSet(); - } - } - - private static CpuLoadMetricSet loadOptionalPackage() { - try { - @SuppressWarnings("unchecked") - Class clazz = (Class)Class.forName(OPTIONAL_CPU_LOAD_METRIC_SET_CLASSPATH); - try { - return clazz.newInstance(); - } catch (Exception e) { - LOGGER.error("Error instantiating optional package.", e); - } - } catch (ClassNotFoundException e) { - LOGGER.info("Optional package not found."); - } - return null; - } - - private static boolean canLoadOptionalPackage() { - // JDK 1.7 이상인지만 확인 - return JvmUtils.supportsVersion(JvmVersion.JAVA_7); - } - - private static boolean canLoadDefault() { - return JvmUtils.getVersion() != JvmVersion.UNSUPPORTED; - } -} +package com.nhn.pinpoint.profiler.monitor.codahale.cpu; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.common.util.JvmVersion; +import com.nhn.pinpoint.common.util.JvmUtils; +import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.CpuLoadMetricSet; +import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.DefaultCpuLoadMetricSet; +import com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.EmptyCpuLoadMetricSet; + +/** + * @author hyungil.jeong + */ +public class CpuLoadMetricSetSelector { + + private static final Logger LOGGER = LoggerFactory.getLogger(CpuLoadMetricSetSelector.class); + + private static final String OPTIONAL_CPU_LOAD_METRIC_SET_CLASSPATH = "com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric.EnhancedCpuLoadMetricSet"; + + private CpuLoadMetricSetSelector() { + throw new IllegalAccessError(); + } + + public static CpuLoadMetricSet getCpuLoadMetricSet() { + if (canLoadOptionalPackage()) { + CpuLoadMetricSet optionalPackage = loadOptionalPackage(); + if (optionalPackage != null) { + return optionalPackage; + } + } + if (canLoadDefault()) { + return new DefaultCpuLoadMetricSet(); + } else { + return new EmptyCpuLoadMetricSet(); + } + } + + private static CpuLoadMetricSet loadOptionalPackage() { + try { + @SuppressWarnings("unchecked") + Class clazz = (Class)Class.forName(OPTIONAL_CPU_LOAD_METRIC_SET_CLASSPATH); + try { + return clazz.newInstance(); + } catch (Exception e) { + LOGGER.error("Error instantiating optional package.", e); + } + } catch (ClassNotFoundException e) { + LOGGER.info("Optional package not found."); + } + return null; + } + + private static boolean canLoadOptionalPackage() { + // JDK 1.7 이상인지만 확인 + return JvmUtils.supportsVersion(JvmVersion.JAVA_7); + } + + private static boolean canLoadDefault() { + return JvmUtils.getVersion() != JvmVersion.UNSUPPORTED; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/AbstractCpuLoadMetricSet.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/AbstractCpuLoadMetricSet.java index 99480e895b45..60e2eefbc4de 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/AbstractCpuLoadMetricSet.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/AbstractCpuLoadMetricSet.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; - -import java.lang.management.ManagementFactory; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import com.codahale.metrics.Gauge; -import com.codahale.metrics.Metric; -import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues; - -/** - * @author hyungil.jeong - */ -public abstract class AbstractCpuLoadMetricSet implements CpuLoadMetricSet { - - private final com.sun.management.OperatingSystemMXBean mxBean; - - protected AbstractCpuLoadMetricSet() { - this.mxBean = (com.sun.management.OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean(); - } - - protected abstract Gauge getJvmCpuLoadGauge(final com.sun.management.OperatingSystemMXBean operatingSystemMXBean); - - protected abstract Gauge getSystemCpuLoadGauge(final com.sun.management.OperatingSystemMXBean operatingSystemMXBean); - - @Override - public Map getMetrics() { - final Map gauges = new HashMap(); - gauges.put(MetricMonitorValues.CPU_LOAD_JVM, getJvmCpuLoadGauge(this.mxBean)); - gauges.put(MetricMonitorValues.CPU_LOAD_SYSTEM, getSystemCpuLoadGauge(this.mxBean)); - return Collections.unmodifiableMap(gauges); - } -} +package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; + +import java.lang.management.ManagementFactory; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Metric; +import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues; + +/** + * @author hyungil.jeong + */ +public abstract class AbstractCpuLoadMetricSet implements CpuLoadMetricSet { + + private final com.sun.management.OperatingSystemMXBean mxBean; + + protected AbstractCpuLoadMetricSet() { + this.mxBean = (com.sun.management.OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean(); + } + + protected abstract Gauge getJvmCpuLoadGauge(final com.sun.management.OperatingSystemMXBean operatingSystemMXBean); + + protected abstract Gauge getSystemCpuLoadGauge(final com.sun.management.OperatingSystemMXBean operatingSystemMXBean); + + @Override + public Map getMetrics() { + final Map gauges = new HashMap(); + gauges.put(MetricMonitorValues.CPU_LOAD_JVM, getJvmCpuLoadGauge(this.mxBean)); + gauges.put(MetricMonitorValues.CPU_LOAD_SYSTEM, getSystemCpuLoadGauge(this.mxBean)); + return Collections.unmodifiableMap(gauges); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/CpuLoadMetricSet.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/CpuLoadMetricSet.java index c0f669f4e3f7..e9fb861f107a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/CpuLoadMetricSet.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/CpuLoadMetricSet.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; - -import com.codahale.metrics.MetricSet; - -/** - * @author hyungil.jeong - */ -public interface CpuLoadMetricSet extends MetricSet { - -} +package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; + +import com.codahale.metrics.MetricSet; + +/** + * @author hyungil.jeong + */ +public interface CpuLoadMetricSet extends MetricSet { + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/DefaultCpuLoadMetricSet.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/DefaultCpuLoadMetricSet.java index f6ac7dfd0edb..90482b3957eb 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/DefaultCpuLoadMetricSet.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/DefaultCpuLoadMetricSet.java @@ -1,77 +1,77 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; - -import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; - -import com.codahale.metrics.Gauge; -import com.sun.management.OperatingSystemMXBean; - -/** - * @author hyungil.jeong - */ -public final class DefaultCpuLoadMetricSet extends AbstractCpuLoadMetricSet { - - private static final int UNSUPPORTED = -1; - private static final int UNINITIALIZED = -1; - private static final Double UNSUPPORTED_CPU_LOAD_METRIC = -1.0D; - - private final RuntimeMXBean runtimeMXBean; - - public DefaultCpuLoadMetricSet() { - this.runtimeMXBean = ManagementFactory.getRuntimeMXBean(); - } - - @Override - protected Gauge getJvmCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { - return new Gauge() { - - private long lastCpuTimeNS = UNINITIALIZED; - private long lastUpTimeMS = UNINITIALIZED; - - @Override - public Double getValue() { - - final long cpuTimeNS = operatingSystemMXBean.getProcessCpuTime(); - if (cpuTimeNS == UNSUPPORTED) { - return UNSUPPORTED_CPU_LOAD_METRIC; - } - final long upTimeMS = runtimeMXBean.getUptime(); - - if (this.lastCpuTimeNS == UNINITIALIZED || this.lastUpTimeMS == UNINITIALIZED) { - this.lastCpuTimeNS = cpuTimeNS; - this.lastUpTimeMS = upTimeMS; - return 0.0D; - } - - final long totalCpuTimeNS = cpuTimeNS - lastCpuTimeNS; - final long diffUpTimeMS = upTimeMS - lastUpTimeMS; - final int numProcessors = Runtime.getRuntime().availableProcessors(); - final long totalUpTimeNS = (diffUpTimeMS * 1000000) * numProcessors; - - final double cpuLoad = totalUpTimeNS > 0 ? - Math.min(100F, totalCpuTimeNS / (float)totalUpTimeNS) : UNSUPPORTED; - - this.lastCpuTimeNS = cpuTimeNS; - this.lastUpTimeMS = upTimeMS; - - return cpuLoad; - } - }; - } - - @Override - protected Gauge getSystemCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { - return new Gauge() { - @Override - public Double getValue() { - return UNSUPPORTED_CPU_LOAD_METRIC; - } - }; - } - - @Override - public String toString() { - return "Default CpuLoadMetricSet for Java 1.6"; - } - -} +package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; + +import com.codahale.metrics.Gauge; +import com.sun.management.OperatingSystemMXBean; + +/** + * @author hyungil.jeong + */ +public final class DefaultCpuLoadMetricSet extends AbstractCpuLoadMetricSet { + + private static final int UNSUPPORTED = -1; + private static final int UNINITIALIZED = -1; + private static final Double UNSUPPORTED_CPU_LOAD_METRIC = -1.0D; + + private final RuntimeMXBean runtimeMXBean; + + public DefaultCpuLoadMetricSet() { + this.runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + } + + @Override + protected Gauge getJvmCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { + return new Gauge() { + + private long lastCpuTimeNS = UNINITIALIZED; + private long lastUpTimeMS = UNINITIALIZED; + + @Override + public Double getValue() { + + final long cpuTimeNS = operatingSystemMXBean.getProcessCpuTime(); + if (cpuTimeNS == UNSUPPORTED) { + return UNSUPPORTED_CPU_LOAD_METRIC; + } + final long upTimeMS = runtimeMXBean.getUptime(); + + if (this.lastCpuTimeNS == UNINITIALIZED || this.lastUpTimeMS == UNINITIALIZED) { + this.lastCpuTimeNS = cpuTimeNS; + this.lastUpTimeMS = upTimeMS; + return 0.0D; + } + + final long totalCpuTimeNS = cpuTimeNS - lastCpuTimeNS; + final long diffUpTimeMS = upTimeMS - lastUpTimeMS; + final int numProcessors = Runtime.getRuntime().availableProcessors(); + final long totalUpTimeNS = (diffUpTimeMS * 1000000) * numProcessors; + + final double cpuLoad = totalUpTimeNS > 0 ? + Math.min(100F, totalCpuTimeNS / (float)totalUpTimeNS) : UNSUPPORTED; + + this.lastCpuTimeNS = cpuTimeNS; + this.lastUpTimeMS = upTimeMS; + + return cpuLoad; + } + }; + } + + @Override + protected Gauge getSystemCpuLoadGauge(final OperatingSystemMXBean operatingSystemMXBean) { + return new Gauge() { + @Override + public Double getValue() { + return UNSUPPORTED_CPU_LOAD_METRIC; + } + }; + } + + @Override + public String toString() { + return "Default CpuLoadMetricSet for Java 1.6"; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EmptyCpuLoadMetricSet.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EmptyCpuLoadMetricSet.java index e83d1e404ee0..b7b9a7dde30d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EmptyCpuLoadMetricSet.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/cpu/metric/EmptyCpuLoadMetricSet.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import com.codahale.metrics.Gauge; -import com.codahale.metrics.Metric; -import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues; - -/** - * @author hyungil.jeong - */ -public final class EmptyCpuLoadMetricSet implements CpuLoadMetricSet { - - private static final Double UNSUPPORTED_CPU_LOAD_METRIC = -1.0d; - private static final Gauge UNSUPPORTED_CPU_LOAD_METRIC_GAUGE = new Gauge() { - @Override - public Double getValue() { - return UNSUPPORTED_CPU_LOAD_METRIC; - } - }; - - @Override - public Map getMetrics() { - final Map gauges = new HashMap(); - gauges.put(MetricMonitorValues.CPU_LOAD_JVM, UNSUPPORTED_CPU_LOAD_METRIC_GAUGE); - gauges.put(MetricMonitorValues.CPU_LOAD_SYSTEM, UNSUPPORTED_CPU_LOAD_METRIC_GAUGE); - return Collections.unmodifiableMap(gauges); - } - - @Override - public String toString() { - return "Disabled CpuLoadMetricSet"; - } - -} +package com.nhn.pinpoint.profiler.monitor.codahale.cpu.metric; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.codahale.metrics.Gauge; +import com.codahale.metrics.Metric; +import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues; + +/** + * @author hyungil.jeong + */ +public final class EmptyCpuLoadMetricSet implements CpuLoadMetricSet { + + private static final Double UNSUPPORTED_CPU_LOAD_METRIC = -1.0d; + private static final Gauge UNSUPPORTED_CPU_LOAD_METRIC_GAUGE = new Gauge() { + @Override + public Double getValue() { + return UNSUPPORTED_CPU_LOAD_METRIC; + } + }; + + @Override + public Map getMetrics() { + final Map gauges = new HashMap(); + gauges.put(MetricMonitorValues.CPU_LOAD_JVM, UNSUPPORTED_CPU_LOAD_METRIC_GAUGE); + gauges.put(MetricMonitorValues.CPU_LOAD_SYSTEM, UNSUPPORTED_CPU_LOAD_METRIC_GAUGE); + return Collections.unmodifiableMap(gauges); + } + + @Override + public String toString() { + return "Disabled CpuLoadMetricSet"; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/UnknownGarbageCollector.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/UnknownGarbageCollector.java index 8e7c016f8880..1081acd76b39 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/UnknownGarbageCollector.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/UnknownGarbageCollector.java @@ -1,31 +1,31 @@ -package com.nhn.pinpoint.profiler.monitor.codahale.gc; - -import com.nhn.pinpoint.thrift.dto.TJvmGc; -import com.nhn.pinpoint.thrift.dto.TJvmGcType; - -/** - * Unknown Garbage collector - * @author hyungil.jeong - */ -public class UnknownGarbageCollector implements GarbageCollector { - - public static final TJvmGcType GC_TYPE = TJvmGcType.UNKNOWN; - - @Override - public int getTypeCode() { - return GC_TYPE.ordinal(); - } - - @Override - public TJvmGc collect() { - // 아예 전송을 안하려고 null을 리턴한다. - //(Thrift DTO에서 gc 필드는 optional) - return null; - } - - @Override - public String toString() { - return "Unknown Garbage collector"; - } - -} +package com.nhn.pinpoint.profiler.monitor.codahale.gc; + +import com.nhn.pinpoint.thrift.dto.TJvmGc; +import com.nhn.pinpoint.thrift.dto.TJvmGcType; + +/** + * Unknown Garbage collector + * @author hyungil.jeong + */ +public class UnknownGarbageCollector implements GarbageCollector { + + public static final TJvmGcType GC_TYPE = TJvmGcType.UNKNOWN; + + @Override + public int getTypeCode() { + return GC_TYPE.ordinal(); + } + + @Override + public TJvmGc collect() { + // 아예 전송을 안하려고 null을 리턴한다. + //(Thrift DTO에서 gc 필드는 optional) + return null; + } + + @Override + public String toString() { + return "Unknown Garbage collector"; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/AcceptHistogram.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/AcceptHistogram.java index 4ad458d59aeb..85e6b24c22ab 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/AcceptHistogram.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/AcceptHistogram.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -/** - * @author emeroad - */ -public interface AcceptHistogram { - public boolean addResponseTime(String parentApplicationName, short serviceType, int millis); -} +package com.nhn.pinpoint.profiler.monitor.metric; + +/** + * @author emeroad + */ +public interface AcceptHistogram { + public boolean addResponseTime(String parentApplicationName, short serviceType, int millis); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/ContextMetric.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/ContextMetric.java index 69827d3866f2..533867f4d0d2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/ContextMetric.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/ContextMetric.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.ServiceType; - -/** - * @author emeroad - */ -public class ContextMetric { - // 실제 WAS 응답속도. - private final Histogram responseMetric; - // 모르는 user의 속도. - private final Histogram userHistogram; - - private final ServiceType contextServiceType; - - // 어떤놈이 호출했는지 아는 경우. - private final AcceptHistogram acceptHistogram = new DefaultAcceptHistogram(); - - public ContextMetric(ServiceType contextServiceType) { - if (contextServiceType == null) { - throw new NullPointerException("contextServiceType must not be null"); - } - - this.contextServiceType = contextServiceType; - - this.responseMetric = new LongAdderHistogram(contextServiceType); - this.userHistogram = new LongAdderHistogram(contextServiceType); - } - - public void addResponseTime(int millis) { - this.responseMetric.addResponseTime(millis); - } - - public void addAcceptHistogram(String parentApplicationName, short serviceType, int millis) { - if (parentApplicationName == null) { - throw new NullPointerException("parentApplicationName must not be null"); - } - this.acceptHistogram.addResponseTime(parentApplicationName, serviceType, millis); - } - - public void addUserAcceptHistogram(int millis) { - this.userHistogram.addResponseTime(millis); - } - - - - -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.ServiceType; + +/** + * @author emeroad + */ +public class ContextMetric { + // 실제 WAS 응답속도. + private final Histogram responseMetric; + // 모르는 user의 속도. + private final Histogram userHistogram; + + private final ServiceType contextServiceType; + + // 어떤놈이 호출했는지 아는 경우. + private final AcceptHistogram acceptHistogram = new DefaultAcceptHistogram(); + + public ContextMetric(ServiceType contextServiceType) { + if (contextServiceType == null) { + throw new NullPointerException("contextServiceType must not be null"); + } + + this.contextServiceType = contextServiceType; + + this.responseMetric = new LongAdderHistogram(contextServiceType); + this.userHistogram = new LongAdderHistogram(contextServiceType); + } + + public void addResponseTime(int millis) { + this.responseMetric.addResponseTime(millis); + } + + public void addAcceptHistogram(String parentApplicationName, short serviceType, int millis) { + if (parentApplicationName == null) { + throw new NullPointerException("parentApplicationName must not be null"); + } + this.acceptHistogram.addResponseTime(parentApplicationName, serviceType, millis); + } + + public void addUserAcceptHistogram(int millis) { + this.userHistogram.addResponseTime(millis); + } + + + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultAcceptHistogram.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultAcceptHistogram.java index c79b483d1cb0..8e88983845c5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultAcceptHistogram.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultAcceptHistogram.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class DefaultAcceptHistogram implements AcceptHistogram { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final AcceptHistogram staticAcceptHistogram = new StaticAcceptHistogram(); - - private final AcceptHistogram dynamicAcceptHistogram = new DynamicAcceptHistogram(); - - @Override - public boolean addResponseTime(String parentApplicationName, short serviceType, int millis) { - - final boolean staticResult = this.staticAcceptHistogram.addResponseTime(parentApplicationName, serviceType, millis); - if (staticResult) { - return true; - } - - final boolean dynamicResult = this.dynamicAcceptHistogram.addResponseTime(parentApplicationName, serviceType, millis); - if (!dynamicResult) { - logger.info("response data add fail. parentApplicationName:{} serviceType:{} millis:{}", parentApplicationName, serviceType, millis); - return true; - } - return false; - } -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class DefaultAcceptHistogram implements AcceptHistogram { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final AcceptHistogram staticAcceptHistogram = new StaticAcceptHistogram(); + + private final AcceptHistogram dynamicAcceptHistogram = new DynamicAcceptHistogram(); + + @Override + public boolean addResponseTime(String parentApplicationName, short serviceType, int millis) { + + final boolean staticResult = this.staticAcceptHistogram.addResponseTime(parentApplicationName, serviceType, millis); + if (staticResult) { + return true; + } + + final boolean dynamicResult = this.dynamicAcceptHistogram.addResponseTime(parentApplicationName, serviceType, millis); + if (!dynamicResult) { + logger.info("response data add fail. parentApplicationName:{} serviceType:{} millis:{}", parentApplicationName, serviceType, millis); + return true; + } + return false; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetric.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetric.java index d50fa4dee7ee..16a4358562b1 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetric.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetric.java @@ -1,61 +1,61 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.ServiceType; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class DefaultRpcMetric implements RpcMetric { - - private final ServiceType serviceType; - // TODO lru cache로 변경할것. lru로 변경할 경우 counting이 틀려질 가능성이 있으나, oom이 발생하는것을 막을수 있음. - private final ConcurrentMap histogramMap = new ConcurrentHashMap(); - - public DefaultRpcMetric(ServiceType serviceType) { - if (serviceType == null) { - throw new NullPointerException("serviceType must not be null"); - } - this.serviceType = serviceType; - } - - @Override - public void addResponseTime(String destinationId, int millis) { - if (destinationId == null) { - throw new NullPointerException("destinationId must not be null"); - } - Histogram histogram = getHistogram0(destinationId); - histogram.addResponseTime(millis); - } - - private Histogram getHistogram0(String destinationId) { - final Histogram hit = histogramMap.get(destinationId); - if (hit != null) { - return hit; - } - final Histogram histogram = createHistogram(); - - final Histogram exist = histogramMap.putIfAbsent(destinationId, histogram); - if (exist != null) { - return exist; - } - return histogram; - } - - private LongAdderHistogram createHistogram() { - return new LongAdderHistogram(serviceType); - } - - public List createSnapshotList() { - final List histogramSnapshotList = new ArrayList(histogramMap.size() + 4); - for (Histogram histogram : histogramMap.values()) { - final HistogramSnapshot snapshot = histogram.createSnapshot(); - histogramSnapshotList.add(snapshot); - } - return histogramSnapshotList; - } -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.ServiceType; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class DefaultRpcMetric implements RpcMetric { + + private final ServiceType serviceType; + // TODO lru cache로 변경할것. lru로 변경할 경우 counting이 틀려질 가능성이 있으나, oom이 발생하는것을 막을수 있음. + private final ConcurrentMap histogramMap = new ConcurrentHashMap(); + + public DefaultRpcMetric(ServiceType serviceType) { + if (serviceType == null) { + throw new NullPointerException("serviceType must not be null"); + } + this.serviceType = serviceType; + } + + @Override + public void addResponseTime(String destinationId, int millis) { + if (destinationId == null) { + throw new NullPointerException("destinationId must not be null"); + } + Histogram histogram = getHistogram0(destinationId); + histogram.addResponseTime(millis); + } + + private Histogram getHistogram0(String destinationId) { + final Histogram hit = histogramMap.get(destinationId); + if (hit != null) { + return hit; + } + final Histogram histogram = createHistogram(); + + final Histogram exist = histogramMap.putIfAbsent(destinationId, histogram); + if (exist != null) { + return exist; + } + return histogram; + } + + private LongAdderHistogram createHistogram() { + return new LongAdderHistogram(serviceType); + } + + public List createSnapshotList() { + final List histogramSnapshotList = new ArrayList(histogramMap.size() + 4); + for (Histogram histogram : histogramMap.values()) { + final HistogramSnapshot snapshot = histogram.createSnapshot(); + histogramSnapshotList.add(snapshot); + } + return histogramSnapshotList; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DynamicAcceptHistogram.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DynamicAcceptHistogram.java index 509d61d8f248..17dbb28549cf 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DynamicAcceptHistogram.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/DynamicAcceptHistogram.java @@ -1,100 +1,100 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.ServiceType; - - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class DynamicAcceptHistogram implements AcceptHistogram { - - private final ConcurrentMap map; - - public DynamicAcceptHistogram() { - this.map = new ConcurrentHashMap(); - } - - @Override - public boolean addResponseTime(String parentApplicationName, short serviceTypeCode, int millis) { - if (parentApplicationName == null) { - throw new NullPointerException("parentApplicationName must not be null"); - } - // ServiceType object로 변경하면 안됨. 새로운 타입이 추가되었을 경우 undefined 로 될수 있음. - if (!ServiceType.isWas(serviceTypeCode)) { - return false; - } - // TODO 여기서 undefined가 발생함. 이미 모르는 type이 추가 되었을때 어떻게 해야 하는가? - // histogramSchema의 type이라도 있으면 유추가 되기는 함. code + schemaType 으로 할 경우 서버에서는 판정가능. - final ServiceType serviceType = ServiceType.findServiceType(serviceTypeCode); - if (serviceType == ServiceType.UNDEFINED) { - return false; - } - final ResponseKey responseKey = new ResponseKey(parentApplicationName, serviceType); - final Histogram histogram = getHistogram(responseKey); - histogram.addResponseTime(millis); - return true; - } - - private Histogram getHistogram(ResponseKey responseKey) { - final Histogram hit = map.get(responseKey); - if (hit != null) { - return hit; - } - final Histogram histogram = new LongAdderHistogram(responseKey.getServiceType()); - final Histogram old = map.putIfAbsent(responseKey, histogram); - if (old != null) { - return old; - } - return histogram; - } - - - private static final class ResponseKey { - private final ServiceType serviceType; - private final String parentApplicationName; - - private ResponseKey(String parentApplicationName, ServiceType serviceType) { - if (parentApplicationName == null) { - throw new NullPointerException("parentApplicationName must not be null"); - } - if (serviceType == null) { - throw new NullPointerException("serviceType must not be null"); - } - - this.parentApplicationName = parentApplicationName; - this.serviceType = serviceType; - } - - public String getParentApplicationName() { - return parentApplicationName; - } - - public ServiceType getServiceType() { - return serviceType; - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ResponseKey that = (ResponseKey) o; - - if (!parentApplicationName.equals(that.parentApplicationName)) return false; - if (serviceType != that.serviceType) return false; - - return true; - } - - @Override - public int hashCode() { - int result = serviceType.hashCode(); - result = 31 * result + parentApplicationName.hashCode(); - return result; - } - } -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.ServiceType; + + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class DynamicAcceptHistogram implements AcceptHistogram { + + private final ConcurrentMap map; + + public DynamicAcceptHistogram() { + this.map = new ConcurrentHashMap(); + } + + @Override + public boolean addResponseTime(String parentApplicationName, short serviceTypeCode, int millis) { + if (parentApplicationName == null) { + throw new NullPointerException("parentApplicationName must not be null"); + } + // ServiceType object로 변경하면 안됨. 새로운 타입이 추가되었을 경우 undefined 로 될수 있음. + if (!ServiceType.isWas(serviceTypeCode)) { + return false; + } + // TODO 여기서 undefined가 발생함. 이미 모르는 type이 추가 되었을때 어떻게 해야 하는가? + // histogramSchema의 type이라도 있으면 유추가 되기는 함. code + schemaType 으로 할 경우 서버에서는 판정가능. + final ServiceType serviceType = ServiceType.findServiceType(serviceTypeCode); + if (serviceType == ServiceType.UNDEFINED) { + return false; + } + final ResponseKey responseKey = new ResponseKey(parentApplicationName, serviceType); + final Histogram histogram = getHistogram(responseKey); + histogram.addResponseTime(millis); + return true; + } + + private Histogram getHistogram(ResponseKey responseKey) { + final Histogram hit = map.get(responseKey); + if (hit != null) { + return hit; + } + final Histogram histogram = new LongAdderHistogram(responseKey.getServiceType()); + final Histogram old = map.putIfAbsent(responseKey, histogram); + if (old != null) { + return old; + } + return histogram; + } + + + private static final class ResponseKey { + private final ServiceType serviceType; + private final String parentApplicationName; + + private ResponseKey(String parentApplicationName, ServiceType serviceType) { + if (parentApplicationName == null) { + throw new NullPointerException("parentApplicationName must not be null"); + } + if (serviceType == null) { + throw new NullPointerException("serviceType must not be null"); + } + + this.parentApplicationName = parentApplicationName; + this.serviceType = serviceType; + } + + public String getParentApplicationName() { + return parentApplicationName; + } + + public ServiceType getServiceType() { + return serviceType; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ResponseKey that = (ResponseKey) o; + + if (!parentApplicationName.equals(that.parentApplicationName)) return false; + if (serviceType != that.serviceType) return false; + + return true; + } + + @Override + public int hashCode() { + int result = serviceType.hashCode(); + result = 31 * result + parentApplicationName.hashCode(); + return result; + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/Histogram.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/Histogram.java index 3f269699cd2e..8dacd8710ce6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/Histogram.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/Histogram.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.bootstrap.context.Metric; -import com.nhn.pinpoint.common.ServiceType; - -/** - * @author emeroad - */ -public interface Histogram extends Metric { - short getServiceType(); - - void addResponseTime(int millis); - - HistogramSnapshot createSnapshot(); -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.bootstrap.context.Metric; +import com.nhn.pinpoint.common.ServiceType; + +/** + * @author emeroad + */ +public interface Histogram extends Metric { + short getServiceType(); + + void addResponseTime(int millis); + + HistogramSnapshot createSnapshot(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramSnapshot.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramSnapshot.java index 14121d97150d..a0bcb6acd8e4 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramSnapshot.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramSnapshot.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -/** - * @author emeroad - */ -public class HistogramSnapshot { - private final short serviceType; - private final long fastCount; - private final long normalCount; - private final long slowCount; - private final long verySlowCount; - - private final long errorCount; - - public HistogramSnapshot(short serviceType, long fastCount, long normalCount, long slowCount, long verySlowCount, long errorCounter) { - - this.serviceType = serviceType; - this.fastCount = fastCount; - this.normalCount = normalCount; - this.slowCount = slowCount; - this.verySlowCount = verySlowCount; - this.errorCount = errorCounter; - } - - public short getServiceType() { - return serviceType; - } - - public long getFastCount() { - return fastCount; - } - - public long getNormalCount() { - return normalCount; - } - - public long getSlowCount() { - return slowCount; - } - - public long getVerySlowCount() { - return verySlowCount; - } - - public long getErrorCount() { - return errorCount; - } - - @Override - public String toString() { - return "HistogramSnapshot{" + - "serviceType=" + serviceType + - "fast=" + fastCount + - ", normal=" + normalCount + - ", slow=" + slowCount + - ", verySlow=" + verySlowCount + - ", error=" + errorCount + - '}'; - } -} +package com.nhn.pinpoint.profiler.monitor.metric; + +/** + * @author emeroad + */ +public class HistogramSnapshot { + private final short serviceType; + private final long fastCount; + private final long normalCount; + private final long slowCount; + private final long verySlowCount; + + private final long errorCount; + + public HistogramSnapshot(short serviceType, long fastCount, long normalCount, long slowCount, long verySlowCount, long errorCounter) { + + this.serviceType = serviceType; + this.fastCount = fastCount; + this.normalCount = normalCount; + this.slowCount = slowCount; + this.verySlowCount = verySlowCount; + this.errorCount = errorCounter; + } + + public short getServiceType() { + return serviceType; + } + + public long getFastCount() { + return fastCount; + } + + public long getNormalCount() { + return normalCount; + } + + public long getSlowCount() { + return slowCount; + } + + public long getVerySlowCount() { + return verySlowCount; + } + + public long getErrorCount() { + return errorCount; + } + + @Override + public String toString() { + return "HistogramSnapshot{" + + "serviceType=" + serviceType + + "fast=" + fastCount + + ", normal=" + normalCount + + ", slow=" + slowCount + + ", verySlow=" + verySlowCount + + ", error=" + errorCount + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/LongAdderHistogram.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/LongAdderHistogram.java index d4be6c0b3401..128be8c04584 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/LongAdderHistogram.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/LongAdderHistogram.java @@ -1,83 +1,83 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.HistogramSlot; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.SlotType; -import com.nhn.pinpoint.profiler.util.jdk.LongAdder; - -/** - * @author emeroad - */ -public class LongAdderHistogram implements Histogram { - // fastCounter만 LongAdder를 사용하고 나머지는 AtomicLong을 사용하는 방법도 있음. - private final LongAdder fastCounter = new LongAdder(); - private final LongAdder normalCounter = new LongAdder(); - private final LongAdder slowCounter = new LongAdder(); - private final LongAdder verySlowCounter = new LongAdder(); - - private final LongAdder errorCounter = new LongAdder(); - - private final short serviceType; - private final HistogramSchema histogramSchema; - - public LongAdderHistogram(ServiceType serviceType) { - this(serviceType.getCode(), serviceType.getHistogramSchema()); - } - - public LongAdderHistogram(short serviceType, HistogramSchema histogramSchema) { - this.serviceType = serviceType; - this.histogramSchema = histogramSchema; - } - - public short getServiceType() { - return serviceType; - } - - public void addResponseTime(int millis) { - final HistogramSlot histogramSlot = histogramSchema.findHistogramSlot(millis); - final SlotType slotType = histogramSlot.getSlotType(); - switch (slotType) { - case FAST: - fastCounter.increment(); - return; - case NORMAL: - normalCounter.increment(); - return; - case SLOW: - slowCounter.increment(); - return; - case VERY_SLOW: - verySlowCounter.increment(); - return; - case ERROR: - errorCounter.increment(); - return; - default: - throw new IllegalArgumentException("slot Type notFound:" + slotType); - } - } - - - public HistogramSnapshot createSnapshot() { - long fast = fastCounter.sum(); - long normal = normalCounter.sum(); - long slow = slowCounter.sum(); - long verySlow = verySlowCounter.sum(); - long error = errorCounter.sum(); - - return new HistogramSnapshot(this.serviceType, fast, normal, slow, verySlow, error); - } - - @Override - public String toString() { - return "LongAdderHistogram{" + - "fastCounter=" + fastCounter + - ", normalCounter=" + normalCounter + - ", slowCounter=" + slowCounter + - ", verySlowCounter=" + verySlowCounter + - ", errorCounter=" + errorCounter + - ", serviceType=" + serviceType + - '}'; - } -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.HistogramSlot; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.SlotType; +import com.nhn.pinpoint.profiler.util.jdk.LongAdder; + +/** + * @author emeroad + */ +public class LongAdderHistogram implements Histogram { + // fastCounter만 LongAdder를 사용하고 나머지는 AtomicLong을 사용하는 방법도 있음. + private final LongAdder fastCounter = new LongAdder(); + private final LongAdder normalCounter = new LongAdder(); + private final LongAdder slowCounter = new LongAdder(); + private final LongAdder verySlowCounter = new LongAdder(); + + private final LongAdder errorCounter = new LongAdder(); + + private final short serviceType; + private final HistogramSchema histogramSchema; + + public LongAdderHistogram(ServiceType serviceType) { + this(serviceType.getCode(), serviceType.getHistogramSchema()); + } + + public LongAdderHistogram(short serviceType, HistogramSchema histogramSchema) { + this.serviceType = serviceType; + this.histogramSchema = histogramSchema; + } + + public short getServiceType() { + return serviceType; + } + + public void addResponseTime(int millis) { + final HistogramSlot histogramSlot = histogramSchema.findHistogramSlot(millis); + final SlotType slotType = histogramSlot.getSlotType(); + switch (slotType) { + case FAST: + fastCounter.increment(); + return; + case NORMAL: + normalCounter.increment(); + return; + case SLOW: + slowCounter.increment(); + return; + case VERY_SLOW: + verySlowCounter.increment(); + return; + case ERROR: + errorCounter.increment(); + return; + default: + throw new IllegalArgumentException("slot Type notFound:" + slotType); + } + } + + + public HistogramSnapshot createSnapshot() { + long fast = fastCounter.sum(); + long normal = normalCounter.sum(); + long slow = slowCounter.sum(); + long verySlow = verySlowCounter.sum(); + long error = errorCounter.sum(); + + return new HistogramSnapshot(this.serviceType, fast, normal, slow, verySlow, error); + } + + @Override + public String toString() { + return "LongAdderHistogram{" + + "fastCounter=" + fastCounter + + ", normalCounter=" + normalCounter + + ", slowCounter=" + slowCounter + + ", verySlowCounter=" + verySlowCounter + + ", errorCounter=" + errorCounter + + ", serviceType=" + serviceType + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistry.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistry.java index b2050a065c1f..22b5de1e09be 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistry.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistry.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.ServiceType; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class MetricRegistry { - - private final ConcurrentMap rpcCache = new ConcurrentHashMap(); - - private final ContextMetric contextMetric; - - - public MetricRegistry(ServiceType serviceType) { - if (serviceType == null) { - throw new NullPointerException("serviceType must not be null"); - } - if (!serviceType.isWas()) { - throw new IllegalArgumentException("illegal serviceType:" + serviceType); - } - - this.contextMetric = new ContextMetric(serviceType); - } - - public RpcMetric getRpcMetric(ServiceType serviceType) { - if (serviceType == null) { - throw new NullPointerException("serviceType must not be null"); - } - if (!serviceType.isRecordStatistics()) { - throw new IllegalArgumentException("illegal serviceType:" + serviceType); - } - final Short code = serviceType.getCode(); - final RpcMetric hit = rpcCache.get(code); - if (hit != null) { - return hit; - } - final RpcMetric rpcMetric = new DefaultRpcMetric(serviceType); - final RpcMetric exist = rpcCache.putIfAbsent(code, rpcMetric); - if (exist != null) { - return exist; - } - - return rpcMetric; - } - - public ContextMetric getResponseMetric() { - return contextMetric; - } - - public void addResponseTime(int mills) { - this.contextMetric.addResponseTime(mills); - } - - public Collection createRpcResponseSnapshot() { - final List histogramSnapshotList = new ArrayList(16); - for (RpcMetric metric : rpcCache.values()) { - histogramSnapshotList.addAll(metric.createSnapshotList()); - } - return histogramSnapshotList; - } - - public HistogramSnapshot createWasResponseSnapshot() { - return null; - } -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.ServiceType; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class MetricRegistry { + + private final ConcurrentMap rpcCache = new ConcurrentHashMap(); + + private final ContextMetric contextMetric; + + + public MetricRegistry(ServiceType serviceType) { + if (serviceType == null) { + throw new NullPointerException("serviceType must not be null"); + } + if (!serviceType.isWas()) { + throw new IllegalArgumentException("illegal serviceType:" + serviceType); + } + + this.contextMetric = new ContextMetric(serviceType); + } + + public RpcMetric getRpcMetric(ServiceType serviceType) { + if (serviceType == null) { + throw new NullPointerException("serviceType must not be null"); + } + if (!serviceType.isRecordStatistics()) { + throw new IllegalArgumentException("illegal serviceType:" + serviceType); + } + final Short code = serviceType.getCode(); + final RpcMetric hit = rpcCache.get(code); + if (hit != null) { + return hit; + } + final RpcMetric rpcMetric = new DefaultRpcMetric(serviceType); + final RpcMetric exist = rpcCache.putIfAbsent(code, rpcMetric); + if (exist != null) { + return exist; + } + + return rpcMetric; + } + + public ContextMetric getResponseMetric() { + return contextMetric; + } + + public void addResponseTime(int mills) { + this.contextMetric.addResponseTime(mills); + } + + public Collection createRpcResponseSnapshot() { + final List histogramSnapshotList = new ArrayList(16); + for (RpcMetric metric : rpcCache.values()) { + histogramSnapshotList.addAll(metric.createSnapshotList()); + } + return histogramSnapshotList; + } + + public HistogramSnapshot createWasResponseSnapshot() { + return null; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/RpcMetric.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/RpcMetric.java index 1fb99b07cde8..6a34c41bfc30 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/RpcMetric.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/RpcMetric.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.bootstrap.context.Metric; - -import java.util.Collection; - -/** - * @author emeroad - */ -public interface RpcMetric extends Metric { - - void addResponseTime(String destinationId, int millis); - - Collection createSnapshotList(); - -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.bootstrap.context.Metric; + +import java.util.Collection; + +/** + * @author emeroad + */ +public interface RpcMetric extends Metric { + + void addResponseTime(String destinationId, int millis); + + Collection createSnapshotList(); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/StaticAcceptHistogram.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/StaticAcceptHistogram.java index 583a979e6255..d63160d07c06 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/StaticAcceptHistogram.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/metric/StaticAcceptHistogram.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.IntHashMap; -import com.nhn.pinpoint.common.ServiceType; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class StaticAcceptHistogram implements AcceptHistogram { - // 동적으로 데이터 등록이 가능하지 않음. thread safe하지 않으므로 절대 put을 하지 말것. - private final IntHashMap> map; - - public StaticAcceptHistogram() { - this.map = new IntHashMap>(); - bindMap(map); - } - - private void bindMap(IntHashMap> map) { - ServiceType[] serviceTypeList = ServiceType.values(); - for (ServiceType serviceType : serviceTypeList) { - if (serviceType.isWas()) { - ConcurrentMap caller = new ConcurrentHashMap(); - map.put(serviceType.getCode(), caller); - } - } - } - - - @Override - public boolean addResponseTime(String parentApplicationName, short serviceType, int millis) { - if (parentApplicationName == null) { - throw new NullPointerException("parentApplicationName must not be null"); - } - - final ConcurrentMap histogramMap = this.map.get(serviceType); - if (histogramMap == null) { - return false; - } - final Histogram histogram = getHistogram(histogramMap, parentApplicationName, serviceType); - histogram.addResponseTime(millis); - return true; - } - - private Histogram getHistogram(ConcurrentMap histogramMap, String parentApplicationName, short serviceTypeCode) { - final Histogram hit = histogramMap.get(parentApplicationName); - if (hit != null) { - return hit; - } - final ServiceType serviceType = ServiceType.findServiceType(serviceTypeCode); - final Histogram histogram = new LongAdderHistogram(serviceType); - final Histogram old = histogramMap.putIfAbsent(parentApplicationName, histogram); - if (old != null) { - return old; - } - return histogram; - } -} +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.util.apache.IntHashMap; +import com.nhn.pinpoint.common.ServiceType; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class StaticAcceptHistogram implements AcceptHistogram { + // 동적으로 데이터 등록이 가능하지 않음. thread safe하지 않으므로 절대 put을 하지 말것. + private final IntHashMap> map; + + public StaticAcceptHistogram() { + this.map = new IntHashMap>(); + bindMap(map); + } + + private void bindMap(IntHashMap> map) { + ServiceType[] serviceTypeList = ServiceType.values(); + for (ServiceType serviceType : serviceTypeList) { + if (serviceType.isWas()) { + ConcurrentMap caller = new ConcurrentHashMap(); + map.put(serviceType.getCode(), caller); + } + } + } + + + @Override + public boolean addResponseTime(String parentApplicationName, short serviceType, int millis) { + if (parentApplicationName == null) { + throw new NullPointerException("parentApplicationName must not be null"); + } + + final ConcurrentMap histogramMap = this.map.get(serviceType); + if (histogramMap == null) { + return false; + } + final Histogram histogram = getHistogram(histogramMap, parentApplicationName, serviceType); + histogram.addResponseTime(millis); + return true; + } + + private Histogram getHistogram(ConcurrentMap histogramMap, String parentApplicationName, short serviceTypeCode) { + final Histogram hit = histogramMap.get(parentApplicationName); + if (hit != null) { + return hit; + } + final ServiceType serviceType = ServiceType.findServiceType(serviceTypeCode); + final Histogram histogram = new LongAdderHistogram(serviceType); + final Histogram old = histogramMap.putIfAbsent(parentApplicationName, histogram); + if (old != null) { + return old; + } + return histogram; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/CommandDispatcher.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/CommandDispatcher.java index d6dece3e7e7b..32f7d4804447 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/CommandDispatcher.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/CommandDispatcher.java @@ -1,124 +1,127 @@ -package com.nhn.pinpoint.profiler.receiver; - -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.protocol.TProtocolFactory; -import org.jboss.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.common.Version; -import com.nhn.pinpoint.profiler.receiver.bo.ThreadDumpBO; -import com.nhn.pinpoint.rpc.client.MessageListener; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.ResponsePacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.dto.command.TCommandThreadDump; -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; -import com.nhn.pinpoint.thrift.io.SerializerFactory; -import com.nhn.pinpoint.thrift.io.TBaseLocator; -import com.nhn.pinpoint.thrift.io.TCommandRegistry; -import com.nhn.pinpoint.thrift.io.TCommandTypeVersion; - -/** - * @author koo.taejin - */ -public class CommandDispatcher implements MessageListener { - - // 일단은 현재 스레드가 워커스레드로 되는 것을 등록 (이후에 변경하자.) - - private static final TProtocolFactory DEFAULT_PROTOCOL_FACTORY = new TCompactProtocol.Factory(); - private static final TBaseLocator commandTbaseLocator = new TCommandRegistry(TCommandTypeVersion.getVersion(Version.VERSION)); - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - // 여기만 따로 TBaseLocator를 상속받아 만들어주는 것이 좋을듯 - - private final TBaseBOLocator locator; - - private final SerializerFactory serializerFactory = new HeaderTBaseSerializerFactory(true, HeaderTBaseSerializerFactory.DEFAULT_UDP_STREAM_MAX_SIZE, DEFAULT_PROTOCOL_FACTORY, commandTbaseLocator); - private final HeaderTBaseDeserializerFactory deserializerFactory = new HeaderTBaseDeserializerFactory(DEFAULT_PROTOCOL_FACTORY, commandTbaseLocator); - - public CommandDispatcher() { - TBaseBORegistry registry = new TBaseBORegistry(); - registry.addBO(TCommandThreadDump.class, new ThreadDumpBO()); - - this.locator = registry; - } - - @Override - public void handleRequest(RequestPacket packet, Channel channel) { - logger.info("MessageReceive {} {}", packet, channel); - - TBase request = deserialize(packet.getPayload()); - - TBase response = null; - if (request == null) { - TResult tResult = new TResult(false); - tResult.setMessage("Unsupported Type."); - - response = tResult; - } else { - TBaseRequestBO bo = locator.getRequestBO(request); - - if (bo == null) { - TResult tResult = new TResult(false); - tResult.setMessage("Unsupported Listener."); - - response = tResult; - } else { - response = bo.handleRequest(request); - } - } - - byte[] payload = serialize(response); - if (payload != null) { - channel.write(new ResponsePacket(packet.getRequestId(), payload)); - } - } - - @Override - public void handleSend(SendPacket packet, Channel channel) { - logger.info("MessageReceive {} {}", packet, channel); - } - - private TBase deserialize(byte[] payload) { - if (payload == null) { - logger.warn("Payload may not be null."); - return null; - } - - try { - final HeaderTBaseDeserializer deserializer = deserializerFactory.createDeserializer(); - TBase tBase = deserializer.deserialize(payload); - return tBase; - } catch (TException e) { - logger.warn(e.getMessage(), e); - } - - return null; - } - - private byte[] serialize(TBase result) { - if (result == null) { - logger.warn("tBase may not be null."); - return null; - } - - try { - HeaderTBaseSerializer serializer = serializerFactory.createSerializer(); - byte[] payload = serializer.serialize(result); - return payload; - } catch (TException e) { - logger.warn(e.getMessage(), e); - } - - return null; - } - -} +package com.nhn.pinpoint.profiler.receiver; + +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.protocol.TProtocolFactory; +import org.jboss.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.common.Version; +import com.nhn.pinpoint.profiler.receiver.bo.EchoBO; +import com.nhn.pinpoint.profiler.receiver.bo.ThreadDumpBO; +import com.nhn.pinpoint.rpc.client.MessageListener; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.ResponsePacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.dto.command.TCommandEcho; +import com.nhn.pinpoint.thrift.dto.command.TCommandThreadDump; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; +import com.nhn.pinpoint.thrift.io.SerializerFactory; +import com.nhn.pinpoint.thrift.io.TBaseLocator; +import com.nhn.pinpoint.thrift.io.TCommandRegistry; +import com.nhn.pinpoint.thrift.io.TCommandTypeVersion; + +/** + * @author koo.taejin + */ +public class CommandDispatcher implements MessageListener { + + // 일단은 현재 스레드가 워커스레드로 되는 것을 등록 (이후에 변경하자.) + + private static final TProtocolFactory DEFAULT_PROTOCOL_FACTORY = new TCompactProtocol.Factory(); + private static final TBaseLocator commandTbaseLocator = new TCommandRegistry(TCommandTypeVersion.getVersion(Version.VERSION)); + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + // 여기만 따로 TBaseLocator를 상속받아 만들어주는 것이 좋을듯 + + private final TBaseBOLocator locator; + + private final SerializerFactory serializerFactory = new HeaderTBaseSerializerFactory(true, HeaderTBaseSerializerFactory.DEFAULT_UDP_STREAM_MAX_SIZE, DEFAULT_PROTOCOL_FACTORY, commandTbaseLocator); + private final HeaderTBaseDeserializerFactory deserializerFactory = new HeaderTBaseDeserializerFactory(DEFAULT_PROTOCOL_FACTORY, commandTbaseLocator); + + public CommandDispatcher() { + TBaseBORegistry registry = new TBaseBORegistry(); + registry.addBO(TCommandThreadDump.class, new ThreadDumpBO()); + registry.addBO(TCommandEcho.class, new EchoBO()); + + this.locator = registry; + } + + @Override + public void handleRequest(RequestPacket packet, Channel channel) { + logger.info("MessageReceive {} {}", packet, channel); + + TBase request = deserialize(packet.getPayload()); + + TBase response = null; + if (request == null) { + TResult tResult = new TResult(false); + tResult.setMessage("Unsupported Type."); + + response = tResult; + } else { + TBaseRequestBO bo = locator.getRequestBO(request); + + if (bo == null) { + TResult tResult = new TResult(false); + tResult.setMessage("Unsupported Listener."); + + response = tResult; + } else { + response = bo.handleRequest(request); + } + } + + byte[] payload = serialize(response); + if (payload != null) { + channel.write(new ResponsePacket(packet.getRequestId(), payload)); + } + } + + @Override + public void handleSend(SendPacket packet, Channel channel) { + logger.info("MessageReceive {} {}", packet, channel); + } + + private TBase deserialize(byte[] payload) { + if (payload == null) { + logger.warn("Payload may not be null."); + return null; + } + + try { + final HeaderTBaseDeserializer deserializer = deserializerFactory.createDeserializer(); + TBase tBase = deserializer.deserialize(payload); + return tBase; + } catch (TException e) { + logger.warn(e.getMessage(), e); + } + + return null; + } + + private byte[] serialize(TBase result) { + if (result == null) { + logger.warn("tBase may not be null."); + return null; + } + + try { + HeaderTBaseSerializer serializer = serializerFactory.createSerializer(); + byte[] payload = serializer.serialize(result); + return payload; + } catch (TException e) { + logger.warn(e.getMessage(), e); + } + + return null; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBO.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBO.java index 7e5622e368d4..fb69d2de8b47 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBO.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBO.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.profiler.receiver; - -/** - * @author koo.taejin - */ -public interface TBaseBO { - -} +package com.nhn.pinpoint.profiler.receiver; + +/** + * @author koo.taejin + */ +public interface TBaseBO { + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBOLocator.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBOLocator.java index aad58df3b64f..278b83f08238 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBOLocator.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBOLocator.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.profiler.receiver; - -import org.apache.thrift.TBase; - -/** - * @author koo.taejin - */ -public interface TBaseBOLocator { - - TBaseBO getBO(TBase tBase); - - TBaseSimpleBO getSimpleBO(TBase tBase); - - TBaseRequestBO getRequestBO(TBase tBase); - -} +package com.nhn.pinpoint.profiler.receiver; + +import org.apache.thrift.TBase; + +/** + * @author koo.taejin + */ +public interface TBaseBOLocator { + + TBaseBO getBO(TBase tBase); + + TBaseSimpleBO getSimpleBO(TBase tBase); + + TBaseRequestBO getRequestBO(TBase tBase); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBORegistry.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBORegistry.java index 0c28c4609eda..88f43fcd4e0a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBORegistry.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseBORegistry.java @@ -1,91 +1,91 @@ -package com.nhn.pinpoint.profiler.receiver; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author koo.taejin - */ -public class TBaseBORegistry implements TBaseBOLocator { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Map, TBaseBO> tbaseBORepository; - - public TBaseBORegistry() { - tbaseBORepository = new HashMap, TBaseBO>(); - } - - /** - * not guarantee thread safe. - */ - public boolean addBO(Class clazz, TBaseBO bo) { - if (tbaseBORepository.containsKey(clazz)) { - logger.warn("Already Register Type({}).", clazz.getName()); - return false; - } - - tbaseBORepository.put(clazz, bo); - return true; - } - - @Override - public TBaseBO getBO(TBase tBase) { - if (tBase == null) { - throw new NullPointerException("Params may not be null."); - } - - TBaseBO bo = tbaseBORepository.get(tBase.getClass()); - if (bo != null) { - return bo; - } - - List candidateHandlerList = new ArrayList(); - for (Map.Entry, TBaseBO> entry : tbaseBORepository.entrySet()) { - if (entry.getKey().isInstance(tBase)) { - candidateHandlerList.add(entry.getValue()); - } - } - - if (candidateHandlerList.size() == 1) { - return candidateHandlerList.get(0); - } - - if (candidateHandlerList.size() > 1) { - logger.warn("Ambigous Pinpoint Handler ({})", candidateHandlerList); - } - - return null; - } - - @Override - public TBaseSimpleBO getSimpleBO(TBase tBase) { - TBaseBO bo = getBO(tBase); - - // null체크 필요없음 - if (bo instanceof TBaseSimpleBO) { - return (TBaseSimpleBO) bo; - } - - return null; - } - - @Override - public TBaseRequestBO getRequestBO(TBase tBase) { - TBaseBO bo = getBO(tBase); - - // null체크 필요없음 - if (bo instanceof TBaseRequestBO) { - return (TBaseRequestBO) bo; - } - - return null; - } - -} +package com.nhn.pinpoint.profiler.receiver; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author koo.taejin + */ +public class TBaseBORegistry implements TBaseBOLocator { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Map, TBaseBO> tbaseBORepository; + + public TBaseBORegistry() { + tbaseBORepository = new HashMap, TBaseBO>(); + } + + /** + * not guarantee thread safe. + */ + public boolean addBO(Class clazz, TBaseBO bo) { + if (tbaseBORepository.containsKey(clazz)) { + logger.warn("Already Register Type({}).", clazz.getName()); + return false; + } + + tbaseBORepository.put(clazz, bo); + return true; + } + + @Override + public TBaseBO getBO(TBase tBase) { + if (tBase == null) { + throw new NullPointerException("Params may not be null."); + } + + TBaseBO bo = tbaseBORepository.get(tBase.getClass()); + if (bo != null) { + return bo; + } + + List candidateHandlerList = new ArrayList(); + for (Map.Entry, TBaseBO> entry : tbaseBORepository.entrySet()) { + if (entry.getKey().isInstance(tBase)) { + candidateHandlerList.add(entry.getValue()); + } + } + + if (candidateHandlerList.size() == 1) { + return candidateHandlerList.get(0); + } + + if (candidateHandlerList.size() > 1) { + logger.warn("Ambigous Pinpoint Handler ({})", candidateHandlerList); + } + + return null; + } + + @Override + public TBaseSimpleBO getSimpleBO(TBase tBase) { + TBaseBO bo = getBO(tBase); + + // null체크 필요없음 + if (bo instanceof TBaseSimpleBO) { + return (TBaseSimpleBO) bo; + } + + return null; + } + + @Override + public TBaseRequestBO getRequestBO(TBase tBase) { + TBaseBO bo = getBO(tBase); + + // null체크 필요없음 + if (bo instanceof TBaseRequestBO) { + return (TBaseRequestBO) bo; + } + + return null; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseRequestBO.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseRequestBO.java index 2b112a44e13b..839a9e98c481 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseRequestBO.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseRequestBO.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.profiler.receiver; - -import org.apache.thrift.TBase; - -/** - * @author koo.taejin - */ -public interface TBaseRequestBO extends TBaseBO { - - TBase handleRequest(TBase tBase); - -} +package com.nhn.pinpoint.profiler.receiver; + +import org.apache.thrift.TBase; + +/** + * @author koo.taejin + */ +public interface TBaseRequestBO extends TBaseBO { + + TBase handleRequest(TBase tBase); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseSimpleBO.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseSimpleBO.java index ccbb92c703e6..252bb3e1c917 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseSimpleBO.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/TBaseSimpleBO.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.profiler.receiver; - -import org.apache.thrift.TBase; - -/** - * @author koo.taejin - */ -public interface TBaseSimpleBO extends TBaseBO { - - void handleSimple(TBase tbase); - -} +package com.nhn.pinpoint.profiler.receiver; + +import org.apache.thrift.TBase; + +/** + * @author koo.taejin + */ +public interface TBaseSimpleBO extends TBaseBO { + + void handleSimple(TBase tbase); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/bo/EchoBO.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/bo/EchoBO.java new file mode 100644 index 000000000000..ce2e95948cc8 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/bo/EchoBO.java @@ -0,0 +1,24 @@ +package com.nhn.pinpoint.profiler.receiver.bo; + +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.profiler.receiver.TBaseRequestBO; +import com.nhn.pinpoint.thrift.dto.command.TCommandEcho; + +/** + * @author koo.taejin + */ +public class EchoBO implements TBaseRequestBO { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public TBase handleRequest(TBase tbase) { + logger.info("{} execute {}.", this, tbase); + + TCommandEcho param = (TCommandEcho) tbase; + return param; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/bo/ThreadDumpBO.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/bo/ThreadDumpBO.java index a3d312e9dee2..eb6782e9141b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/bo/ThreadDumpBO.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/receiver/bo/ThreadDumpBO.java @@ -1,112 +1,112 @@ -package com.nhn.pinpoint.profiler.receiver.bo; - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadInfo; -import java.lang.management.ThreadMXBean; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.profiler.receiver.TBaseRequestBO; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.dto.command.TCommandThreadDump; -import com.nhn.pinpoint.thrift.dto.command.TThreadDumpType; - -/** - * @author koo.taejin - */ -public class ThreadDumpBO implements TBaseRequestBO { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - public TBase handleRequest(TBase tbase) { - logger.info("{} execute {}.", this, tbase); - - TCommandThreadDump param = (TCommandThreadDump) tbase; - TThreadDumpType type = param.getType(); - - List threadInfoList = null; - if (TThreadDumpType.TARGET == type) { - threadInfoList = getThreadInfo(param.getName()); - } else if (TThreadDumpType.PENDING == type) { - threadInfoList = getThreadInfo(param.getPendingTimeMillis()); - } else { - threadInfoList = Arrays.asList(getAllThreadInfo()); - } - - StringBuilder dump = new StringBuilder(); - for (ThreadInfo info : threadInfoList) { - dump.append(info.getThreadName()); - dump.append("\t Thread.State: "); - dump.append(info.getThreadState()); - - StackTraceElement[] elements = info.getStackTrace(); - for (StackTraceElement element : elements) { - dump.append("\r\n\t at"); - dump.append(element); - } - dump.append("\r\n"); - dump.append("\r\n"); - } - - TResult result = new TResult(true); - result.setMessage(dump.toString()); - - logger.debug("Result = {}", result); - - return result; - } - - private List getThreadInfo(String threadName) { - List result = new ArrayList(); - - if (threadName == null || threadName.trim().equals("")) { - return Arrays.asList(getAllThreadInfo()); - } - - ThreadInfo[] threadInfos = getAllThreadInfo(); - for (ThreadInfo threadIno : getAllThreadInfo()) { - if (threadName.equals(threadIno.getThreadName())) { - result.add(threadIno); - } - } - - return result; - } - - // 이건 나중에 수정이 필요함 - private List getThreadInfo(long pendingTimeMillis) { - List result = new ArrayList(); - - if (pendingTimeMillis <= 0) { - return Arrays.asList(getAllThreadInfo()); - } - - for (ThreadInfo threadInfo : getAllThreadInfo()) { - if (threadInfo.getBlockedTime() >= pendingTimeMillis) { - result.add(threadInfo); - continue; - } - - if (threadInfo.getWaitedTime() >= pendingTimeMillis) { - result.add(threadInfo); - continue; - } - } - - return result; - } - - private ThreadInfo[] getAllThreadInfo() { - ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean(); - ThreadInfo[] threadInfos = threadMxBean.getThreadInfo(threadMxBean.getAllThreadIds(), 100); - - return threadInfos; - } - -} +package com.nhn.pinpoint.profiler.receiver.bo; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.profiler.receiver.TBaseRequestBO; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.dto.command.TCommandThreadDump; +import com.nhn.pinpoint.thrift.dto.command.TThreadDumpType; + +/** + * @author koo.taejin + */ +public class ThreadDumpBO implements TBaseRequestBO { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public TBase handleRequest(TBase tbase) { + logger.info("{} execute {}.", this, tbase); + + TCommandThreadDump param = (TCommandThreadDump) tbase; + TThreadDumpType type = param.getType(); + + List threadInfoList = null; + if (TThreadDumpType.TARGET == type) { + threadInfoList = getThreadInfo(param.getName()); + } else if (TThreadDumpType.PENDING == type) { + threadInfoList = getThreadInfo(param.getPendingTimeMillis()); + } else { + threadInfoList = Arrays.asList(getAllThreadInfo()); + } + + StringBuilder dump = new StringBuilder(); + for (ThreadInfo info : threadInfoList) { + dump.append(info.getThreadName()); + dump.append("\t Thread.State: "); + dump.append(info.getThreadState()); + + StackTraceElement[] elements = info.getStackTrace(); + for (StackTraceElement element : elements) { + dump.append("\r\n\t at"); + dump.append(element); + } + dump.append("\r\n"); + dump.append("\r\n"); + } + + TResult result = new TResult(true); + result.setMessage(dump.toString()); + + logger.debug("Result = {}", result); + + return result; + } + + private List getThreadInfo(String threadName) { + List result = new ArrayList(); + + if (threadName == null || threadName.trim().equals("")) { + return Arrays.asList(getAllThreadInfo()); + } + + ThreadInfo[] threadInfos = getAllThreadInfo(); + for (ThreadInfo threadIno : getAllThreadInfo()) { + if (threadName.equals(threadIno.getThreadName())) { + result.add(threadIno); + } + } + + return result; + } + + // 이건 나중에 수정이 필요함 + private List getThreadInfo(long pendingTimeMillis) { + List result = new ArrayList(); + + if (pendingTimeMillis <= 0) { + return Arrays.asList(getAllThreadInfo()); + } + + for (ThreadInfo threadInfo : getAllThreadInfo()) { + if (threadInfo.getBlockedTime() >= pendingTimeMillis) { + result.add(threadInfo); + continue; + } + + if (threadInfo.getWaitedTime() >= pendingTimeMillis) { + result.add(threadInfo); + continue; + } + } + + return result; + } + + private ThreadInfo[] getAllThreadInfo() { + ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] threadInfos = threadMxBean.getThreadInfo(threadMxBean.getAllThreadIds(), 100); + + return threadInfos; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/FalseSampler.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/FalseSampler.java index c8d741187363..02e07dbbd401 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/FalseSampler.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/FalseSampler.java @@ -1,19 +1,19 @@ -package com.nhn.pinpoint.profiler.sampler; - -import com.nhn.pinpoint.bootstrap.sampler.Sampler; - -/** - * @author emeroad - */ -public class FalseSampler implements Sampler { - @Override - public boolean isSampling() { - return false; - } - - @Override - public String toString() { - // getClass하면 class명이 변경되어 다르게 나올수 있음. - return "FalseSampler"; - } -} +package com.nhn.pinpoint.profiler.sampler; + +import com.nhn.pinpoint.bootstrap.sampler.Sampler; + +/** + * @author emeroad + */ +public class FalseSampler implements Sampler { + @Override + public boolean isSampling() { + return false; + } + + @Override + public String toString() { + // getClass하면 class명이 변경되어 다르게 나올수 있음. + return "FalseSampler"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java index bbde06c89da0..fef2085f56ce 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.profiler.sampler; - -import com.nhn.pinpoint.bootstrap.sampler.Sampler; - -/** - * @author emeroad - */ -public class SamplerFactory { - public Sampler createSampler(boolean sampling, int samplingRate) { - if (!sampling || samplingRate <= 0) { - return new FalseSampler(); - } - if (samplingRate == 1) { - return new TrueSampler(); - } - return new SamplingRateSampler(samplingRate); - } -} +package com.nhn.pinpoint.profiler.sampler; + +import com.nhn.pinpoint.bootstrap.sampler.Sampler; + +/** + * @author emeroad + */ +public class SamplerFactory { + public Sampler createSampler(boolean sampling, int samplingRate) { + if (!sampling || samplingRate <= 0) { + return new FalseSampler(); + } + if (samplingRate == 1) { + return new TrueSampler(); + } + return new SamplingRateSampler(samplingRate); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java index 21f2a4dcf83a..0212e7e08005 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.profiler.sampler; - -import com.nhn.pinpoint.bootstrap.sampler.Sampler; -import com.nhn.pinpoint.common.util.MathUtils; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class SamplingRateSampler implements Sampler { - - private final AtomicInteger counter = new AtomicInteger(0); - private final int samplingRate; - - public SamplingRateSampler(int samplingRate) { - if (samplingRate <= 0) { - throw new IllegalArgumentException("Invalid samplingRate " + samplingRate); - } - this.samplingRate = samplingRate; - } - - - - @Override - public boolean isSampling() { - int samplingCount = MathUtils.fastAbs(counter.getAndIncrement()); - int isSampling = samplingCount % samplingRate; - return isSampling == 0; - } - - @Override - public String toString() { - return "SamplingRateSampler{" + - "counter=" + counter + - "samplingRate=" + samplingRate + - '}'; - } -} +package com.nhn.pinpoint.profiler.sampler; + +import com.nhn.pinpoint.bootstrap.sampler.Sampler; +import com.nhn.pinpoint.common.util.MathUtils; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class SamplingRateSampler implements Sampler { + + private final AtomicInteger counter = new AtomicInteger(0); + private final int samplingRate; + + public SamplingRateSampler(int samplingRate) { + if (samplingRate <= 0) { + throw new IllegalArgumentException("Invalid samplingRate " + samplingRate); + } + this.samplingRate = samplingRate; + } + + + + @Override + public boolean isSampling() { + int samplingCount = MathUtils.fastAbs(counter.getAndIncrement()); + int isSampling = samplingCount % samplingRate; + return isSampling == 0; + } + + @Override + public String toString() { + return "SamplingRateSampler{" + + "counter=" + counter + + "samplingRate=" + samplingRate + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/TrueSampler.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/TrueSampler.java index a7fe8dc53203..4dba6c528286 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/TrueSampler.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/TrueSampler.java @@ -1,20 +1,20 @@ -package com.nhn.pinpoint.profiler.sampler; - -import com.nhn.pinpoint.bootstrap.sampler.Sampler; - -/** - * @author emeroad - */ -public class TrueSampler implements Sampler { - - @Override - public boolean isSampling() { - return true; - } - - @Override - public String toString() { - // getClass하면 class명이 변경되어 다르게 나올수 있음. - return "TrueSampler"; - } -} +package com.nhn.pinpoint.profiler.sampler; + +import com.nhn.pinpoint.bootstrap.sampler.Sampler; + +/** + * @author emeroad + */ +public class TrueSampler implements Sampler { + + @Override + public boolean isSampling() { + return true; + } + + @Override + public String toString() { + // getClass하면 class명이 변경되어 다르게 나올수 있음. + return "TrueSampler"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AbstractDataSender.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AbstractDataSender.java index 8a541d5c3316..abf5b9c7c1ae 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AbstractDataSender.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AbstractDataSender.java @@ -1,114 +1,114 @@ -package com.nhn.pinpoint.profiler.sender; - -import java.util.Collection; - -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.FutureListener; -import com.nhn.pinpoint.rpc.ResponseMessage; -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; - -/** - * - * @author koo.taejin - */ -public abstract class AbstractDataSender implements DataSender { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - abstract protected void sendPacket(Object dto); - - protected void sendPacketN(Collection messageList) { - // 자체적인 List를 사용하고 있어서 toArray(T[] array] 사용이 불가능 ㅠ_ㅠ - Object[] dataList = messageList.toArray(); - - // 일단 single thread에서 하는거라 구지 복사 안해도 될것 같음. - // Object[] copy = Arrays.copyOf(original, original.length); - - // for (Object data : dataList) { - // 이렇게 바꾸지 말것. copy해서 return 하는게 아니라 항상 max치가 나옴. - final int size = messageList.size(); - for (int i = 0; i < size; i++) { - try { - sendPacket(dataList[i]); - } catch (Throwable th) { - logger.warn("Unexpected Error. Cause:{}", th.getMessage(), th); - } - } - } - - protected AsyncQueueingExecutor createAsyncQueueingExecutor(int queueSize, String executorName) { - final AsyncQueueingExecutor executor = new AsyncQueueingExecutor(queueSize, executorName); - executor.setListener(new AsyncQueueingExecutorListener() { - @Override - public void execute(Collection messageList) { - sendPacketN(messageList); - } - - @Override - public void execute(Object message) { - sendPacket(message); - } - }); - return executor; - } - - protected byte[] serialize(HeaderTBaseSerializer serializer, TBase tBase) { - try { - return serializer.serialize(tBase); - } catch (TException e) { - if (logger.isWarnEnabled()) { - logger.warn("Serialize fail:{} Caused:{}", tBase, e.getMessage(), e); - } - return null; - } - } - protected TBase deserialize(HeaderTBaseDeserializer deserializer, ResponseMessage responseMessage) { - byte[] message = responseMessage.getMessage(); - try { - return deserializer.deserialize(message); - } catch (TException e) { - if (logger.isWarnEnabled()) { - logger.warn("Deserialize fail. Caused:{}", e.getMessage(), e); - } - return null; - } - } - - - protected static class RequestMarker { - private final TBase tBase; - private final int retryCount; - private final FutureListener futureListener; - - protected RequestMarker(TBase tBase, int retryCount) { - this.tBase = tBase; - this.retryCount = retryCount; - this.futureListener = null; - } - - protected RequestMarker(TBase tBase, FutureListener futureListener) { - this.tBase = tBase; - this.retryCount = 3; - this.futureListener = futureListener; - } - - protected TBase getTBase() { - return tBase; - } - - protected int getRetryCount() { - return retryCount; - } - - protected FutureListener getFutureListener() { - return futureListener; - } - } - -} +package com.nhn.pinpoint.profiler.sender; + +import java.util.Collection; + +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.FutureListener; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; + +/** + * + * @author koo.taejin + */ +public abstract class AbstractDataSender implements DataSender { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + abstract protected void sendPacket(Object dto); + + protected void sendPacketN(Collection messageList) { + // 자체적인 List를 사용하고 있어서 toArray(T[] array] 사용이 불가능 ㅠ_ㅠ + Object[] dataList = messageList.toArray(); + + // 일단 single thread에서 하는거라 구지 복사 안해도 될것 같음. + // Object[] copy = Arrays.copyOf(original, original.length); + + // for (Object data : dataList) { + // 이렇게 바꾸지 말것. copy해서 return 하는게 아니라 항상 max치가 나옴. + final int size = messageList.size(); + for (int i = 0; i < size; i++) { + try { + sendPacket(dataList[i]); + } catch (Throwable th) { + logger.warn("Unexpected Error. Cause:{}", th.getMessage(), th); + } + } + } + + protected AsyncQueueingExecutor createAsyncQueueingExecutor(int queueSize, String executorName) { + final AsyncQueueingExecutor executor = new AsyncQueueingExecutor(queueSize, executorName); + executor.setListener(new AsyncQueueingExecutorListener() { + @Override + public void execute(Collection messageList) { + sendPacketN(messageList); + } + + @Override + public void execute(Object message) { + sendPacket(message); + } + }); + return executor; + } + + protected byte[] serialize(HeaderTBaseSerializer serializer, TBase tBase) { + try { + return serializer.serialize(tBase); + } catch (TException e) { + if (logger.isWarnEnabled()) { + logger.warn("Serialize fail:{} Caused:{}", tBase, e.getMessage(), e); + } + return null; + } + } + protected TBase deserialize(HeaderTBaseDeserializer deserializer, ResponseMessage responseMessage) { + byte[] message = responseMessage.getMessage(); + try { + return deserializer.deserialize(message); + } catch (TException e) { + if (logger.isWarnEnabled()) { + logger.warn("Deserialize fail. Caused:{}", e.getMessage(), e); + } + return null; + } + } + + + protected static class RequestMarker { + private final TBase tBase; + private final int retryCount; + private final FutureListener futureListener; + + protected RequestMarker(TBase tBase, int retryCount) { + this.tBase = tBase; + this.retryCount = retryCount; + this.futureListener = null; + } + + protected RequestMarker(TBase tBase, FutureListener futureListener) { + this.tBase = tBase; + this.retryCount = 3; + this.futureListener = futureListener; + } + + protected TBase getTBase() { + return tBase; + } + + protected int getRetryCount() { + return retryCount; + } + + protected FutureListener getFutureListener() { + return futureListener; + } + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutor.java index ee233a3a7970..d11cd510089e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutor.java @@ -1,184 +1,184 @@ -package com.nhn.pinpoint.profiler.sender; - -import java.util.Collection; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.common.util.PinpointThreadFactory; - -/** - * @author emeroad - */ -public class AsyncQueueingExecutor implements Runnable { - - private static final AsyncQueueingExecutorListener EMPTY_LISTENER = new EmptyAsyncQueueingExecutorListener(); - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final boolean isWarn = logger.isWarnEnabled(); - - private final LinkedBlockingQueue queue; - private final AtomicBoolean isRun = new AtomicBoolean(true); - private final Thread executeThread; - private final String executorName; - - private final int maxDrainSize = 10; - // 주의 single thread용임. ArrayList보다 더 단순한 오퍼레이션을 수행하는 Collection. - private final Collection drain = new UnsafeArrayCollection(maxDrainSize); - - private AsyncQueueingExecutorListener listener = EMPTY_LISTENER; - - - public AsyncQueueingExecutor() { - this(1024 * 5, "Pinpoint-AsyncQueueingExecutor"); - } - - public AsyncQueueingExecutor(int queueSize, String executorName) { - if (executorName == null) { - throw new NullPointerException("executorName must not be null"); - } - this.queue = new LinkedBlockingQueue(queueSize); - this.executeThread = this.createExecuteThread(executorName); - this.executorName = executeThread.getName(); - } - - private Thread createExecuteThread(String executorName) { - final ThreadFactory threadFactory = new PinpointThreadFactory(executorName, true); - Thread thread = threadFactory.newThread(this); - thread.start(); - return thread; - } - - @Override - public void run() { - logger.info("{} started.", executorName); - doExecute(); - } - - private void doExecute() { - drainStartEntry: - while (isRun()) { - try { - Collection dtoList = getDrainQueue(); - int drainSize = takeN(dtoList, this.maxDrainSize); - if (drainSize > 0) { - doExecute(dtoList); - continue; - } - - while (isRun()) { - T dto = takeOne(); - if (dto != null) { - doExecute(dto); - continue drainStartEntry; - } - } - } catch (Throwable th) { - logger.warn("{} doExecute(). Unexpected Error. Cause:{}", executorName, th.getMessage(), th); - } - } - flushQueue(); - } - - private void flushQueue() { - boolean debugEnabled = logger.isDebugEnabled(); - if (debugEnabled) { - logger.debug("Loop is stop."); - } - while(true) { - Collection dtoList = getDrainQueue(); - int drainSize = takeN(dtoList, this.maxDrainSize); - if (drainSize == 0) { - break; - } - if (debugEnabled) { - logger.debug("flushData size {}", drainSize); - } - doExecute(dtoList); - } - } - - protected T takeOne() { - try { - return queue.poll(1000 * 2, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return null; - } - } - - protected int takeN(Collection drain, int maxDrainSize) { - return queue.drainTo(drain, maxDrainSize); - } - - public boolean execute(T data) { - if (data == null) { - if (isWarn) { - logger.warn("execute(). data is null"); - } - return false; - } - if (!isRun.get()) { - if (isWarn) { - logger.warn("{} is shutdown. discard data:{}", executorName, data); - } - return false; - } - boolean offer = queue.offer(data); - if (!offer) { - if (isWarn) { - logger.warn("{} Drop data. queue is full. size:{}", executorName, queue.size()); - } - } - return offer; - } - - public void setListener(AsyncQueueingExecutorListener listener) { - if (listener == null) { - throw new NullPointerException("listener must not be null"); - } - this.listener = listener; - } - - private void doExecute(Collection dtoList) { - this.listener.execute(dtoList); - } - - private void doExecute(T dto) { - this.listener.execute(dto); - } - - public boolean isEmpty() { - return queue.isEmpty(); - } - - public boolean isRun() { - return isRun.get(); - } - - public void stop() { - isRun.set(false); - - if (!isEmpty()) { - logger.info("Wait 5 seconds. Flushing queued data."); - } - executeThread.interrupt(); - try { - executeThread.join(5000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.warn("{} stopped incompletely.", executorName); - } - - logger.info("{} stopped.", executorName); - } - - Collection getDrainQueue() { - this.drain.clear(); - return drain; - } -} +package com.nhn.pinpoint.profiler.sender; + +import java.util.Collection; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.common.util.PinpointThreadFactory; + +/** + * @author emeroad + */ +public class AsyncQueueingExecutor implements Runnable { + + private static final AsyncQueueingExecutorListener EMPTY_LISTENER = new EmptyAsyncQueueingExecutorListener(); + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final boolean isWarn = logger.isWarnEnabled(); + + private final LinkedBlockingQueue queue; + private final AtomicBoolean isRun = new AtomicBoolean(true); + private final Thread executeThread; + private final String executorName; + + private final int maxDrainSize = 10; + // 주의 single thread용임. ArrayList보다 더 단순한 오퍼레이션을 수행하는 Collection. + private final Collection drain = new UnsafeArrayCollection(maxDrainSize); + + private AsyncQueueingExecutorListener listener = EMPTY_LISTENER; + + + public AsyncQueueingExecutor() { + this(1024 * 5, "Pinpoint-AsyncQueueingExecutor"); + } + + public AsyncQueueingExecutor(int queueSize, String executorName) { + if (executorName == null) { + throw new NullPointerException("executorName must not be null"); + } + this.queue = new LinkedBlockingQueue(queueSize); + this.executeThread = this.createExecuteThread(executorName); + this.executorName = executeThread.getName(); + } + + private Thread createExecuteThread(String executorName) { + final ThreadFactory threadFactory = new PinpointThreadFactory(executorName, true); + Thread thread = threadFactory.newThread(this); + thread.start(); + return thread; + } + + @Override + public void run() { + logger.info("{} started.", executorName); + doExecute(); + } + + private void doExecute() { + drainStartEntry: + while (isRun()) { + try { + Collection dtoList = getDrainQueue(); + int drainSize = takeN(dtoList, this.maxDrainSize); + if (drainSize > 0) { + doExecute(dtoList); + continue; + } + + while (isRun()) { + T dto = takeOne(); + if (dto != null) { + doExecute(dto); + continue drainStartEntry; + } + } + } catch (Throwable th) { + logger.warn("{} doExecute(). Unexpected Error. Cause:{}", executorName, th.getMessage(), th); + } + } + flushQueue(); + } + + private void flushQueue() { + boolean debugEnabled = logger.isDebugEnabled(); + if (debugEnabled) { + logger.debug("Loop is stop."); + } + while(true) { + Collection dtoList = getDrainQueue(); + int drainSize = takeN(dtoList, this.maxDrainSize); + if (drainSize == 0) { + break; + } + if (debugEnabled) { + logger.debug("flushData size {}", drainSize); + } + doExecute(dtoList); + } + } + + protected T takeOne() { + try { + return queue.poll(1000 * 2, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return null; + } + } + + protected int takeN(Collection drain, int maxDrainSize) { + return queue.drainTo(drain, maxDrainSize); + } + + public boolean execute(T data) { + if (data == null) { + if (isWarn) { + logger.warn("execute(). data is null"); + } + return false; + } + if (!isRun.get()) { + if (isWarn) { + logger.warn("{} is shutdown. discard data:{}", executorName, data); + } + return false; + } + boolean offer = queue.offer(data); + if (!offer) { + if (isWarn) { + logger.warn("{} Drop data. queue is full. size:{}", executorName, queue.size()); + } + } + return offer; + } + + public void setListener(AsyncQueueingExecutorListener listener) { + if (listener == null) { + throw new NullPointerException("listener must not be null"); + } + this.listener = listener; + } + + private void doExecute(Collection dtoList) { + this.listener.execute(dtoList); + } + + private void doExecute(T dto) { + this.listener.execute(dto); + } + + public boolean isEmpty() { + return queue.isEmpty(); + } + + public boolean isRun() { + return isRun.get(); + } + + public void stop() { + isRun.set(false); + + if (!isEmpty()) { + logger.info("Wait 5 seconds. Flushing queued data."); + } + executeThread.interrupt(); + try { + executeThread.join(5000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("{} stopped incompletely.", executorName); + } + + logger.info("{} stopped.", executorName); + } + + Collection getDrainQueue() { + this.drain.clear(); + return drain; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutorListener.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutorListener.java index 55eb08ed6cd9..774b890da951 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutorListener.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/AsyncQueueingExecutorListener.java @@ -1,14 +1,14 @@ -package com.nhn.pinpoint.profiler.sender; - -import java.util.Collection; - -/** - * @author emeroad - */ -public interface AsyncQueueingExecutorListener { - - void execute(Collection messageList); - - void execute(T message); - -} +package com.nhn.pinpoint.profiler.sender; + +import java.util.Collection; + +/** + * @author emeroad + */ +public interface AsyncQueueingExecutorListener { + + void execute(Collection messageList); + + void execute(T message); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/DataSender.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/DataSender.java index 2096383fe71d..256294581539 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/DataSender.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/DataSender.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.profiler.sender; - -import org.apache.thrift.TBase; - -/** - * @author emeroad - * @author netspider - */ -public interface DataSender { - - boolean send(TBase data); - - void stop(); - - boolean isNetworkAvailable(); -} +package com.nhn.pinpoint.profiler.sender; + +import org.apache.thrift.TBase; + +/** + * @author emeroad + * @author netspider + */ +public interface DataSender { + + boolean send(TBase data); + + void stop(); + + boolean isNetworkAvailable(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EmptyAsyncQueueingExecutorListener.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EmptyAsyncQueueingExecutorListener.java index 95c34cd01a7d..c163dce8f36f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EmptyAsyncQueueingExecutorListener.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EmptyAsyncQueueingExecutorListener.java @@ -1,30 +1,30 @@ -package com.nhn.pinpoint.profiler.sender; - -import java.util.Collection; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class EmptyAsyncQueueingExecutorListener implements AsyncQueueingExecutorListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final boolean isDebug = logger.isDebugEnabled(); - - @Override - public void execute(Collection dtoList) { - if (isDebug) { - logger.debug("execute()"); - } - } - - @Override - public void execute(T dto) { - if (isDebug) { - logger.debug("execute()"); - } - } -} +package com.nhn.pinpoint.profiler.sender; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class EmptyAsyncQueueingExecutorListener implements AsyncQueueingExecutorListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final boolean isDebug = logger.isDebugEnabled(); + + @Override + public void execute(Collection dtoList) { + if (isDebug) { + logger.debug("execute()"); + } + } + + @Override + public void execute(T dto) { + if (isDebug) { + logger.debug("execute()"); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EnhancedDataSender.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EnhancedDataSender.java index 2ce0ebd439d6..c10599b8f901 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EnhancedDataSender.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/EnhancedDataSender.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.profiler.sender; - -import com.nhn.pinpoint.rpc.ResponseMessage; -import org.apache.thrift.TBase; - -import com.nhn.pinpoint.rpc.FutureListener; -import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; - -/** - * @author emeroad - */ -public interface EnhancedDataSender extends DataSender { - - boolean request(TBase data); - boolean request(TBase data, int retry); - boolean request(TBase data, FutureListener listener); - - boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener); - boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener); - -} +package com.nhn.pinpoint.profiler.sender; + +import com.nhn.pinpoint.rpc.ResponseMessage; +import org.apache.thrift.TBase; + +import com.nhn.pinpoint.rpc.FutureListener; +import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; + +/** + * @author emeroad + */ +public interface EnhancedDataSender extends DataSender { + + boolean request(TBase data); + boolean request(TBase data, int retry); + boolean request(TBase data, FutureListener listener); + + boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener); + boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/LoggingDataSender.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/LoggingDataSender.java index 6d65d2f13d93..638b1e572490 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/LoggingDataSender.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/LoggingDataSender.java @@ -1,69 +1,69 @@ -package com.nhn.pinpoint.profiler.sender; - -import com.nhn.pinpoint.rpc.ResponseMessage; -import org.apache.thrift.TBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.FutureListener; -import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; - - -/** - * @author emeroad - * @author netspider - */ -public class LoggingDataSender implements EnhancedDataSender { - - public static final DataSender DEFAULT_LOGGING_DATA_SENDER = new LoggingDataSender(); - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - public boolean send(TBase data) { - logger.info("send tBase:{}", data); - return true; - } - - - @Override - public void stop() { - logger.info("LoggingDataSender stop"); - } - - @Override - public boolean request(TBase data) { - logger.info("request tBase:{}", data); - return true; - } - - @Override - public boolean request(TBase data, int retry) { - logger.info("request tBase:{} retry:{}", data, retry); - return false; - } - - - @Override - public boolean request(TBase data, FutureListener listener) { - logger.info("request tBase:{} FutureListener:{}", data, listener); - return false; - } - - @Override - public boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - logger.info("addReconnectEventListener eventListener:{}", eventListener); - return false; - } - - @Override - public boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - logger.info("removeReconnectEventListener eventListener:{}", eventListener); - return false; - } - - @Override - public boolean isNetworkAvailable() { - return true; - } -} +package com.nhn.pinpoint.profiler.sender; + +import com.nhn.pinpoint.rpc.ResponseMessage; +import org.apache.thrift.TBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.FutureListener; +import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; + + +/** + * @author emeroad + * @author netspider + */ +public class LoggingDataSender implements EnhancedDataSender { + + public static final DataSender DEFAULT_LOGGING_DATA_SENDER = new LoggingDataSender(); + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public boolean send(TBase data) { + logger.info("send tBase:{}", data); + return true; + } + + + @Override + public void stop() { + logger.info("LoggingDataSender stop"); + } + + @Override + public boolean request(TBase data) { + logger.info("request tBase:{}", data); + return true; + } + + @Override + public boolean request(TBase data, int retry) { + logger.info("request tBase:{} retry:{}", data, retry); + return false; + } + + + @Override + public boolean request(TBase data, FutureListener listener) { + logger.info("request tBase:{} FutureListener:{}", data, listener); + return false; + } + + @Override + public boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + logger.info("addReconnectEventListener eventListener:{}", eventListener); + return false; + } + + @Override + public boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + logger.info("removeReconnectEventListener eventListener:{}", eventListener); + return false; + } + + @Override + public boolean isNetworkAvailable() { + return true; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryMessage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryMessage.java index 0533ef2111e5..b9d580f8228c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryMessage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryMessage.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.profiler.sender; - -/** - * @author emeroad - */ -public class RetryMessage { - private int retryCount; - private byte[] bytes; - - public RetryMessage(int retryCount, byte[] bytes) { - this.retryCount = retryCount; - this.bytes = bytes; - } - - public int getRetryCount() { - return retryCount; - } - - public byte[] getBytes() { - return bytes; - } - - public int fail() { - return ++retryCount; - } -} +package com.nhn.pinpoint.profiler.sender; + +/** + * @author emeroad + */ +public class RetryMessage { + private int retryCount; + private byte[] bytes; + + public RetryMessage(int retryCount, byte[] bytes) { + this.retryCount = retryCount; + this.bytes = bytes; + } + + public int getRetryCount() { + return retryCount; + } + + public byte[] getBytes() { + return bytes; + } + + public int fail() { + return ++retryCount; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryQueue.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryQueue.java index ff0d4f41e956..01b0f74d0c17 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryQueue.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/RetryQueue.java @@ -1,64 +1,64 @@ -package com.nhn.pinpoint.profiler.sender; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * @author emeroad - */ -public class RetryQueue { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - // 우선순위 큐로 재전송 횟수가 적은것 순으로 남기고 싶지만. 갯수제한이 안되니 그냥 만듬. - private final BlockingQueue queue; - private final int capacity; - private final int maxRetry; - private final int halfCapacity; - - - public RetryQueue(int capacity, int maxRetry) { - this.queue = new LinkedBlockingQueue(); - this.capacity = capacity; - this.halfCapacity = capacity / 2; - this.maxRetry = maxRetry; - } - - public RetryQueue() { - this(1024, 3); - } - - public void add(RetryMessage retryMessage) { - if (retryMessage == null) { - throw new NullPointerException("retryMessage must not be null"); - } - - final int retryCount = retryMessage.getRetryCount(); - if (retryCount >= this.maxRetry) { - logger.warn("discard retry message. retryCount:{}", retryCount); - return; - } - final int queueSize = queue.size(); - if (queueSize >= capacity) { - logger.warn("discard retry message. queueSize:{}", queueSize); - return; - } - if (queueSize >= halfCapacity && retryCount >= 1) { - logger.warn("discard retry message. retryCount:{}", retryCount); - return; - } - final boolean offer = this.queue.offer(retryMessage); - if (!offer) { - logger.warn("offer() fail. discard retry message. retryCount:{}", retryCount); - } - } - - public RetryMessage get() { - return this.queue.poll(); - } - - public int size() { - return this.queue.size(); - } -} +package com.nhn.pinpoint.profiler.sender; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * @author emeroad + */ +public class RetryQueue { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + // 우선순위 큐로 재전송 횟수가 적은것 순으로 남기고 싶지만. 갯수제한이 안되니 그냥 만듬. + private final BlockingQueue queue; + private final int capacity; + private final int maxRetry; + private final int halfCapacity; + + + public RetryQueue(int capacity, int maxRetry) { + this.queue = new LinkedBlockingQueue(); + this.capacity = capacity; + this.halfCapacity = capacity / 2; + this.maxRetry = maxRetry; + } + + public RetryQueue() { + this(1024, 3); + } + + public void add(RetryMessage retryMessage) { + if (retryMessage == null) { + throw new NullPointerException("retryMessage must not be null"); + } + + final int retryCount = retryMessage.getRetryCount(); + if (retryCount >= this.maxRetry) { + logger.warn("discard retry message. retryCount:{}", retryCount); + return; + } + final int queueSize = queue.size(); + if (queueSize >= capacity) { + logger.warn("discard retry message. queueSize:{}", queueSize); + return; + } + if (queueSize >= halfCapacity && retryCount >= 1) { + logger.warn("discard retry message. retryCount:{}", retryCount); + return; + } + final boolean offer = this.queue.offer(retryMessage); + if (!offer) { + logger.warn("offer() fail. discard retry message. retryCount:{}", retryCount); + } + } + + public RetryMessage get() { + return this.queue.poll(); + } + + public int size() { + return this.queue.size(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/TcpDataSender.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/TcpDataSender.java index 744cab1f0e90..a3a28776196c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/TcpDataSender.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/TcpDataSender.java @@ -1,230 +1,230 @@ -package com.nhn.pinpoint.profiler.sender; - - -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.thrift.TBase; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.Timer; -import org.jboss.netty.util.TimerTask; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.FutureListener; -import com.nhn.pinpoint.rpc.ResponseMessage; -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; -import com.nhn.pinpoint.rpc.util.TimerFactory; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; - -/** - * @author emeroad - * @author koo.taejin - * @author netspider - */ -public class TcpDataSender extends AbstractDataSender implements EnhancedDataSender { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - static { - // preClassLoad - ChannelBuffers.buffer(2); - } - - private final PinpointSocket socket; - private final Timer timer; - - private final AtomicBoolean fireState = new AtomicBoolean(false); - - private final WriteFailFutureListener writeFailFutureListener; - - - private final HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); - - private final RetryQueue retryQueue = new RetryQueue(); - - private AsyncQueueingExecutor executor; - - public TcpDataSender(PinpointSocket socket) { - this.socket = socket; - this.timer = createTimer(); - writeFailFutureListener = new WriteFailFutureListener(logger, "io write fail.", "host", -1); - this.executor = createAsyncQueueingExecutor(1024 * 5, "Pinpoint-TcpDataExecutor"); - } - - private Timer createTimer() { - HashedWheelTimer timer = TimerFactory.createHashedWheelTimer("Pinpoint-DataSender-Timer", 100, TimeUnit.MILLISECONDS, 512); - timer.start(); - return timer; - } - - @Override - public boolean send(TBase data) { - return executor.execute(data); - } - - @Override - public boolean request(TBase data) { - return this.request(data, 3); - } - - @Override - public boolean request(TBase data, int retryCount) { - RequestMarker message = new RequestMarker(data, retryCount); - return executor.execute(message); - } - - @Override - public boolean request(TBase data, FutureListener listener) { - RequestMarker message = new RequestMarker(data, listener); - return executor.execute(message); - } - - @Override - public boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - return this.socket.addPinpointSocketReconnectEventListener(eventListener); - } - - @Override - public boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - return this.socket.removePinpointSocketReconnectEventListener(eventListener); - } - - @Override - public void stop() { - executor.stop(); - - Set stop = timer.stop(); - if (!stop.isEmpty()) { - logger.info("stop Timeout:{}", stop.size()); - } - } - - @Override - protected void sendPacket(Object message) { - try { - if (message instanceof TBase) { - byte[] copy = serialize(serializer, (TBase) message); - if (copy == null) { - return; - } - doSend(copy); - } else if (message instanceof RequestMarker) { - RequestMarker requestMarker = (RequestMarker) message; - - TBase tBase = requestMarker.getTBase(); - int retryCount = requestMarker.getRetryCount(); - FutureListener futureListener = requestMarker.getFutureListener(); - byte[] copy = serialize(serializer, tBase); - if (copy == null) { - return; - } - - if (futureListener != null) { - doRequest(copy, futureListener); - } else { - doRequest(copy, retryCount, tBase); - } - } else { - logger.error("sendPacket fail. invalid dto type:{}", message.getClass()); - return; - } - } catch (Exception e) { - // 일단 exception 계층이 좀 엉터리라 Exception으로 그냥 잡음. - logger.warn("tcp send fail. Caused:{}", e.getMessage(), e); - } - } - - private void doSend(byte[] copy) { - Future write = this.socket.sendAsync(copy); - write.setListener(writeFailFutureListener); - } - - private void doRequest(final byte[] requestPacket, final int retryCount, final Object targetClass) { - FutureListener futureListner = (new FutureListener() { - @Override - public void onComplete(Future future) { - if (future.isSuccess()) { - // caching해야 될려나? - HeaderTBaseDeserializer deserializer = HeaderTBaseDeserializerFactory.DEFAULT_FACTORY.createDeserializer(); - TBase response = deserialize(deserializer, future.getResult()); - if (response instanceof TResult) { - TResult result = (TResult) response; - if (result.isSuccess()) { - logger.debug("result success"); - } else { - logger.warn("request fail. clazz:{} Caused:{}", targetClass, result.getMessage()); - retryRequest(requestPacket, retryCount, targetClass.getClass().getSimpleName()); - } - } else { - logger.warn("Invalid ResponseMessage. {}", response); -// response가 이상하게 오는 케이스는 재전송 케이스가 아니고 로그를 통한 정확한 원인 분석이 필요한 케이스이다. -// null이 떨어질수도 있음. -// retryRequest(requestPacket); - } - } else { - logger.warn("request fail. clazz:{} Caused:{}", targetClass, future.getCause().getMessage(), future.getCause()); - retryRequest(requestPacket, retryCount, targetClass.getClass().getSimpleName()); - } - } - }); - - doRequest(requestPacket, futureListner); - } - - private void retryRequest(byte[] requestPacket, int retryCount, final String className) { - RetryMessage retryMessage = new RetryMessage(retryCount, requestPacket); - retryQueue.add(retryMessage); - if (fireTimeout()) { - timer.newTimeout(new TimerTask() { - @Override - public void run(Timeout timeout) throws Exception { - while(true) { - RetryMessage retryMessage = retryQueue.get(); - if (retryMessage == null) { - // 동시성이 약간 안맞을 가능성 있는거 같기는 하나. 크게 문제 없을거 같아서 일단 패스. - fireComplete(); - return; - } - int fail = retryMessage.fail(); - doRequest(retryMessage.getBytes(), fail, className); - } - } - }, 1000 * 10, TimeUnit.MILLISECONDS); - } - } - - private void doRequest(final byte[] requestPacket, FutureListener futureListener) { - final Future response = this.socket.request(requestPacket); - response.setListener(futureListener); - } - - private boolean fireTimeout() { - if (fireState.compareAndSet(false, true)) { - return true; - } else { - return false; - } - } - - private void fireComplete() { - logger.debug("fireComplete"); - fireState.compareAndSet(true, false); - } - - @Override - public boolean isNetworkAvailable() { - if (this.socket == null) { - return false; - } - return this.socket.isConnected(); - } -} +package com.nhn.pinpoint.profiler.sender; + + +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.thrift.TBase; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.Timer; +import org.jboss.netty.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.FutureListener; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; +import com.nhn.pinpoint.rpc.util.TimerFactory; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; + +/** + * @author emeroad + * @author koo.taejin + * @author netspider + */ +public class TcpDataSender extends AbstractDataSender implements EnhancedDataSender { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + static { + // preClassLoad + ChannelBuffers.buffer(2); + } + + private final PinpointSocket socket; + private final Timer timer; + + private final AtomicBoolean fireState = new AtomicBoolean(false); + + private final WriteFailFutureListener writeFailFutureListener; + + + private final HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); + + private final RetryQueue retryQueue = new RetryQueue(); + + private AsyncQueueingExecutor executor; + + public TcpDataSender(PinpointSocket socket) { + this.socket = socket; + this.timer = createTimer(); + writeFailFutureListener = new WriteFailFutureListener(logger, "io write fail.", "host", -1); + this.executor = createAsyncQueueingExecutor(1024 * 5, "Pinpoint-TcpDataExecutor"); + } + + private Timer createTimer() { + HashedWheelTimer timer = TimerFactory.createHashedWheelTimer("Pinpoint-DataSender-Timer", 100, TimeUnit.MILLISECONDS, 512); + timer.start(); + return timer; + } + + @Override + public boolean send(TBase data) { + return executor.execute(data); + } + + @Override + public boolean request(TBase data) { + return this.request(data, 3); + } + + @Override + public boolean request(TBase data, int retryCount) { + RequestMarker message = new RequestMarker(data, retryCount); + return executor.execute(message); + } + + @Override + public boolean request(TBase data, FutureListener listener) { + RequestMarker message = new RequestMarker(data, listener); + return executor.execute(message); + } + + @Override + public boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + return this.socket.addPinpointSocketReconnectEventListener(eventListener); + } + + @Override + public boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + return this.socket.removePinpointSocketReconnectEventListener(eventListener); + } + + @Override + public void stop() { + executor.stop(); + + Set stop = timer.stop(); + if (!stop.isEmpty()) { + logger.info("stop Timeout:{}", stop.size()); + } + } + + @Override + protected void sendPacket(Object message) { + try { + if (message instanceof TBase) { + byte[] copy = serialize(serializer, (TBase) message); + if (copy == null) { + return; + } + doSend(copy); + } else if (message instanceof RequestMarker) { + RequestMarker requestMarker = (RequestMarker) message; + + TBase tBase = requestMarker.getTBase(); + int retryCount = requestMarker.getRetryCount(); + FutureListener futureListener = requestMarker.getFutureListener(); + byte[] copy = serialize(serializer, tBase); + if (copy == null) { + return; + } + + if (futureListener != null) { + doRequest(copy, futureListener); + } else { + doRequest(copy, retryCount, tBase); + } + } else { + logger.error("sendPacket fail. invalid dto type:{}", message.getClass()); + return; + } + } catch (Exception e) { + // 일단 exception 계층이 좀 엉터리라 Exception으로 그냥 잡음. + logger.warn("tcp send fail. Caused:{}", e.getMessage(), e); + } + } + + private void doSend(byte[] copy) { + Future write = this.socket.sendAsync(copy); + write.setListener(writeFailFutureListener); + } + + private void doRequest(final byte[] requestPacket, final int retryCount, final Object targetClass) { + FutureListener futureListner = (new FutureListener() { + @Override + public void onComplete(Future future) { + if (future.isSuccess()) { + // caching해야 될려나? + HeaderTBaseDeserializer deserializer = HeaderTBaseDeserializerFactory.DEFAULT_FACTORY.createDeserializer(); + TBase response = deserialize(deserializer, future.getResult()); + if (response instanceof TResult) { + TResult result = (TResult) response; + if (result.isSuccess()) { + logger.debug("result success"); + } else { + logger.warn("request fail. clazz:{} Caused:{}", targetClass, result.getMessage()); + retryRequest(requestPacket, retryCount, targetClass.getClass().getSimpleName()); + } + } else { + logger.warn("Invalid ResponseMessage. {}", response); +// response가 이상하게 오는 케이스는 재전송 케이스가 아니고 로그를 통한 정확한 원인 분석이 필요한 케이스이다. +// null이 떨어질수도 있음. +// retryRequest(requestPacket); + } + } else { + logger.warn("request fail. clazz:{} Caused:{}", targetClass, future.getCause().getMessage(), future.getCause()); + retryRequest(requestPacket, retryCount, targetClass.getClass().getSimpleName()); + } + } + }); + + doRequest(requestPacket, futureListner); + } + + private void retryRequest(byte[] requestPacket, int retryCount, final String className) { + RetryMessage retryMessage = new RetryMessage(retryCount, requestPacket); + retryQueue.add(retryMessage); + if (fireTimeout()) { + timer.newTimeout(new TimerTask() { + @Override + public void run(Timeout timeout) throws Exception { + while(true) { + RetryMessage retryMessage = retryQueue.get(); + if (retryMessage == null) { + // 동시성이 약간 안맞을 가능성 있는거 같기는 하나. 크게 문제 없을거 같아서 일단 패스. + fireComplete(); + return; + } + int fail = retryMessage.fail(); + doRequest(retryMessage.getBytes(), fail, className); + } + } + }, 1000 * 10, TimeUnit.MILLISECONDS); + } + } + + private void doRequest(final byte[] requestPacket, FutureListener futureListener) { + final Future response = this.socket.request(requestPacket); + response.setListener(futureListener); + } + + private boolean fireTimeout() { + if (fireState.compareAndSet(false, true)) { + return true; + } else { + return false; + } + } + + private void fireComplete() { + logger.debug("fireComplete"); + fireState.compareAndSet(true, false); + } + + @Override + public boolean isNetworkAvailable() { + if (this.socket == null) { + return false; + } + return this.socket.isConnected(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/UnsafeArrayCollection.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/UnsafeArrayCollection.java index fdd2377377ad..eb84cd9d5365 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/UnsafeArrayCollection.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/UnsafeArrayCollection.java @@ -1,59 +1,59 @@ -package com.nhn.pinpoint.profiler.sender; - -import java.util.AbstractCollection; -import java.util.Iterator; - -/** - * @author emeroad - */ -class UnsafeArrayCollection extends AbstractCollection { - - private int size = 0; - private final Object[] array; - - public UnsafeArrayCollection(int maxSize) { - this.array = new Object[maxSize]; - } - - - @Override - public boolean add(E o) { - if (array.length < size) { - throw new IndexOutOfBoundsException("size:" + this.size + " array.length:" + array.length); - } - // array index 체크 안함. - array[size] = o; - size++; - return true; - } - - @Override - public void clear() { - // array의 값은 지워줘야 함. 지우지 않으면 cpu는 덜쓰나 나머지 값이 메모리에 계속 있음. - for (int i = 0; i < size; i++) { - this.array[i] = null; - } - this.size = 0; - } - - @Override - public boolean isEmpty() { - return this.size == 0; - } - - @Override - public Iterator iterator() { - throw new UnsupportedOperationException(); - } - - @Override - public int size() { - return size; - } - - @Override - public Object[] toArray() { - // internal buf를 그대로 전달 - return array; - } -} +package com.nhn.pinpoint.profiler.sender; + +import java.util.AbstractCollection; +import java.util.Iterator; + +/** + * @author emeroad + */ +class UnsafeArrayCollection extends AbstractCollection { + + private int size = 0; + private final Object[] array; + + public UnsafeArrayCollection(int maxSize) { + this.array = new Object[maxSize]; + } + + + @Override + public boolean add(E o) { + if (array.length < size) { + throw new IndexOutOfBoundsException("size:" + this.size + " array.length:" + array.length); + } + // array index 체크 안함. + array[size] = o; + size++; + return true; + } + + @Override + public void clear() { + // array의 값은 지워줘야 함. 지우지 않으면 cpu는 덜쓰나 나머지 값이 메모리에 계속 있음. + for (int i = 0; i < size; i++) { + this.array[i] = null; + } + this.size = 0; + } + + @Override + public boolean isEmpty() { + return this.size == 0; + } + + @Override + public Iterator iterator() { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + return size; + } + + @Override + public Object[] toArray() { + // internal buf를 그대로 전달 + return array; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/WriteFailFutureListener.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/WriteFailFutureListener.java index e8e38a371ccc..3f66d5752cbb 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/WriteFailFutureListener.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/WriteFailFutureListener.java @@ -1,38 +1,38 @@ -package com.nhn.pinpoint.profiler.sender; - -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.FutureListener; -import org.slf4j.Logger; - -/** - * @author emeroad - */ -public class WriteFailFutureListener implements FutureListener { - - private final Logger logger; - private final String message; - private final String host; - private final String port; - private final boolean isWarn; - - - public WriteFailFutureListener(Logger logger, String message, String host, int port) { - if (logger == null) { - throw new NullPointerException("logger must not be null"); - } - this.logger = logger; - this.message = message; - this.host = host; - this.port = String.valueOf(port); - this.isWarn = logger.isWarnEnabled(); - } - - @Override - public void onComplete(Future future) { - if (!future.isSuccess()) { - if (isWarn) { - logger.warn("{} {}/{}", message, host, port); - } - } - } +package com.nhn.pinpoint.profiler.sender; + +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.FutureListener; +import org.slf4j.Logger; + +/** + * @author emeroad + */ +public class WriteFailFutureListener implements FutureListener { + + private final Logger logger; + private final String message; + private final String host; + private final String port; + private final boolean isWarn; + + + public WriteFailFutureListener(Logger logger, String message, String host, int port) { + if (logger == null) { + throw new NullPointerException("logger must not be null"); + } + this.logger = logger; + this.message = message; + this.host = host; + this.port = String.valueOf(port); + this.isWarn = logger.isWarnEnabled(); + } + + @Override + public void onComplete(Future future) { + if (!future.isSuccess()) { + if (isWarn) { + logger.warn("{} {}/{}", message, host, port); + } + } + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApiUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApiUtils.java index 26503f930013..887d3cfdacfc 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApiUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApiUtils.java @@ -1,53 +1,53 @@ -package com.nhn.pinpoint.profiler.util; - -import java.util.Arrays; - -/** - * @author emeroad - */ -public final class ApiUtils { - - private final static String EMPTY_ARRAY = "()"; - - private ApiUtils() { - } - - public static String mergeParameterVariableNameDescription(String[] parameterType, String[] variableName) { - if (parameterType == null ) { - if (variableName == null) { - return EMPTY_ARRAY; - } else { - throw new IllegalArgumentException("invalid null pair parameterType:" + Arrays.toString(parameterType) + ", variableName:" + Arrays.toString(variableName)); - } - } - if (parameterType.length != variableName.length) { - throw new IllegalArgumentException("args size not equal"); - } - if (parameterType.length == 0) { - return EMPTY_ARRAY; - } - - StringBuilder sb = new StringBuilder(64); - sb.append('('); - int end = parameterType.length - 1; - for (int i = 0; i < parameterType.length; i++) { - sb.append(parameterType[i]); - sb.append(' '); - sb.append(variableName[i]); - if (i < end) { - sb.append(", "); - } - } - sb.append(')'); - return sb.toString(); - } - - public static String mergeApiDescriptor(String className, String methodName, String parameterDescriptor) { - StringBuilder buffer = new StringBuilder(256); - buffer.append(className); - buffer.append("."); - buffer.append(methodName); - buffer.append(parameterDescriptor); - return buffer.toString(); - } -} +package com.nhn.pinpoint.profiler.util; + +import java.util.Arrays; + +/** + * @author emeroad + */ +public final class ApiUtils { + + private final static String EMPTY_ARRAY = "()"; + + private ApiUtils() { + } + + public static String mergeParameterVariableNameDescription(String[] parameterType, String[] variableName) { + if (parameterType == null ) { + if (variableName == null) { + return EMPTY_ARRAY; + } else { + throw new IllegalArgumentException("invalid null pair parameterType:" + Arrays.toString(parameterType) + ", variableName:" + Arrays.toString(variableName)); + } + } + if (parameterType.length != variableName.length) { + throw new IllegalArgumentException("args size not equal"); + } + if (parameterType.length == 0) { + return EMPTY_ARRAY; + } + + StringBuilder sb = new StringBuilder(64); + sb.append('('); + int end = parameterType.length - 1; + for (int i = 0; i < parameterType.length; i++) { + sb.append(parameterType[i]); + sb.append(' '); + sb.append(variableName[i]); + if (i < end) { + sb.append(", "); + } + } + sb.append(')'); + return sb.toString(); + } + + public static String mergeApiDescriptor(String className, String methodName, String parameterDescriptor) { + StringBuilder buffer = new StringBuilder(256); + buffer.append(className); + buffer.append("."); + buffer.append(methodName); + buffer.append(parameterDescriptor); + return buffer.toString(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApplicationServerTypeResolver.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApplicationServerTypeResolver.java index f2a0982debf2..79a6a19a757d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApplicationServerTypeResolver.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ApplicationServerTypeResolver.java @@ -1,132 +1,132 @@ -package com.nhn.pinpoint.profiler.util; - -import com.nhn.pinpoint.common.ServiceType; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; - -/** - * @author emeroad - * @author netspider - */ -public class ApplicationServerTypeResolver { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private ServiceType serverType; - private String[] serverLibPath; - - private ServiceType defaultType; - - /** - * Agent를 수동으로 startup해야하는가 여부. - * Application에 별도 acceptor가 없어서 startup함수를 agent 초기화 할 때 해주어야하는 경우. - * 예를 들어 서비스타입이 BLOC, STAND_ALONE인 경우. - */ - private boolean manuallyStartupRequired = false; - - public ApplicationServerTypeResolver(ServiceType defaultType) { - this.defaultType = defaultType; - } - - public ApplicationServerTypeResolver() { - } - - public String[] getServerLibPath() { - return serverLibPath; - } - - public ServiceType getServerType() { - return serverType; - } - - public boolean isManuallyStartupRequired() { - return manuallyStartupRequired; - } - - public boolean resolve() { - String applicationHome = System.getProperty("catalina.home"); - - if (applicationHome == null) { - // FIXME BLOC_HOME, BLOC_BASE가 있을 듯. - applicationHome = System.getProperty("user.dir"); - } - - if (logger.isInfoEnabled()) { - logger.info("Resolved ApplicationHome:{}", applicationHome); - } - - /** - * application type이 설정파일에 지정되어있는 경우. - */ - if (defaultType != null) { - logger.info("Configured applicationServerType:{}", defaultType); - return initializeApplicationInfo(applicationHome, defaultType); - } - - /** - * application type이 설정파일에 없으면 자동 검색 - */ - final File bloc3CatalinaJar = new File(applicationHome + "/server/lib/catalina.jar"); - final File bloc3ServletApiJar = new File(applicationHome + "/common/lib/servlet-api.jar"); - final File bloc4LibDir = new File(applicationHome + "/libs"); - - if (isFileExist(bloc3CatalinaJar) && isFileExist(bloc3ServletApiJar)) { - this.manuallyStartupRequired = false; - return initializeApplicationInfo(applicationHome, ServiceType.BLOC); - } else if (isFileExist(bloc4LibDir)) { - this.manuallyStartupRequired = true; - return initializeApplicationInfo(applicationHome, ServiceType.BLOC); - } else if (isFileExist(new File(applicationHome + "/lib/catalina.jar"))) { - this.manuallyStartupRequired = false; - return initializeApplicationInfo(applicationHome, ServiceType.TOMCAT); - } else { - this.manuallyStartupRequired = true; - return initializeApplicationInfo(applicationHome, ServiceType.STAND_ALONE); - } - } - - private boolean initializeApplicationInfo(String applicationHome, ServiceType serviceType) { - if (applicationHome == null) { - logger.warn("applicationHome is null"); - return false; - } - - if (ServiceType.TOMCAT.equals(serviceType)) { - this.serverLibPath = new String[] { applicationHome + "/lib/servlet-api.jar", applicationHome + "/lib/catalina.jar" }; - } else if (ServiceType.BLOC.equals(serviceType)) { - // FIXME serverLibPath지정 방법을 개선할 수 있을 듯. - if (manuallyStartupRequired) { - // BLOC 4.x - this.serverLibPath = new String[] {}; - } else { - // BLOC 3.x - this.serverLibPath = new String[] { applicationHome + "/server/lib/catalina.jar", applicationHome + "/common/lib/servlet-api.jar" }; - } - } else if (ServiceType.STAND_ALONE.equals(serviceType)) { - this.serverLibPath = new String[] {}; - } else if (ServiceType.TEST_STAND_ALONE.equals(serviceType)) { - this.serverLibPath = new String[] {}; - } else { - logger.warn("Invalid Default ApplicationServiceType:{} ", defaultType); - return false; - } - - this.serverType = serviceType; - - logger.info("ApplicationServerType:{}, RequiredServerLibraryPath:{}", serverType, serverLibPath); - - return true; - } - - private boolean isFileExist(File libFile) { - final boolean found = libFile.exists(); // && libFile.isFile(); - if (found) { - logger.debug("libFile found:{}", libFile); - } else { - logger.debug("libFile not found:{}", libFile); - } - return found; - } -} +package com.nhn.pinpoint.profiler.util; + +import com.nhn.pinpoint.common.ServiceType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * @author emeroad + * @author netspider + */ +public class ApplicationServerTypeResolver { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private ServiceType serverType; + private String[] serverLibPath; + + private ServiceType defaultType; + + /** + * Agent를 수동으로 startup해야하는가 여부. + * Application에 별도 acceptor가 없어서 startup함수를 agent 초기화 할 때 해주어야하는 경우. + * 예를 들어 서비스타입이 BLOC, STAND_ALONE인 경우. + */ + private boolean manuallyStartupRequired = false; + + public ApplicationServerTypeResolver(ServiceType defaultType) { + this.defaultType = defaultType; + } + + public ApplicationServerTypeResolver() { + } + + public String[] getServerLibPath() { + return serverLibPath; + } + + public ServiceType getServerType() { + return serverType; + } + + public boolean isManuallyStartupRequired() { + return manuallyStartupRequired; + } + + public boolean resolve() { + String applicationHome = System.getProperty("catalina.home"); + + if (applicationHome == null) { + // FIXME BLOC_HOME, BLOC_BASE가 있을 듯. + applicationHome = System.getProperty("user.dir"); + } + + if (logger.isInfoEnabled()) { + logger.info("Resolved ApplicationHome:{}", applicationHome); + } + + /** + * application type이 설정파일에 지정되어있는 경우. + */ + if (defaultType != null) { + logger.info("Configured applicationServerType:{}", defaultType); + return initializeApplicationInfo(applicationHome, defaultType); + } + + /** + * application type이 설정파일에 없으면 자동 검색 + */ + final File bloc3CatalinaJar = new File(applicationHome + "/server/lib/catalina.jar"); + final File bloc3ServletApiJar = new File(applicationHome + "/common/lib/servlet-api.jar"); + final File bloc4LibDir = new File(applicationHome + "/libs"); + + if (isFileExist(bloc3CatalinaJar) && isFileExist(bloc3ServletApiJar)) { + this.manuallyStartupRequired = false; + return initializeApplicationInfo(applicationHome, ServiceType.BLOC); + } else if (isFileExist(bloc4LibDir)) { + this.manuallyStartupRequired = true; + return initializeApplicationInfo(applicationHome, ServiceType.BLOC); + } else if (isFileExist(new File(applicationHome + "/lib/catalina.jar"))) { + this.manuallyStartupRequired = false; + return initializeApplicationInfo(applicationHome, ServiceType.TOMCAT); + } else { + this.manuallyStartupRequired = true; + return initializeApplicationInfo(applicationHome, ServiceType.STAND_ALONE); + } + } + + private boolean initializeApplicationInfo(String applicationHome, ServiceType serviceType) { + if (applicationHome == null) { + logger.warn("applicationHome is null"); + return false; + } + + if (ServiceType.TOMCAT.equals(serviceType)) { + this.serverLibPath = new String[] { applicationHome + "/lib/servlet-api.jar", applicationHome + "/lib/catalina.jar" }; + } else if (ServiceType.BLOC.equals(serviceType)) { + // FIXME serverLibPath지정 방법을 개선할 수 있을 듯. + if (manuallyStartupRequired) { + // BLOC 4.x + this.serverLibPath = new String[] {}; + } else { + // BLOC 3.x + this.serverLibPath = new String[] { applicationHome + "/server/lib/catalina.jar", applicationHome + "/common/lib/servlet-api.jar" }; + } + } else if (ServiceType.STAND_ALONE.equals(serviceType)) { + this.serverLibPath = new String[] {}; + } else if (ServiceType.TEST_STAND_ALONE.equals(serviceType)) { + this.serverLibPath = new String[] {}; + } else { + logger.warn("Invalid Default ApplicationServiceType:{} ", defaultType); + return false; + } + + this.serverType = serviceType; + + logger.info("ApplicationServerType:{}, RequiredServerLibraryPath:{}", serverType, serverLibPath); + + return true; + } + + private boolean isFileExist(File libFile) { + final boolean found = libFile.exists(); // && libFile.isFile(); + if (found) { + logger.debug("libFile found:{}", libFile); + } else { + logger.debug("libFile not found:{}", libFile); + } + return found; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ArrayUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ArrayUtils.java index 627b4166eee9..e0db6db3939a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ArrayUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ArrayUtils.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.profiler.util; - -/** - * @author emeroad - */ -public final class ArrayUtils { - - private ArrayUtils() { - } - - public static String dropToString(byte[] bytes) { - return dropToString(bytes, 32); - } - - public static String dropToString(byte[] bytes, int limit) { - if (bytes == null) { - return "null"; - } - if (limit < 0) { - throw new IllegalArgumentException("negative limit:" + limit); - } - // TODO limit음수일 경우 예외처리 필요. - // size 4인 배열의 경 3에서 멈춰야 하므로 -1 - int bytesMaxLength = bytes.length - 1; - final int maxLimit = limit - 1; - if (bytesMaxLength > maxLimit) { - bytesMaxLength = maxLimit; - } - if (bytesMaxLength == -1) { - if (bytes.length == 0) { - return "[]"; - } else { - return "[...(" + bytes.length + ")]"; - } - } - - - final StringBuilder sb = new StringBuilder(); - sb.append('['); - for (int i = 0; ; i++) { - sb.append(bytes[i]); - if (i == bytesMaxLength) { - if ((bytes.length - 1) <= maxLimit) { - return sb.append(']').toString(); - } else { - sb.append(", ...("); - sb.append(bytes.length - (i+1)); - sb.append(")]"); - return sb.toString(); - } - } - sb.append(", "); - } - } - - -} +package com.nhn.pinpoint.profiler.util; + +/** + * @author emeroad + */ +public final class ArrayUtils { + + private ArrayUtils() { + } + + public static String dropToString(byte[] bytes) { + return dropToString(bytes, 32); + } + + public static String dropToString(byte[] bytes, int limit) { + if (bytes == null) { + return "null"; + } + if (limit < 0) { + throw new IllegalArgumentException("negative limit:" + limit); + } + // TODO limit음수일 경우 예외처리 필요. + // size 4인 배열의 경 3에서 멈춰야 하므로 -1 + int bytesMaxLength = bytes.length - 1; + final int maxLimit = limit - 1; + if (bytesMaxLength > maxLimit) { + bytesMaxLength = maxLimit; + } + if (bytesMaxLength == -1) { + if (bytes.length == 0) { + return "[]"; + } else { + return "[...(" + bytes.length + ")]"; + } + } + + + final StringBuilder sb = new StringBuilder(); + sb.append('['); + for (int i = 0; ; i++) { + sb.append(bytes[i]); + if (i == bytesMaxLength) { + if ((bytes.length - 1) <= maxLimit) { + return sb.append(']').toString(); + } else { + sb.append(", ...("); + sb.append(bytes.length - (i+1)); + sb.append(")]"); + return sb.toString(); + } + } + sb.append(", "); + } + } + + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/BindVariableFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/BindVariableFilter.java index 2e97a70f7b77..5a9e38aaf226 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/BindVariableFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/BindVariableFilter.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.profiler.util; - -import java.lang.reflect.Method; - -/** - * @author emeroad - */ -public interface BindVariableFilter { - boolean filter(Method method); -} +package com.nhn.pinpoint.profiler.util; + +import java.lang.reflect.Method; + +/** + * @author emeroad + */ +public interface BindVariableFilter { + boolean filter(Method method); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ClassUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ClassUtils.java index ee99f3d188a7..a1ba6b3871be 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ClassUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ClassUtils.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.profiler.util; - -/** - * @author koo.taejin - */ -public final class ClassUtils { - - private ClassUtils() { - } - - public static boolean isAssignableValue(Class type, Object value) { - if (type == null) { - return false; - } - - if (type.isPrimitive()) { - return false; - } - - if (value == null) { - return false; - } - - return type.isInstance(value); - } - -} +package com.nhn.pinpoint.profiler.util; + +/** + * @author koo.taejin + */ +public final class ClassUtils { + + private ClassUtils() { + } + + public static boolean isAssignableValue(Class type, Object value) { + if (type == null) { + return false; + } + + if (type.isPrimitive()) { + return false; + } + + if (value == null) { + return false; + } + + return type.isInstance(value); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/DepthScope.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/DepthScope.java index 07b7e03a248f..3aac97834ff7 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/DepthScope.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/DepthScope.java @@ -1,69 +1,69 @@ -package com.nhn.pinpoint.profiler.util; - -/** - * @author emeroad - */ -public final class DepthScope implements Scope { - - public static final int ZERO = 0; - - private final NamedThreadLocal scope; - - - public DepthScope(final String scopeName) { - this.scope = new NamedThreadLocal(scopeName) { - @Override - protected Depth initialValue() { - return new Depth(); - } - }; - } - - @Override - public int push() { - final Depth depth = scope.get(); - return depth.push(); - } - - @Override - public int depth() { - final Depth depth = scope.get(); - return depth.depth(); - } - - @Override - public int pop() { - final Depth depth = scope.get(); - return depth.pop(); - } - - private static final class Depth { - private int depth = 0; - - public int push() { - return depth++; - } - - public int pop() { - return --depth; - } - - public int depth() { - return depth; - } - - } - - @Override - public String getName() { - return scope.getName(); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("DepthScope{"); - sb.append("scope=").append(scope.getName()); - sb.append('}'); - return sb.toString(); - } +package com.nhn.pinpoint.profiler.util; + +/** + * @author emeroad + */ +public final class DepthScope implements Scope { + + public static final int ZERO = 0; + + private final NamedThreadLocal scope; + + + public DepthScope(final String scopeName) { + this.scope = new NamedThreadLocal(scopeName) { + @Override + protected Depth initialValue() { + return new Depth(); + } + }; + } + + @Override + public int push() { + final Depth depth = scope.get(); + return depth.push(); + } + + @Override + public int depth() { + final Depth depth = scope.get(); + return depth.depth(); + } + + @Override + public int pop() { + final Depth depth = scope.get(); + return depth.pop(); + } + + private static final class Depth { + private int depth = 0; + + public int push() { + return depth++; + } + + public int pop() { + return --depth; + } + + public int depth() { + return depth; + } + + } + + @Override + public String getName() { + return scope.getName(); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("DepthScope{"); + sb.append("scope=").append(scope.getName()); + sb.append('}'); + return sb.toString(); + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ErrorInjectUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ErrorInjectUtils.java index edab28008f87..12b3b2ecc4bb 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ErrorInjectUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ErrorInjectUtils.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.profiler.util; - -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * - */ -public class ErrorInjectUtils { - - private static final Random random = new Random(); - - public static void randomSleep(int mod) { - int i = Math.abs(random.nextInt() % mod); - try { - Thread.sleep(i); - } catch (InterruptedException e) { - } - } - -} +package com.nhn.pinpoint.profiler.util; + +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * + */ +public class ErrorInjectUtils { + + private static final Random random = new Random(); + + public static void randomSleep(int mod) { + int i = Math.abs(random.nextInt() % mod); + try { + Thread.sleep(i); + } catch (InterruptedException e) { + } + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ExcludeBindVariableFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ExcludeBindVariableFilter.java index e840be251440..2e9d091825a1 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ExcludeBindVariableFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/ExcludeBindVariableFilter.java @@ -1,31 +1,31 @@ -package com.nhn.pinpoint.profiler.util; - -import java.lang.reflect.Method; - -/** - * @author emeroad - */ -public class ExcludeBindVariableFilter implements BindVariableFilter { - - private String[] excudes; - - public ExcludeBindVariableFilter(String[] excludes) { - if (excludes == null) { - throw new NullPointerException("excludes must not be null"); - } - this.excudes = excludes; - } - - @Override - public boolean filter(Method method) { - if (method == null) { - throw new NullPointerException("method must not be null"); - } - for (String exclude : excudes) { - if(method.getName().equals(exclude)) { - return false; - } - } - return true; - } -} +package com.nhn.pinpoint.profiler.util; + +import java.lang.reflect.Method; + +/** + * @author emeroad + */ +public class ExcludeBindVariableFilter implements BindVariableFilter { + + private String[] excudes; + + public ExcludeBindVariableFilter(String[] excludes) { + if (excludes == null) { + throw new NullPointerException("excludes must not be null"); + } + this.excudes = excludes; + } + + @Override + public boolean filter(Method method) { + if (method == null) { + throw new NullPointerException("method must not be null"); + } + for (String exclude : excudes) { + if(method.getName().equals(exclude)) { + return false; + } + } + return true; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/IncludeBindVariableFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/IncludeBindVariableFilter.java index 20a0e4020ebd..6f6b967184a1 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/IncludeBindVariableFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/IncludeBindVariableFilter.java @@ -1,30 +1,30 @@ -package com.nhn.pinpoint.profiler.util; - -import java.lang.reflect.Method; - -/** - * @author emeroad - */ -public class IncludeBindVariableFilter implements BindVariableFilter { - private String[] includes; - - public IncludeBindVariableFilter(String[] includes) { - if (includes == null) { - throw new NullPointerException("includes must not be null"); - } - this.includes = includes; - } - - @Override - public boolean filter(Method method) { - if (method == null) { - throw new NullPointerException("method must not be null"); - } - for (String include: includes) { - if(method.getName().equals(include)) { - return true; - } - } - return false; - } -} +package com.nhn.pinpoint.profiler.util; + +import java.lang.reflect.Method; + +/** + * @author emeroad + */ +public class IncludeBindVariableFilter implements BindVariableFilter { + private String[] includes; + + public IncludeBindVariableFilter(String[] includes) { + if (includes == null) { + throw new NullPointerException("includes must not be null"); + } + this.includes = includes; + } + + @Override + public boolean filter(Method method) { + if (method == null) { + throw new NullPointerException("method must not be null"); + } + for (String include: includes) { + if(method.getName().equals(include)) { + return true; + } + } + return false; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java index 400f21fd423b..dc8bb43120c1 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java @@ -1,264 +1,264 @@ -package com.nhn.pinpoint.profiler.util; - -import javassist.*; -import javassist.bytecode.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public final class JavaAssistUtils { - private final static String EMTPY_ARRAY = "()"; - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - - private static final Logger logger = LoggerFactory.getLogger(JavaAssistUtils.class); - - private JavaAssistUtils() { - } - - /** - * test(int, java.lang.String) 일경우 - * (int, java.lang.String)로 생성된다. - * - * @param params - * @return - */ - public static String getParameterDescription(CtClass[] params) { - if (params == null) { - return EMTPY_ARRAY; - } - StringBuilder sb = new StringBuilder(64); - sb.append('('); - int end = params.length - 1; - for (int i = 0; i < params.length; i++) { - sb.append(params[i].getName()); - if (i < end) { - sb.append(", "); - } - } - sb.append(')'); - return sb.toString(); - } - - - public static String[] getParameterType(Class[] paramsClass) { - if (paramsClass == null) { - return null; - } - String[] paramsString = new String[paramsClass.length]; - for (int i = 0; i < paramsClass.length; i++) { - paramsString[i] = paramsClass[i].getName(); - } - return paramsString; - } - - public static String[] getParameterSimpleType(CtClass[] paramsClass) { - if (paramsClass == null) { - return null; - } - String[] paramsString = new String[paramsClass.length]; - for (int i = 0; i < paramsClass.length; i++) { - paramsString[i] = paramsClass[i].getSimpleName(); - } - return paramsString; - } - - public static String[] getParameterType(CtClass[] paramsClass) { - if (paramsClass == null) { - return null; - } - String[] paramsString = new String[paramsClass.length]; - for (int i = 0; i < paramsClass.length; i++) { - paramsString[i] = paramsClass[i].getName(); - } - return paramsString; - } - - public static String getParameterDescription(Class[] params) { - if (params == null) { - return EMTPY_ARRAY; - } - StringBuilder sb = new StringBuilder(64); - sb.append('('); - int end = params.length - 1; - for (int i = 0; i < params.length; i++) { - sb.append(params[i].getName()); - if (i < end) { - sb.append(", "); - } - } - sb.append(')'); - return sb.toString(); - } - - - public static String getParameterDescription(String[] params) { - if (params == null) { - return EMTPY_ARRAY; - } - StringBuilder sb = new StringBuilder(64); - sb.append('('); - int end = params.length - 1; - for (int i = 0; i < params.length; i++) { - sb.append(params[i]); - if (i < end) { - sb.append(", "); - } - } - sb.append(')'); - return sb.toString(); - } - - public static CtClass[] getCtParameter(String[] args, ClassPool pool) throws NotFoundException { - if (args == null) { - return null; - } - CtClass[] params = new CtClass[args.length]; - for (int i = 0; i < args.length; i++) { - params[i] = pool.getCtClass(args[i]); - } - return params; - } - - - public static int getLineNumber(CtBehavior method) { - if (method == null) { - return -1; - } - return method.getMethodInfo().getLineNumber(0); - } - - - public CtMethod findAllMethod(CtClass ctClass, String methodName, String[] args) throws NotFoundException { - if (ctClass == null) { - throw new NullPointerException("ctClass must not be null"); - } - if (methodName == null) { - throw new NullPointerException("methodName must not be null"); - } - CtClass[] params = getCtParameter(args, ctClass.getClassPool()); - String paramDescriptor = Descriptor.ofParameters(params); - CtMethod[] methods = ctClass.getMethods(); - for (CtMethod method : methods) { - if (method.getName().equals(methodName) && method.getMethodInfo2().getDescriptor().startsWith(paramDescriptor)) { - return method; - } - } - throw new NotFoundException(methodName + "(..) is not found in " + ctClass.getName()); - } - - public static boolean isStaticBehavior(CtBehavior behavior) { - if (behavior == null) { - throw new NullPointerException("behavior must not be null"); - } - int modifiers = behavior.getModifiers(); - return Modifier.isStatic(modifiers); - } - - - public static String[] getParameterVariableName(CtBehavior method) throws NotFoundException { - if (method == null) { - throw new NullPointerException("method must not be null"); - } - LocalVariableAttribute localVariableAttribute = lookupLocalVariableAttribute(method); - if (localVariableAttribute == null) { - return getParameterDefaultVariableName(method); - } - return getParameterVariableName(method, localVariableAttribute); - } - - /** - * LocalVariable 메모리 공간을 얻어 온다. - * - * @param method - * @return null일 경우 debug모드로 컴파일 되지 않아서 그럼. - */ - public static LocalVariableAttribute lookupLocalVariableAttribute(CtBehavior method) { - if (method == null) { - throw new NullPointerException("method must not be null"); - } - MethodInfo methodInfo = method.getMethodInfo2(); - CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); - AttributeInfo localVariableTable = codeAttribute.getAttribute(LocalVariableAttribute.tag); - LocalVariableAttribute local = (LocalVariableAttribute) localVariableTable; - return local; - } - - public static String[] getParameterVariableName(CtBehavior method, LocalVariableAttribute localVariableAttribute) throws NotFoundException { - // http://www.jarvana.com/jarvana/view/org/jboss/weld/servlet/weld-servlet/1.0.1-Final/weld-servlet-1.0.1-Final-sources.jar!/org/slf4j/instrumentation/JavassistHelper.java?format=ok - // http://grepcode.com/file/repo1.maven.org/maven2/jp.objectfanatics/assertion-weaver/0.0.30/jp/objectfanatics/commons/javassist/JavassistUtils.java - // 이거 참고함. - if (localVariableAttribute == null) { - // null이라는건 debug모드로 컴파일 되지 않았다는 의미이다. - // parameter class명을 default로 넘기는 건 아래 메소드가 함. getParameterDefaultVariableName. - return null; - } - - dump(localVariableAttribute); - CtClass[] parameterTypes = method.getParameterTypes(); - if (parameterTypes.length == 0) { - return EMPTY_STRING_ARRAY; - } - String[] parameterVariableNames = new String[parameterTypes.length]; - boolean thisExist = thisExist(method); - - int paramIndex = 0; - for (int i = 0; i < localVariableAttribute.tableLength(); i++) { - // start pc가 0이 아닐경우 parameter를 나타내는 localVariableName이 아님. - if (localVariableAttribute.startPc(i) != 0) { - continue; - } - int index = localVariableAttribute.index(i); - if (index == 0 && thisExist) { - // this 변수임. skip - continue; - } - String variablename = localVariableAttribute.variableName(i); - parameterVariableNames[paramIndex++] = variablename; - } - return parameterVariableNames; - } - - private static boolean thisExist(CtBehavior method) { - int modifiers = method.getModifiers(); - if (Modifier.isStatic(modifiers)) { - return false; - } else { - // this 포함이므로 1; - return true; - } - } - - private static void dump(LocalVariableAttribute lva) { - if (logger.isDebugEnabled()) { - StringBuilder buffer = new StringBuilder(1024); - for (int i = 0; i < lva.tableLength(); i++) { - buffer.append("\n"); - buffer.append(i); - buffer.append(" start_pc:"); - buffer.append(lva.startPc(i)); - buffer.append(" index:"); - buffer.append(lva.index(i)); - buffer.append(" name:"); - buffer.append(lva.variableName(i)); - buffer.append(" nameIndex:"); - buffer.append(lva.nameIndex(i)); - } - logger.debug(buffer.toString()); - } - } - - - public static String[] getParameterDefaultVariableName(CtBehavior method) throws NotFoundException { - if (method == null) { - throw new NullPointerException("method must not be null"); - } - CtClass[] parameterTypes = method.getParameterTypes(); - String[] variableName = new String[parameterTypes.length]; - for (int i = 0; i < variableName.length; i++) { - variableName[i] = parameterTypes[i].getSimpleName().toLowerCase(); - } - return variableName; - } -} +package com.nhn.pinpoint.profiler.util; + +import javassist.*; +import javassist.bytecode.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public final class JavaAssistUtils { + private final static String EMTPY_ARRAY = "()"; + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + private static final Logger logger = LoggerFactory.getLogger(JavaAssistUtils.class); + + private JavaAssistUtils() { + } + + /** + * test(int, java.lang.String) 일경우 + * (int, java.lang.String)로 생성된다. + * + * @param params + * @return + */ + public static String getParameterDescription(CtClass[] params) { + if (params == null) { + return EMTPY_ARRAY; + } + StringBuilder sb = new StringBuilder(64); + sb.append('('); + int end = params.length - 1; + for (int i = 0; i < params.length; i++) { + sb.append(params[i].getName()); + if (i < end) { + sb.append(", "); + } + } + sb.append(')'); + return sb.toString(); + } + + + public static String[] getParameterType(Class[] paramsClass) { + if (paramsClass == null) { + return null; + } + String[] paramsString = new String[paramsClass.length]; + for (int i = 0; i < paramsClass.length; i++) { + paramsString[i] = paramsClass[i].getName(); + } + return paramsString; + } + + public static String[] getParameterSimpleType(CtClass[] paramsClass) { + if (paramsClass == null) { + return null; + } + String[] paramsString = new String[paramsClass.length]; + for (int i = 0; i < paramsClass.length; i++) { + paramsString[i] = paramsClass[i].getSimpleName(); + } + return paramsString; + } + + public static String[] getParameterType(CtClass[] paramsClass) { + if (paramsClass == null) { + return null; + } + String[] paramsString = new String[paramsClass.length]; + for (int i = 0; i < paramsClass.length; i++) { + paramsString[i] = paramsClass[i].getName(); + } + return paramsString; + } + + public static String getParameterDescription(Class[] params) { + if (params == null) { + return EMTPY_ARRAY; + } + StringBuilder sb = new StringBuilder(64); + sb.append('('); + int end = params.length - 1; + for (int i = 0; i < params.length; i++) { + sb.append(params[i].getName()); + if (i < end) { + sb.append(", "); + } + } + sb.append(')'); + return sb.toString(); + } + + + public static String getParameterDescription(String[] params) { + if (params == null) { + return EMTPY_ARRAY; + } + StringBuilder sb = new StringBuilder(64); + sb.append('('); + int end = params.length - 1; + for (int i = 0; i < params.length; i++) { + sb.append(params[i]); + if (i < end) { + sb.append(", "); + } + } + sb.append(')'); + return sb.toString(); + } + + public static CtClass[] getCtParameter(String[] args, ClassPool pool) throws NotFoundException { + if (args == null) { + return null; + } + CtClass[] params = new CtClass[args.length]; + for (int i = 0; i < args.length; i++) { + params[i] = pool.getCtClass(args[i]); + } + return params; + } + + + public static int getLineNumber(CtBehavior method) { + if (method == null) { + return -1; + } + return method.getMethodInfo().getLineNumber(0); + } + + + public CtMethod findAllMethod(CtClass ctClass, String methodName, String[] args) throws NotFoundException { + if (ctClass == null) { + throw new NullPointerException("ctClass must not be null"); + } + if (methodName == null) { + throw new NullPointerException("methodName must not be null"); + } + CtClass[] params = getCtParameter(args, ctClass.getClassPool()); + String paramDescriptor = Descriptor.ofParameters(params); + CtMethod[] methods = ctClass.getMethods(); + for (CtMethod method : methods) { + if (method.getName().equals(methodName) && method.getMethodInfo2().getDescriptor().startsWith(paramDescriptor)) { + return method; + } + } + throw new NotFoundException(methodName + "(..) is not found in " + ctClass.getName()); + } + + public static boolean isStaticBehavior(CtBehavior behavior) { + if (behavior == null) { + throw new NullPointerException("behavior must not be null"); + } + int modifiers = behavior.getModifiers(); + return Modifier.isStatic(modifiers); + } + + + public static String[] getParameterVariableName(CtBehavior method) throws NotFoundException { + if (method == null) { + throw new NullPointerException("method must not be null"); + } + LocalVariableAttribute localVariableAttribute = lookupLocalVariableAttribute(method); + if (localVariableAttribute == null) { + return getParameterDefaultVariableName(method); + } + return getParameterVariableName(method, localVariableAttribute); + } + + /** + * LocalVariable 메모리 공간을 얻어 온다. + * + * @param method + * @return null일 경우 debug모드로 컴파일 되지 않아서 그럼. + */ + public static LocalVariableAttribute lookupLocalVariableAttribute(CtBehavior method) { + if (method == null) { + throw new NullPointerException("method must not be null"); + } + MethodInfo methodInfo = method.getMethodInfo2(); + CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); + AttributeInfo localVariableTable = codeAttribute.getAttribute(LocalVariableAttribute.tag); + LocalVariableAttribute local = (LocalVariableAttribute) localVariableTable; + return local; + } + + public static String[] getParameterVariableName(CtBehavior method, LocalVariableAttribute localVariableAttribute) throws NotFoundException { + // http://www.jarvana.com/jarvana/view/org/jboss/weld/servlet/weld-servlet/1.0.1-Final/weld-servlet-1.0.1-Final-sources.jar!/org/slf4j/instrumentation/JavassistHelper.java?format=ok + // http://grepcode.com/file/repo1.maven.org/maven2/jp.objectfanatics/assertion-weaver/0.0.30/jp/objectfanatics/commons/javassist/JavassistUtils.java + // 이거 참고함. + if (localVariableAttribute == null) { + // null이라는건 debug모드로 컴파일 되지 않았다는 의미이다. + // parameter class명을 default로 넘기는 건 아래 메소드가 함. getParameterDefaultVariableName. + return null; + } + + dump(localVariableAttribute); + CtClass[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 0) { + return EMPTY_STRING_ARRAY; + } + String[] parameterVariableNames = new String[parameterTypes.length]; + boolean thisExist = thisExist(method); + + int paramIndex = 0; + for (int i = 0; i < localVariableAttribute.tableLength(); i++) { + // start pc가 0이 아닐경우 parameter를 나타내는 localVariableName이 아님. + if (localVariableAttribute.startPc(i) != 0) { + continue; + } + int index = localVariableAttribute.index(i); + if (index == 0 && thisExist) { + // this 변수임. skip + continue; + } + String variablename = localVariableAttribute.variableName(i); + parameterVariableNames[paramIndex++] = variablename; + } + return parameterVariableNames; + } + + private static boolean thisExist(CtBehavior method) { + int modifiers = method.getModifiers(); + if (Modifier.isStatic(modifiers)) { + return false; + } else { + // this 포함이므로 1; + return true; + } + } + + private static void dump(LocalVariableAttribute lva) { + if (logger.isDebugEnabled()) { + StringBuilder buffer = new StringBuilder(1024); + for (int i = 0; i < lva.tableLength(); i++) { + buffer.append("\n"); + buffer.append(i); + buffer.append(" start_pc:"); + buffer.append(lva.startPc(i)); + buffer.append(" index:"); + buffer.append(lva.index(i)); + buffer.append(" name:"); + buffer.append(lva.variableName(i)); + buffer.append(" nameIndex:"); + buffer.append(lva.nameIndex(i)); + } + logger.debug(buffer.toString()); + } + } + + + public static String[] getParameterDefaultVariableName(CtBehavior method) throws NotFoundException { + if (method == null) { + throw new NullPointerException("method must not be null"); + } + CtClass[] parameterTypes = method.getParameterTypes(); + String[] variableName = new String[parameterTypes.length]; + for (int i = 0; i < variableName.length; i++) { + variableName[i] = parameterTypes[i].getSimpleName().toLowerCase(); + } + return variableName; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/NamedThreadLocal.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/NamedThreadLocal.java index 6301c891dbbb..89c4662d8f18 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/NamedThreadLocal.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/NamedThreadLocal.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.profiler.util; - -/** - * NamedThreadLocal 사용시 thread local leak 발생시 추적이 쉬움 - * - * @author emeroad - */ -public class NamedThreadLocal extends ThreadLocal { - private final String name; - - public NamedThreadLocal(String name) { - this.name = name; - } - - public String getName() { - return name; - } -} +package com.nhn.pinpoint.profiler.util; + +/** + * NamedThreadLocal 사용시 thread local leak 발생시 추적이 쉬움 + * + * @author emeroad + */ +public class NamedThreadLocal extends ThreadLocal { + private final String name; + + public NamedThreadLocal(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtils.java index df2210beb18d..c676bfa7c2dd 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtils.java @@ -1,88 +1,88 @@ -package com.nhn.pinpoint.profiler.util; - - -import java.lang.reflect.Method; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Pattern; - -/** - * @author emeroad - */ -public class PreparedStatementUtils { - - private static final Pattern BIND_SETTER = Pattern.compile("set[A-Z]([a-zA-Z]+)"); - - private static final List bindMethod; - - static { - bindMethod = findBindVariableSetMethod0(); - } - - public static List findBindVariableSetMethod() { - return bindMethod; - } - - public static List findBindVariableSetMethod(BindVariableFilter filter) { - if (filter == null) { - throw new NullPointerException("filter must not be null"); - } - - List temp = new ArrayList(bindMethod.size()); - for (Method method : bindMethod) { - if (filter.filter(method)) { - temp.add(method); - } - } - return temp; - } - - static List findBindVariableSetMethod0() { - Method[] methods = PreparedStatement.class.getDeclaredMethods(); - List bindMethod = new LinkedList(); - for (Method method : methods) { - if (isSetter(method.getName())) { - Class[] parameterTypes = method.getParameterTypes(); - - if (parameterTypes.length < 2) { - continue; - } - if (parameterTypes[0] != int.class) { - continue; - } - if (method.getReturnType() != void.class) { - continue; - } - // sql exception을 던지는지 본다. - if (!throwSqlException(method)) { - continue; - } - bindMethod.add(method); - } - } - return Collections.unmodifiableList(bindMethod); - } - - private static boolean throwSqlException(Method method) { - Class[] exceptionTypes = method.getExceptionTypes(); - if (exceptionTypes.length == 1) { - Class exceptionType = exceptionTypes[0]; - if (exceptionType.equals(SQLException.class)) { - return true; - } - } - return false; - } - - - public static boolean isSetter(String name) { - if (name == null) { - return false; - } - return BIND_SETTER.matcher(name).matches(); - } -} +package com.nhn.pinpoint.profiler.util; + + +import java.lang.reflect.Method; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @author emeroad + */ +public class PreparedStatementUtils { + + private static final Pattern BIND_SETTER = Pattern.compile("set[A-Z]([a-zA-Z]+)"); + + private static final List bindMethod; + + static { + bindMethod = findBindVariableSetMethod0(); + } + + public static List findBindVariableSetMethod() { + return bindMethod; + } + + public static List findBindVariableSetMethod(BindVariableFilter filter) { + if (filter == null) { + throw new NullPointerException("filter must not be null"); + } + + List temp = new ArrayList(bindMethod.size()); + for (Method method : bindMethod) { + if (filter.filter(method)) { + temp.add(method); + } + } + return temp; + } + + static List findBindVariableSetMethod0() { + Method[] methods = PreparedStatement.class.getDeclaredMethods(); + List bindMethod = new LinkedList(); + for (Method method : methods) { + if (isSetter(method.getName())) { + Class[] parameterTypes = method.getParameterTypes(); + + if (parameterTypes.length < 2) { + continue; + } + if (parameterTypes[0] != int.class) { + continue; + } + if (method.getReturnType() != void.class) { + continue; + } + // sql exception을 던지는지 본다. + if (!throwSqlException(method)) { + continue; + } + bindMethod.add(method); + } + } + return Collections.unmodifiableList(bindMethod); + } + + private static boolean throwSqlException(Method method) { + Class[] exceptionTypes = method.getExceptionTypes(); + if (exceptionTypes.length == 1) { + Class exceptionType = exceptionTypes[0]; + if (exceptionType.equals(SQLException.class)) { + return true; + } + } + return false; + } + + + public static boolean isSetter(String name) { + if (name == null) { + return false; + } + return BIND_SETTER.matcher(name).matches(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtils.java index 86a375b1c70a..fbc21685d8bf 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtils.java @@ -1,73 +1,73 @@ -package com.nhn.pinpoint.profiler.util; - -import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; -import java.util.Random; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author emeroad - */ -public final class RuntimeMXBeanUtils { - private static final RuntimeMXBean RUNTIME_MBEAN = ManagementFactory.getRuntimeMXBean(); - - private static long START_TIME = 0; - private static int PID = 0; - private static final Random RANDOM = new Random(); - - private RuntimeMXBeanUtils() { - } - - public static int getPid() { - if (PID == 0) { - PID = getPid0(); - } - return PID; - } - - private static int getPid0() { - final String name = RUNTIME_MBEAN.getName(); - final int pidIndex = name.indexOf('@'); - if (pidIndex == -1) { - getLogger().log(Level.WARNING, "invalid pid name:" + name); - return getNegativeRandomValue(); - } - String strPid = name.substring(0, pidIndex); - try { - return Integer.parseInt(strPid); - } catch (NumberFormatException e) { - return getNegativeRandomValue(); - } - } - - private static int getNegativeRandomValue() { - final int abs = Math.abs(RANDOM.nextInt()); - if (abs == Integer.MIN_VALUE) { - return -1; - } - return abs; - } - - public static long getVmStartTime() { - if (START_TIME == 0) { - START_TIME = getVmStartTime0(); - } - return START_TIME; - } - - private static long getVmStartTime0() { - try { - return RUNTIME_MBEAN.getStartTime(); - } catch (UnsupportedOperationException e) { - final Logger logger = getLogger(); - logger.log(Level.WARNING, "RuntimeMXBean.getStartTime() unsupported. Caused:" + e.getMessage(), e); - return System.currentTimeMillis(); - } - } - - private static Logger getLogger() { - return Logger.getLogger(RuntimeMXBeanUtils.class.getName()); - } - -} +package com.nhn.pinpoint.profiler.util; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author emeroad + */ +public final class RuntimeMXBeanUtils { + private static final RuntimeMXBean RUNTIME_MBEAN = ManagementFactory.getRuntimeMXBean(); + + private static long START_TIME = 0; + private static int PID = 0; + private static final Random RANDOM = new Random(); + + private RuntimeMXBeanUtils() { + } + + public static int getPid() { + if (PID == 0) { + PID = getPid0(); + } + return PID; + } + + private static int getPid0() { + final String name = RUNTIME_MBEAN.getName(); + final int pidIndex = name.indexOf('@'); + if (pidIndex == -1) { + getLogger().log(Level.WARNING, "invalid pid name:" + name); + return getNegativeRandomValue(); + } + String strPid = name.substring(0, pidIndex); + try { + return Integer.parseInt(strPid); + } catch (NumberFormatException e) { + return getNegativeRandomValue(); + } + } + + private static int getNegativeRandomValue() { + final int abs = Math.abs(RANDOM.nextInt()); + if (abs == Integer.MIN_VALUE) { + return -1; + } + return abs; + } + + public static long getVmStartTime() { + if (START_TIME == 0) { + START_TIME = getVmStartTime0(); + } + return START_TIME; + } + + private static long getVmStartTime0() { + try { + return RUNTIME_MBEAN.getStartTime(); + } catch (UnsupportedOperationException e) { + final Logger logger = getLogger(); + logger.log(Level.WARNING, "RuntimeMXBean.getStartTime() unsupported. Caused:" + e.getMessage(), e); + return System.currentTimeMillis(); + } + } + + private static Logger getLogger() { + return Logger.getLogger(RuntimeMXBeanUtils.class.getName()); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/StackTraceUtil.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/StackTraceUtil.java index e4a16f4d8ca1..ce396047d149 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/StackTraceUtil.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/StackTraceUtil.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.profiler.util; - -import java.util.logging.Level; -import java.util.logging.Logger; - -public class StackTraceUtil { - - private static final Logger logger = Logger.getLogger(StackTraceUtil.class.getName()); - - public static void printCurrentStackTrace() { - printCurrentStackTrace(logger); - } - - public static void printCurrentStackTrace(Logger logger) { - if (!logger.isLoggable(Level.INFO)) { - return; - } - - StackTraceElement[] stackList = Thread.currentThread().getStackTrace(); - int length = stackList.length; - for (int loop = 2; loop < length; loop++) { - logger.info("***" + stackList[loop].toString()); - } - } - -} +package com.nhn.pinpoint.profiler.util; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class StackTraceUtil { + + private static final Logger logger = Logger.getLogger(StackTraceUtil.class.getName()); + + public static void printCurrentStackTrace() { + printCurrentStackTrace(logger); + } + + public static void printCurrentStackTrace(Logger logger) { + if (!logger.isLoggable(Level.INFO)) { + return; + } + + StackTraceElement[] stackList = Thread.currentThread().getStackTrace(); + int length = stackList.length; + for (int loop = 2; loop < length; loop++) { + logger.info("***" + stackList[loop].toString()); + } + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverter.java index d5832017fb26..f13cf2a6c41c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverter.java @@ -1,98 +1,98 @@ -package com.nhn.pinpoint.profiler.util.bindvalue; - -import java.util.HashMap; -import java.util.Map; - -import com.nhn.pinpoint.profiler.util.bindvalue.converter.*; -import com.nhn.pinpoint.profiler.util.bindvalue.converter.NullTypeConverter; - -public class BindValueConverter { - private static final BindValueConverter converter; - static { - converter = new BindValueConverter(); - converter.register(); - } - - public final Map convertermap = new HashMap() ; - - private void register() { - simpleType(); - classNameType(); - - // null argument 가 3개인것도 있음. - convertermap.put("setNull", new NullTypeConverter()); - - BytesConverter bytesConverter = new BytesConverter(); - convertermap.put("setBytes", bytesConverter); - - // setObject - convertermap.put("setObject", new ObjectConverter()); - } - - private void classNameType() { - // className 데이터를 까볼수 없는 객체의 경우 class명으로 치환 - ClassNameConverter classNameConverter = new ClassNameConverter(); - // 3개짜리 존재 - convertermap.put("setAsciiStream", classNameConverter); - convertermap.put("setUnicodeStream", classNameConverter); - convertermap.put("setBinaryStream", classNameConverter); - - //3개 짜리 존재 - convertermap.put("setBlob", classNameConverter); - //3개 짜리 존재 - convertermap.put("setClob", classNameConverter); - convertermap.put("setArray", classNameConverter); - convertermap.put("setNCharacterStream", classNameConverter); - - // 3개 짜리 존재 - convertermap.put("setNClob", classNameConverter); - - convertermap.put("setCharacterStream", classNameConverter); - convertermap.put("setSQLXML", classNameConverter); - } - - private void simpleType() { - - SimpleTypeConverter simpleTypeConverter = new SimpleTypeConverter(); - convertermap.put("setByte", simpleTypeConverter); - convertermap.put("setBoolean", simpleTypeConverter); - convertermap.put("setShort", simpleTypeConverter); - convertermap.put("setInt", simpleTypeConverter); - convertermap.put("setLong", simpleTypeConverter); - convertermap.put("setFloat", simpleTypeConverter); - convertermap.put("setDouble", simpleTypeConverter); - convertermap.put("setBigDecimal", simpleTypeConverter); - convertermap.put("setString", simpleTypeConverter); - convertermap.put("setDate", simpleTypeConverter); - - // argument 가 3개 가능. - convertermap.put("setTime", simpleTypeConverter); - //convertermap.put("setTime", simpleTypeConverter); - - // argument 가 3개 가능 - convertermap.put("setTimestamp", simpleTypeConverter); - //convertermap.put("setTimestamp", simpleTypeConverter); - - - // 문자열로 치환 가능할것으로 보임. - convertermap.put("setURL", simpleTypeConverter); - // ref도 문자열로 치환 가능할것으로 보임 - convertermap.put("setRef", simpleTypeConverter); - convertermap.put("setNString", simpleTypeConverter); - } - - public String convert0(String methodName, Object[] args) { - Converter converter = this.convertermap.get(methodName); - if (converter == null) { - // Converter를 찾지 못했을 경우 "" 빈문자열을 리턴하도록 한다. - return ""; - } - return converter.convert(args); - } - - - public static String convert(String methodName, Object[] args) { - return converter.convert0(methodName, args); - } - -} +package com.nhn.pinpoint.profiler.util.bindvalue; + +import java.util.HashMap; +import java.util.Map; + +import com.nhn.pinpoint.profiler.util.bindvalue.converter.*; +import com.nhn.pinpoint.profiler.util.bindvalue.converter.NullTypeConverter; + +public class BindValueConverter { + private static final BindValueConverter converter; + static { + converter = new BindValueConverter(); + converter.register(); + } + + public final Map convertermap = new HashMap() ; + + private void register() { + simpleType(); + classNameType(); + + // null argument 가 3개인것도 있음. + convertermap.put("setNull", new NullTypeConverter()); + + BytesConverter bytesConverter = new BytesConverter(); + convertermap.put("setBytes", bytesConverter); + + // setObject + convertermap.put("setObject", new ObjectConverter()); + } + + private void classNameType() { + // className 데이터를 까볼수 없는 객체의 경우 class명으로 치환 + ClassNameConverter classNameConverter = new ClassNameConverter(); + // 3개짜리 존재 + convertermap.put("setAsciiStream", classNameConverter); + convertermap.put("setUnicodeStream", classNameConverter); + convertermap.put("setBinaryStream", classNameConverter); + + //3개 짜리 존재 + convertermap.put("setBlob", classNameConverter); + //3개 짜리 존재 + convertermap.put("setClob", classNameConverter); + convertermap.put("setArray", classNameConverter); + convertermap.put("setNCharacterStream", classNameConverter); + + // 3개 짜리 존재 + convertermap.put("setNClob", classNameConverter); + + convertermap.put("setCharacterStream", classNameConverter); + convertermap.put("setSQLXML", classNameConverter); + } + + private void simpleType() { + + SimpleTypeConverter simpleTypeConverter = new SimpleTypeConverter(); + convertermap.put("setByte", simpleTypeConverter); + convertermap.put("setBoolean", simpleTypeConverter); + convertermap.put("setShort", simpleTypeConverter); + convertermap.put("setInt", simpleTypeConverter); + convertermap.put("setLong", simpleTypeConverter); + convertermap.put("setFloat", simpleTypeConverter); + convertermap.put("setDouble", simpleTypeConverter); + convertermap.put("setBigDecimal", simpleTypeConverter); + convertermap.put("setString", simpleTypeConverter); + convertermap.put("setDate", simpleTypeConverter); + + // argument 가 3개 가능. + convertermap.put("setTime", simpleTypeConverter); + //convertermap.put("setTime", simpleTypeConverter); + + // argument 가 3개 가능 + convertermap.put("setTimestamp", simpleTypeConverter); + //convertermap.put("setTimestamp", simpleTypeConverter); + + + // 문자열로 치환 가능할것으로 보임. + convertermap.put("setURL", simpleTypeConverter); + // ref도 문자열로 치환 가능할것으로 보임 + convertermap.put("setRef", simpleTypeConverter); + convertermap.put("setNString", simpleTypeConverter); + } + + public String convert0(String methodName, Object[] args) { + Converter converter = this.convertermap.get(methodName); + if (converter == null) { + // Converter를 찾지 못했을 경우 "" 빈문자열을 리턴하도록 한다. + return ""; + } + return converter.convert(args); + } + + + public static String convert(String methodName, Object[] args) { + return converter.convert0(methodName, args); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/Types.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/Types.java index 6fbf8558d8e0..563d5ce6ff39 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/Types.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/Types.java @@ -1,35 +1,35 @@ -package com.nhn.pinpoint.profiler.util.bindvalue; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -/** - * @author emeroad - */ -public class Types { - - private static final Map MAP; - - static { - MAP = inverse(); - } - - static Map inverse() { - Map map = new HashMap(); - Field[] fields = java.sql.Types.class.getFields(); - for (Field field : fields) { - String name = field.getName(); - try { - Integer value = (Integer) field.get(java.sql.Types.class); - map.put(value, name); - } catch (IllegalAccessException e) { - } - } - return map; - } - - public static String findType(int type) { - return MAP.get(type); - } -} +package com.nhn.pinpoint.profiler.util.bindvalue; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +/** + * @author emeroad + */ +public class Types { + + private static final Map MAP; + + static { + MAP = inverse(); + } + + static Map inverse() { + Map map = new HashMap(); + Field[] fields = java.sql.Types.class.getFields(); + for (Field field : fields) { + String name = field.getName(); + try { + Integer value = (Integer) field.get(java.sql.Types.class); + map.put(value, name); + } catch (IllegalAccessException e) { + } + } + return map; + } + + public static String findType(int type) { + return MAP.get(type); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/BytesConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/BytesConverter.java index 6099cc3c774b..ff064bdef311 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/BytesConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/BytesConverter.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.profiler.util.bindvalue.converter; - -import com.nhn.pinpoint.profiler.util.ArrayUtils; - -/** - * @author emeroad - */ -public class BytesConverter implements Converter { - @Override - public String convert(Object[] args) { - if (args == null) { - return "null"; - } - if (args.length == 2) { - byte[] bytes = (byte[]) args[1]; - if (bytes == null) { - return "null"; - } else { - return ArrayUtils.dropToString(bytes); - } - } - return "error"; - } -} +package com.nhn.pinpoint.profiler.util.bindvalue.converter; + +import com.nhn.pinpoint.profiler.util.ArrayUtils; + +/** + * @author emeroad + */ +public class BytesConverter implements Converter { + @Override + public String convert(Object[] args) { + if (args == null) { + return "null"; + } + if (args.length == 2) { + byte[] bytes = (byte[]) args[1]; + if (bytes == null) { + return "null"; + } else { + return ArrayUtils.dropToString(bytes); + } + } + return "error"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ClassNameConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ClassNameConverter.java index ba92470dd729..6f351a7c705a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ClassNameConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ClassNameConverter.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.profiler.util.bindvalue.converter; - -import com.nhn.pinpoint.bootstrap.util.StringUtils; - -/** - * @author emeroad - */ -public class ClassNameConverter implements Converter { - @Override - public String convert(Object[] args) { - if (args == null) { - return "null"; - } - if (args.length == 2) { - return StringUtils.drop(getClassName(args[1])); - } else if(args.length == 3) { - // 3일때의 추가 처리? - return StringUtils.drop(getClassName(args[1])); - } - return "error"; - } - - private String getClassName(Object args) { - if (args == null) { - return "null"; - } - return args.getClass().getName(); - } -} +package com.nhn.pinpoint.profiler.util.bindvalue.converter; + +import com.nhn.pinpoint.bootstrap.util.StringUtils; + +/** + * @author emeroad + */ +public class ClassNameConverter implements Converter { + @Override + public String convert(Object[] args) { + if (args == null) { + return "null"; + } + if (args.length == 2) { + return StringUtils.drop(getClassName(args[1])); + } else if(args.length == 3) { + // 3일때의 추가 처리? + return StringUtils.drop(getClassName(args[1])); + } + return "error"; + } + + private String getClassName(Object args) { + if (args == null) { + return "null"; + } + return args.getClass().getName(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/Converter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/Converter.java index fefa669ef26a..b2e475604206 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/Converter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/Converter.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.profiler.util.bindvalue.converter; - -/** - * @author emeroad - */ -public interface Converter { - String convert(Object[] args); -} +package com.nhn.pinpoint.profiler.util.bindvalue.converter; + +/** + * @author emeroad + */ +public interface Converter { + String convert(Object[] args); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/NullTypeConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/NullTypeConverter.java index ce497d33c825..ec1c755b4871 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/NullTypeConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/NullTypeConverter.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.profiler.util.bindvalue.converter; - -/** - * @author emeroad - */ -public class NullTypeConverter implements Converter { - - @Override - public String convert(Object[] args) { - return "null"; - } -} +package com.nhn.pinpoint.profiler.util.bindvalue.converter; + +/** + * @author emeroad + */ +public class NullTypeConverter implements Converter { + + @Override + public String convert(Object[] args) { + return "null"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ObjectConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ObjectConverter.java index 3a14bcff5b45..5b64d19014b9 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ObjectConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/ObjectConverter.java @@ -1,83 +1,83 @@ -package com.nhn.pinpoint.profiler.util.bindvalue.converter; - -import com.nhn.pinpoint.profiler.util.ArrayUtils; -import com.nhn.pinpoint.bootstrap.util.StringUtils; - -import java.io.InputStream; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Time; -import java.sql.Timestamp; - -/** - * @author emeroad - */ -public class ObjectConverter implements Converter { - @Override - public String convert(Object[] args) { - if (args == null) { - return "null"; - } - if (args.length == 2) { - Object param = args[1]; - return getParameter(param); - - } else if (args.length == 3) { - Object param = args[1]; - return getParameter(param); - } - return "error"; - } - - private String getParameter(Object param) { - if(param == null) { - return "null"; - } else { - if (param instanceof Byte) { - return dropToString(param); - } else if (param instanceof String) { - return StringUtils.drop((String) param); - } else if (param instanceof BigDecimal) { - return dropToString(param); - } else if (param instanceof Short) { - return dropToString(param); - } else if (param instanceof Integer) { - return dropToString(param); - } else if (param instanceof Long) { - return dropToString(param); - } else if (param instanceof Float) { - return dropToString(param); - } else if (param instanceof Double) { - return dropToString(param); - } else if (param instanceof BigInteger) { - return dropToString(param); - } else if (param instanceof java.sql.Date) { - return dropToString(param); - } else if (param instanceof Time) { - return dropToString(param); - } else if (param instanceof Timestamp) { - return dropToString(param); - } else if (param instanceof Boolean) { - return dropToString(param); - } else if (param instanceof byte[]) { - return ArrayUtils.dropToString((byte[]) param); - } else if (param instanceof InputStream) { - return getClassName(param); - } else if (param instanceof java.sql.Blob) { - return getClassName(param); - } else if (param instanceof java.sql.Clob) { - return getClassName(param); - } else { - return getClassName(param); - } - } - } - - private String dropToString(Object param) { - return StringUtils.drop(param.toString()); - } - - private String getClassName(Object param) { - return param.getClass().getName(); - } -} +package com.nhn.pinpoint.profiler.util.bindvalue.converter; + +import com.nhn.pinpoint.profiler.util.ArrayUtils; +import com.nhn.pinpoint.bootstrap.util.StringUtils; + +import java.io.InputStream; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Time; +import java.sql.Timestamp; + +/** + * @author emeroad + */ +public class ObjectConverter implements Converter { + @Override + public String convert(Object[] args) { + if (args == null) { + return "null"; + } + if (args.length == 2) { + Object param = args[1]; + return getParameter(param); + + } else if (args.length == 3) { + Object param = args[1]; + return getParameter(param); + } + return "error"; + } + + private String getParameter(Object param) { + if(param == null) { + return "null"; + } else { + if (param instanceof Byte) { + return dropToString(param); + } else if (param instanceof String) { + return StringUtils.drop((String) param); + } else if (param instanceof BigDecimal) { + return dropToString(param); + } else if (param instanceof Short) { + return dropToString(param); + } else if (param instanceof Integer) { + return dropToString(param); + } else if (param instanceof Long) { + return dropToString(param); + } else if (param instanceof Float) { + return dropToString(param); + } else if (param instanceof Double) { + return dropToString(param); + } else if (param instanceof BigInteger) { + return dropToString(param); + } else if (param instanceof java.sql.Date) { + return dropToString(param); + } else if (param instanceof Time) { + return dropToString(param); + } else if (param instanceof Timestamp) { + return dropToString(param); + } else if (param instanceof Boolean) { + return dropToString(param); + } else if (param instanceof byte[]) { + return ArrayUtils.dropToString((byte[]) param); + } else if (param instanceof InputStream) { + return getClassName(param); + } else if (param instanceof java.sql.Blob) { + return getClassName(param); + } else if (param instanceof java.sql.Clob) { + return getClassName(param); + } else { + return getClassName(param); + } + } + } + + private String dropToString(Object param) { + return StringUtils.drop(param.toString()); + } + + private String getClassName(Object param) { + return param.getClass().getName(); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/SimpleTypeConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/SimpleTypeConverter.java index ed7fd80edce5..ddcb3786adda 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/SimpleTypeConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/bindvalue/converter/SimpleTypeConverter.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.profiler.util.bindvalue.converter; - -import com.nhn.pinpoint.bootstrap.util.StringUtils; - -/** - * @author emeroad - */ -public class SimpleTypeConverter implements Converter { - @Override - public String convert(Object[] args) { - if (args == null) { - return "null"; - } - if (args.length == 2) { - return StringUtils.drop(StringUtils.toString(args[1])); - } else if (args.length == 3) { - // TODO 3일때 추가 처리? - return StringUtils.drop(StringUtils.toString(args[1])); - } - return "error"; - } -} +package com.nhn.pinpoint.profiler.util.bindvalue.converter; + +import com.nhn.pinpoint.bootstrap.util.StringUtils; + +/** + * @author emeroad + */ +public class SimpleTypeConverter implements Converter { + @Override + public String convert(Object[] args) { + if (args == null) { + return "null"; + } + if (args.length == 2) { + return StringUtils.drop(StringUtils.toString(args[1])); + } else if (args.length == 3) { + // TODO 3일때 추가 처리? + return StringUtils.drop(StringUtils.toString(args[1])); + } + return "error"; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/LongAdder.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/LongAdder.java index f87cd03037ea..e5792c61c488 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/LongAdder.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/LongAdder.java @@ -1,208 +1,208 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -/* - * Source: - * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8 - */ - -package com.nhn.pinpoint.profiler.util.jdk; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.concurrent.atomic.AtomicLong; - -/** - * One or more variables that together maintain an initially zero - * {@code long} sum. When updates (method {@link #add}) are contended - * across threads, the set of variables may grow dynamically to reduce - * contention. Method {@link #sum} (or, equivalently, {@link - * #longValue}) returns the current total combined across the - * variables maintaining the sum. - * - *

This class is usually preferable to {@link java.util.concurrent.atomic.AtomicLong} when - * multiple threads update a common sum that is used for purposes such - * as collecting statistics, not for fine-grained synchronization - * control. Under low update contention, the two classes have similar - * characteristics. But under high contention, expected throughput of - * this class is significantly higher, at the expense of higher space - * consumption. - * - *

This class extends {@link Number}, but does not define - * methods such as {@code hashCode} and {@code compareTo} because - * instances are expected to be mutated, and so are not useful as - * collection keys. - * - *

jsr166e note: This class is targeted to be placed in - * java.util.concurrent.atomic - * - * @since 1.8 - * @author Doug Lea - */ -public final class LongAdder extends Striped64 implements Serializable { - private static final long serialVersionUID = 7249069246863182397L; - - /** - * Version of plus for use in retryUpdate - */ - final long fn(long v, long x) { return v + x; } - - /** - * Creates a new adder with initial sum of zero. - */ - public LongAdder() { - } - - /** - * Adds the given value. - * - * @param x the value to add - */ - public void add(long x) { - Cell[] as; long b, v; HashCode hc; Cell a; int n; - if ((as = cells) != null || !casBase(b = base, b + x)) { - boolean uncontended = true; - int h = (hc = threadHashCode.get()).code; - if (as == null || (n = as.length) < 1 || - (a = as[(n - 1) & h]) == null || - !(uncontended = a.cas(v = a.value, v + x))) - retryUpdate(x, hc, uncontended); - } - } - - /** - * Equivalent to {@code add(1)}. - */ - public void increment() { - add(1L); - } - - /** - * Equivalent to {@code add(-1)}. - */ - public void decrement() { - add(-1L); - } - - /** - * Returns the current sum. The returned value is NOT an - * atomic getSnapshot: Invocation in the absence of concurrent - * updates returns an accurate result, but concurrent updates that - * occur while the sum is being calculated might not be - * incorporated. - * - * @return the sum - */ - public long sum() { - long sum = base; - Cell[] as = cells; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - sum += a.value; - } - } - return sum; - } - - /** - * Resets variables maintaining the sum to zero. This method may - * be a useful alternative to creating a new adder, but is only - * effective if there are no concurrent updates. Because this - * method is intrinsically racy, it should only be used when it is - * known that no threads are concurrently updating. - */ - public void reset() { - internalReset(0L); - } - - /** - * Equivalent in effect to {@link #sum} followed by {@link - * #reset}. This method may apply for example during quiescent - * points between multithreaded computations. If there are - * updates concurrent with this method, the returned value is - * not guaranteed to be the final value occurring before - * the reset. - * - * @return the sum - */ - public long sumThenReset() { - long sum = base; - Cell[] as = cells; - base = 0L; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) { - sum += a.value; - a.value = 0L; - } - } - } - return sum; - } - - /** - * Returns the String representation of the {@link #sum}. - * @return the String representation of the {@link #sum} - */ - public String toString() { - return Long.toString(sum()); - } - - /** - * Equivalent to {@link #sum}. - * - * @return the sum - */ - public long longValue() { - return sum(); - } - - /** - * Returns the {@link #sum} as an {@code int} after a narrowing - * primitive conversion. - */ - public int intValue() { - return (int)sum(); - } - - /** - * Returns the {@link #sum} as a {@code float} - * after a widening primitive conversion. - */ - public float floatValue() { - return (float)sum(); - } - - /** - * Returns the {@link #sum} as a {@code double} after a widening - * primitive conversion. - */ - public double doubleValue() { - return (double)sum(); - } - - private void writeObject(ObjectOutputStream s) - throws java.io.IOException { - s.defaultWriteObject(); - s.writeLong(sum()); - } - - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject(); - busy = 0; - cells = null; - base = s.readLong(); - } - -} +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* + * Source: + * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8 + */ + +package com.nhn.pinpoint.profiler.util.jdk; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.concurrent.atomic.AtomicLong; + +/** + * One or more variables that together maintain an initially zero + * {@code long} sum. When updates (method {@link #add}) are contended + * across threads, the set of variables may grow dynamically to reduce + * contention. Method {@link #sum} (or, equivalently, {@link + * #longValue}) returns the current total combined across the + * variables maintaining the sum. + * + *

This class is usually preferable to {@link java.util.concurrent.atomic.AtomicLong} when + * multiple threads update a common sum that is used for purposes such + * as collecting statistics, not for fine-grained synchronization + * control. Under low update contention, the two classes have similar + * characteristics. But under high contention, expected throughput of + * this class is significantly higher, at the expense of higher space + * consumption. + * + *

This class extends {@link Number}, but does not define + * methods such as {@code hashCode} and {@code compareTo} because + * instances are expected to be mutated, and so are not useful as + * collection keys. + * + *

jsr166e note: This class is targeted to be placed in + * java.util.concurrent.atomic + * + * @since 1.8 + * @author Doug Lea + */ +public final class LongAdder extends Striped64 implements Serializable { + private static final long serialVersionUID = 7249069246863182397L; + + /** + * Version of plus for use in retryUpdate + */ + final long fn(long v, long x) { return v + x; } + + /** + * Creates a new adder with initial sum of zero. + */ + public LongAdder() { + } + + /** + * Adds the given value. + * + * @param x the value to add + */ + public void add(long x) { + Cell[] as; long b, v; HashCode hc; Cell a; int n; + if ((as = cells) != null || !casBase(b = base, b + x)) { + boolean uncontended = true; + int h = (hc = threadHashCode.get()).code; + if (as == null || (n = as.length) < 1 || + (a = as[(n - 1) & h]) == null || + !(uncontended = a.cas(v = a.value, v + x))) + retryUpdate(x, hc, uncontended); + } + } + + /** + * Equivalent to {@code add(1)}. + */ + public void increment() { + add(1L); + } + + /** + * Equivalent to {@code add(-1)}. + */ + public void decrement() { + add(-1L); + } + + /** + * Returns the current sum. The returned value is NOT an + * atomic getSnapshot: Invocation in the absence of concurrent + * updates returns an accurate result, but concurrent updates that + * occur while the sum is being calculated might not be + * incorporated. + * + * @return the sum + */ + public long sum() { + long sum = base; + Cell[] as = cells; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + sum += a.value; + } + } + return sum; + } + + /** + * Resets variables maintaining the sum to zero. This method may + * be a useful alternative to creating a new adder, but is only + * effective if there are no concurrent updates. Because this + * method is intrinsically racy, it should only be used when it is + * known that no threads are concurrently updating. + */ + public void reset() { + internalReset(0L); + } + + /** + * Equivalent in effect to {@link #sum} followed by {@link + * #reset}. This method may apply for example during quiescent + * points between multithreaded computations. If there are + * updates concurrent with this method, the returned value is + * not guaranteed to be the final value occurring before + * the reset. + * + * @return the sum + */ + public long sumThenReset() { + long sum = base; + Cell[] as = cells; + base = 0L; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) { + sum += a.value; + a.value = 0L; + } + } + } + return sum; + } + + /** + * Returns the String representation of the {@link #sum}. + * @return the String representation of the {@link #sum} + */ + public String toString() { + return Long.toString(sum()); + } + + /** + * Equivalent to {@link #sum}. + * + * @return the sum + */ + public long longValue() { + return sum(); + } + + /** + * Returns the {@link #sum} as an {@code int} after a narrowing + * primitive conversion. + */ + public int intValue() { + return (int)sum(); + } + + /** + * Returns the {@link #sum} as a {@code float} + * after a widening primitive conversion. + */ + public float floatValue() { + return (float)sum(); + } + + /** + * Returns the {@link #sum} as a {@code double} after a widening + * primitive conversion. + */ + public double doubleValue() { + return (double)sum(); + } + + private void writeObject(ObjectOutputStream s) + throws java.io.IOException { + s.defaultWriteObject(); + s.writeLong(sum()); + } + + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + busy = 0; + cells = null; + base = s.readLong(); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/Striped64.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/Striped64.java index ce347322cc4d..9608ac6bb678 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/Striped64.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/Striped64.java @@ -1,347 +1,347 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -/* - * Source: - * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.7 - */ - -package com.nhn.pinpoint.profiler.util.jdk; - -import java.util.Random; - -/** - * A package-local class holding common representation and mechanics - * for classes supporting dynamic striping on 64bit values. The class - * extends Number so that concrete subclasses must publicly do so. - */ -abstract class Striped64 extends Number { - /* - * This class maintains a lazily-initialized table of atomically - * updated variables, plus an extra "base" field. The table size - * is a power of two. Indexing uses masked per-thread hash codes. - * Nearly all declarations in this class are package-private, - * accessed directly by subclasses. - * - * Table entries are of class Cell; a variant of AtomicLong padded - * to reduce cache contention on most processors. Padding is - * overkill for most Atomics because they are usually irregularly - * scattered in memory and thus don't interfere much with each - * other. But Atomic objects residing in arrays will tend to be - * placed adjacent to each other, and so will most often share - * cache lines (with a huge negative performance impact) without - * this precaution. - * - * In part because Cells are relatively large, we avoid creating - * them until they are needed. When there is no contention, all - * updates are made to the base field. Upon first contention (a - * failed CAS on base update), the table is initialized to size 2. - * The table size is doubled upon further contention until - * reaching the nearest power of two greater than or equal to the - * number of CPUS. Table slots remain empty (null) until they are - * needed. - * - * A single spinlock ("busy") is used for initializing and - * resizing the table, as well as populating slots with new Cells. - * There is no need for a blocking lock: When the lock is not - * available, threads try other slots (or the base). During these - * retries, there is increased contention and reduced locality, - * which is still better than alternatives. - * - * Per-thread hash codes are initialized to random values. - * Contention and/or table collisions are indicated by failed - * CASes when performing an update operation (see method - * retryUpdate). Upon a collision, if the table size is less than - * the capacity, it is doubled in size unless some other thread - * holds the lock. If a hashed slot is empty, and lock is - * available, a new Cell is created. Otherwise, if the slot - * exists, a CAS is tried. Retries proceed by "double hashing", - * using a secondary hash (Marsaglia XorShift) to try to find a - * free slot. - * - * The table size is capped because, when there are more threads - * than CPUs, supposing that each thread were bound to a CPU, - * there would exist a perfect hash function mapping threads to - * slots that eliminates collisions. When we reach capacity, we - * search for this mapping by randomly varying the hash codes of - * colliding threads. Because search is random, and collisions - * only become known via CAS failures, convergence can be slow, - * and because threads are typically not bound to CPUS forever, - * may not occur at all. However, despite these limitations, - * observed contention rates are typically low in these cases. - * - * It is possible for a Cell to become unused when threads that - * once hashed to it terminate, as well as in the case where - * doubling the table causes no thread to hash to it under - * expanded mask. We do not try to detect or remove such cells, - * under the assumption that for long-running instances, observed - * contention levels will recur, so the cells will eventually be - * needed again; and for short-lived ones, it does not matter. - */ - - /** - * Padded variant of AtomicLong supporting only raw accesses plus CAS. - * The value field is placed between pads, hoping that the JVM doesn't - * reorder them. - * - * JVM intrinsics note: It would be possible to use a release-only - * form of CAS here, if it were provided. - */ - static final class Cell { - volatile long p0, p1, p2, p3, p4, p5, p6; - volatile long value; - volatile long q0, q1, q2, q3, q4, q5, q6; - Cell(long x) { value = x; } - - final boolean cas(long cmp, long val) { - return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val); - } - - // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long valueOffset; - static { - try { - UNSAFE = getUnsafe(); - Class ak = Cell.class; - valueOffset = UNSAFE.objectFieldOffset - (ak.getDeclaredField("value")); - } catch (Exception e) { - throw new Error(e); - } - } - - } - - /** - * Holder for the thread-local hash code. The code is initially - * random, but may be set to a different value upon collisions. - */ - static final class HashCode { - static final Random rng = new Random(); - int code; - HashCode() { - int h = rng.nextInt(); // Avoid zero to allow xorShift rehash - code = (h == 0) ? 1 : h; - } - } - - /** - * The corresponding ThreadLocal class - */ - static final class ThreadHashCode extends ThreadLocal { - public HashCode initialValue() { return new HashCode(); } - } - - /** - * Static per-thread hash codes. Shared across all instances to - * reduce ThreadLocal pollution and because adjustments due to - * collisions in one table are likely to be appropriate for - * others. - */ - static final ThreadHashCode threadHashCode = new ThreadHashCode(); - - /** Number of CPUS, to place bound on table size */ - static final int NCPU = Runtime.getRuntime().availableProcessors(); - - /** - * Table of cells. When non-null, size is a power of 2. - */ - transient volatile Cell[] cells; - - /** - * Base value, used mainly when there is no contention, but also as - * a fallback during table initialization races. Updated via CAS. - */ - transient volatile long base; - - /** - * Spinlock (locked via CAS) used when resizing and/or creating Cells. - */ - transient volatile int busy; - - /** - * Package-private default constructor - */ - Striped64() { - } - - /** - * CASes the base field. - */ - final boolean casBase(long cmp, long val) { - return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val); - } - - /** - * CASes the busy field from 0 to 1 to acquire lock. - */ - final boolean casBusy() { - return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1); - } - - /** - * Computes the function of current and new value. Subclasses - * should open-code this update function for most uses, but the - * virtualized form is needed within retryUpdate. - * - * @param currentValue the current value (of either base or a cell) - * @param newValue the argument from a user update call - * @return result of the update function - */ - abstract long fn(long currentValue, long newValue); - - /** - * Handles cases of updates involving initialization, resizing, - * creating new Cells, and/or contention. See above for - * explanation. This method suffers the usual non-modularity - * problems of optimistic retry code, relying on rechecked sets of - * reads. - * - * @param x the value - * @param hc the hash code holder - * @param wasUncontended false if CAS failed before call - */ - final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { - int h = hc.code; - boolean collide = false; // True if last slot nonempty - for (;;) { - Cell[] as; Cell a; int n; long v; - if ((as = cells) != null && (n = as.length) > 0) { - if ((a = as[(n - 1) & h]) == null) { - if (busy == 0) { // Try to attach new Cell - Cell r = new Cell(x); // Optimistically create - if (busy == 0 && casBusy()) { - boolean created = false; - try { // Recheck under lock - Cell[] rs; int m, j; - if ((rs = cells) != null && - (m = rs.length) > 0 && - rs[j = (m - 1) & h] == null) { - rs[j] = r; - created = true; - } - } finally { - busy = 0; - } - if (created) - break; - continue; // Slot is now non-empty - } - } - collide = false; - } - else if (!wasUncontended) // CAS already known to fail - wasUncontended = true; // Continue after rehash - else if (a.cas(v = a.value, fn(v, x))) - break; - else if (n >= NCPU || cells != as) - collide = false; // At max size or stale - else if (!collide) - collide = true; - else if (busy == 0 && casBusy()) { - try { - if (cells == as) { // Expand table unless stale - Cell[] rs = new Cell[n << 1]; - for (int i = 0; i < n; ++i) - rs[i] = as[i]; - cells = rs; - } - } finally { - busy = 0; - } - collide = false; - continue; // Retry with expanded table - } - h ^= h << 13; // Rehash - h ^= h >>> 17; - h ^= h << 5; - } - else if (busy == 0 && cells == as && casBusy()) { - boolean init = false; - try { // Initialize table - if (cells == as) { - Cell[] rs = new Cell[2]; - rs[h & 1] = new Cell(x); - cells = rs; - init = true; - } - } finally { - busy = 0; - } - if (init) - break; - } - else if (casBase(v = base, fn(v, x))) - break; // Fall back on using base - } - hc.code = h; // Record index for next time - } - - /** - * Sets base and all cells to the given value. - */ - final void internalReset(long initialValue) { - Cell[] as = cells; - base = initialValue; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - a.value = initialValue; - } - } - } - - // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long baseOffset; - private static final long busyOffset; - static { - try { - UNSAFE = getUnsafe(); - Class sk = Striped64.class; - baseOffset = UNSAFE.objectFieldOffset - (sk.getDeclaredField("base")); - busyOffset = UNSAFE.objectFieldOffset - (sk.getDeclaredField("busy")); - } catch (Exception e) { - throw new Error(e); - } - } - - /** - * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. - * Replace with a simple call to Unsafe.getUnsafe when integrating - * into a jdk. - * - * @return a sun.misc.Unsafe - */ - private static sun.misc.Unsafe getUnsafe() { - try { - return sun.misc.Unsafe.getUnsafe(); - } catch (SecurityException tryReflectionInstead) {} - try { - return java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public sun.misc.Unsafe run() throws Exception { - Class k = sun.misc.Unsafe.class; - for (java.lang.reflect.Field f : k.getDeclaredFields()) { - f.setAccessible(true); - Object x = f.get(null); - if (k.isInstance(x)) - return k.cast(x); - } - throw new NoSuchFieldError("the Unsafe"); - }}); - } catch (java.security.PrivilegedActionException e) { - throw new RuntimeException("Could not initialize intrinsics", - e.getCause()); - } - } - -} +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* + * Source: + * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.7 + */ + +package com.nhn.pinpoint.profiler.util.jdk; + +import java.util.Random; + +/** + * A package-local class holding common representation and mechanics + * for classes supporting dynamic striping on 64bit values. The class + * extends Number so that concrete subclasses must publicly do so. + */ +abstract class Striped64 extends Number { + /* + * This class maintains a lazily-initialized table of atomically + * updated variables, plus an extra "base" field. The table size + * is a power of two. Indexing uses masked per-thread hash codes. + * Nearly all declarations in this class are package-private, + * accessed directly by subclasses. + * + * Table entries are of class Cell; a variant of AtomicLong padded + * to reduce cache contention on most processors. Padding is + * overkill for most Atomics because they are usually irregularly + * scattered in memory and thus don't interfere much with each + * other. But Atomic objects residing in arrays will tend to be + * placed adjacent to each other, and so will most often share + * cache lines (with a huge negative performance impact) without + * this precaution. + * + * In part because Cells are relatively large, we avoid creating + * them until they are needed. When there is no contention, all + * updates are made to the base field. Upon first contention (a + * failed CAS on base update), the table is initialized to size 2. + * The table size is doubled upon further contention until + * reaching the nearest power of two greater than or equal to the + * number of CPUS. Table slots remain empty (null) until they are + * needed. + * + * A single spinlock ("busy") is used for initializing and + * resizing the table, as well as populating slots with new Cells. + * There is no need for a blocking lock: When the lock is not + * available, threads try other slots (or the base). During these + * retries, there is increased contention and reduced locality, + * which is still better than alternatives. + * + * Per-thread hash codes are initialized to random values. + * Contention and/or table collisions are indicated by failed + * CASes when performing an update operation (see method + * retryUpdate). Upon a collision, if the table size is less than + * the capacity, it is doubled in size unless some other thread + * holds the lock. If a hashed slot is empty, and lock is + * available, a new Cell is created. Otherwise, if the slot + * exists, a CAS is tried. Retries proceed by "double hashing", + * using a secondary hash (Marsaglia XorShift) to try to find a + * free slot. + * + * The table size is capped because, when there are more threads + * than CPUs, supposing that each thread were bound to a CPU, + * there would exist a perfect hash function mapping threads to + * slots that eliminates collisions. When we reach capacity, we + * search for this mapping by randomly varying the hash codes of + * colliding threads. Because search is random, and collisions + * only become known via CAS failures, convergence can be slow, + * and because threads are typically not bound to CPUS forever, + * may not occur at all. However, despite these limitations, + * observed contention rates are typically low in these cases. + * + * It is possible for a Cell to become unused when threads that + * once hashed to it terminate, as well as in the case where + * doubling the table causes no thread to hash to it under + * expanded mask. We do not try to detect or remove such cells, + * under the assumption that for long-running instances, observed + * contention levels will recur, so the cells will eventually be + * needed again; and for short-lived ones, it does not matter. + */ + + /** + * Padded variant of AtomicLong supporting only raw accesses plus CAS. + * The value field is placed between pads, hoping that the JVM doesn't + * reorder them. + * + * JVM intrinsics note: It would be possible to use a release-only + * form of CAS here, if it were provided. + */ + static final class Cell { + volatile long p0, p1, p2, p3, p4, p5, p6; + volatile long value; + volatile long q0, q1, q2, q3, q4, q5, q6; + Cell(long x) { value = x; } + + final boolean cas(long cmp, long val) { + return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val); + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long valueOffset; + static { + try { + UNSAFE = getUnsafe(); + Class ak = Cell.class; + valueOffset = UNSAFE.objectFieldOffset + (ak.getDeclaredField("value")); + } catch (Exception e) { + throw new Error(e); + } + } + + } + + /** + * Holder for the thread-local hash code. The code is initially + * random, but may be set to a different value upon collisions. + */ + static final class HashCode { + static final Random rng = new Random(); + int code; + HashCode() { + int h = rng.nextInt(); // Avoid zero to allow xorShift rehash + code = (h == 0) ? 1 : h; + } + } + + /** + * The corresponding ThreadLocal class + */ + static final class ThreadHashCode extends ThreadLocal { + public HashCode initialValue() { return new HashCode(); } + } + + /** + * Static per-thread hash codes. Shared across all instances to + * reduce ThreadLocal pollution and because adjustments due to + * collisions in one table are likely to be appropriate for + * others. + */ + static final ThreadHashCode threadHashCode = new ThreadHashCode(); + + /** Number of CPUS, to place bound on table size */ + static final int NCPU = Runtime.getRuntime().availableProcessors(); + + /** + * Table of cells. When non-null, size is a power of 2. + */ + transient volatile Cell[] cells; + + /** + * Base value, used mainly when there is no contention, but also as + * a fallback during table initialization races. Updated via CAS. + */ + transient volatile long base; + + /** + * Spinlock (locked via CAS) used when resizing and/or creating Cells. + */ + transient volatile int busy; + + /** + * Package-private default constructor + */ + Striped64() { + } + + /** + * CASes the base field. + */ + final boolean casBase(long cmp, long val) { + return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val); + } + + /** + * CASes the busy field from 0 to 1 to acquire lock. + */ + final boolean casBusy() { + return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1); + } + + /** + * Computes the function of current and new value. Subclasses + * should open-code this update function for most uses, but the + * virtualized form is needed within retryUpdate. + * + * @param currentValue the current value (of either base or a cell) + * @param newValue the argument from a user update call + * @return result of the update function + */ + abstract long fn(long currentValue, long newValue); + + /** + * Handles cases of updates involving initialization, resizing, + * creating new Cells, and/or contention. See above for + * explanation. This method suffers the usual non-modularity + * problems of optimistic retry code, relying on rechecked sets of + * reads. + * + * @param x the value + * @param hc the hash code holder + * @param wasUncontended false if CAS failed before call + */ + final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { + int h = hc.code; + boolean collide = false; // True if last slot nonempty + for (;;) { + Cell[] as; Cell a; int n; long v; + if ((as = cells) != null && (n = as.length) > 0) { + if ((a = as[(n - 1) & h]) == null) { + if (busy == 0) { // Try to attach new Cell + Cell r = new Cell(x); // Optimistically create + if (busy == 0 && casBusy()) { + boolean created = false; + try { // Recheck under lock + Cell[] rs; int m, j; + if ((rs = cells) != null && + (m = rs.length) > 0 && + rs[j = (m - 1) & h] == null) { + rs[j] = r; + created = true; + } + } finally { + busy = 0; + } + if (created) + break; + continue; // Slot is now non-empty + } + } + collide = false; + } + else if (!wasUncontended) // CAS already known to fail + wasUncontended = true; // Continue after rehash + else if (a.cas(v = a.value, fn(v, x))) + break; + else if (n >= NCPU || cells != as) + collide = false; // At max size or stale + else if (!collide) + collide = true; + else if (busy == 0 && casBusy()) { + try { + if (cells == as) { // Expand table unless stale + Cell[] rs = new Cell[n << 1]; + for (int i = 0; i < n; ++i) + rs[i] = as[i]; + cells = rs; + } + } finally { + busy = 0; + } + collide = false; + continue; // Retry with expanded table + } + h ^= h << 13; // Rehash + h ^= h >>> 17; + h ^= h << 5; + } + else if (busy == 0 && cells == as && casBusy()) { + boolean init = false; + try { // Initialize table + if (cells == as) { + Cell[] rs = new Cell[2]; + rs[h & 1] = new Cell(x); + cells = rs; + init = true; + } + } finally { + busy = 0; + } + if (init) + break; + } + else if (casBase(v = base, fn(v, x))) + break; // Fall back on using base + } + hc.code = h; // Record index for next time + } + + /** + * Sets base and all cells to the given value. + */ + final void internalReset(long initialValue) { + Cell[] as = cells; + base = initialValue; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + a.value = initialValue; + } + } + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long baseOffset; + private static final long busyOffset; + static { + try { + UNSAFE = getUnsafe(); + Class sk = Striped64.class; + baseOffset = UNSAFE.objectFieldOffset + (sk.getDeclaredField("base")); + busyOffset = UNSAFE.objectFieldOffset + (sk.getDeclaredField("busy")); + } catch (Exception e) { + throw new Error(e); + } + } + + /** + * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. + * Replace with a simple call to Unsafe.getUnsafe when integrating + * into a jdk. + * + * @return a sun.misc.Unsafe + */ + private static sun.misc.Unsafe getUnsafe() { + try { + return sun.misc.Unsafe.getUnsafe(); + } catch (SecurityException tryReflectionInstead) {} + try { + return java.security.AccessController.doPrivileged + (new java.security.PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + Class k = sun.misc.Unsafe.class; + for (java.lang.reflect.Field f : k.getDeclaredFields()) { + f.setAccessible(true); + Object x = f.get(null); + if (k.isInstance(x)) + return k.cast(x); + } + throw new NoSuchFieldError("the Unsafe"); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); + } + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/ThreadLocalRandom.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/ThreadLocalRandom.java index 62f7bd331f2a..435fbe0f1e9d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/ThreadLocalRandom.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/jdk/ThreadLocalRandom.java @@ -1,202 +1,202 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - * - * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java?view=markup - */ -package com.nhn.pinpoint.profiler.util.jdk; - -import java.util.Random; - -/** - * Copied directly from the JSR-166 project. - */ -/** - * A random number generator isolated to the current thread. Like the - * global {@link java.util.Random} generator used by the {@link - * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized - * with an internally generated seed that may not otherwise be - * modified. When applicable, use of {@code ThreadLocalRandom} rather - * than shared {@code Random} objects in concurrent programs will - * typically encounter much less overhead and contention. Use of - * {@code ThreadLocalRandom} is particularly appropriate when multiple - * tasks (for example, each a {@link ForkJoinTask}) use random numbers - * in parallel in thread pools. - * - *

Usages of this class should typically be of the form: - * {@code ThreadLocalRandom.current().nextX(...)} (where - * {@code X} is {@code Int}, {@code Long}, etc). - * When all usages are of this form, it is never possible to - * accidently share a {@code ThreadLocalRandom} across multiple threads. - * - *

This class also provides additional commonly used bounded random - * generation methods. - * - * @since 1.7 - * @author Doug Lea - */ -public class ThreadLocalRandom extends Random { - // same constants as Random, but must be redeclared because private - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - - /** - * The random seed. We can't use super.seed. - */ - private long rnd; - - /** - * Initialization flag to permit calls to setSeed to succeed only - * while executing the Random constructor. We can't allow others - * since it would cause setting seed in one part of a program to - * unintentionally impact other usages by the thread. - */ - boolean initialized; - - // Padding to help avoid memory contention among seed updates in - // different TLRs in the common case that they are located near - // each other. - private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; - - /** - * The actual ThreadLocal - */ - private static final ThreadLocal localRandom = - new ThreadLocal() { - protected ThreadLocalRandom initialValue() { - return new ThreadLocalRandom(); - } - }; - - - /** - * Constructor called only by localRandom.initialValue. - */ - ThreadLocalRandom() { - super(); - initialized = true; - } - - /** - * Returns the current thread's {@code ThreadLocalRandom}. - * - * @return the current thread's {@code ThreadLocalRandom} - */ - public static ThreadLocalRandom current() { - return localRandom.get(); - } - - /** - * Throws {@code UnsupportedOperationException}. Setting seeds in - * this generator is not supported. - * - * @throws UnsupportedOperationException always - */ - public void setSeed(long seed) { - if (initialized) - throw new UnsupportedOperationException(); - rnd = (seed ^ multiplier) & mask; - } - - protected int next(int bits) { - rnd = (rnd * multiplier + addend) & mask; - return (int) (rnd >>> (48-bits)); - } - - /** - * Returns a pseudorandom, uniformly distributed value between the - * given least value (inclusive) and bound (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @throws IllegalArgumentException if least greater than or equal - * to bound - * @return the next value - */ - public int nextInt(int least, int bound) { - if (least >= bound) - throw new IllegalArgumentException(); - return nextInt(bound - least) + least; - } - - /** - * Returns a pseudorandom, uniformly distributed value - * between 0 (inclusive) and the specified value (exclusive). - * - * @param n the bound on the random number to be returned. Must be - * positive. - * @return the next value - * @throws IllegalArgumentException if n is not positive - */ - public long nextLong(long n) { - if (n <= 0) - throw new IllegalArgumentException("n must be positive"); - // Divide n by two until small enough for nextInt. On each - // iteration (at most 31 of them but usually much less), - // randomly choose both whether to include high bit in result - // (offset) and whether to continue with the lower vs upper - // half (which makes a difference only if odd). - long offset = 0; - while (n >= Integer.MAX_VALUE) { - int bits = next(2); - long half = n >>> 1; - long nextn = ((bits & 2) == 0) ? half : n - half; - if ((bits & 1) == 0) - offset += n - nextn; - n = nextn; - } - return offset + nextInt((int) n); - } - - /** - * Returns a pseudorandom, uniformly distributed value between the - * given least value (inclusive) and bound (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @return the next value - * @throws IllegalArgumentException if least greater than or equal - * to bound - */ - public long nextLong(long least, long bound) { - if (least >= bound) - throw new IllegalArgumentException(); - return nextLong(bound - least) + least; - } - - /** - * Returns a pseudorandom, uniformly distributed {@code double} value - * between 0 (inclusive) and the specified value (exclusive). - * - * @param n the bound on the random number to be returned. Must be - * positive. - * @return the next value - * @throws IllegalArgumentException if n is not positive - */ - public double nextDouble(double n) { - if (n <= 0) - throw new IllegalArgumentException("n must be positive"); - return nextDouble() * n; - } - - /** - * Returns a pseudorandom, uniformly distributed value between the - * given least value (inclusive) and bound (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @return the next value - * @throws IllegalArgumentException if least greater than or equal - * to bound - */ - public double nextDouble(double least, double bound) { - if (least >= bound) - throw new IllegalArgumentException(); - return nextDouble() * (bound - least) + least; - } - - private static final long serialVersionUID = -5851777807851030925L; -} - +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + * + * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java?view=markup + */ +package com.nhn.pinpoint.profiler.util.jdk; + +import java.util.Random; + +/** + * Copied directly from the JSR-166 project. + */ +/** + * A random number generator isolated to the current thread. Like the + * global {@link java.util.Random} generator used by the {@link + * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized + * with an internally generated seed that may not otherwise be + * modified. When applicable, use of {@code ThreadLocalRandom} rather + * than shared {@code Random} objects in concurrent programs will + * typically encounter much less overhead and contention. Use of + * {@code ThreadLocalRandom} is particularly appropriate when multiple + * tasks (for example, each a {@link ForkJoinTask}) use random numbers + * in parallel in thread pools. + * + *

Usages of this class should typically be of the form: + * {@code ThreadLocalRandom.current().nextX(...)} (where + * {@code X} is {@code Int}, {@code Long}, etc). + * When all usages are of this form, it is never possible to + * accidently share a {@code ThreadLocalRandom} across multiple threads. + * + *

This class also provides additional commonly used bounded random + * generation methods. + * + * @since 1.7 + * @author Doug Lea + */ +public class ThreadLocalRandom extends Random { + // same constants as Random, but must be redeclared because private + private static final long multiplier = 0x5DEECE66DL; + private static final long addend = 0xBL; + private static final long mask = (1L << 48) - 1; + + /** + * The random seed. We can't use super.seed. + */ + private long rnd; + + /** + * Initialization flag to permit calls to setSeed to succeed only + * while executing the Random constructor. We can't allow others + * since it would cause setting seed in one part of a program to + * unintentionally impact other usages by the thread. + */ + boolean initialized; + + // Padding to help avoid memory contention among seed updates in + // different TLRs in the common case that they are located near + // each other. + private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + /** + * The actual ThreadLocal + */ + private static final ThreadLocal localRandom = + new ThreadLocal() { + protected ThreadLocalRandom initialValue() { + return new ThreadLocalRandom(); + } + }; + + + /** + * Constructor called only by localRandom.initialValue. + */ + ThreadLocalRandom() { + super(); + initialized = true; + } + + /** + * Returns the current thread's {@code ThreadLocalRandom}. + * + * @return the current thread's {@code ThreadLocalRandom} + */ + public static ThreadLocalRandom current() { + return localRandom.get(); + } + + /** + * Throws {@code UnsupportedOperationException}. Setting seeds in + * this generator is not supported. + * + * @throws UnsupportedOperationException always + */ + public void setSeed(long seed) { + if (initialized) + throw new UnsupportedOperationException(); + rnd = (seed ^ multiplier) & mask; + } + + protected int next(int bits) { + rnd = (rnd * multiplier + addend) & mask; + return (int) (rnd >>> (48-bits)); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @throws IllegalArgumentException if least greater than or equal + * to bound + * @return the next value + */ + public int nextInt(int least, int bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextInt(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public long nextLong(long n) { + if (n <= 0) + throw new IllegalArgumentException("n must be positive"); + // Divide n by two until small enough for nextInt. On each + // iteration (at most 31 of them but usually much less), + // randomly choose both whether to include high bit in result + // (offset) and whether to continue with the lower vs upper + // half (which makes a difference only if odd). + long offset = 0; + while (n >= Integer.MAX_VALUE) { + int bits = next(2); + long half = n >>> 1; + long nextn = ((bits & 2) == 0) ? half : n - half; + if ((bits & 1) == 0) + offset += n - nextn; + n = nextn; + } + return offset + nextInt((int) n); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public long nextLong(long least, long bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextLong(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed {@code double} value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public double nextDouble(double n) { + if (n <= 0) + throw new IllegalArgumentException("n must be positive"); + return nextDouble() * n; + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public double nextDouble(double least, double bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextDouble() * (bound - least) + least; + } + + private static final long serialVersionUID = -5851777807851030925L; +} + diff --git a/profiler/src/main/resources-dev/log4j.xml b/profiler/src/main/resources-dev/log4j.xml index c94dd51a90a2..e7a8bee7a7e5 100644 --- a/profiler/src/main/resources-dev/log4j.xml +++ b/profiler/src/main/resources-dev/log4j.xml @@ -1,39 +1,39 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/profiler/src/main/resources-dev/pinpoint.config b/profiler/src/main/resources-dev/pinpoint.config index fbd26a58172d..6811a852e3f1 100644 --- a/profiler/src/main/resources-dev/pinpoint.config +++ b/profiler/src/main/resources-dev/pinpoint.config @@ -1,171 +1,174 @@ -# -# Pinpoint agent configuration -# (Phase : dev) -# - -########################################################### -# Collector server # -########################################################### -profiler.collector.ip=dev.collector.pinpoint.navercorp.com -profiler.collector.udpspan.port=9996 -profiler.collector.udp.port=9995 -profiler.collector.tcp.port=9994 - - -########################################################### -# Profiler Global Configuration # -########################################################### -profiler.enable=true - -profiler.jvm.collect.interval=1000 - -profiler.sampling.enable=true - -# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈) -profiler.sampling.rate=1 - -# span을 Io에 flush할 경우 buffering 여부 -profiler.io.buffering.enable=true - -# buffering 시 몇개 까지 저장할지 여부 -profiler.io.buffering.buffersize=20 - -profiler.spandatasender.write.queue.size=5120 -#profiler.spandatasender.socket.sendbuffersize=1048576 -#profiler.spandatasender.socket.timeout=3000 - -profiler.statdatasender.write.queue.size=5120 -#profiler.statdatasender.socket.sendbuffersize=1048576 -#profiler.statdatasender.socket.timeout=3000 - -profiler.heartbeat.interval=300000 - -# Tcp Data Command 허용 여부 -profiler.tcpdatasender.command.accept.enable=true - -########################################################### -# application type # -########################################################### -#profiler.applicationservertype=TOMCAT -#profiler.applicationservertype=BLOC - - -########################################################### -# user defined classes # -########################################################### -profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass - - -########################################################### -# JDBC # -########################################################### -profiler.jdbc=true -profiler.jdbc.sqlcachesize=1024 -profiler.jdbc.maxsqlbindvaluesize=1024 - -# -# MYSQL -# -profiler.jdbc.mysql=true -profiler.jdbc.mysql.setautocommit=true -profiler.jdbc.mysql.commit=true -profiler.jdbc.mysql.rollback=true - -# -# MSSQL -# -profiler.jdbc.mssql=false - -# -# Oracle -# -profiler.jdbc.oracle=true -profiler.jdbc.oracle.setautocommit=true -profiler.jdbc.oracle.commit=true -profiler.jdbc.oracle.rollback=true - -# -# CUBRID -# -profiler.jdbc.cubrid=true -profiler.jdbc.cubrid.setautocommit=true -profiler.jdbc.cubrid.commit=true -profiler.jdbc.cubrid.rollback=true - -# -# DBCP -# -profiler.jdbc.dbcp=true -profiler.jdbc.dbcp.connectionclose=true - - -########################################################### -# Apache HTTP Client 4.x # -########################################################### -profiler.apache.httpclient4=true -profiler.apache.httpclient4.cookie=true - -# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.cookie.dumptype=ALWAYS -profiler.apache.httpclient4.cookie.sampling.rate=1 - -# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. -profiler.apache.httpclient4.entity=true - -# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.entity.dumptype=ALWAYS -profiler.apache.httpclient4.entity.sampling.rate=1 - -profiler.apache.nio.httpclient4=true - - -########################################################### -# Ning Async HTTP Client # -########################################################### -profiler.ning.asynchttpclient=true -profiler.ning.asynchttpclient.cookie=true -profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS -profiler.ning.asynchttpclient.cookie.dumpsize=1024 -profiler.ning.asynchttpclient.cookie.sampling.rate=1 -profiler.ning.asynchttpclient.entity=true -profiler.ning.asynchttpclient.entity.dumptype=ALWAYS -profiler.ning.asynchttpclient.entity.dumpsize=1024 -profiler.ning.asynchttpclient.entity.sampling.rate=1 -profiler.ning.asynchttpclient.param=true -profiler.ning.asynchttpclient.param.dumptype=ALWAYS -profiler.ning.asynchttpclient.param.dumpsize=1024 -profiler.ning.asynchttpclient.param.sampling.rate=1 - - -########################################################### -# LINE+ baseframework # -########################################################### -profiler.line.game.netty.param.dumpsize=512 -profiler.line.game.netty.entity.dumpsize=512 - - -########################################################### -# Arcus # -########################################################### -profiler.arcus=true -profiler.arcus.keytrace=true - - -########################################################### -# Memcached # -########################################################### -profiler.memcached=true -profiler.memcached.keytrace=true - - -########################################################### -# ibatis # -########################################################### -profiler.orm.ibatis=true - - -########################################################### -# mybatis # -########################################################### -profiler.orm.mybatis=true - +# +# Pinpoint agent configuration +# (Phase : dev) +# + +########################################################### +# Collector server # +########################################################### +profiler.collector.ip=dev.collector.pinpoint.navercorp.com +profiler.collector.udpspan.port=9996 +profiler.collector.udp.port=9995 +profiler.collector.tcp.port=9994 + + +########################################################### +# Profiler Global Configuration # +########################################################### +profiler.enable=true + +profiler.jvm.collect.interval=1000 + +profiler.sampling.enable=true + +# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈) +profiler.sampling.rate=1 + +# span을 Io에 flush할 경우 buffering 여부 +profiler.io.buffering.enable=true + +# buffering 시 몇개 까지 저장할지 여부 +profiler.io.buffering.buffersize=20 + +profiler.spandatasender.write.queue.size=5120 +#profiler.spandatasender.socket.sendbuffersize=1048576 +#profiler.spandatasender.socket.timeout=3000 + +profiler.statdatasender.write.queue.size=5120 +#profiler.statdatasender.socket.sendbuffersize=1048576 +#profiler.statdatasender.socket.timeout=3000 + +profiler.heartbeat.interval=300000 + +# Tcp Data Command 허용 여부 +profiler.tcpdatasender.command.accept.enable=true + +########################################################### +# application type # +########################################################### +#profiler.applicationservertype=TOMCAT +#profiler.applicationservertype=BLOC + + +########################################################### +# user defined classes # +########################################################### +profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass + + +########################################################### +# JDBC # +########################################################### +profiler.jdbc=true +profiler.jdbc.sqlcachesize=1024 +profiler.jdbc.maxsqlbindvaluesize=1024 + +# +# MYSQL +# +profiler.jdbc.mysql=true +profiler.jdbc.mysql.setautocommit=true +profiler.jdbc.mysql.commit=true +profiler.jdbc.mysql.rollback=true + +# +# MSSQL Jtds +# +profiler.jdbc.jtds=true +profiler.jdbc.jtds.setautocommit=true +profiler.jdbc.jtds.commit=true +profiler.jdbc.jtds.rollback=true + +# +# Oracle +# +profiler.jdbc.oracle=true +profiler.jdbc.oracle.setautocommit=true +profiler.jdbc.oracle.commit=true +profiler.jdbc.oracle.rollback=true + +# +# CUBRID +# +profiler.jdbc.cubrid=true +profiler.jdbc.cubrid.setautocommit=true +profiler.jdbc.cubrid.commit=true +profiler.jdbc.cubrid.rollback=true + +# +# DBCP +# +profiler.jdbc.dbcp=true +profiler.jdbc.dbcp.connectionclose=true + + +########################################################### +# Apache HTTP Client 4.x # +########################################################### +profiler.apache.httpclient4=true +profiler.apache.httpclient4.cookie=true + +# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.cookie.dumptype=ALWAYS +profiler.apache.httpclient4.cookie.sampling.rate=1 + +# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. +profiler.apache.httpclient4.entity=true + +# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.entity.dumptype=ALWAYS +profiler.apache.httpclient4.entity.sampling.rate=1 + +profiler.apache.nio.httpclient4=true + + +########################################################### +# Ning Async HTTP Client # +########################################################### +profiler.ning.asynchttpclient=true +profiler.ning.asynchttpclient.cookie=true +profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS +profiler.ning.asynchttpclient.cookie.dumpsize=1024 +profiler.ning.asynchttpclient.cookie.sampling.rate=1 +profiler.ning.asynchttpclient.entity=true +profiler.ning.asynchttpclient.entity.dumptype=ALWAYS +profiler.ning.asynchttpclient.entity.dumpsize=1024 +profiler.ning.asynchttpclient.entity.sampling.rate=1 +profiler.ning.asynchttpclient.param=true +profiler.ning.asynchttpclient.param.dumptype=ALWAYS +profiler.ning.asynchttpclient.param.dumpsize=1024 +profiler.ning.asynchttpclient.param.sampling.rate=1 + + +########################################################### +# LINE+ baseframework # +########################################################### +profiler.line.game.netty.param.dumpsize=512 +profiler.line.game.netty.entity.dumpsize=512 + + +########################################################### +# Arcus # +########################################################### +profiler.arcus=true +profiler.arcus.keytrace=true + + +########################################################### +# Memcached # +########################################################### +profiler.memcached=true +profiler.memcached.keytrace=true + + +########################################################### +# ibatis # +########################################################### +profiler.orm.ibatis=true + + +########################################################### +# mybatis # +########################################################### +profiler.orm.mybatis=true + diff --git a/profiler/src/main/resources-local/log4j.xml b/profiler/src/main/resources-local/log4j.xml index 525bde798643..26b454ac39b9 100644 --- a/profiler/src/main/resources-local/log4j.xml +++ b/profiler/src/main/resources-local/log4j.xml @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/profiler/src/main/resources-local/pinpoint.config b/profiler/src/main/resources-local/pinpoint.config index 1ad8c0bb4cc2..4c55d7aa0c40 100644 --- a/profiler/src/main/resources-local/pinpoint.config +++ b/profiler/src/main/resources-local/pinpoint.config @@ -1,179 +1,182 @@ -# -# Pinpoint agent configuration -# (Phase : local) -# - -########################################################### -# Collector server # -########################################################### -# 로컬 -profiler.collector.ip=127.0.0.1 -# 개발 -#profiler.collector.ip=10.64.84.188 -# 운영 -#profiler.collector.ip=10.25.149.249 - -profiler.collector.udpspan.port=9996 -profiler.collector.udp.port=9995 -profiler.collector.tcp.port=9994 - - -########################################################### -# Profiler Global Configuration # -########################################################### -profiler.enable=true - -profiler.jvm.collect.interval=1000 - -profiler.sampling.enable=true - -# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈) -profiler.sampling.rate=1 - -# span을 Io에 flush할 경우 buffering 여부 -profiler.io.buffering.enable=true - -# buffering 시 몇개 까지 저장할지 여부 -profiler.io.buffering.buffersize=20 - - - -profiler.spandatasender.write.queue.size=5120 -#profiler.spandatasender.socket.sendbuffersize=1048576 -#profiler.spandatasender.socket.timeout=3000 - -profiler.statdatasender.write.queue.size=5120 -#profiler.statdatasender.socket.sendbuffersize=1048576 -#profiler.statdatasender.socket.timeout=3000 - -profiler.heartbeat.interval=300000 - -# Tcp Data Command 허용 여부 -profiler.tcpdatasender.command.accept.enable=true - -########################################################### -# application type # -########################################################### -#profiler.applicationservertype=TOMCAT -#profiler.applicationservertype=BLOC - - -########################################################### -# user defined classes # -########################################################### -profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass - - -########################################################### -# JDBC # -########################################################### -profiler.jdbc=true -profiler.jdbc.sqlcachesize=1024 -profiler.jdbc.maxsqlbindvaluesize=1024 - -# -# MYSQL -# -profiler.jdbc.mysql=true -profiler.jdbc.mysql.setautocommit=true -profiler.jdbc.mysql.commit=true -profiler.jdbc.mysql.rollback=true - -# -# MSSQL -# -profiler.jdbc.mssql=false - -# -# Oracle -# -profiler.jdbc.oracle=true -profiler.jdbc.oracle.setautocommit=true -profiler.jdbc.oracle.commit=true -profiler.jdbc.oracle.rollback=true - -# -# CUBRID -# -profiler.jdbc.cubrid=true -profiler.jdbc.cubrid.setautocommit=true -profiler.jdbc.cubrid.commit=true -profiler.jdbc.cubrid.rollback=true - -# -# DBCP -# -profiler.jdbc.dbcp=true -profiler.jdbc.dbcp.connectionclose=true - - -########################################################### -# Apache HTTP Client 4.x # -########################################################### -profiler.apache.httpclient4=true -profiler.apache.httpclient4.cookie=true - -# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.cookie.dumptype=ALWAYS -profiler.apache.httpclient4.cookie.sampling.rate=1 - -# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. -profiler.apache.httpclient4.entity=true - -# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.entity.dumptype=ALWAYS -profiler.apache.httpclient4.entity.sampling.rate=1 - -profiler.apache.nio.httpclient4=true - - -########################################################### -# Ning Async HTTP Client # -########################################################### -profiler.ning.asynchttpclient=true -profiler.ning.asynchttpclient.cookie=true -profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS -profiler.ning.asynchttpclient.cookie.dumpsize=1024 -profiler.ning.asynchttpclient.cookie.sampling.rate=1 -profiler.ning.asynchttpclient.entity=true -profiler.ning.asynchttpclient.entity.dumptype=ALWAYS -profiler.ning.asynchttpclient.entity.dumpsize=1024 -profiler.ning.asynchttpclient.entity.sampling.rate=1 -profiler.ning.asynchttpclient.param=true -profiler.ning.asynchttpclient.param.dumptype=ALWAYS -profiler.ning.asynchttpclient.param.dumpsize=1024 -profiler.ning.asynchttpclient.param.sampling.rate=1 - - -########################################################### -# LINE+ baseframework # -########################################################### -profiler.line.game.netty.param.dumpsize=512 -profiler.line.game.netty.entity.dumpsize=512 - - -########################################################### -# Arcus # -########################################################### -profiler.arcus=true -profiler.arcus.keytrace=true - - -########################################################### -# Memcached # -########################################################### -profiler.memcached=true -profiler.memcached.keytrace=true - - -########################################################### -# ibatis # -########################################################### -profiler.orm.ibatis=true - - -########################################################### -# mybatis # -########################################################### -profiler.orm.mybatis=true - +# +# Pinpoint agent configuration +# (Phase : local) +# + +########################################################### +# Collector server # +########################################################### +# local +profiler.collector.ip=127.0.0.1 +# dev +#profiler.collector.ip=10.64.84.188 +# real +#profiler.collector.ip=10.25.149.249 + +profiler.collector.udpspan.port=9996 +profiler.collector.udp.port=9995 +profiler.collector.tcp.port=9994 + + +########################################################### +# Profiler Global Configuration # +########################################################### +profiler.enable=true + +profiler.jvm.collect.interval=1000 + +profiler.sampling.enable=true + +# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈) +profiler.sampling.rate=1 + +# span을 Io에 flush할 경우 buffering 여부 +profiler.io.buffering.enable=true + +# buffering 시 몇개 까지 저장할지 여부 +profiler.io.buffering.buffersize=20 + + + +profiler.spandatasender.write.queue.size=5120 +#profiler.spandatasender.socket.sendbuffersize=1048576 +#profiler.spandatasender.socket.timeout=3000 + +profiler.statdatasender.write.queue.size=5120 +#profiler.statdatasender.socket.sendbuffersize=1048576 +#profiler.statdatasender.socket.timeout=3000 + +profiler.heartbeat.interval=300000 + +# Tcp Data Command 허용 여부 +profiler.tcpdatasender.command.accept.enable=true + +########################################################### +# application type # +########################################################### +#profiler.applicationservertype=TOMCAT +#profiler.applicationservertype=BLOC + + +########################################################### +# user defined classes # +########################################################### +profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass + + +########################################################### +# JDBC # +########################################################### +profiler.jdbc=true +profiler.jdbc.sqlcachesize=1024 +profiler.jdbc.maxsqlbindvaluesize=1024 + +# +# MYSQL +# +profiler.jdbc.mysql=true +profiler.jdbc.mysql.setautocommit=true +profiler.jdbc.mysql.commit=true +profiler.jdbc.mysql.rollback=true + +# +# MSSQL Jtds +# +profiler.jdbc.jtds=true +profiler.jdbc.jtds.setautocommit=true +profiler.jdbc.jtds.commit=true +profiler.jdbc.jtds.rollback=true + +# +# Oracle +# +profiler.jdbc.oracle=true +profiler.jdbc.oracle.setautocommit=true +profiler.jdbc.oracle.commit=true +profiler.jdbc.oracle.rollback=true + +# +# CUBRID +# +profiler.jdbc.cubrid=true +profiler.jdbc.cubrid.setautocommit=true +profiler.jdbc.cubrid.commit=true +profiler.jdbc.cubrid.rollback=true + +# +# DBCP +# +profiler.jdbc.dbcp=true +profiler.jdbc.dbcp.connectionclose=true + + +########################################################### +# Apache HTTP Client 4.x # +########################################################### +profiler.apache.httpclient4=true +profiler.apache.httpclient4.cookie=true + +# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.cookie.dumptype=ALWAYS +profiler.apache.httpclient4.cookie.sampling.rate=1 + +# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. +profiler.apache.httpclient4.entity=true + +# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.entity.dumptype=ALWAYS +profiler.apache.httpclient4.entity.sampling.rate=1 + +profiler.apache.nio.httpclient4=true + + +########################################################### +# Ning Async HTTP Client # +########################################################### +profiler.ning.asynchttpclient=true +profiler.ning.asynchttpclient.cookie=true +profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS +profiler.ning.asynchttpclient.cookie.dumpsize=1024 +profiler.ning.asynchttpclient.cookie.sampling.rate=1 +profiler.ning.asynchttpclient.entity=true +profiler.ning.asynchttpclient.entity.dumptype=ALWAYS +profiler.ning.asynchttpclient.entity.dumpsize=1024 +profiler.ning.asynchttpclient.entity.sampling.rate=1 +profiler.ning.asynchttpclient.param=true +profiler.ning.asynchttpclient.param.dumptype=ALWAYS +profiler.ning.asynchttpclient.param.dumpsize=1024 +profiler.ning.asynchttpclient.param.sampling.rate=1 + + +########################################################### +# LINE+ baseframework # +########################################################### +profiler.line.game.netty.param.dumpsize=512 +profiler.line.game.netty.entity.dumpsize=512 + + +########################################################### +# Arcus # +########################################################### +profiler.arcus=true +profiler.arcus.keytrace=true + + +########################################################### +# Memcached # +########################################################### +profiler.memcached=true +profiler.memcached.keytrace=true + + +########################################################### +# ibatis # +########################################################### +profiler.orm.ibatis=true + + +########################################################### +# mybatis # +########################################################### +profiler.orm.mybatis=true + diff --git a/profiler/src/main/resources-release/log4j.xml b/profiler/src/main/resources-release/log4j.xml index 3e403c6878b3..bb43eaf4b752 100644 --- a/profiler/src/main/resources-release/log4j.xml +++ b/profiler/src/main/resources-release/log4j.xml @@ -1,38 +1,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/profiler/src/main/resources-release/pinpoint.config b/profiler/src/main/resources-release/pinpoint.config index 6928d6c94b91..ca16e06cd36c 100644 --- a/profiler/src/main/resources-release/pinpoint.config +++ b/profiler/src/main/resources-release/pinpoint.config @@ -1,174 +1,177 @@ -# -# Pinpoint agent configuration -# (Phase : release) -# - -########################################################### -# Collector server # -########################################################### -profiler.collector.ip=collector.pinpoint.nhncorp.com -profiler.collector.udpspan.port=9996 -profiler.collector.udp.port=9995 -profiler.collector.tcp.port=9994 - - -########################################################### -# Profiler Global Configuration # -########################################################### -profiler.enable=true - -profiler.jvm.collect.interval=1000 - -profiler.sampling.enable=true - -# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈) -profiler.sampling.rate=20 - -# span을 Io에 flush할 경우 buffering 여부 -profiler.io.buffering.enable=true - -# buffering 시 몇개 까지 저장할지 여부 -profiler.io.buffering.buffersize=20 - - -profiler.spandatasender.write.queue.size=5120 -#profiler.spandatasender.socket.sendbuffersize=1048576 -#profiler.spandatasender.socket.timeout=3000 - -profiler.statdatasender.write.queue.size=5120 -#profiler.statdatasender.socket.sendbuffersize=1048576 -#profiler.statdatasender.socket.timeout=3000 - - -profiler.heartbeat.interval=60000 - -# Tcp Data Command 허용 여부 -profiler.tcpdatasender.command.accept.enable=true - - -########################################################### -# application type # -########################################################### -#profiler.applicationservertype=TOMCAT -#profiler.applicationservertype=BLOC - - -########################################################### -# user defined classes # -########################################################### -profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass - - -########################################################### -# JDBC # -########################################################### -profiler.jdbc=true -profiler.jdbc.sqlcachesize=1024 -profiler.jdbc.maxsqlbindvaluesize=1024 - -# -# MYSQL -# -profiler.jdbc.mysql=true -profiler.jdbc.mysql.setautocommit=false -profiler.jdbc.mysql.commit=false -profiler.jdbc.mysql.rollback=false - -# -# MSSQL -# -profiler.jdbc.mssql=false - -# -# Oracle -# -profiler.jdbc.oracle=true -profiler.jdbc.oracle.setautocommit=false -profiler.jdbc.oracle.commit=false -profiler.jdbc.oracle.rollback=false - -# -# CUBRID -# -profiler.jdbc.cubrid=true -profiler.jdbc.cubrid.setautocommit=false -profiler.jdbc.cubrid.commit=false -profiler.jdbc.cubrid.rollback=false - -# -# DBCP -# -profiler.jdbc.dbcp=true -profiler.jdbc.dbcp.connectionclose=false - - -########################################################### -# Apache HTTP Client 4.x # -########################################################### -profiler.apache.httpclient4=true -profiler.apache.httpclient4.cookie=true - -# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.cookie.dumptype=EXCEPTION -profiler.apache.httpclient4.cookie.sampling.rate=10 - -# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. -profiler.apache.httpclient4.entity=false - -# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.entity.dumptype=EXCEPTION -profiler.apache.httpclient4.entity.sampling.rate=10 - -profiler.apache.nio.httpclient4=true - - -########################################################### -# Ning Async HTTP Client # -########################################################### -profiler.ning.asynchttpclient=true -profiler.ning.asynchttpclient.cookie=true -profiler.ning.asynchttpclient.cookie.dumptype=EXCEPTION -profiler.ning.asynchttpclient.cookie.dumpsize=1024 -profiler.ning.asynchttpclient.cookie.sampling.rate=10 -profiler.ning.asynchttpclient.entity=false -profiler.ning.asynchttpclient.entity.dumptype=EXCEPTION -profiler.ning.asynchttpclient.entity.dumpsize=1024 -profiler.ning.asynchttpclient.entity.sampling.rate=10 -profiler.ning.asynchttpclient.param=false -profiler.ning.asynchttpclient.param.dumptype=EXCEPTION -profiler.ning.asynchttpclient.param.dumpsize=1024 -profiler.ning.asynchttpclient.param.sampling.rate=10 - - -########################################################### -# LINE+ baseframework # -########################################################### -profiler.line.game.netty.param.dumpsize=512 -profiler.line.game.netty.entity.dumpsize=512 - - -########################################################### -# Arcus # -########################################################### -profiler.arcus=true -profiler.arcus.keytrace=false - - -########################################################### -# Memcached # -########################################################### -profiler.memcached=true -profiler.memcached.keytrace=false - - -########################################################### -# ibatis # -########################################################### -profiler.orm.ibatis=true - - -########################################################### -# mybatis # -########################################################### -profiler.orm.mybatis=true - +# +# Pinpoint agent configuration +# (Phase : release) +# + +########################################################### +# Collector server # +########################################################### +profiler.collector.ip=collector.pinpoint.nhncorp.com +profiler.collector.udpspan.port=9996 +profiler.collector.udp.port=9995 +profiler.collector.tcp.port=9994 + + +########################################################### +# Profiler Global Configuration # +########################################################### +profiler.enable=true + +profiler.jvm.collect.interval=1000 + +profiler.sampling.enable=true + +# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈) +profiler.sampling.rate=20 + +# span을 Io에 flush할 경우 buffering 여부 +profiler.io.buffering.enable=true + +# buffering 시 몇개 까지 저장할지 여부 +profiler.io.buffering.buffersize=20 + + +profiler.spandatasender.write.queue.size=5120 +#profiler.spandatasender.socket.sendbuffersize=1048576 +#profiler.spandatasender.socket.timeout=3000 + +profiler.statdatasender.write.queue.size=5120 +#profiler.statdatasender.socket.sendbuffersize=1048576 +#profiler.statdatasender.socket.timeout=3000 + + +profiler.heartbeat.interval=60000 + +# Tcp Data Command 허용 여부 +profiler.tcpdatasender.command.accept.enable=true + + +########################################################### +# application type # +########################################################### +#profiler.applicationservertype=TOMCAT +#profiler.applicationservertype=BLOC + + +########################################################### +# user defined classes # +########################################################### +profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass + + +########################################################### +# JDBC # +########################################################### +profiler.jdbc=true +profiler.jdbc.sqlcachesize=1024 +profiler.jdbc.maxsqlbindvaluesize=1024 + +# +# MYSQL +# +profiler.jdbc.mysql=true +profiler.jdbc.mysql.setautocommit=false +profiler.jdbc.mysql.commit=false +profiler.jdbc.mysql.rollback=false + +# +# MSSQL Jtds +# +profiler.jdbc.jtds=true +profiler.jdbc.jtds.setautocommit=false +profiler.jdbc.jtds.commit=false +profiler.jdbc.jtds.rollback=false + +# +# Oracle +# +profiler.jdbc.oracle=true +profiler.jdbc.oracle.setautocommit=false +profiler.jdbc.oracle.commit=false +profiler.jdbc.oracle.rollback=false + +# +# CUBRID +# +profiler.jdbc.cubrid=true +profiler.jdbc.cubrid.setautocommit=false +profiler.jdbc.cubrid.commit=false +profiler.jdbc.cubrid.rollback=false + +# +# DBCP +# +profiler.jdbc.dbcp=true +profiler.jdbc.dbcp.connectionclose=false + + +########################################################### +# Apache HTTP Client 4.x # +########################################################### +profiler.apache.httpclient4=true +profiler.apache.httpclient4.cookie=true + +# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.cookie.dumptype=EXCEPTION +profiler.apache.httpclient4.cookie.sampling.rate=10 + +# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. +profiler.apache.httpclient4.entity=false + +# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.entity.dumptype=EXCEPTION +profiler.apache.httpclient4.entity.sampling.rate=10 + +profiler.apache.nio.httpclient4=true + + +########################################################### +# Ning Async HTTP Client # +########################################################### +profiler.ning.asynchttpclient=true +profiler.ning.asynchttpclient.cookie=true +profiler.ning.asynchttpclient.cookie.dumptype=EXCEPTION +profiler.ning.asynchttpclient.cookie.dumpsize=1024 +profiler.ning.asynchttpclient.cookie.sampling.rate=10 +profiler.ning.asynchttpclient.entity=false +profiler.ning.asynchttpclient.entity.dumptype=EXCEPTION +profiler.ning.asynchttpclient.entity.dumpsize=1024 +profiler.ning.asynchttpclient.entity.sampling.rate=10 +profiler.ning.asynchttpclient.param=false +profiler.ning.asynchttpclient.param.dumptype=EXCEPTION +profiler.ning.asynchttpclient.param.dumpsize=1024 +profiler.ning.asynchttpclient.param.sampling.rate=10 + + +########################################################### +# LINE+ baseframework # +########################################################### +profiler.line.game.netty.param.dumpsize=512 +profiler.line.game.netty.entity.dumpsize=512 + + +########################################################### +# Arcus # +########################################################### +profiler.arcus=true +profiler.arcus.keytrace=false + + +########################################################### +# Memcached # +########################################################### +profiler.memcached=true +profiler.memcached.keytrace=false + + +########################################################### +# ibatis # +########################################################### +profiler.orm.ibatis=true + + +########################################################### +# mybatis # +########################################################### +profiler.orm.mybatis=true + diff --git a/profiler/src/main/resources-test/log4j.xml b/profiler/src/main/resources-test/log4j.xml index 525bde798643..26b454ac39b9 100644 --- a/profiler/src/main/resources-test/log4j.xml +++ b/profiler/src/main/resources-test/log4j.xml @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/profiler/src/main/resources-test/pinpoint.config b/profiler/src/main/resources-test/pinpoint.config index c24a0a53d1b6..63d3065173f7 100644 --- a/profiler/src/main/resources-test/pinpoint.config +++ b/profiler/src/main/resources-test/pinpoint.config @@ -1,97 +1,102 @@ -profiler.collector.ip=test.collector.pinpoint.navercorp.com -profiler.collector.udpspan.port=9996 -profiler.collector.udp.port=9995 -profiler.collector.tcp.port=9994 - -# 지정하지 않으면 자동 검출, 자동 검출을 추천함. -#profiler.applicationservertype=TOMCAT -#profiler.applicationservertype=BLOC - - -profiler.enable=true - -profiler.jdbc=true -profiler.jdbc.sqlcachesize=1024 -profiler.jdbc.maxsqlbindvaluesize=1024 - -# mysql -profiler.jdbc.mysql=true -profiler.jdbc.mysql.setautocommit=true -profiler.jdbc.mysql.commit=true -profiler.jdbc.mysql.rollback=true - -# mssql 아직 미개발 -profiler.jdbc.mssql=false - -# oracle -profiler.jdbc.oracle=true -profiler.jdbc.oracle.setautocommit=true -profiler.jdbc.oracle.commit=true -profiler.jdbc.oracle.rollback=true - -# cubrid -profiler.jdbc.cubrid=true -profiler.jdbc.cubrid.setautocommit=true -profiler.jdbc.cubrid.commit=true -profiler.jdbc.cubrid.rollback=true - -#dbcp -profiler.jdbc.dbcp=true -profiler.jdbc.dbcp.connectionclose=true - - -#apache httpclient4.x ---------------------------------------------------------------------------------- -profiler.apache.httpclient4=true - -#cookie를 덤프해주는기능. -profiler.apache.httpclient4.cookie=true -#cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.cookie.dumptype=ALWAYS -profiler.apache.httpclient4.cookie.sampling.rate=1 - -#post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. -profiler.apache.httpclient4.entity=true -#entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 -profiler.apache.httpclient4.entity.dumptype=ALWAYS -profiler.apache.httpclient4.entity.sampling.rate=1 - -#ning asyncHttpClient -profiler.ning.asynchttpclient=true -profiler.ning.asynchttpclient.cookie=true -profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS -profiler.ning.asynchttpclient.cookie.dumpsize=1024 -profiler.ning.asynchttpclient.cookie.sampling.rate=1 -profiler.ning.asynchttpclient.entity=true -profiler.ning.asynchttpclient.entity.dumptype=ALWAYS -profiler.ning.asynchttpclient.entity.dumpsize=1024 -profiler.ning.asynchttpclient.entity.sampling.rate=1 -profiler.ning.asynchttpclient.param=true -profiler.ning.asynchttpclient.param.dumptype=ALWAYS -profiler.ning.asynchttpclient.param.dumpsize=1024 -profiler.ning.asynchttpclient.param.sampling.rate=1 - -#line game netty config -profiler.line.game.netty.param.dumpsize=512 -profiler.line.game.netty.entity.dumpsize=512 - -profiler.jvm.collect.interval=1000 - -profiler.sampling.enable=true -profiler.sampling.rate=1 - -#web view 테스트용. 나중에 필요하면 정규식형태로 바꿔도 되고 필요 없으면 삭제. -profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass - -# span을 Io에 flush할 경우 buffering 여부 -profiler.io.buffering.enable=true - -# buffering 시 몇개 까지 저장할지 여부 -profiler.io.buffering.buffersize=20 - -profiler.spandatasender.write.queue.size=5120 -#profiler.spandatasender.socket.sendbuffersize=1048576 -#profiler.spandatasender.socket.timeout=3000 - -profiler.statdatasender.write.queue.size=5120 -#profiler.statdatasender.socket.sendbuffersize=1048576 +profiler.collector.ip=test.collector.pinpoint.navercorp.com +profiler.collector.udpspan.port=9996 +profiler.collector.udp.port=9995 +profiler.collector.tcp.port=9994 + +# 지정하지 않으면 자동 검출, 자동 검출을 추천함. +#profiler.applicationservertype=TOMCAT +#profiler.applicationservertype=BLOC + + +profiler.enable=true + +profiler.jdbc=true +profiler.jdbc.sqlcachesize=1024 +profiler.jdbc.maxsqlbindvaluesize=1024 + +# mysql +profiler.jdbc.mysql=true +profiler.jdbc.mysql.setautocommit=true +profiler.jdbc.mysql.commit=true +profiler.jdbc.mysql.rollback=true + +# +# MSSQL Jtds +# +profiler.jdbc.jtds=true +profiler.jdbc.jtds.setautocommit=true +profiler.jdbc.jtds.commit=true +profiler.jdbc.jtds.rollback=true + +# oracle +profiler.jdbc.oracle=true +profiler.jdbc.oracle.setautocommit=true +profiler.jdbc.oracle.commit=true +profiler.jdbc.oracle.rollback=true + +# cubrid +profiler.jdbc.cubrid=true +profiler.jdbc.cubrid.setautocommit=true +profiler.jdbc.cubrid.commit=true +profiler.jdbc.cubrid.rollback=true + +#dbcp +profiler.jdbc.dbcp=true +profiler.jdbc.dbcp.connectionclose=true + + +#apache httpclient4.x ---------------------------------------------------------------------------------- +profiler.apache.httpclient4=true + +#cookie를 덤프해주는기능. +profiler.apache.httpclient4.cookie=true +#cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.cookie.dumptype=ALWAYS +profiler.apache.httpclient4.cookie.sampling.rate=1 + +#post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다. +profiler.apache.httpclient4.entity=true +#entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지 +profiler.apache.httpclient4.entity.dumptype=ALWAYS +profiler.apache.httpclient4.entity.sampling.rate=1 + +#ning asyncHttpClient +profiler.ning.asynchttpclient=true +profiler.ning.asynchttpclient.cookie=true +profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS +profiler.ning.asynchttpclient.cookie.dumpsize=1024 +profiler.ning.asynchttpclient.cookie.sampling.rate=1 +profiler.ning.asynchttpclient.entity=true +profiler.ning.asynchttpclient.entity.dumptype=ALWAYS +profiler.ning.asynchttpclient.entity.dumpsize=1024 +profiler.ning.asynchttpclient.entity.sampling.rate=1 +profiler.ning.asynchttpclient.param=true +profiler.ning.asynchttpclient.param.dumptype=ALWAYS +profiler.ning.asynchttpclient.param.dumpsize=1024 +profiler.ning.asynchttpclient.param.sampling.rate=1 + +#line game netty config +profiler.line.game.netty.param.dumpsize=512 +profiler.line.game.netty.entity.dumpsize=512 + +profiler.jvm.collect.interval=1000 + +profiler.sampling.enable=true +profiler.sampling.rate=1 + +#web view 테스트용. 나중에 필요하면 정규식형태로 바꿔도 되고 필요 없으면 삭제. +profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass + +# span을 Io에 flush할 경우 buffering 여부 +profiler.io.buffering.enable=true + +# buffering 시 몇개 까지 저장할지 여부 +profiler.io.buffering.buffersize=20 + +profiler.spandatasender.write.queue.size=5120 +#profiler.spandatasender.socket.sendbuffersize=1048576 +#profiler.spandatasender.socket.timeout=3000 + +profiler.statdatasender.write.queue.size=5120 +#profiler.statdatasender.socket.sendbuffersize=1048576 #profiler.statdatasender.socket.timeout=3000 \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentTest.java index 66bc51daba29..9ca7fdbf72f8 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentTest.java @@ -1,19 +1,19 @@ -package com.nhn.pinpoint.profiler; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class AgentTest { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testGetIdentifier() throws Exception { - // identifier가 pid기반으로 변경되어 테스트 삭제. - } - -} +package com.nhn.pinpoint.profiler; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class AgentTest { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testGetIdentifier() throws Exception { + // identifier가 pid기반으로 변경되어 테스트 삭제. + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/DummyInstrumentation.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/DummyInstrumentation.java index 03fa394308e0..ab7cdc6f67da 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/DummyInstrumentation.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/DummyInstrumentation.java @@ -1,87 +1,87 @@ -package com.nhn.pinpoint.profiler; - -import java.lang.instrument.ClassDefinition; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; -import java.util.jar.JarFile; - -/** - * @author emeroad - */ -public class DummyInstrumentation implements Instrumentation { - @Override - public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { - - } - - @Override - public void addTransformer(ClassFileTransformer transformer) { - - } - - @Override - public boolean removeTransformer(ClassFileTransformer transformer) { - return false; - } - - @Override - public boolean isRetransformClassesSupported() { - return false; - } - - @Override - public void retransformClasses(Class... classes) throws UnmodifiableClassException { - - } - - @Override - public boolean isRedefineClassesSupported() { - return false; - } - - @Override - public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException { - - } - - @Override - public boolean isModifiableClass(Class theClass) { - return false; - } - - @Override - public Class[] getAllLoadedClasses() { - return new Class[0]; - } - - @Override - public Class[] getInitiatedClasses(ClassLoader loader) { - return new Class[0]; - } - - @Override - public long getObjectSize(Object objectToSize) { - return 0; - } - - @Override - public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public void appendToSystemClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public boolean isNativeMethodPrefixSupported() { - return false; - } - - @Override - public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { - - } -} +package com.nhn.pinpoint.profiler; + +import java.lang.instrument.ClassDefinition; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; +import java.util.jar.JarFile; + +/** + * @author emeroad + */ +public class DummyInstrumentation implements Instrumentation { + @Override + public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { + + } + + @Override + public void addTransformer(ClassFileTransformer transformer) { + + } + + @Override + public boolean removeTransformer(ClassFileTransformer transformer) { + return false; + } + + @Override + public boolean isRetransformClassesSupported() { + return false; + } + + @Override + public void retransformClasses(Class... classes) throws UnmodifiableClassException { + + } + + @Override + public boolean isRedefineClassesSupported() { + return false; + } + + @Override + public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException { + + } + + @Override + public boolean isModifiableClass(Class theClass) { + return false; + } + + @Override + public Class[] getAllLoadedClasses() { + return new Class[0]; + } + + @Override + public Class[] getInitiatedClasses(ClassLoader loader) { + return new Class[0]; + } + + @Override + public long getObjectSize(Object objectToSize) { + return 0; + } + + @Override + public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { + + } + + @Override + public void appendToSystemClassLoaderSearch(JarFile jarfile) { + + } + + @Override + public boolean isNativeMethodPrefixSupported() { + return false; + } + + @Override + public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerStressTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerStressTest.java index cfe5160a4a90..c2f895985fe7 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerStressTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerStressTest.java @@ -1,203 +1,203 @@ -package com.nhn.pinpoint.profiler; - -import java.util.Collections; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.thrift.TException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; -import com.nhn.pinpoint.profiler.sender.TcpDataSender; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.client.MessageListener; -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import com.nhn.pinpoint.rpc.server.PinpointServerSocket; -import com.nhn.pinpoint.rpc.server.ServerMessageListener; -import com.nhn.pinpoint.rpc.server.ServerStreamChannel; -import com.nhn.pinpoint.rpc.server.SocketChannel; -import com.nhn.pinpoint.thrift.dto.TAgentInfo; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; - -public class HeartBitCheckerStressTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final int PORT = 10050; - public static final String HOST = "127.0.0.1"; - - private static final long STRESS_TEST_TIME = 10 * 60 * 1000; - private static final int RANDOM_MAX_TIME = 3000; - - public void stressTest() throws InterruptedException { - AtomicInteger requestCount = new AtomicInteger(); - AtomicInteger successCount = new AtomicInteger(); - - ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount); - - PinpointSocketFactory socketFactory = createPinpointSocketFactory(); - PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); - - TcpDataSender sender = new TcpDataSender(socket); - HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); - - long strarTime = System.currentTimeMillis(); - - - try { - checker.start(); - - Random random = new Random(System.currentTimeMillis()); - - while (System.currentTimeMillis() < strarTime + STRESS_TEST_TIME) { - createAndDeleteServer(serverListener, Math.abs(random.nextInt(RANDOM_MAX_TIME))); - Thread.sleep(Math.abs(random.nextInt(1000))); - } - - } finally { - if (checker != null) { - checker.stop(); - } - - if (socket != null) { - socket.close(); - } - - if (socketFactory != null) { - socketFactory.release(); - } - } - } - - private PinpointServerSocket createServer(ServerMessageListener listener) { - PinpointServerSocket server = new PinpointServerSocket(); - // server.setMessageListener(new - // NoResponseServerMessageListener(requestCount)); - server.setMessageListener(listener); - server.bind(HOST, PORT); - - return server; - } - - private void createAndDeleteServer(ServerMessageListener listner, long waitTimeMillis) throws InterruptedException { - PinpointServerSocket server = null; - try { - server = createServer(listner); - Thread.sleep(waitTimeMillis); - } finally { - if (server != null) { - server.close(); - } - } - } - - private void closeAll(PinpointServerSocket server, HeartBitChecker checker) { - if (server != null) { - server.close(); - } - - if (checker != null) { - checker.stop(); - } - } - - private TAgentInfo getAgentInfo() { - TAgentInfo agentInfo = new TAgentInfo("hostname", "127.0.0.1", "8081", "agentId", "appName", (short) 2, 1111, "1", System.currentTimeMillis()); - return agentInfo; - } - - class ResponseServerMessageListener implements ServerMessageListener { - private final AtomicInteger requestCount; - private final AtomicInteger successCount; - - private final int successCondition; - - public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount) { - this(requestCount, successCount, 1); - } - - public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount, int successCondition) { - this.requestCount = requestCount; - this.successCount = successCount; - this.successCondition = successCondition; - } - - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - logger.info("handleSend:{}", sendPacket); - - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - int requestCount = this.requestCount.incrementAndGet(); - - if (requestCount < successCondition) { - return; - } - - logger.info("handleRequest~~~:{}", requestPacket); - - try { - HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); - - TResult result = new TResult(true); - byte[] resultBytes = serializer.serialize(result); - - this.successCount.incrementAndGet(); - - channel.sendResponseMessage(requestPacket, resultBytes); - } catch (TException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.info("handleStreamPacket:{}", streamPacket); - } - - @Override - public int handleEnableWorker(Map arg0) { - return 0; - } - } - - private PinpointSocketFactory createPinpointSocketFactory() { - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setTimeoutMillis(1000 * 5); - pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); - - return pinpointSocketFactory; - } - - - private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { - MessageListener messageListener = new CommandDispatcher(); - - PinpointSocket socket = null; - for (int i = 0; i < 3; i++) { - try { - socket = factory.connect(host, port, messageListener); - logger.info("tcp connect success:{}/{}", host, port); - return socket; - } catch (PinpointSocketException e) { - logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); - } - } - logger.warn("change background tcp connect mode {}/{} ", host, port); - socket = factory.scheduledConnect(host, port, messageListener); - - return socket; - } - -} +package com.nhn.pinpoint.profiler; + +import java.util.Collections; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.thrift.TException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; +import com.nhn.pinpoint.profiler.sender.TcpDataSender; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.client.MessageListener; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import com.nhn.pinpoint.rpc.server.ServerMessageListener; +import com.nhn.pinpoint.rpc.server.ServerStreamChannel; +import com.nhn.pinpoint.rpc.server.SocketChannel; +import com.nhn.pinpoint.thrift.dto.TAgentInfo; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; + +public class HeartBitCheckerStressTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final int PORT = 10050; + public static final String HOST = "127.0.0.1"; + + private static final long STRESS_TEST_TIME = 10 * 60 * 1000; + private static final int RANDOM_MAX_TIME = 3000; + + public void stressTest() throws InterruptedException { + AtomicInteger requestCount = new AtomicInteger(); + AtomicInteger successCount = new AtomicInteger(); + + ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount); + + PinpointSocketFactory socketFactory = createPinpointSocketFactory(); + PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); + + TcpDataSender sender = new TcpDataSender(socket); + HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); + + long strarTime = System.currentTimeMillis(); + + + try { + checker.start(); + + Random random = new Random(System.currentTimeMillis()); + + while (System.currentTimeMillis() < strarTime + STRESS_TEST_TIME) { + createAndDeleteServer(serverListener, Math.abs(random.nextInt(RANDOM_MAX_TIME))); + Thread.sleep(Math.abs(random.nextInt(1000))); + } + + } finally { + if (checker != null) { + checker.stop(); + } + + if (socket != null) { + socket.close(); + } + + if (socketFactory != null) { + socketFactory.release(); + } + } + } + + private PinpointServerSocket createServer(ServerMessageListener listener) { + PinpointServerSocket server = new PinpointServerSocket(); + // server.setMessageListener(new + // NoResponseServerMessageListener(requestCount)); + server.setMessageListener(listener); + server.bind(HOST, PORT); + + return server; + } + + private void createAndDeleteServer(ServerMessageListener listner, long waitTimeMillis) throws InterruptedException { + PinpointServerSocket server = null; + try { + server = createServer(listner); + Thread.sleep(waitTimeMillis); + } finally { + if (server != null) { + server.close(); + } + } + } + + private void closeAll(PinpointServerSocket server, HeartBitChecker checker) { + if (server != null) { + server.close(); + } + + if (checker != null) { + checker.stop(); + } + } + + private TAgentInfo getAgentInfo() { + TAgentInfo agentInfo = new TAgentInfo("hostname", "127.0.0.1", "8081", "agentId", "appName", (short) 2, 1111, "1", System.currentTimeMillis()); + return agentInfo; + } + + class ResponseServerMessageListener implements ServerMessageListener { + private final AtomicInteger requestCount; + private final AtomicInteger successCount; + + private final int successCondition; + + public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount) { + this(requestCount, successCount, 1); + } + + public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount, int successCondition) { + this.requestCount = requestCount; + this.successCount = successCount; + this.successCondition = successCondition; + } + + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.info("handleSend:{}", sendPacket); + + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + int requestCount = this.requestCount.incrementAndGet(); + + if (requestCount < successCondition) { + return; + } + + logger.info("handleRequest~~~:{}", requestPacket); + + try { + HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); + + TResult result = new TResult(true); + byte[] resultBytes = serializer.serialize(result); + + this.successCount.incrementAndGet(); + + channel.sendResponseMessage(requestPacket, resultBytes); + } catch (TException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.info("handleStreamPacket:{}", streamPacket); + } + + @Override + public int handleEnableWorker(Map arg0) { + return 0; + } + } + + private PinpointSocketFactory createPinpointSocketFactory() { + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setTimeoutMillis(1000 * 5); + pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); + + return pinpointSocketFactory; + } + + + private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { + MessageListener messageListener = new CommandDispatcher(); + + PinpointSocket socket = null; + for (int i = 0; i < 3; i++) { + try { + socket = factory.connect(host, port, messageListener); + logger.info("tcp connect success:{}/{}", host, port); + return socket; + } catch (PinpointSocketException e) { + logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); + } + } + logger.warn("change background tcp connect mode {}/{} ", host, port); + socket = factory.scheduledConnect(host, port, messageListener); + + return socket; + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerTest.java index 2d31987f45fb..e0068e17badc 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitCheckerTest.java @@ -1,253 +1,253 @@ -package com.nhn.pinpoint.profiler; - - -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; - -import junit.framework.Assert; - -import org.apache.thrift.TException; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; -import com.nhn.pinpoint.profiler.sender.TcpDataSender; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.client.MessageListener; -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import com.nhn.pinpoint.rpc.server.PinpointServerSocket; -import com.nhn.pinpoint.rpc.server.ServerMessageListener; -import com.nhn.pinpoint.rpc.server.ServerStreamChannel; -import com.nhn.pinpoint.rpc.server.SocketChannel; -import com.nhn.pinpoint.thrift.dto.TAgentInfo; -import com.nhn.pinpoint.thrift.dto.TResult; -import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; - -public class HeartBitCheckerTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final int PORT = 10050; - public static final String HOST = "127.0.0.1"; - - @Test - public void checkerTest1() throws InterruptedException { - AtomicInteger requestCount = new AtomicInteger(); - AtomicInteger successCount = new AtomicInteger(); - - ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount); - - PinpointServerSocket server = createServer(serverListener); - - PinpointSocketFactory socketFactory = createPinpointSocketFactory(); - PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); - - TcpDataSender sender = new TcpDataSender(socket); - HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); - - try { - checker.start(); - - Thread.sleep(10000); - - Assert.assertEquals(1, successCount.get()); - } finally { - closeAll(server, checker, socket, socketFactory); - } - } - - @Test - public void checkerTest2() throws InterruptedException { - AtomicInteger requestCount = new AtomicInteger(); - AtomicInteger successCount = new AtomicInteger(); - - ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount, Integer.MAX_VALUE); - - PinpointServerSocket server = createServer(serverListener); - - PinpointSocketFactory socketFactory = createPinpointSocketFactory(); - PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); - - TcpDataSender sender = new TcpDataSender(socket); - HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); - - try { - checker.start(); - - Thread.sleep(10000); - - Assert.assertEquals(2, requestCount.get()); - Assert.assertEquals(0, successCount.get()); - } finally { - closeAll(server, checker, socket, socketFactory); - } - } - - @Test - public void checkerTest3() throws InterruptedException { - AtomicInteger requestCount = new AtomicInteger(); - AtomicInteger successCount = new AtomicInteger(); - - ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount); - - PinpointSocketFactory socketFactory = createPinpointSocketFactory(); - PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); - - TcpDataSender sender = new TcpDataSender(socket); - HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); - - try { - checker.start(); - - createAndDeleteServer(serverListener, 10000L); - Thread.sleep(1000); - createAndDeleteServer(serverListener, 10000L); - Thread.sleep(1000); - createAndDeleteServer(serverListener, 10000L); - - Assert.assertEquals(3, successCount.get()); - } finally { - closeAll(null, checker, socket, socketFactory); - } - } - - private PinpointServerSocket createServer(ServerMessageListener listener) { - PinpointServerSocket server = new PinpointServerSocket(); - // server.setMessageListener(new - // NoResponseServerMessageListener(requestCount)); - server.setMessageListener(listener); - server.bind(HOST, PORT); - - return server; - } - - private void createAndDeleteServer(ServerMessageListener listner, long waitTimeMillis) throws InterruptedException { - PinpointServerSocket server = null; - try { - server = createServer(listner); - Thread.sleep(waitTimeMillis); - } finally { - if (server != null) { - server.close(); - } - } - } - - private void closeAll(PinpointServerSocket server, HeartBitChecker checker, PinpointSocket socket, PinpointSocketFactory factory) { - if (server != null) { - server.close(); - } - - if (checker != null) { - checker.stop(); - } - - if (socket != null) { - socket.close(); - } - - if (factory != null) { - factory.release(); - } - } - - private TAgentInfo getAgentInfo() { - TAgentInfo agentInfo = new TAgentInfo("hostname", "127.0.0.1", "8081", "agentId", "appName", (short) 2, 1111, "1", System.currentTimeMillis()); - return agentInfo; - } - - class ResponseServerMessageListener implements ServerMessageListener { - private final AtomicInteger requestCount; - private final AtomicInteger successCount; - - private final int successCondition; - - public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount) { - this(requestCount, successCount, 1); - } - - public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount, int successCondition) { - this.requestCount = requestCount; - this.successCount = successCount; - this.successCondition = successCondition; - } - - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - logger.info("handleSend:{}", sendPacket); - - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - int requestCount = this.requestCount.incrementAndGet(); - - if (requestCount < successCondition) { - return; - } - - logger.info("handleRequest~~~:{}", requestPacket); - - try { - HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); - - TResult result = new TResult(true); - byte[] resultBytes = serializer.serialize(result); - - this.successCount.incrementAndGet(); - - channel.sendResponseMessage(requestPacket, resultBytes); - } catch (TException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.info("handleStreamPacket:{}", streamPacket); - } - - @Override - public int handleEnableWorker(Map arg0) { - return 0; - } - } - - private PinpointSocketFactory createPinpointSocketFactory() { - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setTimeoutMillis(1000 * 5); - pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); - - return pinpointSocketFactory; - } - - - private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { - MessageListener messageListener = new CommandDispatcher(); - - PinpointSocket socket = null; - for (int i = 0; i < 3; i++) { - try { - socket = factory.connect(host, port, messageListener); - logger.info("tcp connect success:{}/{}", host, port); - return socket; - } catch (PinpointSocketException e) { - logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); - } - } - logger.warn("change background tcp connect mode {}/{} ", host, port); - socket = factory.scheduledConnect(host, port, messageListener); - - return socket; - } - -} +package com.nhn.pinpoint.profiler; + + +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializerFactory; + +import junit.framework.Assert; + +import org.apache.thrift.TException; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; +import com.nhn.pinpoint.profiler.sender.TcpDataSender; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.client.MessageListener; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import com.nhn.pinpoint.rpc.server.ServerMessageListener; +import com.nhn.pinpoint.rpc.server.ServerStreamChannel; +import com.nhn.pinpoint.rpc.server.SocketChannel; +import com.nhn.pinpoint.thrift.dto.TAgentInfo; +import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.io.HeaderTBaseSerializer; + +public class HeartBitCheckerTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final int PORT = 10050; + public static final String HOST = "127.0.0.1"; + + @Test + public void checkerTest1() throws InterruptedException { + AtomicInteger requestCount = new AtomicInteger(); + AtomicInteger successCount = new AtomicInteger(); + + ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount); + + PinpointServerSocket server = createServer(serverListener); + + PinpointSocketFactory socketFactory = createPinpointSocketFactory(); + PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); + + TcpDataSender sender = new TcpDataSender(socket); + HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); + + try { + checker.start(); + + Thread.sleep(10000); + + Assert.assertEquals(1, successCount.get()); + } finally { + closeAll(server, checker, socket, socketFactory); + } + } + + @Test + public void checkerTest2() throws InterruptedException { + AtomicInteger requestCount = new AtomicInteger(); + AtomicInteger successCount = new AtomicInteger(); + + ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount, Integer.MAX_VALUE); + + PinpointServerSocket server = createServer(serverListener); + + PinpointSocketFactory socketFactory = createPinpointSocketFactory(); + PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); + + TcpDataSender sender = new TcpDataSender(socket); + HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); + + try { + checker.start(); + + Thread.sleep(10000); + + Assert.assertEquals(2, requestCount.get()); + Assert.assertEquals(0, successCount.get()); + } finally { + closeAll(server, checker, socket, socketFactory); + } + } + + @Test + public void checkerTest3() throws InterruptedException { + AtomicInteger requestCount = new AtomicInteger(); + AtomicInteger successCount = new AtomicInteger(); + + ResponseServerMessageListener serverListener = new ResponseServerMessageListener(requestCount, successCount); + + PinpointSocketFactory socketFactory = createPinpointSocketFactory(); + PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); + + TcpDataSender sender = new TcpDataSender(socket); + HeartBitChecker checker = new HeartBitChecker(sender, 1000L, getAgentInfo()); + + try { + checker.start(); + + createAndDeleteServer(serverListener, 10000L); + Thread.sleep(1000); + createAndDeleteServer(serverListener, 10000L); + Thread.sleep(1000); + createAndDeleteServer(serverListener, 10000L); + + Assert.assertEquals(3, successCount.get()); + } finally { + closeAll(null, checker, socket, socketFactory); + } + } + + private PinpointServerSocket createServer(ServerMessageListener listener) { + PinpointServerSocket server = new PinpointServerSocket(); + // server.setMessageListener(new + // NoResponseServerMessageListener(requestCount)); + server.setMessageListener(listener); + server.bind(HOST, PORT); + + return server; + } + + private void createAndDeleteServer(ServerMessageListener listner, long waitTimeMillis) throws InterruptedException { + PinpointServerSocket server = null; + try { + server = createServer(listner); + Thread.sleep(waitTimeMillis); + } finally { + if (server != null) { + server.close(); + } + } + } + + private void closeAll(PinpointServerSocket server, HeartBitChecker checker, PinpointSocket socket, PinpointSocketFactory factory) { + if (server != null) { + server.close(); + } + + if (checker != null) { + checker.stop(); + } + + if (socket != null) { + socket.close(); + } + + if (factory != null) { + factory.release(); + } + } + + private TAgentInfo getAgentInfo() { + TAgentInfo agentInfo = new TAgentInfo("hostname", "127.0.0.1", "8081", "agentId", "appName", (short) 2, 1111, "1", System.currentTimeMillis()); + return agentInfo; + } + + class ResponseServerMessageListener implements ServerMessageListener { + private final AtomicInteger requestCount; + private final AtomicInteger successCount; + + private final int successCondition; + + public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount) { + this(requestCount, successCount, 1); + } + + public ResponseServerMessageListener(AtomicInteger requestCount, AtomicInteger successCount, int successCondition) { + this.requestCount = requestCount; + this.successCount = successCount; + this.successCondition = successCondition; + } + + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.info("handleSend:{}", sendPacket); + + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + int requestCount = this.requestCount.incrementAndGet(); + + if (requestCount < successCondition) { + return; + } + + logger.info("handleRequest~~~:{}", requestPacket); + + try { + HeaderTBaseSerializer serializer = HeaderTBaseSerializerFactory.DEFAULT_FACTORY.createSerializer(); + + TResult result = new TResult(true); + byte[] resultBytes = serializer.serialize(result); + + this.successCount.incrementAndGet(); + + channel.sendResponseMessage(requestPacket, resultBytes); + } catch (TException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.info("handleStreamPacket:{}", streamPacket); + } + + @Override + public int handleEnableWorker(Map arg0) { + return 0; + } + } + + private PinpointSocketFactory createPinpointSocketFactory() { + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setTimeoutMillis(1000 * 5); + pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); + + return pinpointSocketFactory; + } + + + private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { + MessageListener messageListener = new CommandDispatcher(); + + PinpointSocket socket = null; + for (int i = 0; i < 3; i++) { + try { + socket = factory.connect(host, port, messageListener); + logger.info("tcp connect success:{}/{}", host, port); + return socket; + } catch (PinpointSocketException e) { + logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); + } + } + logger.warn("change background tcp connect mode {}/{} ", host, port); + socket = factory.scheduledConnect(host, port, messageListener); + + return socket; + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitStateTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitStateTest.java index e481d5569e41..5766d74de114 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitStateTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/HeartBitStateTest.java @@ -1,75 +1,75 @@ -package com.nhn.pinpoint.profiler; - - -import junit.framework.Assert; - -import org.junit.Test; - -public class HeartBitStateTest { - - @Test - public void changeStateTest1() throws InterruptedException { - HeartBitStateContext stateContext = new HeartBitStateContext(); - Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); - - changeStateToNeedNotRequest(stateContext); - changeStateToFinishRequest(stateContext); - } - - @Test - public void changeStateTest2() throws InterruptedException { - HeartBitStateContext stateContext = new HeartBitStateContext(); - Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); - - changeStateToNeedRequest(stateContext); - changeStateToFinishRequest(stateContext); - } - - @Test - public void changeStateTest3() throws InterruptedException { - HeartBitStateContext stateContext = new HeartBitStateContext(); - Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); - - changeStateToNeedRequest(stateContext); - changeStateToFinishRequest(stateContext); - - Thread.sleep(1); - boolean isSuccess = stateContext.changeStateToFinish(); - Assert.assertFalse(isSuccess); - } - - @Test - public void changeStateTest4() throws InterruptedException { - HeartBitStateContext stateContext = new HeartBitStateContext(); - Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); - - Thread.sleep(1); - boolean isSuccess = stateContext.changeStateToFinish(); - Assert.assertFalse(isSuccess); - } - - private void changeStateToNeedRequest(HeartBitStateContext stateContext) throws InterruptedException { - Thread.sleep(1); - boolean isSuccess = stateContext.changeStateToNeedRequest(System.currentTimeMillis()); - - Assert.assertTrue(isSuccess); - Assert.assertEquals(HeartBitState.NEED_REQUEST, stateContext.getState()); - } - - private void changeStateToNeedNotRequest(HeartBitStateContext stateContext) throws InterruptedException { - Thread.sleep(1); - boolean isSuccess = stateContext.changeStateToNeedNotRequest(System.currentTimeMillis()); - - Assert.assertTrue(isSuccess); - Assert.assertEquals(HeartBitState.NEED_NOT_REQUEST, stateContext.getState()); - } - - private void changeStateToFinishRequest(HeartBitStateContext stateContext) throws InterruptedException { - Thread.sleep(1); - boolean isSuccess = stateContext.changeStateToFinish(); - - Assert.assertTrue(isSuccess); - Assert.assertEquals(HeartBitState.FINISH, stateContext.getState()); - } - -} +package com.nhn.pinpoint.profiler; + + +import junit.framework.Assert; + +import org.junit.Test; + +public class HeartBitStateTest { + + @Test + public void changeStateTest1() throws InterruptedException { + HeartBitStateContext stateContext = new HeartBitStateContext(); + Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); + + changeStateToNeedNotRequest(stateContext); + changeStateToFinishRequest(stateContext); + } + + @Test + public void changeStateTest2() throws InterruptedException { + HeartBitStateContext stateContext = new HeartBitStateContext(); + Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); + + changeStateToNeedRequest(stateContext); + changeStateToFinishRequest(stateContext); + } + + @Test + public void changeStateTest3() throws InterruptedException { + HeartBitStateContext stateContext = new HeartBitStateContext(); + Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); + + changeStateToNeedRequest(stateContext); + changeStateToFinishRequest(stateContext); + + Thread.sleep(1); + boolean isSuccess = stateContext.changeStateToFinish(); + Assert.assertFalse(isSuccess); + } + + @Test + public void changeStateTest4() throws InterruptedException { + HeartBitStateContext stateContext = new HeartBitStateContext(); + Assert.assertEquals(HeartBitState.NONE, stateContext.getState()); + + Thread.sleep(1); + boolean isSuccess = stateContext.changeStateToFinish(); + Assert.assertFalse(isSuccess); + } + + private void changeStateToNeedRequest(HeartBitStateContext stateContext) throws InterruptedException { + Thread.sleep(1); + boolean isSuccess = stateContext.changeStateToNeedRequest(System.currentTimeMillis()); + + Assert.assertTrue(isSuccess); + Assert.assertEquals(HeartBitState.NEED_REQUEST, stateContext.getState()); + } + + private void changeStateToNeedNotRequest(HeartBitStateContext stateContext) throws InterruptedException { + Thread.sleep(1); + boolean isSuccess = stateContext.changeStateToNeedNotRequest(System.currentTimeMillis()); + + Assert.assertTrue(isSuccess); + Assert.assertEquals(HeartBitState.NEED_NOT_REQUEST, stateContext.getState()); + } + + private void changeStateToFinishRequest(HeartBitStateContext stateContext) throws InterruptedException { + Thread.sleep(1); + boolean isSuccess = stateContext.changeStateToFinish(); + + Assert.assertTrue(isSuccess); + Assert.assertEquals(HeartBitState.FINISH, stateContext.getState()); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java index 624a1d9f6c7e..3178a365d7b8 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java @@ -1,63 +1,63 @@ -package com.nhn.pinpoint.profiler.context; - -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class CallStackTest { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testPush() throws Exception { - DefaultTraceId traceId = new DefaultTraceId("test", 0, 1); - Span span = new Span(); - span.setAgentId("agentId"); - span.recordTraceId(traceId); - CallStack callStack = new CallStack(span); - int stackIndex = callStack.getStackFrameIndex(); - logger.info(String.valueOf(stackIndex)); - callStack.push(); - - callStack.popRoot(); - } - - @Test - public void testPushPop1() throws Exception { - CallStack callStack = new CallStack(new Span()); - - callStack.push(); - callStack.popRoot(); - - } - - @Test - public void testPushPop2() throws Exception { - CallStack callStack = new CallStack(new Span()); - - callStack.push(); - callStack.push(); - - callStack.pop(); - callStack.popRoot(); - - } - - @Ignore - @Test - public void testPop_Fail() throws Exception { - CallStack callStack = new CallStack(new Span()); - - callStack.push(); - callStack.push(); - - callStack.pop(); - - callStack.pop(); - // pop일때의 인덱스 조정을 다시 생각해 보는게 좋을듯하다. - } +package com.nhn.pinpoint.profiler.context; + +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class CallStackTest { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testPush() throws Exception { + DefaultTraceId traceId = new DefaultTraceId("test", 0, 1); + Span span = new Span(); + span.setAgentId("agentId"); + span.recordTraceId(traceId); + CallStack callStack = new CallStack(span); + int stackIndex = callStack.getStackFrameIndex(); + logger.info(String.valueOf(stackIndex)); + callStack.push(); + + callStack.popRoot(); + } + + @Test + public void testPushPop1() throws Exception { + CallStack callStack = new CallStack(new Span()); + + callStack.push(); + callStack.popRoot(); + + } + + @Test + public void testPushPop2() throws Exception { + CallStack callStack = new CallStack(new Span()); + + callStack.push(); + callStack.push(); + + callStack.pop(); + callStack.popRoot(); + + } + + @Ignore + @Test + public void testPop_Fail() throws Exception { + CallStack callStack = new CallStack(new Span()); + + callStack.push(); + callStack.push(); + + callStack.pop(); + + callStack.pop(); + // pop일때의 인덱스 조정을 다시 생각해 보는게 좋을듯하다. + } } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContextTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContextTest.java index 4aab000f67be..e4c9f3fd8604 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContextTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContextTest.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.TraceId; -import com.nhn.pinpoint.common.util.TransactionId; -import com.nhn.pinpoint.common.util.TransactionIdUtils; -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class DefaultTraceContextTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void parseTest() { - String agent= "test"; - long agentStartTime = System.currentTimeMillis(); - long agentTransactionCount = 10; - TraceId traceID = new DefaultTraceId(agent, agentStartTime, agentTransactionCount); - - String id = traceID.getTransactionId(); - logger.info("id={}", id); - - TransactionId transactionid = TransactionIdUtils.parseTransactionId(id); - - Assert.assertEquals(transactionid.getAgentId(), agent); - Assert.assertEquals(transactionid.getAgentStartTime(), agentStartTime); - Assert.assertEquals(transactionid.getTransactionSequence(), agentTransactionCount); - - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.TraceId; +import com.nhn.pinpoint.common.util.TransactionId; +import com.nhn.pinpoint.common.util.TransactionIdUtils; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class DefaultTraceContextTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void parseTest() { + String agent= "test"; + long agentStartTime = System.currentTimeMillis(); + long agentTransactionCount = 10; + TraceId traceID = new DefaultTraceId(agent, agentStartTime, agentTransactionCount); + + String id = traceID.getTransactionId(); + logger.info("id={}", id); + + TransactionId transactionid = TransactionIdUtils.parseTransactionId(id); + + Assert.assertEquals(transactionid.getAgentId(), agent); + Assert.assertEquals(transactionid.getAgentStartTime(), agentStartTime); + Assert.assertEquals(transactionid.getTransactionSequence(), agentTransactionCount); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java index c2a708e3fe09..0e00a4417595 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java @@ -1,59 +1,59 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.Version; -import com.nhn.pinpoint.profiler.AgentInformation; -import com.nhn.pinpoint.profiler.context.storage.SpanStorage; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinderInitializer; -import com.nhn.pinpoint.profiler.sender.LoggingDataSender; -import org.junit.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class DefaultTraceTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @BeforeClass - public static void before() throws Exception { - Slf4jLoggerBinderInitializer.beforeClass(); - } - - @AfterClass - public static void after() throws Exception { - Slf4jLoggerBinderInitializer.afterClass(); - } - - - @Test - public void testPushPop() { - DefaultTraceContext defaultTraceContext = new DefaultTraceContext(); - defaultTraceContext.setAgentInformation(new AgentInformation("agentId", "applicationName", System.currentTimeMillis(), 10, "test", ServiceType.TOMCAT.getCode(), Version.VERSION)); - DefaultTrace trace = new DefaultTrace(defaultTraceContext, 1); - - trace.setStorage(new SpanStorage(LoggingDataSender.DEFAULT_LOGGING_DATA_SENDER)); - - Assert.assertEquals(0, trace.getCallStackDepth()); - - trace.traceBlockBegin(); - - Assert.assertEquals(1, trace.getCallStackDepth()); - - trace.traceBlockBegin(); - Assert.assertEquals(2, trace.getCallStackDepth()); - - trace.traceBlockEnd(); - - Assert.assertEquals(1, trace.getCallStackDepth()); - - trace.traceBlockEnd(); - - Assert.assertEquals(0, trace.getCallStackDepth()); - - trace.traceRootBlockEnd(); - - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.Version; +import com.nhn.pinpoint.profiler.AgentInformation; +import com.nhn.pinpoint.profiler.context.storage.SpanStorage; +import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinderInitializer; +import com.nhn.pinpoint.profiler.sender.LoggingDataSender; +import org.junit.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class DefaultTraceTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @BeforeClass + public static void before() throws Exception { + Slf4jLoggerBinderInitializer.beforeClass(); + } + + @AfterClass + public static void after() throws Exception { + Slf4jLoggerBinderInitializer.afterClass(); + } + + + @Test + public void testPushPop() { + DefaultTraceContext defaultTraceContext = new DefaultTraceContext(); + defaultTraceContext.setAgentInformation(new AgentInformation("agentId", "applicationName", System.currentTimeMillis(), 10, "test", ServiceType.TOMCAT.getCode(), Version.VERSION)); + DefaultTrace trace = new DefaultTrace(defaultTraceContext, 1); + + trace.setStorage(new SpanStorage(LoggingDataSender.DEFAULT_LOGGING_DATA_SENDER)); + + Assert.assertEquals(0, trace.getCallStackDepth()); + + trace.traceBlockBegin(); + + Assert.assertEquals(1, trace.getCallStackDepth()); + + trace.traceBlockBegin(); + Assert.assertEquals(2, trace.getCallStackDepth()); + + trace.traceBlockEnd(); + + Assert.assertEquals(1, trace.getCallStackDepth()); + + trace.traceBlockEnd(); + + Assert.assertEquals(0, trace.getCallStackDepth()); + + trace.traceRootBlockEnd(); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/HeaderTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/HeaderTest.java index a1118793f700..03f12c1be278 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/HeaderTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/HeaderTest.java @@ -1,11 +1,17 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.Header; -import org.junit.Test; - -public class HeaderTest { - @Test - public void testToString() throws Exception { - System.out.println(Header.HTTP_FLAGS); - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.Header; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class HeaderTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void testToString() throws Exception { + logger.debug("{}", Header.HTTP_FLAGS); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/LinkStatMapTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/LinkStatMapTest.java index 9388fe120566..55fe03cee24a 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/LinkStatMapTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/LinkStatMapTest.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.profiler.context; - -import junit.framework.Assert; -import org.junit.Test; -import java.util.List; - -/** - * @author emeroad - */ -public class LinkStatMapTest { - - @Test - public void testRecord() throws Exception { -// LinkStatMap map = new LinkStatMap(); -// -// map.recordLink("aa", (short) 0, "test", 0, true); -// map.recordLink("aa", (short) 0, "test", 0, true); -// List all = map.getAll(); -// -// Assert.assertEquals(all.size(), 1); -// Assert.assertEquals(all., 1); - - - } -} +package com.nhn.pinpoint.profiler.context; + +import junit.framework.Assert; +import org.junit.Test; +import java.util.List; + +/** + * @author emeroad + */ +public class LinkStatMapTest { + + @Test + public void testRecord() throws Exception { +// LinkStatMap map = new LinkStatMap(); +// +// map.recordLink("aa", (short) 0, "test", 0, true); +// map.recordLink("aa", (short) 0, "test", 0, true); +// List all = map.getAll(); +// +// Assert.assertEquals(all.size(), 1); +// Assert.assertEquals(all., 1); + + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java index 168b31bb4356..bf07fb922601 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.sender.LoggingDataSender; - -/** - * @author emeroad - */ -public class MockTraceContextFactory { - public TraceContext create() { - DefaultTraceContext traceContext = new DefaultTraceContext() ; - return traceContext; - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.sender.LoggingDataSender; + +/** + * @author emeroad + */ +public class MockTraceContextFactory { + public TraceContext create() { + DefaultTraceContext traceContext = new DefaultTraceContext() ; + return traceContext; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java index 4dac8dfc3db3..7ade709105e6 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java @@ -1,40 +1,40 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.Version; -import com.nhn.pinpoint.profiler.AgentInformation; -import org.junit.Assert; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public class SpanChunkFactoryTest { - @Test - public void create() { - AgentInformation agentInformation = new AgentInformation("agentId", "applicationName", 0,0, "machineName", ServiceType.TOMCAT.getCode(), Version.VERSION); - SpanChunkFactory spanChunkFactory = new SpanChunkFactory(agentInformation); - - try { - spanChunkFactory.create(new ArrayList()); - Assert.fail(); - } catch (Exception e) { - } - // one spanEvent - List spanEvents = new ArrayList(); - spanEvents.add(new SpanEvent(new Span())); - spanChunkFactory.create(spanEvents); - - // two spanEvent - spanEvents.add(new SpanEvent(new Span())); - spanChunkFactory.create(spanEvents); - - // three - spanEvents.add(new SpanEvent(new Span())); - spanChunkFactory.create(spanEvents); - - } -} +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.Version; +import com.nhn.pinpoint.profiler.AgentInformation; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class SpanChunkFactoryTest { + @Test + public void create() { + AgentInformation agentInformation = new AgentInformation("agentId", "applicationName", 0,0, "machineName", ServiceType.TOMCAT.getCode(), Version.VERSION); + SpanChunkFactory spanChunkFactory = new SpanChunkFactory(agentInformation); + + try { + spanChunkFactory.create(new ArrayList()); + Assert.fail(); + } catch (Exception e) { + } + // one spanEvent + List spanEvents = new ArrayList(); + spanEvents.add(new SpanEvent(new Span())); + spanChunkFactory.create(spanEvents); + + // two spanEvent + spanEvents.add(new SpanEvent(new Span())); + spanChunkFactory.create(spanEvents); + + // three + spanEvents.add(new SpanEvent(new Span())); + spanChunkFactory.create(spanEvents); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java index 1a176868f012..3cb4764fe591 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java @@ -1,49 +1,49 @@ -package com.nhn.pinpoint.profiler.context; - -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class SpanEventTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testMarkStartTime() throws Exception { - final DefaultTraceId traceId = new DefaultTraceId("agentTime", 0, 0); - Span span = new Span(); - span.setAgentId("agentId"); - span.recordTraceId(traceId); - span.markBeforeTime(); - Thread.sleep(10); - span.markAfterTime(); - logger.debug("span:{}", span); - - final SpanEvent spanEvent = new SpanEvent(span); - spanEvent.markStartTime(); - Thread.sleep(10); - spanEvent.markAfterTime(); - logger.debug("spanEvent:{}", spanEvent); - - Assert.assertEquals("startTime", span.getStartTime() + spanEvent.getStartElapsed(), spanEvent.getStartTime()); - Assert.assertEquals("endTime", span.getStartTime() + spanEvent.getStartElapsed() + spanEvent.getEndElapsed(), spanEvent.getAfterTime()); - } - - @Test - public void testGetStartTime() throws Exception { - - } - - @Test - public void testMarkEndTime() throws Exception { - - } - - @Test - public void testGetEndTime() throws Exception { - - } -} +package com.nhn.pinpoint.profiler.context; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class SpanEventTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testMarkStartTime() throws Exception { + final DefaultTraceId traceId = new DefaultTraceId("agentTime", 0, 0); + Span span = new Span(); + span.setAgentId("agentId"); + span.recordTraceId(traceId); + span.markBeforeTime(); + Thread.sleep(10); + span.markAfterTime(); + logger.debug("span:{}", span); + + final SpanEvent spanEvent = new SpanEvent(span); + spanEvent.markStartTime(); + Thread.sleep(10); + spanEvent.markAfterTime(); + logger.debug("spanEvent:{}", spanEvent); + + Assert.assertEquals("startTime", span.getStartTime() + spanEvent.getStartElapsed(), spanEvent.getStartTime()); + Assert.assertEquals("endTime", span.getStartTime() + spanEvent.getStartElapsed() + spanEvent.getEndElapsed(), spanEvent.getAfterTime()); + } + + @Test + public void testGetStartTime() throws Exception { + + } + + @Test + public void testMarkEndTime() throws Exception { + + } + + @Test + public void testGetEndTime() throws Exception { + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactoryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactoryTest.java index f03fd55381df..0c086579564e 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactoryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/ThreadLocalTraceFactoryTest.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.profiler.context; - -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.context.storage.LogStorageFactory; -import com.nhn.pinpoint.profiler.monitor.metric.MetricRegistry; -import com.nhn.pinpoint.profiler.sampler.TrueSampler; -import junit.framework.Assert; -import org.junit.Test; - -public class ThreadLocalTraceFactoryTest { - - private ThreadLocalTraceFactory getTraceFactory() { - LogStorageFactory logStorageFactory = new LogStorageFactory(); - TrueSampler trueSampler = new TrueSampler(); - DefaultTraceContext traceContext = new DefaultTraceContext(100, ServiceType.TOMCAT.getCode(), logStorageFactory, trueSampler); - MetricRegistry metricRegistry = new MetricRegistry(ServiceType.TOMCAT); - return new ThreadLocalTraceFactory(traceContext, metricRegistry, logStorageFactory, trueSampler); - } - - @Test - public void nullTraceObject() { - ThreadLocalTraceFactory traceFactory = getTraceFactory(); - - Trace currentTraceObject = traceFactory.currentTraceObject(); - Assert.assertNull(currentTraceObject); - - Trace rawTraceObject = traceFactory.currentRawTraceObject(); - Assert.assertNull(rawTraceObject); - - } - - @Test - public void testCurrentTraceObject() throws Exception { - ThreadLocalTraceFactory traceFactory = getTraceFactory(); - - Trace trace = traceFactory.currentTraceObject(); - - - } - - - @Test - public void testCurrentRpcTraceObject() throws Exception { - - } - - @Test - public void testCurrentRawTraceObject() throws Exception { - - } - - @Test - public void testDisableSampling() throws Exception { - - } - - @Test - public void testContinueTraceObject() throws Exception { - - } - - @Test - public void testNewTraceObject() throws Exception { - - } - - @Test - public void testDetachTraceObject() throws Exception { - - } +package com.nhn.pinpoint.profiler.context; + +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.context.storage.LogStorageFactory; +import com.nhn.pinpoint.profiler.monitor.metric.MetricRegistry; +import com.nhn.pinpoint.profiler.sampler.TrueSampler; +import junit.framework.Assert; +import org.junit.Test; + +public class ThreadLocalTraceFactoryTest { + + private ThreadLocalTraceFactory getTraceFactory() { + LogStorageFactory logStorageFactory = new LogStorageFactory(); + TrueSampler trueSampler = new TrueSampler(); + DefaultTraceContext traceContext = new DefaultTraceContext(100, ServiceType.TOMCAT.getCode(), logStorageFactory, trueSampler); + MetricRegistry metricRegistry = new MetricRegistry(ServiceType.TOMCAT); + return new ThreadLocalTraceFactory(traceContext, metricRegistry, logStorageFactory, trueSampler); + } + + @Test + public void nullTraceObject() { + ThreadLocalTraceFactory traceFactory = getTraceFactory(); + + Trace currentTraceObject = traceFactory.currentTraceObject(); + Assert.assertNull(currentTraceObject); + + Trace rawTraceObject = traceFactory.currentRawTraceObject(); + Assert.assertNull(rawTraceObject); + + } + + @Test + public void testCurrentTraceObject() throws Exception { + ThreadLocalTraceFactory traceFactory = getTraceFactory(); + + Trace trace = traceFactory.currentTraceObject(); + + + } + + + @Test + public void testCurrentRpcTraceObject() throws Exception { + + } + + @Test + public void testCurrentRawTraceObject() throws Exception { + + } + + @Test + public void testDisableSampling() throws Exception { + + } + + @Test + public void testContinueTraceObject() throws Exception { + + } + + @Test + public void testNewTraceObject() throws Exception { + + } + + @Test + public void testDetachTraceObject() throws Exception { + + } } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java index 42c7d2501cd7..8896370472f2 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java @@ -1,87 +1,87 @@ -package com.nhn.pinpoint.profiler.context.storage; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.Version; -import com.nhn.pinpoint.profiler.AgentInformation; -import com.nhn.pinpoint.profiler.context.Span; -import com.nhn.pinpoint.profiler.context.SpanChunkFactory; -import com.nhn.pinpoint.profiler.context.SpanEvent; -import com.nhn.pinpoint.profiler.context.storage.BufferedStorage; -import com.nhn.pinpoint.profiler.sender.CountingDataSender; -import junit.framework.Assert; -import org.junit.Before; -import org.junit.Test; - -public class BufferedStorageTest { - - private AgentInformation agentInformation = new AgentInformation("agentId", "applicationName", 0, 1, "hostName", ServiceType.TOMCAT.getCode(), Version.VERSION); - private SpanChunkFactory spanChunkFactory = new SpanChunkFactory(agentInformation); - private CountingDataSender countingDataSender = new CountingDataSender(); - - @Before - public void before() { - countingDataSender.stop(); - } - - @Test - public void testStore_Noflush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); - - Span span = new Span(); - SpanEvent spanEvent = new SpanEvent(span); - bufferedStorage.store(spanEvent); - bufferedStorage.store(spanEvent); - - Assert.assertEquals(0, countingDataSender.getTotalCount()); - } - - @Test - public void testStore_flush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 1); - - Span span = new Span(); - SpanEvent spanEvent = new SpanEvent(span); - bufferedStorage.store(spanEvent); - bufferedStorage.store(spanEvent); - - Assert.assertEquals(0, countingDataSender.getSenderCounter(), 2); - Assert.assertEquals(0, countingDataSender.getTotalCount(), 2); - - Assert.assertEquals(0, countingDataSender.getSpanChunkCounter(), 2); - Assert.assertEquals(0, countingDataSender.getSpanCounter(), 0); - } - - - @Test - public void testStore_spanFlush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); - - Span span = new Span(); - bufferedStorage.store(span); - bufferedStorage.store(span); - bufferedStorage.store(span); - - Assert.assertEquals(0, countingDataSender.getSenderCounter(), 3); - Assert.assertEquals(0, countingDataSender.getTotalCount(), 3); - - Assert.assertEquals(0, countingDataSender.getSpanCounter(), 3); - Assert.assertEquals(0, countingDataSender.getSpanChunkCounter(), 0); - } - - @Test - public void testStore_spanLastFlush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); - - Span span = new Span(); - SpanEvent spanEvent = new SpanEvent(span); - bufferedStorage.store(spanEvent); - bufferedStorage.store(spanEvent); - bufferedStorage.store(span); - - Assert.assertEquals(0, countingDataSender.getSenderCounter(), 1); - Assert.assertEquals(0, countingDataSender.getTotalCount(), 1); - - Assert.assertEquals(0, countingDataSender.getSpanCounter(), 1); - Assert.assertEquals(0, countingDataSender.getSpanChunkCounter(), 0); - } +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.Version; +import com.nhn.pinpoint.profiler.AgentInformation; +import com.nhn.pinpoint.profiler.context.Span; +import com.nhn.pinpoint.profiler.context.SpanChunkFactory; +import com.nhn.pinpoint.profiler.context.SpanEvent; +import com.nhn.pinpoint.profiler.context.storage.BufferedStorage; +import com.nhn.pinpoint.profiler.sender.CountingDataSender; +import junit.framework.Assert; +import org.junit.Before; +import org.junit.Test; + +public class BufferedStorageTest { + + private AgentInformation agentInformation = new AgentInformation("agentId", "applicationName", 0, 1, "hostName", ServiceType.TOMCAT.getCode(), Version.VERSION); + private SpanChunkFactory spanChunkFactory = new SpanChunkFactory(agentInformation); + private CountingDataSender countingDataSender = new CountingDataSender(); + + @Before + public void before() { + countingDataSender.stop(); + } + + @Test + public void testStore_Noflush() throws Exception { + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); + + Span span = new Span(); + SpanEvent spanEvent = new SpanEvent(span); + bufferedStorage.store(spanEvent); + bufferedStorage.store(spanEvent); + + Assert.assertEquals(0, countingDataSender.getTotalCount()); + } + + @Test + public void testStore_flush() throws Exception { + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 1); + + Span span = new Span(); + SpanEvent spanEvent = new SpanEvent(span); + bufferedStorage.store(spanEvent); + bufferedStorage.store(spanEvent); + + Assert.assertEquals(0, countingDataSender.getSenderCounter(), 2); + Assert.assertEquals(0, countingDataSender.getTotalCount(), 2); + + Assert.assertEquals(0, countingDataSender.getSpanChunkCounter(), 2); + Assert.assertEquals(0, countingDataSender.getSpanCounter(), 0); + } + + + @Test + public void testStore_spanFlush() throws Exception { + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); + + Span span = new Span(); + bufferedStorage.store(span); + bufferedStorage.store(span); + bufferedStorage.store(span); + + Assert.assertEquals(0, countingDataSender.getSenderCounter(), 3); + Assert.assertEquals(0, countingDataSender.getTotalCount(), 3); + + Assert.assertEquals(0, countingDataSender.getSpanCounter(), 3); + Assert.assertEquals(0, countingDataSender.getSpanChunkCounter(), 0); + } + + @Test + public void testStore_spanLastFlush() throws Exception { + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); + + Span span = new Span(); + SpanEvent spanEvent = new SpanEvent(span); + bufferedStorage.store(spanEvent); + bufferedStorage.store(spanEvent); + bufferedStorage.store(span); + + Assert.assertEquals(0, countingDataSender.getSenderCounter(), 1); + Assert.assertEquals(0, countingDataSender.getTotalCount(), 1); + + Assert.assertEquals(0, countingDataSender.getSpanCounter(), 1); + Assert.assertEquals(0, countingDataSender.getSpanChunkCounter(), 0); + } } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/HoldingSpanStorage.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/HoldingSpanStorage.java new file mode 100644 index 000000000000..582650618eac --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/HoldingSpanStorage.java @@ -0,0 +1,36 @@ +package com.nhn.pinpoint.profiler.context.storage; + +import org.apache.thrift.TBase; + +import com.nhn.pinpoint.profiler.context.Span; +import com.nhn.pinpoint.profiler.context.SpanEvent; +import com.nhn.pinpoint.profiler.sender.PeekableDataSender; + +/** + * @author hyungil.jeong + */ +public final class HoldingSpanStorage implements Storage { + + private final PeekableDataSender> dataSender; + + public HoldingSpanStorage(PeekableDataSender> dataSender) { + this.dataSender = dataSender; + } + + @Override + public void store(SpanEvent spanEvent) { + if (spanEvent == null) { + throw new NullPointerException("spanEvent must not be null"); + } + this.dataSender.send(spanEvent); + } + + @Override + public void store(Span span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + this.dataSender.send(span); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/HoldingSpanStorageFactory.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/HoldingSpanStorageFactory.java new file mode 100644 index 000000000000..84448185a455 --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/HoldingSpanStorageFactory.java @@ -0,0 +1,29 @@ +package com.nhn.pinpoint.profiler.context.storage; + +import com.nhn.pinpoint.profiler.sender.DataSender; +import com.nhn.pinpoint.profiler.sender.PeekableDataSender; + +/** + * @author hyungil.jeong + */ +public class HoldingSpanStorageFactory implements StorageFactory { + + private final PeekableDataSender dataSender; + + public HoldingSpanStorageFactory(DataSender dataSender) { + if (dataSender == null) { + throw new NullPointerException("dataSender must not be null"); + } + if (dataSender instanceof PeekableDataSender) { + this.dataSender = (PeekableDataSender)dataSender; + } else { + throw new IllegalArgumentException("dataSender must be an instance of PeekableDataSender."); + } + } + + @Override + public Storage createStorage() { + return new HoldingSpanStorage(this.dataSender); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/errorTest/ConcurrentCall.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/errorTest/ConcurrentCall.java index 1f84bc39a37d..4c4519527d21 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/errorTest/ConcurrentCall.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/errorTest/ConcurrentCall.java @@ -1,92 +1,92 @@ -package com.nhn.pinpoint.profiler.errorTest; - -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicInteger; - - -/** - * @author emeroad - */ -@Ignore -public class ConcurrentCall { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private String host = "http://localhost:8080"; - private String[] urls = new String[]{ - "/mysql", "/mysqlStatement", - "/combination", - "/donothing", - "/oracle/selectOne", "/oracle/createStatement", - "/mysql/selectOne", "/mysql/createStatement", - "/arcus", - "/nested" - }; - private String pinpoint = ".pinpoint"; - - private AtomicInteger id = new AtomicInteger(new Random().nextInt()); - private ExecutorService executorService = Executors.newFixedThreadPool(200); - - @Test - public void test() throws IOException, InterruptedException { - ((ThreadPoolExecutor) executorService).prestartAllCoreThreads(); - - ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(); - cm.setMaxTotal(200); - cm.setDefaultMaxPerRoute(200); - - final HttpClient client = new DefaultHttpClient(cm); - int call = 400; - final CountDownLatch latch = new CountDownLatch(call); - for (int i = 0; i < call; i++) { - executorService.execute(new Runnable() { - @Override - public void run() { - try { - String url = getUrl(); - logger.info("execute {}", url); - final HttpGet httpGet = new HttpGet(url); - final HttpResponse execute = client.execute(httpGet); - execute.getEntity().getContent().close(); - - } catch (ClientProtocolException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } finally { - latch.countDown(); - } - } - }); - } - latch.await(); - executorService.shutdown(); - cm.shutdown(); - - - } - - private String getUrl() { - return host + getUrls() + pinpoint; - } - - private String getUrls() { - final int index = Math.abs(id.getAndIncrement() % urls.length); - return urls[index]; - } -} +package com.nhn.pinpoint.profiler.errorTest; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicInteger; + + +/** + * @author emeroad + */ +@Ignore +public class ConcurrentCall { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private String host = "http://localhost:8080"; + private String[] urls = new String[]{ + "/mysql", "/mysqlStatement", + "/combination", + "/donothing", + "/oracle/selectOne", "/oracle/createStatement", + "/mysql/selectOne", "/mysql/createStatement", + "/arcus", + "/nested" + }; + private String pinpoint = ".pinpoint"; + + private AtomicInteger id = new AtomicInteger(new Random().nextInt()); + private ExecutorService executorService = Executors.newFixedThreadPool(200); + + @Test + public void test() throws IOException, InterruptedException { + ((ThreadPoolExecutor) executorService).prestartAllCoreThreads(); + + ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(); + cm.setMaxTotal(200); + cm.setDefaultMaxPerRoute(200); + + final HttpClient client = new DefaultHttpClient(cm); + int call = 400; + final CountDownLatch latch = new CountDownLatch(call); + for (int i = 0; i < call; i++) { + executorService.execute(new Runnable() { + @Override + public void run() { + try { + String url = getUrl(); + logger.info("execute {}", url); + final HttpGet httpGet = new HttpGet(url); + final HttpResponse execute = client.execute(httpGet); + execute.getEntity().getContent().close(); + + } catch (ClientProtocolException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } finally { + latch.countDown(); + } + } + }); + } + latch.await(); + executorService.shutdown(); + cm.shutdown(); + + + } + + private String getUrl() { + return host + getUrls() + pinpoint; + } + + private String getUrls() { + final int index = Math.abs(id.getAndIncrement() % urls.length); + return urls[index]; + } +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/AroundInterceptor.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/AroundInterceptor.java similarity index 72% rename from bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/AroundInterceptor.java rename to profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/AroundInterceptor.java index eec2bf884fcf..3367d955c380 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/AroundInterceptor.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/AroundInterceptor.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -/** - * @author emeroad - */ -@Deprecated -public interface AroundInterceptor { - - void before(InterceptorContext ctx); - - void after(InterceptorContext ctx); -} +package com.nhn.pinpoint.profiler.interceptor; + +/** + * @author emeroad + */ +@Deprecated +public interface AroundInterceptor { + + void before(InterceptorContext ctx); + + void after(InterceptorContext ctx); +} diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorContext.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/InterceptorContext.java similarity index 91% rename from bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorContext.java rename to profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/InterceptorContext.java index 1a9dc5d52c91..ac663f152253 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorContext.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/InterceptorContext.java @@ -1,70 +1,70 @@ -package com.nhn.pinpoint.bootstrap.interceptor; - -import java.util.Arrays; - -/** - * @author emeroad - */ -@Deprecated -public class InterceptorContext { - private Object target; - private String className; - private String methodName; - private Object[] parameter; - private Object value; - - private Object result; - - public Object getTarget() { - return target; - } - - public void setTarget(Object target) { - this.target = target; - } - - public String getClassName() { - return className; - } - - public void setClassName(String className) { - this.className = className; - } - - public String getMethodName() { - return methodName; - } - - public void setMethodName(String methodName) { - this.methodName = methodName; - } - - public Object[] getParameter() { - return parameter; - } - - public void setParameter(Object[] parameter) { - this.parameter = parameter; - } - - public Object getResult() { - return result; - } - - public void setResult(Object result) { - this.result = result; - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - @Override - public String toString() { - return "InterceptorContext{" + "target=" + target + ", className='" + className + '\'' + ", methodName='" + methodName + '\'' + ", parameter=" + (parameter == null ? null : Arrays.asList(parameter)) + ", value=" + value + ", result=" + result + '}'; - } -} +package com.nhn.pinpoint.profiler.interceptor; + +import java.util.Arrays; + +/** + * @author emeroad + */ +@Deprecated +public class InterceptorContext { + private Object target; + private String className; + private String methodName; + private Object[] parameter; + private Object value; + + private Object result; + + public Object getTarget() { + return target; + } + + public void setTarget(Object target) { + this.target = target; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getMethodName() { + return methodName; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public Object[] getParameter() { + return parameter; + } + + public void setParameter(Object[] parameter) { + this.parameter = parameter; + } + + public Object getResult() { + return result; + } + + public void setResult(Object result) { + this.result = result; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + @Override + public String toString() { + return "InterceptorContext{" + "target=" + target + ", className='" + className + '\'' + ", methodName='" + methodName + '\'' + ", parameter=" + (parameter == null ? null : Arrays.asList(parameter)) + ", value=" + value + ", result=" + result + '}'; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/InterceptorRegistryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/InterceptorRegistryTest.java index 9a622831f266..ce5534c783cc 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/InterceptorRegistryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/InterceptorRegistryTest.java @@ -1,205 +1,203 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.AroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.bootstrap.interceptor.InterceptorContext; -import com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry; -import com.nhn.pinpoint.profiler.interceptor.bci.TestObject; -import javassist.*; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Map; - -/** - * @author emeroad - */ -public class InterceptorRegistryTest { - - private final Logger logger = LoggerFactory.getLogger(InterceptorRegistryTest.class.getName()); - - private InterceptorRegistry registry = new InterceptorRegistry(); - - @Test - public void addInterceptor() throws Exception { - TestBeforeInterceptor interceptor = new TestBeforeInterceptor(); - - int key = registry.addInterceptor0(interceptor); - Interceptor find = registry.getInterceptor0(key); - - Assert.assertEquals(interceptor, find); - } - -// @Test - public void methodName() throws NoSuchMethodException { - Method[] toString = Map.class.getDeclaredMethods(); - for(Method m : toString) { - logger.info("methodObject:" + m); - logger.info("methodObject" + m.toGenericString()); - } - } - -// @Test - public void ctClassName() throws NotFoundException { - ClassPool pool = new ClassPool(); - pool.appendSystemPath(); - CtClass ctClass = pool.get("java.lang.String"); - logger.info("ctClass:" + ctClass); - logger.info("ctClass:" + ctClass.getName()); - logger.info("ctClass:" + ctClass.getSimpleName()); - } - - @Deprecated - public void interceptor() throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException, IOException { - AroundInterceptor aroundInterceptor = new AroundInterceptor() { - @Override - public void before(InterceptorContext ctx) { - System.out.println("before ctx:" + ctx); - } - - @Override - public void after(InterceptorContext ctx) { - System.out.println("after ctx:" + ctx); - } - }; -// int i = InterceptorRegistry.addInterceptor(aroundInterceptor); - - - ClassPool p = ClassPool.getDefault(); - CtClass throwable = p.get(Throwable.class.getName()); - - - - CtClass ctClass = p.get("TestObject"); - System.out.println(ctClass); - final CtMethod hello = ctClass.getMethod("hello", "(Ljava/lang/String;)Ljava/lang/String;"); - System.out.println("langname:" + hello.getLongName()); - System.out.println("name:" + hello.getName()); - CtClass ctx = p.get(InterceptorContext.class.getName()); - hello.addLocalVariable("ctx", ctx); - - CtClass interceptor = p.get(AroundInterceptor.class.getName()); - - hello.addLocalVariable("interceptor", interceptor); - - CtClass object = p.get(Object.class.getName()); - hello.addLocalVariable("result", object); - - hello.insertBefore("{" + - "ctx = new InterceptorContext();" + - "ctx.setParameter($args);" + -// InterceptorRegistry.class.getName() + ".getInterceptor(\"a\").before(ctx);" + - "interceptor = (AroundInterceptor) " + InterceptorRegistry.class.getName() + ".getInterceptor(1);"+ - "interceptor.before(ctx);" + - "}"); - hello.addCatch("{" + -// " interceptor.after(ctx);"+ -// " AroundInterceptor a = (AroundInterceptor) " + InterceptorRegistry.class.getName() + ".getInterceptor(\"a\");"+ - " throw $e;" + - "}", throwable); - hello.insertAfter("{" + - "interceptor.after(ctx); " + - "}"); - - -// - -// hello.setBody(generatedAroundInterceptor("TestObject", "hello")); -// hello.setBody("{ System.out.println(\"ddd\"); }", ClassMap map ); - hello.insertBefore(" System.out.println(\" before + \");"); - hello.insertAfter(" System.out.println($_);"); -// hello.insertAfter(" System.out.println($r);"); -// hello.insertAfter(" System.out.println($w);"); - hello.insertAfter(" System.out.println($sig);"); - hello.insertAfter(" System.out.println($type);"); - hello.insertAfter(" System.out.println($class);"); -// hello.instrument(new ExprEditor() { -// public void edit(MethodCall m) -// throws CannotCompileException -// { -// try { -// System.out.println("method call" + m.getMethod().getName()); -// } catch (NotFoundException e) { -// e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. -// } -// String code = generatedAroundInterceptor("TestObject", "hello"); -// m.replace(code); -// } - - -// }); -// hello.addCatch("System.out.println(\"catch\"); throw $e;", throwable); - -// hello.setName("__hello"); -// CtMethod method = CtNewMethod.make("public void hello() { try {__hello(); } catch(Throwable th){throw th;}}", ctClass); - -// CtMethod method = CtNewMethod.make("public void hello() { System.out.println(\"ddd\"); } catch(Throwable th){throw th;}}", ctClass); -// ctClass.addMethod(method); - - - - ctClass.freeze(); -// ctClass.writeFile("./debug"); - ctClass.debugWriteFile("./debug"); - Class aClass = ctClass.toClass(); - TestObject o = (TestObject) aClass.newInstance(); - -// ctClass.getMethod("toString", null); -// ctClass.getDeclaredMethod("toString", null); - - try { - o.hello("aaaaaa"); - } catch (Exception e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - -// o.hello(); - } - - private String generatedAroundInterceptor(String className, String methodName) { - StringBuilder sb = new StringBuilder(); - sb.append("{"); - sb.append(" ctx = new InterceptorContext();"); - sb.append(" ctx.setParameter($args);"); - sb.append(" ctx.setTarget(this);"); - sb.append(" "); -// sb.append(" ctx.setMethodName(\"" + methodName + "\");"); -// sb.append(" System.out.println(\"args check : \" + $args );"); -// sb.append(" System.out.println(\"0 check : \" + $0 );"); -// sb.append(" System.out.println(\"1 check : \" + $1 );"); -// sb.append(" System.out.println(\"sig check : \" + $sig );"); -// sb.append(" System.out.println(\"class check : \" + $class );"); -// sb.append(" System.out.println(\" r check : \" + $r);"); - - sb.append("}"); - sb.append("{"); - sb.append(" interceptor = (AroundInterceptor) " + InterceptorRegistry.class.getName() + ".getInterceptor(\"a\");"); - sb.append(" interceptor.before(ctx);"); - sb.append(" result = null;"); -// println(sb, "before systemout \"ttt\""); - sb.append("}"); - sb.append("try {"); - sb.append(" $_ = $proceed($$);"); - sb.append(" result = $_;"); - sb.append("}"); -// sb.append("catch(Throwable th) {"); -// sb.append(" System.out.println(\"test11\" + th);"); -// sb.append(" ctx.setErrCode(th);"); -// sb.append(" System.out.println(\"catch\");"); -// sb.append("}"); - sb.append("finally {"); -// sb.append(" System.out.println(\"finally\");"); - sb.append(" ctx.setReturnValue(result);"); - sb.append(" interceptor.after(ctx);"); - sb.append("}"); -// System.out.println(sb); - return sb.toString(); - } - public void println(StringBuilder sb, String out) { - sb.append("System.out.println(\"" + out.replace("\"", "\\\"") + "\");"); - } -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry; +import com.nhn.pinpoint.profiler.interceptor.bci.TestObject; +import javassist.*; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Map; + +/** + * @author emeroad + */ +public class InterceptorRegistryTest { + + private final Logger logger = LoggerFactory.getLogger(InterceptorRegistryTest.class.getName()); + + private InterceptorRegistry registry = new InterceptorRegistry(); + + @Test + public void addInterceptor() throws Exception { + TestBeforeInterceptor interceptor = new TestBeforeInterceptor(); + + int key = registry.addInterceptor0(interceptor); + Interceptor find = registry.getInterceptor0(key); + + Assert.assertEquals(interceptor, find); + } + +// @Test + public void methodName() throws NoSuchMethodException { + Method[] toString = Map.class.getDeclaredMethods(); + for(Method m : toString) { + logger.info("methodObject:" + m); + logger.info("methodObject" + m.toGenericString()); + } + } + +// @Test + public void ctClassName() throws NotFoundException { + ClassPool pool = new ClassPool(); + pool.appendSystemPath(); + CtClass ctClass = pool.get("java.lang.String"); + logger.info("ctClass:" + ctClass); + logger.info("ctClass:" + ctClass.getName()); + logger.info("ctClass:" + ctClass.getSimpleName()); + } + + @Deprecated + public void interceptor() throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException, IOException { + AroundInterceptor aroundInterceptor = new AroundInterceptor() { + @Override + public void before(InterceptorContext ctx) { + System.out.println("before ctx:" + ctx); + } + + @Override + public void after(InterceptorContext ctx) { + System.out.println("after ctx:" + ctx); + } + }; +// int i = InterceptorRegistry.addInterceptor(aroundInterceptor); + + + ClassPool p = ClassPool.getDefault(); + CtClass throwable = p.get(Throwable.class.getName()); + + + + CtClass ctClass = p.get("TestObject"); + System.out.println(ctClass); + final CtMethod hello = ctClass.getMethod("hello", "(Ljava/lang/String;)Ljava/lang/String;"); + System.out.println("langname:" + hello.getLongName()); + System.out.println("name:" + hello.getName()); + CtClass ctx = p.get(InterceptorContext.class.getName()); + hello.addLocalVariable("ctx", ctx); + + CtClass interceptor = p.get(AroundInterceptor.class.getName()); + + hello.addLocalVariable("interceptor", interceptor); + + CtClass object = p.get(Object.class.getName()); + hello.addLocalVariable("result", object); + + hello.insertBefore("{" + + "ctx = new InterceptorContext();" + + "ctx.setParameter($args);" + +// InterceptorRegistry.class.getName() + ".getInterceptor(\"a\").before(ctx);" + + "interceptor = (AroundInterceptor) " + InterceptorRegistry.class.getName() + ".getInterceptor(1);"+ + "interceptor.before(ctx);" + + "}"); + hello.addCatch("{" + +// " interceptor.after(ctx);"+ +// " AroundInterceptor a = (AroundInterceptor) " + InterceptorRegistry.class.getName() + ".getInterceptor(\"a\");"+ + " throw $e;" + + "}", throwable); + hello.insertAfter("{" + + "interceptor.after(ctx); " + + "}"); + + +// + +// hello.setBody(generatedAroundInterceptor("TestObject", "hello")); +// hello.setBody("{ System.out.println(\"ddd\"); }", ClassMap map ); + hello.insertBefore(" System.out.println(\" before + \");"); + hello.insertAfter(" System.out.println($_);"); +// hello.insertAfter(" System.out.println($r);"); +// hello.insertAfter(" System.out.println($w);"); + hello.insertAfter(" System.out.println($sig);"); + hello.insertAfter(" System.out.println($type);"); + hello.insertAfter(" System.out.println($class);"); +// hello.instrument(new ExprEditor() { +// public void edit(MethodCall m) +// throws CannotCompileException +// { +// try { +// System.out.println("method call" + m.getMethod().getName()); +// } catch (NotFoundException e) { +// e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. +// } +// String code = generatedAroundInterceptor("TestObject", "hello"); +// m.replace(code); +// } + + +// }); +// hello.addCatch("System.out.println(\"catch\"); throw $e;", throwable); + +// hello.setName("__hello"); +// CtMethod method = CtNewMethod.make("public void hello() { try {__hello(); } catch(Throwable th){throw th;}}", ctClass); + +// CtMethod method = CtNewMethod.make("public void hello() { System.out.println(\"ddd\"); } catch(Throwable th){throw th;}}", ctClass); +// ctClass.addMethod(method); + + + + ctClass.freeze(); +// ctClass.writeFile("./debug"); + ctClass.debugWriteFile("./debug"); + Class aClass = ctClass.toClass(); + TestObject o = (TestObject) aClass.newInstance(); + +// ctClass.getMethod("toString", null); +// ctClass.getDeclaredMethod("toString", null); + + try { + o.hello("aaaaaa"); + } catch (Exception e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + +// o.hello(); + } + + private String generatedAroundInterceptor(String className, String methodName) { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + sb.append(" ctx = new InterceptorContext();"); + sb.append(" ctx.setParameter($args);"); + sb.append(" ctx.setTarget(this);"); + sb.append(" "); +// sb.append(" ctx.setMethodName(\"" + methodName + "\");"); +// sb.append(" System.out.println(\"args check : \" + $args );"); +// sb.append(" System.out.println(\"0 check : \" + $0 );"); +// sb.append(" System.out.println(\"1 check : \" + $1 );"); +// sb.append(" System.out.println(\"sig check : \" + $sig );"); +// sb.append(" System.out.println(\"class check : \" + $class );"); +// sb.append(" System.out.println(\" r check : \" + $r);"); + + sb.append("}"); + sb.append("{"); + sb.append(" interceptor = (AroundInterceptor) " + InterceptorRegistry.class.getName() + ".getInterceptor(\"a\");"); + sb.append(" interceptor.before(ctx);"); + sb.append(" result = null;"); +// println(sb, "before systemout \"ttt\""); + sb.append("}"); + sb.append("try {"); + sb.append(" $_ = $proceed($$);"); + sb.append(" result = $_;"); + sb.append("}"); +// sb.append("catch(Throwable th) {"); +// sb.append(" System.out.println(\"test11\" + th);"); +// sb.append(" ctx.setErrCode(th);"); +// sb.append(" System.out.println(\"catch\");"); +// sb.append("}"); + sb.append("finally {"); +// sb.append(" System.out.println(\"finally\");"); + sb.append(" ctx.setReturnValue(result);"); + sb.append(" interceptor.after(ctx);"); + sb.append("}"); +// System.out.println(sb); + return sb.toString(); + } + public void println(StringBuilder sb, String out) { + sb.append("System.out.println(\"" + out.replace("\"", "\\\"") + "\");"); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAfterInterceptor.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAfterInterceptor.java index abbb08ab20a0..17987e636f94 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAfterInterceptor.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAfterInterceptor.java @@ -1,38 +1,38 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; - -/** - * @author emeroad - */ -public class TestAfterInterceptor implements StaticAroundInterceptor, TargetClassLoader { - private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - public int call = 0; - public Object target; - public String className; - public String methodName; - public Object[] args; - public Object result; - - @Override - public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { - - } - - @Override - public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - logger.info("after target:" + target + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); - this.target = target; - this.className = className; - this.methodName = methodName; - this.args = args; - call++; - this.result = result; - } -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +/** + * @author emeroad + */ +public class TestAfterInterceptor implements StaticAroundInterceptor, TargetClassLoader { + private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + public int call = 0; + public Object target; + public String className; + public String methodName; + public Object[] args; + public Object result; + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + logger.info("after target:" + target + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); + this.target = target; + this.className = className; + this.methodName = methodName; + this.args = args; + call++; + this.result = result; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAroundInterceptor.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAroundInterceptor.java index 6abe345a94dd..c92ca3d6caad 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAroundInterceptor.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestAroundInterceptor.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; - -/** - * @author emeroad - */ -public class TestAroundInterceptor implements StaticAroundInterceptor { - - public TestBeforeInterceptor before = new TestBeforeInterceptor(); - public TestAfterInterceptor after = new TestAfterInterceptor(); - - @Override - public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { - before.before(target, className, methodName, parameterDescription, args); - } - - @Override - public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - after.after(target, className, methodName, parameterDescription, args, result, throwable); - } - - -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; + +/** + * @author emeroad + */ +public class TestAroundInterceptor implements StaticAroundInterceptor { + + public TestBeforeInterceptor before = new TestBeforeInterceptor(); + public TestAfterInterceptor after = new TestAfterInterceptor(); + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + before.before(target, className, methodName, parameterDescription, args); + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + after.after(target, className, methodName, parameterDescription, args, result, throwable); + } + + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestBeforeInterceptor.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestBeforeInterceptor.java index 48c972d22891..fab43409889f 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestBeforeInterceptor.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/TestBeforeInterceptor.java @@ -1,40 +1,40 @@ -package com.nhn.pinpoint.profiler.interceptor; - -import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; -import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; - - -/** - * @author emeroad - */ -public class TestBeforeInterceptor implements StaticAroundInterceptor, TargetClassLoader { - static{ - System.out.println("load TestBeforeInterceptor cl:" + TestBeforeInterceptor.class.getClassLoader()); - } - private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - public int call = 0; - public Object target; - public String className; - public String methodName; - public Object[] args; - - @Override - public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { - logger.info("before target:" + target + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); - this.target = target; - this.className = className; - this.methodName = methodName; - this.args = args; - call++; - } - - @Override - public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { - - } -} +package com.nhn.pinpoint.profiler.interceptor; + +import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor; +import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + + +/** + * @author emeroad + */ +public class TestBeforeInterceptor implements StaticAroundInterceptor, TargetClassLoader { + static{ + System.out.println("load TestBeforeInterceptor cl:" + TestBeforeInterceptor.class.getClassLoader()); + } + private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + public int call = 0; + public Object target; + public String className; + public String methodName; + public Object[] args; + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + logger.info("before target:" + target + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); + this.target = target; + this.className = className; + this.methodName = methodName; + this.args = args; + call++; + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result, Throwable throwable) { + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilderTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilderTest.java index 2a110fbc110e..201aa1db0121 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilderTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/CodeBuilderTest.java @@ -1,40 +1,40 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class CodeBuilderTest { - @Test - public void testCodeBuilder() throws Exception { - CodeBuilder builder = new CodeBuilder(); - builder.begin(); - builder.format("1"); - builder.end(); - Assert.assertEquals("{1}", builder.toString()); - } - - @Test - public void testFormat() throws Exception { - CodeBuilder builder = new CodeBuilder(); - builder.begin(); - builder.format("1"); - builder.format("2"); - builder.end(); - Assert.assertEquals("{12}", builder.toString()); - } - - @Test - public void testFormatAppend() throws Exception { - CodeBuilder builder = new CodeBuilder(); - builder.begin(); - builder.format("1"); - builder.append("2"); - builder.end(); - Assert.assertEquals("{12}", builder.toString()); - } - - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class CodeBuilderTest { + @Test + public void testCodeBuilder() throws Exception { + CodeBuilder builder = new CodeBuilder(); + builder.begin(); + builder.format("1"); + builder.end(); + Assert.assertEquals("{1}", builder.toString()); + } + + @Test + public void testFormat() throws Exception { + CodeBuilder builder = new CodeBuilder(); + builder.begin(); + builder.format("1"); + builder.format("2"); + builder.end(); + Assert.assertEquals("{12}", builder.toString()); + } + + @Test + public void testFormatAppend() throws Exception { + CodeBuilder builder = new CodeBuilder(); + builder.begin(); + builder.format("1"); + builder.append("2"); + builder.end(); + Assert.assertEquals("{12}", builder.toString()); + } + + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/FormatTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/FormatTest.java index f54597e31a71..492d394a35d4 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/FormatTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/FormatTest.java @@ -1,30 +1,35 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import org.junit.Test; - -import java.text.Format; -import java.util.Formatter; - -/** - * @author emeroad - */ -public class FormatTest { - @Test - public void format() { - StringBuilder sb = new StringBuilder(); - Formatter formatter = new Formatter(sb); - formatter.format("interceptor.after(%1s)", "tsest"); - - formatter.format("interceptor.afteddddr(%1s)", "tsest", "dd"); - System.out.println(); - } - @Test - public void format2() { - StringBuilder sb = new StringBuilder(); - sb.append("dddd"); - Formatter formatter = new Formatter(sb); - - formatter.format("interceptor.afteddddr(%s, %s, %s)", 16, 34234, 333); - System.out.println(sb.toString()); - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.Format; +import java.util.Formatter; + +/** + * @author emeroad + */ +public class FormatTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void format() { + StringBuilder buffer = new StringBuilder(); + Formatter formatter = new Formatter(buffer); + formatter.format("%1s", "ab"); + + formatter.format("%3s", "a"); + Assert.assertEquals(buffer.toString(), "ab a"); + } + + @Test + public void format2() { + StringBuilder buffer = new StringBuilder(); + Formatter formatter = new Formatter(buffer); + formatter.format("(%s, %s, %s)", 1, 2, 3); + + Assert.assertEquals(buffer.toString(), "(1, 2, 3)"); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClassTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClassTest.java index a7fda878e5b1..a5e611edad7c 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClassTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClassTest.java @@ -1,381 +1,381 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.IntTraceValue; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.ObjectTraceValue; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; -import com.nhn.pinpoint.profiler.modifier.db.interceptor.UnKnownDatabaseInfo; -import com.nhn.pinpoint.profiler.util.MockAgent; -import com.nhn.pinpoint.profiler.util.TestClassLoader; -import com.nhn.pinpoint.profiler.util.TestModifier; -import javassist.bytecode.Descriptor; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.security.ProtectionDomain; -import java.util.Collections; -import java.util.Map; - -/** - * @author emeroad - */ -public class JavaAssistClassTest { - private Logger logger = LoggerFactory.getLogger(JavaAssistByteCodeInstrumentor.class.getName()); - - @Test - public void addTraceValue() throws Exception { - final TestClassLoader loader = getTestClassLoader(); - final String javassistClassName = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject"; - final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { - - @Override - public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - try { - logger.info("modify cl:{}", classLoader); - - InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); - - Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor"); - addInterceptor(interceptor); - aClass.addTraceValue(ObjectTraceValue.class); - aClass.addTraceValue(IntTraceValue.class); - aClass.addTraceValue(DatabaseInfoTraceValue.class); - aClass.addTraceValue(BindValueTraceValue.class); - - logger.info(interceptor.getClass().getClassLoader().toString()); - String methodName = "callA"; - aClass.addInterceptor(methodName, null, interceptor); - return aClass.toBytecode(); - } catch (InstrumentException e) { - e.printStackTrace(); - throw new RuntimeException(e.getMessage(), e); - } - } - }; - testModifier.setTargetClass(javassistClassName); - loader.addModifier(testModifier); - loader.initialize(); - - Class testObjectClazz = loader.loadClass(javassistClassName); - final String methodName = "callA"; - logger.info("class:{}", testObjectClazz.toString()); - final Object testObject = testObjectClazz.newInstance(); - Method callA = testObjectClazz.getMethod(methodName); - callA.invoke(testObject); - - - if (testObject instanceof ObjectTraceValue) { - ObjectTraceValue objectTraceValue = (ObjectTraceValue) testObject; - objectTraceValue.__setTraceObject("a"); - Object get = objectTraceValue.__getTraceObject(); - Assert.assertEquals("a", get); - } else { - Assert.fail("ObjectTraceValue implements fail"); - } - - if (testObject instanceof IntTraceValue) { - IntTraceValue intTraceValue = (IntTraceValue) testObject; - intTraceValue.__setTraceInt(1); - int a = intTraceValue.__getTraceInt(); - Assert.assertEquals(1, a); - } else { - Assert.fail("IntTraceValue implements fail"); - } - - if (testObject instanceof DatabaseInfoTraceValue) { - DatabaseInfoTraceValue databaseInfoTraceValue = (DatabaseInfoTraceValue) testObject; - databaseInfoTraceValue.__setTraceDatabaseInfo(UnKnownDatabaseInfo.INSTANCE); - DatabaseInfo databaseInfo = databaseInfoTraceValue.__getTraceDatabaseInfo(); - Assert.assertSame(UnKnownDatabaseInfo.INSTANCE, databaseInfo); - } else { - Assert.fail("DatabaseInfoTraceValue implements fail"); - } - - if (testObject instanceof BindValueTraceValue) { - BindValueTraceValue bindValueTraceValue = (BindValueTraceValue) testObject; - Map integerStringMap = Collections.emptyMap(); - bindValueTraceValue.__setTraceBindValue(integerStringMap); - Map bindValueMap = bindValueTraceValue.__getTraceBindValue(); - Assert.assertSame(integerStringMap, bindValueMap); - } else { - Assert.fail("BindValueTraceValue implements fail"); - } - - } - - @Test - public void testBeforeAddInterceptor() throws Exception { - final TestClassLoader loader = getTestClassLoader(); - final String javassistClassName = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject"; - - final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { - - @Override - public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - try { - logger.info("modify cl:{}", classLoader); - - InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); - - Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor"); - addInterceptor(interceptor); - logger.info(interceptor.getClass().getClassLoader().toString()); - String methodName = "callA"; - aClass.addInterceptor(methodName, null, interceptor); - return aClass.toBytecode(); - } catch (InstrumentException e) { - e.printStackTrace(); - throw new RuntimeException(e.getMessage(), e); - } - } - }; - testModifier.setTargetClass(javassistClassName); - loader.addModifier(testModifier); - loader.initialize(); - - - - Class testObjectClazz = loader.loadClass(javassistClassName); - final String methodName = "callA"; - logger.info("class:{}", testObjectClazz.toString()); - final Object testObject = testObjectClazz.newInstance(); - Method callA = testObjectClazz.getMethod(methodName); - callA.invoke(testObject); - - - Interceptor interceptor = testModifier.getInterceptor(0); - assertEqualsIntField(interceptor, "call", 1); - assertEqualsObjectField(interceptor, "className", "com.nhn.pinpoint.profiler.interceptor.bci.TestObject"); - assertEqualsObjectField(interceptor, "methodName", methodName); - assertEqualsObjectField(interceptor, "args", null); - - assertEqualsObjectField(interceptor, "target", testObject); - - } - - private TestClassLoader getTestClassLoader() { - PLoggerFactory.initialize(new Slf4jLoggerBinder()); - - - ProfilerConfig profilerConfig = new ProfilerConfig(); - profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); - DefaultAgent agent = new MockAgent("", profilerConfig); - - return new TestClassLoader(agent); - } - - public void assertEqualsIntField(Object target, String fieldName, int value) throws NoSuchFieldException, IllegalAccessException { - Field field = target.getClass().getField(fieldName); - int anInt = field.getInt(target); - Assert.assertEquals(anInt, value); - } - - public void assertEqualsObjectField(Object target, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { - Field field = target.getClass().getField(fieldName); - Object obj = field.get(target); - Assert.assertEquals(obj, value); - } - - - @Test - public void testBeforeAddInterceptorFormContextClassLoader() throws Exception { - final TestClassLoader loader = getTestClassLoader(); - final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader"; - final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { - - @Override - public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - try { - logger.info("modify cl:{}", classLoader); - InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject); - - Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor"); - addInterceptor(interceptor); - logger.info(interceptor.getClass().getClassLoader().toString()); - String methodName = "callA"; - aClass.addInterceptor(methodName, null, interceptor); - return aClass.toBytecode(); - } catch (InstrumentException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - }; - testModifier.setTargetClass(testClassObject); - loader.addModifier(testModifier); - loader.initialize(); - - - - Class testObjectClazz = loader.loadClass("com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader"); - final String methodName = "callA"; - logger.info("class:{}", testObjectClazz.toString()); - final Object testObject = testObjectClazz.newInstance(); - Method callA = testObjectClazz.getMethod(methodName); - callA.invoke(testObject); - - - final Interceptor interceptor = testModifier.getInterceptor(0); - assertEqualsIntField(interceptor, "call", 1); - assertEqualsObjectField(interceptor, "className", "com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader"); - assertEqualsObjectField(interceptor, "methodName", methodName); - assertEqualsObjectField(interceptor, "args", null); - - assertEqualsObjectField(interceptor, "target", testObject); - - - } - - @Test - public void testAddAfterInterceptor() throws Exception { - // TODO aClass.addInterceptorCallByContextClassLoader 코드의 테스트 케이스도 추가해야함. - - - final TestClassLoader loader = getTestClassLoader(); - final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject2"; - final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { - - @Override - public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - try { - logger.info("modify cl:{}", classLoader); - InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject); - - Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestAfterInterceptor"); - addInterceptor(interceptor); - logger.info(interceptor.getClass().getClassLoader().toString()); - String methodName = "callA"; - aClass.addInterceptor(methodName, null, interceptor); - - Interceptor interceptor2 = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestAfterInterceptor"); - addInterceptor(interceptor2); - String methodName2 = "callB"; - aClass.addInterceptor(methodName2, null, interceptor2); - - return aClass.toBytecode(); - } catch (InstrumentException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - }; - testModifier.setTargetClass(testClassObject); - loader.addModifier(testModifier); - loader.initialize(); - - - - Class testObjectClazz = loader.loadClass(testClassObject); - final String methodName = "callA"; - logger.info("class:{}", testObjectClazz.toString()); - final Object testObject = testObjectClazz.newInstance(); - Method callA = testObjectClazz.getMethod(methodName); - Object result = callA.invoke(testObject); - - - Interceptor interceptor = testModifier.getInterceptor(0); - assertEqualsIntField(interceptor, "call", 1); - assertEqualsObjectField(interceptor, "className", testClassObject); - assertEqualsObjectField(interceptor, "methodName", methodName); - assertEqualsObjectField(interceptor, "args", null); - - assertEqualsObjectField(interceptor, "target", testObject); - assertEqualsObjectField(interceptor, "result", result); - - - final String methodName2 = "callB"; - Method callBMethod = testObject.getClass().getMethod(methodName2); - callBMethod.invoke(testObject); - - Interceptor interceptor2 = testModifier.getInterceptor(1); - assertEqualsIntField(interceptor2, "call", 1); - assertEqualsObjectField(interceptor2, "className", testClassObject); - assertEqualsObjectField(interceptor2, "methodName", methodName2); - assertEqualsObjectField(interceptor2, "args", null); - - assertEqualsObjectField(interceptor2, "target", testObject); - assertEqualsObjectField(interceptor2, "result", null); - - } - - @Test - public void nullDescriptor() { - String nullDescriptor = Descriptor.ofParameters(null); - logger.info("Descript null:{}", nullDescriptor); - } - - @Test - public void testLog() throws Exception { - - final TestClassLoader loader = getTestClassLoader(); - final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestLog"; - final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { - - @Override - public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { - try { - logger.info("modify cl:{}", classLoader); - InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject); - - aClass.addDebugLogBeforeAfterMethod(); - aClass.addDebugLogBeforeAfterConstructor(); - - return aClass.toBytecode(); - } catch (InstrumentException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - }; - testModifier.setTargetClass(testClassObject); - loader.addModifier(testModifier); - loader.initialize(); - - - - Object testObject = loader.loadClass(testClassObject).newInstance(); - - Method test = testObject.getClass().getMethod("test", null); - test.invoke(testObject); - - Method testString = testObject.getClass().getMethod("test", new Class[]{String.class}); - testString.invoke(testObject, "method"); - - Constructor constructor = testObject.getClass().getConstructor(null); - Object o = constructor.newInstance(); - - } - - private Object createInstance(InstrumentClass aClass) throws InstrumentException { - // ci서버에서 test가 2번이상 돌아갈 경우 이미 define된 class를 다시 define하려고 하여 문제가 발생할수 있음. - // 일단 임시 방편으로 다시 define하려고 할 경우. 실패후 그냥 현재 cl에서 class를 찾는 코드로 변경함. - // 좀더 장기적으로는 define할 class를 좀더 정확하게 지정하고 testclass도 지정할수 있도록 해야 될것으로 보임. - try { - Class aClass1 = aClass.toClass(); - return aClass1.newInstance(); - } catch (InstantiationException e) { - throw new InstrumentException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new InstrumentException(e.getMessage(), e); - } catch (InstrumentException linkageError) { - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - try { - return contextClassLoader.loadClass(aClass.getName()).newInstance(); - } catch (Throwable e) { - throw new InstrumentException(e.getMessage(), e); - } - } - } - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.IntTraceValue; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.ObjectTraceValue; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.DefaultAgent; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; +import com.nhn.pinpoint.profiler.modifier.db.interceptor.UnKnownDatabaseInfo; +import com.nhn.pinpoint.profiler.util.MockAgent; +import com.nhn.pinpoint.profiler.util.TestClassLoader; +import com.nhn.pinpoint.profiler.util.TestModifier; +import javassist.bytecode.Descriptor; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.security.ProtectionDomain; +import java.util.Collections; +import java.util.Map; + +/** + * @author emeroad + */ +public class JavaAssistClassTest { + private Logger logger = LoggerFactory.getLogger(JavaAssistByteCodeInstrumentor.class.getName()); + + @Test + public void addTraceValue() throws Exception { + final TestClassLoader loader = getTestClassLoader(); + final String javassistClassName = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject"; + final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { + + @Override + public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + try { + logger.info("modify cl:{}", classLoader); + + InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); + + Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor"); + addInterceptor(interceptor); + aClass.addTraceValue(ObjectTraceValue.class); + aClass.addTraceValue(IntTraceValue.class); + aClass.addTraceValue(DatabaseInfoTraceValue.class); + aClass.addTraceValue(BindValueTraceValue.class); + + logger.info(interceptor.getClass().getClassLoader().toString()); + String methodName = "callA"; + aClass.addInterceptor(methodName, null, interceptor); + return aClass.toBytecode(); + } catch (InstrumentException e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage(), e); + } + } + }; + testModifier.setTargetClass(javassistClassName); + loader.addModifier(testModifier); + loader.initialize(); + + Class testObjectClazz = loader.loadClass(javassistClassName); + final String methodName = "callA"; + logger.info("class:{}", testObjectClazz.toString()); + final Object testObject = testObjectClazz.newInstance(); + Method callA = testObjectClazz.getMethod(methodName); + callA.invoke(testObject); + + + if (testObject instanceof ObjectTraceValue) { + ObjectTraceValue objectTraceValue = (ObjectTraceValue) testObject; + objectTraceValue.__setTraceObject("a"); + Object get = objectTraceValue.__getTraceObject(); + Assert.assertEquals("a", get); + } else { + Assert.fail("ObjectTraceValue implements fail"); + } + + if (testObject instanceof IntTraceValue) { + IntTraceValue intTraceValue = (IntTraceValue) testObject; + intTraceValue.__setTraceInt(1); + int a = intTraceValue.__getTraceInt(); + Assert.assertEquals(1, a); + } else { + Assert.fail("IntTraceValue implements fail"); + } + + if (testObject instanceof DatabaseInfoTraceValue) { + DatabaseInfoTraceValue databaseInfoTraceValue = (DatabaseInfoTraceValue) testObject; + databaseInfoTraceValue.__setTraceDatabaseInfo(UnKnownDatabaseInfo.INSTANCE); + DatabaseInfo databaseInfo = databaseInfoTraceValue.__getTraceDatabaseInfo(); + Assert.assertSame(UnKnownDatabaseInfo.INSTANCE, databaseInfo); + } else { + Assert.fail("DatabaseInfoTraceValue implements fail"); + } + + if (testObject instanceof BindValueTraceValue) { + BindValueTraceValue bindValueTraceValue = (BindValueTraceValue) testObject; + Map integerStringMap = Collections.emptyMap(); + bindValueTraceValue.__setTraceBindValue(integerStringMap); + Map bindValueMap = bindValueTraceValue.__getTraceBindValue(); + Assert.assertSame(integerStringMap, bindValueMap); + } else { + Assert.fail("BindValueTraceValue implements fail"); + } + + } + + @Test + public void testBeforeAddInterceptor() throws Exception { + final TestClassLoader loader = getTestClassLoader(); + final String javassistClassName = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject"; + + final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { + + @Override + public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + try { + logger.info("modify cl:{}", classLoader); + + InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); + + Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor"); + addInterceptor(interceptor); + logger.info(interceptor.getClass().getClassLoader().toString()); + String methodName = "callA"; + aClass.addInterceptor(methodName, null, interceptor); + return aClass.toBytecode(); + } catch (InstrumentException e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage(), e); + } + } + }; + testModifier.setTargetClass(javassistClassName); + loader.addModifier(testModifier); + loader.initialize(); + + + + Class testObjectClazz = loader.loadClass(javassistClassName); + final String methodName = "callA"; + logger.info("class:{}", testObjectClazz.toString()); + final Object testObject = testObjectClazz.newInstance(); + Method callA = testObjectClazz.getMethod(methodName); + callA.invoke(testObject); + + + Interceptor interceptor = testModifier.getInterceptor(0); + assertEqualsIntField(interceptor, "call", 1); + assertEqualsObjectField(interceptor, "className", "com.nhn.pinpoint.profiler.interceptor.bci.TestObject"); + assertEqualsObjectField(interceptor, "methodName", methodName); + assertEqualsObjectField(interceptor, "args", null); + + assertEqualsObjectField(interceptor, "target", testObject); + + } + + private TestClassLoader getTestClassLoader() { + PLoggerFactory.initialize(new Slf4jLoggerBinder()); + + + ProfilerConfig profilerConfig = new ProfilerConfig(); + profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); + DefaultAgent agent = new MockAgent("", profilerConfig); + + return new TestClassLoader(agent); + } + + public void assertEqualsIntField(Object target, String fieldName, int value) throws NoSuchFieldException, IllegalAccessException { + Field field = target.getClass().getField(fieldName); + int anInt = field.getInt(target); + Assert.assertEquals(anInt, value); + } + + public void assertEqualsObjectField(Object target, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { + Field field = target.getClass().getField(fieldName); + Object obj = field.get(target); + Assert.assertEquals(obj, value); + } + + + @Test + public void testBeforeAddInterceptorFormContextClassLoader() throws Exception { + final TestClassLoader loader = getTestClassLoader(); + final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader"; + final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { + + @Override + public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + try { + logger.info("modify cl:{}", classLoader); + InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject); + + Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor"); + addInterceptor(interceptor); + logger.info(interceptor.getClass().getClassLoader().toString()); + String methodName = "callA"; + aClass.addInterceptor(methodName, null, interceptor); + return aClass.toBytecode(); + } catch (InstrumentException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + }; + testModifier.setTargetClass(testClassObject); + loader.addModifier(testModifier); + loader.initialize(); + + + + Class testObjectClazz = loader.loadClass("com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader"); + final String methodName = "callA"; + logger.info("class:{}", testObjectClazz.toString()); + final Object testObject = testObjectClazz.newInstance(); + Method callA = testObjectClazz.getMethod(methodName); + callA.invoke(testObject); + + + final Interceptor interceptor = testModifier.getInterceptor(0); + assertEqualsIntField(interceptor, "call", 1); + assertEqualsObjectField(interceptor, "className", "com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader"); + assertEqualsObjectField(interceptor, "methodName", methodName); + assertEqualsObjectField(interceptor, "args", null); + + assertEqualsObjectField(interceptor, "target", testObject); + + + } + + @Test + public void testAddAfterInterceptor() throws Exception { + // TODO aClass.addInterceptorCallByContextClassLoader 코드의 테스트 케이스도 추가해야함. + + + final TestClassLoader loader = getTestClassLoader(); + final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject2"; + final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { + + @Override + public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + try { + logger.info("modify cl:{}", classLoader); + InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject); + + Interceptor interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestAfterInterceptor"); + addInterceptor(interceptor); + logger.info(interceptor.getClass().getClassLoader().toString()); + String methodName = "callA"; + aClass.addInterceptor(methodName, null, interceptor); + + Interceptor interceptor2 = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestAfterInterceptor"); + addInterceptor(interceptor2); + String methodName2 = "callB"; + aClass.addInterceptor(methodName2, null, interceptor2); + + return aClass.toBytecode(); + } catch (InstrumentException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + }; + testModifier.setTargetClass(testClassObject); + loader.addModifier(testModifier); + loader.initialize(); + + + + Class testObjectClazz = loader.loadClass(testClassObject); + final String methodName = "callA"; + logger.info("class:{}", testObjectClazz.toString()); + final Object testObject = testObjectClazz.newInstance(); + Method callA = testObjectClazz.getMethod(methodName); + Object result = callA.invoke(testObject); + + + Interceptor interceptor = testModifier.getInterceptor(0); + assertEqualsIntField(interceptor, "call", 1); + assertEqualsObjectField(interceptor, "className", testClassObject); + assertEqualsObjectField(interceptor, "methodName", methodName); + assertEqualsObjectField(interceptor, "args", null); + + assertEqualsObjectField(interceptor, "target", testObject); + assertEqualsObjectField(interceptor, "result", result); + + + final String methodName2 = "callB"; + Method callBMethod = testObject.getClass().getMethod(methodName2); + callBMethod.invoke(testObject); + + Interceptor interceptor2 = testModifier.getInterceptor(1); + assertEqualsIntField(interceptor2, "call", 1); + assertEqualsObjectField(interceptor2, "className", testClassObject); + assertEqualsObjectField(interceptor2, "methodName", methodName2); + assertEqualsObjectField(interceptor2, "args", null); + + assertEqualsObjectField(interceptor2, "target", testObject); + assertEqualsObjectField(interceptor2, "result", null); + + } + + @Test + public void nullDescriptor() { + String nullDescriptor = Descriptor.ofParameters(null); + logger.info("Descript null:{}", nullDescriptor); + } + + @Test + public void testLog() throws Exception { + + final TestClassLoader loader = getTestClassLoader(); + final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestLog"; + final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) { + + @Override + public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + try { + logger.info("modify cl:{}", classLoader); + InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject); + + aClass.addDebugLogBeforeAfterMethod(); + aClass.addDebugLogBeforeAfterConstructor(); + + return aClass.toBytecode(); + } catch (InstrumentException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + }; + testModifier.setTargetClass(testClassObject); + loader.addModifier(testModifier); + loader.initialize(); + + + + Object testObject = loader.loadClass(testClassObject).newInstance(); + + Method test = testObject.getClass().getMethod("test", null); + test.invoke(testObject); + + Method testString = testObject.getClass().getMethod("test", new Class[]{String.class}); + testString.invoke(testObject, "method"); + + Constructor constructor = testObject.getClass().getConstructor(null); + Object o = constructor.newInstance(); + + } + + private Object createInstance(InstrumentClass aClass) throws InstrumentException { + // ci서버에서 test가 2번이상 돌아갈 경우 이미 define된 class를 다시 define하려고 하여 문제가 발생할수 있음. + // 일단 임시 방편으로 다시 define하려고 할 경우. 실패후 그냥 현재 cl에서 class를 찾는 코드로 변경함. + // 좀더 장기적으로는 define할 class를 좀더 정확하게 지정하고 testclass도 지정할수 있도록 해야 될것으로 보임. + try { + Class aClass1 = aClass.toClass(); + return aClass1.newInstance(); + } catch (InstantiationException e) { + throw new InstrumentException(e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new InstrumentException(e.getMessage(), e); + } catch (InstrumentException linkageError) { + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + return contextClassLoader.loadClass(aClass.getName()).newInstance(); + } catch (Throwable e) { + throw new InstrumentException(e.getMessage(), e); + } + } + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodRenameInterceptorTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodRenameInterceptorTest.java index fe7b9dbdc4a2..d2a1e9b43cf5 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodRenameInterceptorTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/MethodRenameInterceptorTest.java @@ -1,98 +1,98 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import javassist.*; -import org.junit.Test; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * @author emeroad - */ -public class MethodRenameInterceptorTest { - @Test - public void methodRename() { - // Method rename을 사용해서 local 변수를 공유하는 방법의 경우 call stack이 변경되는 문제점이있다. - try { - String methodName = "callA"; - String objectName = "TestObject"; - // start by getting the class file and method - CtClass clas = ClassPool.getDefault().get(objectName); - if (clas == null) { - System.err.println("Class " + objectName + " not found"); - } else { - // add timing interceptor to the class - addTiming(clas, methodName); - clas.writeFile("debug"); - System.out.println("Added timing to method " + objectName + "." + methodName); - - } - Class aClass = clas.toClass(); - Object o = aClass.newInstance(); - Method method = o.getClass().getMethod(methodName); - Object invoke = method.invoke(o); - } catch (CannotCompileException ex) { - ex.printStackTrace(); - } catch (NotFoundException ex) { - ex.printStackTrace(); - } catch (IOException ex) { - ex.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } catch (NoSuchMethodException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } catch (InstantiationException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } catch (IllegalAccessException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - - private static void addTiming(CtClass clas, String mname) - throws NotFoundException, CannotCompileException { - - // get the method information (throws exception if method with - // given name is not declared directly by this class, returns - // arbitrary choice if more than one with the given name) - CtMethod mold = clas.getDeclaredMethod(mname); - - // rename old method to synthetic name, then duplicate the - // method with original name for use as interceptor - String nname = mname + "$impl"; - mold.setName(nname); - CtMethod mnew = CtNewMethod.copy(mold, mname, clas, null); - - // start the body text generation by saving the start time - // to a local variable, then call the timed method; the - // actual code generated needs to depend on whether the - // timed method returns a value - String type = mold.getReturnType().getName(); - StringBuilder body = new StringBuilder(); - body.append("{\nlong start = System.currentTimeMillis();\n"); - if (!"void".equals(type)) { - body.append(type + " result = "); - } - body.append(nname + "($$);\n"); - - // finish body text generation with call to print the timing - // information, and return saved value (if not void) - body.append("System.out.println(\"Call to method " + mname + - " took \" +\n (System.currentTimeMillis()-start) + " + - "\" ms.\");\n"); - if (!"void".equals(type)) { - body.append("return result;\n"); - } - body.append("}"); - - // replace the body of the interceptor method with generated - // code block and add it to class - mnew.setBody(body.toString()); - clas.addMethod(mnew); - // print the generated code block just to show what was done - System.out.println("Interceptor method body:"); - System.out.println(body.toString()); - - } - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import javassist.*; +import org.junit.Test; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * @author emeroad + */ +public class MethodRenameInterceptorTest { + @Test + public void methodRename() { + // Method rename을 사용해서 local 변수를 공유하는 방법의 경우 call stack이 변경되는 문제점이있다. + try { + String methodName = "callA"; + String objectName = "TestObject"; + // start by getting the class file and method + CtClass clas = ClassPool.getDefault().get(objectName); + if (clas == null) { + System.err.println("Class " + objectName + " not found"); + } else { + // add timing interceptor to the class + addTiming(clas, methodName); + clas.writeFile("debug"); + System.out.println("Added timing to method " + objectName + "." + methodName); + + } + Class aClass = clas.toClass(); + Object o = aClass.newInstance(); + Method method = o.getClass().getMethod(methodName); + Object invoke = method.invoke(o); + } catch (CannotCompileException ex) { + ex.printStackTrace(); + } catch (NotFoundException ex) { + ex.printStackTrace(); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (NoSuchMethodException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (InstantiationException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (IllegalAccessException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + + private static void addTiming(CtClass clas, String mname) + throws NotFoundException, CannotCompileException { + + // get the method information (throws exception if method with + // given name is not declared directly by this class, returns + // arbitrary choice if more than one with the given name) + CtMethod mold = clas.getDeclaredMethod(mname); + + // rename old method to synthetic name, then duplicate the + // method with original name for use as interceptor + String nname = mname + "$impl"; + mold.setName(nname); + CtMethod mnew = CtNewMethod.copy(mold, mname, clas, null); + + // start the body text generation by saving the start time + // to a local variable, then call the timed method; the + // actual code generated needs to depend on whether the + // timed method returns a value + String type = mold.getReturnType().getName(); + StringBuilder body = new StringBuilder(); + body.append("{\nlong start = System.currentTimeMillis();\n"); + if (!"void".equals(type)) { + body.append(type + " result = "); + } + body.append(nname + "($$);\n"); + + // finish body text generation with call to print the timing + // information, and return saved value (if not void) + body.append("System.out.println(\"Call to method " + mname + + " took \" +\n (System.currentTimeMillis()-start) + " + + "\" ms.\");\n"); + if (!"void".equals(type)) { + body.append("return result;\n"); + } + body.append("}"); + + // replace the body of the interceptor method with generated + // code block and add it to class + mnew.setBody(body.toString()); + clas.addMethod(mnew); + // print the generated code block just to show what was done + System.out.println("Interceptor method body:"); + System.out.println(body.toString()); + + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/ReflectionTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/ReflectionTest.java index 6190aa48fafd..84a42fe5bcf8 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/ReflectionTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/ReflectionTest.java @@ -1,55 +1,57 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import javassist.*; -import org.junit.Before; -import org.junit.Test; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.Arrays; - -/** - * @author emeroad - */ -public class ReflectionTest { - private ClassPool pool = new ClassPool(); - @Before - public void setUp() throws Exception { - pool.appendSystemPath(); - } - - @Test - public void test() throws NotFoundException { - Constructor[] constructors = String.class.getConstructors(); - for(Constructor c: constructors) { - System.out.println(c.getName()); - } - CtClass ctClass = pool.get("java.lang.String"); - CtConstructor[] constructors1 = ctClass.getConstructors(); - for(CtConstructor cc : constructors1) { - System.out.println(cc.getName()); - System.out.println(cc.getLongName()); - System.out.println(cc.getSignature()); - } - - - } - @Test - public void methodName() throws NotFoundException, ClassNotFoundException, NoSuchMethodException { - CtClass ctClass = pool.get("java.lang.String"); - - CtMethod subString = ctClass.getDeclaredMethod("substring", new CtClass[]{pool.get("int")}); - System.out.println("getLongName:" + subString.getLongName()); - System.out.println("getName:"+ subString.getName()); - System.out.println("getDescriptor:"+ subString.getMethodInfo().getDescriptor()); - System.out.println("getDescriptor2:"+ subString.getMethodInfo2().getDescriptor()); - System.out.println("getSignature:"+ subString.getSignature()); - - - Method substring = String.class.getMethod("substring", int.class); - System.out.println(substring.toString()); - System.out.println(Arrays.toString(substring.getParameterTypes())); - -// M - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import javassist.*; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.Arrays; + +/** + * @author emeroad + */ +public class ReflectionTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private ClassPool pool = new ClassPool(); + @Before + public void setUp() throws Exception { + pool.appendSystemPath(); + } + + @Test + public void test() throws NotFoundException { + Constructor[] constructors = String.class.getConstructors(); + for(Constructor c: constructors) { + logger.debug(c.getName()); + } + CtClass ctClass = pool.get("java.lang.String"); + CtConstructor[] constructors1 = ctClass.getConstructors(); + for(CtConstructor cc : constructors1) { + logger.debug(cc.getName()); + logger.debug(cc.getLongName()); + logger.debug(cc.getSignature()); + } + + + } + @Test + public void methodName() throws NotFoundException, ClassNotFoundException, NoSuchMethodException { + CtClass ctClass = pool.get("java.lang.String"); + + CtMethod subString = ctClass.getDeclaredMethod("substring", new CtClass[]{pool.get("int")}); + logger.debug("getLongName:{}", subString.getLongName()); + logger.debug("getName:{}", subString.getName()); + logger.debug("getDescriptor:{}", subString.getMethodInfo().getDescriptor()); + logger.debug("getDescriptor2:{}", subString.getMethodInfo2().getDescriptor()); + logger.debug("getSignature:{}", subString.getSignature()); + + + Method substring = String.class.getMethod("substring", int.class); + logger.debug(substring.toString()); + logger.debug(Arrays.toString(substring.getParameterTypes())); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestLog.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestLog.java index cb538227b530..034a1735b262 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestLog.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestLog.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class TestLog { - - private final Logger logger = LoggerFactory.getLogger(TestLog.class.getName()); - - public String constructor; - - public TestLog() { - } - - public TestLog(String constructor) { - this.constructor = constructor; - } - - public String test; - public void test() { - logger.info("test"); - } - - public void test(String method) { - this.test = method; - logger.info("test:" + method); - } -} +package com.nhn.pinpoint.profiler.interceptor.bci; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class TestLog { + + private final Logger logger = LoggerFactory.getLogger(TestLog.class.getName()); + + public String constructor; + + public TestLog() { + } + + public TestLog(String constructor) { + this.constructor = constructor; + } + + public String test; + public void test() { + logger.info("test"); + } + + public void test(String method) { + this.test = method; + logger.info("test:" + method); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject.java index ea75c43ad952..d639d1d9de19 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class TestObject { - private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - private int callA; - - public int callA() { - logger.info("callA"); - int i = callA++; - return i; - } - - public String hello(String a) { - System.out.println("a:" + a); - System.out.println("test"); -// throw new RuntimeException("test"); - return "a"; - } - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class TestObject { + private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private int callA; + + public int callA() { + logger.info("callA"); + int i = callA++; + return i; + } + + public String hello(String a) { + System.out.println("a:" + a); + System.out.println("test"); +// throw new RuntimeException("test"); + return "a"; + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject2.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject2.java index 64502cd85786..0a1e0356d6e9 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject2.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObject2.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class TestObject2 { - private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - public int callA; - public int callB; - - public int callA(){ - logger.info("callA"); - int i = callA++; - return i; - } - - public void callB() { - callB++; - } - - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class TestObject2 { + private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + public int callA; + public int callB; + + public int callA(){ + logger.info("callA"); + int i = callA++; + return i; + } + + public void callB() { + callB++; + } + + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObjectContextClassLoader.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObjectContextClassLoader.java index e9c11654f0e8..ea0f09319d3f 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObjectContextClassLoader.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/interceptor/bci/TestObjectContextClassLoader.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.profiler.interceptor.bci; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class TestObjectContextClassLoader { - private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - private int callA; - - public int callA() { - logger.info("callA"); - int i = callA++; - return i; - } - - public String hello(String a) { - System.out.println("a:" + a); - System.out.println("test"); -// throw new RuntimeException("test"); - return "a"; - } - -} +package com.nhn.pinpoint.profiler.interceptor.bci; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class TestObjectContextClassLoader { + private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private int callA; + + public int callA() { + logger.info("callA"); + int i = callA++; + return i; + } + + public String hello(String a) { + System.out.println("a:" + a); + System.out.println("test"); +// throw new RuntimeException("test"); + return "a"; + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/JavaAssistTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/JavaAssistTest.java index 4438cac18d91..13fc41944f59 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/JavaAssistTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/JavaAssistTest.java @@ -1,118 +1,118 @@ -package com.nhn.pinpoint.profiler.javaassist; - -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; -import javassist.NotFoundException; -import javassist.bytecode.Descriptor; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.Method; -import java.net.URL; -import java.util.Arrays; - -/** - * @author emeroad - */ -public class JavaAssistTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private ClassPool pool; - - @Before - public void setUp() throws Exception { - pool = new ClassPool(); - pool.appendSystemPath(); - } - - @Test - public void newClass() { - - } - - @Test - public void testAssist() throws NotFoundException, NoSuchMethodException { - - CtClass ctClass = pool.get(String.class.getName()); - logger.info(ctClass.toString()); - String s = ""; -// ctClass.getMethod("valueOf", "(D)"); - - CtMethod[] methods = ctClass.getMethods(); -// for(CtMethod method : methods) { -// System.out.println(method.getMethodInfo() +" " + method.getSignature()); -// } - - CtMethod endsWith = ctClass.getMethod("endsWith", "(Ljava/lang/String;)Z"); - logger.info(endsWith.getMethodInfo().toString()); - logger.info(endsWith.getSignature()); - logger.info(endsWith.getLongName()); - logger.info(endsWith.toString()); - logger.info(endsWith.getName()); - logger.info(endsWith.getMethodInfo().getName()); - logger.info(endsWith.getMethodInfo().getDescriptor()); - - Method endsWith1 = String.class.getMethod("endsWith", new Class[]{String.class}); - logger.debug(endsWith1.toString()); - - } - - @Test - public void test() { - sout("/java/lang/String.class"); - sout("java.lang.String.class"); - - } - - private void sout(String str) { - URL resource = this.getClass().getClassLoader().getResource(str); - logger.info("" + resource); - -// new URLClassLoader() - } - - @Test - public void genericTest() throws NotFoundException { - CtClass testClass = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass"); -// CtMethod setb = testClass.getMethod("setb"); - CtMethod[] declaredMethods = testClass.getDeclaredMethods(); - for (CtMethod declaredMethod : declaredMethods) { - logger.info(declaredMethod.toString()); - logger.info(declaredMethod.getGenericSignature()); - logger.info(declaredMethod.getSignature()); - logger.info("paramTypes:{}", Arrays.toString(declaredMethod.getParameterTypes())); - logger.info(declaredMethod.getMethodInfo2().getDescriptor()); - logger.info(declaredMethod.getMethodInfo().getDescriptor()); -// logger.info(declaredMethod.()); - } - - - CtMethod setb = testClass.getDeclaredMethod("setA", new CtClass[]{pool.get("int")}); - logger.info(setb.toString()); - CtMethod setStringArray = testClass.getDeclaredMethod("setStringArray", new CtClass[]{pool.get("java.lang.String[]")}); - logger.info(setStringArray.toString()); - - - - } - - @Test - public void innerClass() throws NotFoundException { - CtClass testClass = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass"); - logger.debug(testClass.toString()); - CtClass[] nestedClasses = testClass.getNestedClasses(); - for(CtClass nested : nestedClasses) { - logger.debug("nestedClass:" + nested); - } - - CtClass innerClass = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass$InnerClass"); - logger.debug(""+ innerClass); - - CtClass class1 = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass$1"); - logger.debug(""+ class1); - } -} +package com.nhn.pinpoint.profiler.javaassist; + +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.NotFoundException; +import javassist.bytecode.Descriptor; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; +import java.net.URL; +import java.util.Arrays; + +/** + * @author emeroad + */ +public class JavaAssistTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private ClassPool pool; + + @Before + public void setUp() throws Exception { + pool = new ClassPool(); + pool.appendSystemPath(); + } + + @Test + public void newClass() { + + } + + @Test + public void testAssist() throws NotFoundException, NoSuchMethodException { + + CtClass ctClass = pool.get(String.class.getName()); + logger.info(ctClass.toString()); + String s = ""; +// ctClass.getMethod("valueOf", "(D)"); + + CtMethod[] methods = ctClass.getMethods(); +// for (CtMethod method : methods) { +// logger.debug("{} {}", method.getMethodInfo(), method.getSignature()); +// } + + CtMethod endsWith = ctClass.getMethod("endsWith", "(Ljava/lang/String;)Z"); + logger.info(endsWith.getMethodInfo().toString()); + logger.info(endsWith.getSignature()); + logger.info(endsWith.getLongName()); + logger.info(endsWith.toString()); + logger.info(endsWith.getName()); + logger.info(endsWith.getMethodInfo().getName()); + logger.info(endsWith.getMethodInfo().getDescriptor()); + + Method endsWith1 = String.class.getMethod("endsWith", new Class[]{String.class}); + logger.debug(endsWith1.toString()); + + } + + @Test + public void test() { + sout("/java/lang/String.class"); + sout("java.lang.String.class"); + + } + + private void sout(String str) { + URL resource = this.getClass().getClassLoader().getResource(str); + logger.info("" + resource); + +// new URLClassLoader() + } + + @Test + public void genericTest() throws NotFoundException { + CtClass testClass = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass"); +// CtMethod setb = testClass.getMethod("setb"); + CtMethod[] declaredMethods = testClass.getDeclaredMethods(); + for (CtMethod declaredMethod : declaredMethods) { + logger.info(declaredMethod.toString()); + logger.info(declaredMethod.getGenericSignature()); + logger.info(declaredMethod.getSignature()); + logger.info("paramTypes:{}", Arrays.toString(declaredMethod.getParameterTypes())); + logger.info(declaredMethod.getMethodInfo2().getDescriptor()); + logger.info(declaredMethod.getMethodInfo().getDescriptor()); +// logger.info(declaredMethod.()); + } + + + CtMethod setb = testClass.getDeclaredMethod("setA", new CtClass[]{pool.get("int")}); + logger.info(setb.toString()); + CtMethod setStringArray = testClass.getDeclaredMethod("setStringArray", new CtClass[]{pool.get("java.lang.String[]")}); + logger.info(setStringArray.toString()); + + + + } + + @Test + public void innerClass() throws NotFoundException { + CtClass testClass = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass"); + logger.debug(testClass.toString()); + CtClass[] nestedClasses = testClass.getNestedClasses(); + for(CtClass nested : nestedClasses) { + logger.debug("nestedClass:" + nested); + } + + CtClass innerClass = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass$InnerClass"); + logger.debug(""+ innerClass); + + CtClass class1 = pool.get("com.nhn.pinpoint.profiler.javaassist.TestClass$1"); + logger.debug(""+ class1); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestBootstrapClass.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestBootstrapClass.java index 735cfd662521..2c9c75eebc3e 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestBootstrapClass.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestBootstrapClass.java @@ -1,97 +1,97 @@ -package com.nhn.pinpoint.profiler.javaassist; - -import javassist.CannotCompileException; -import javassist.ClassPool; -import javassist.CtClass; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.ProtectionDomain; - -/** - * @author emeroad - */ -public class TestBootstrapClass { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void test() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, CannotCompileException { - - Class cl = Class.forName("java.lang.ClassLoader"); - - Method defineClass1 = cl.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); - - Method defineClass2 = cl.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class, ProtectionDomain.class}); - - ClassPool cp = new ClassPool(); - cp.appendSystemPath(); - CtClass ctClass = cp.makeClass("com.test.Test"); - byte[] bytes = ctClass.toBytecode(); - - - ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); - logger.info(systemClassLoader.getClass().getName()); - - defineClass(defineClass1, systemClassLoader, new Object[]{"com.test.Test", bytes, 0, bytes.length}); - Class aClass = systemClassLoader.loadClass("com.test.Test"); - - logger.info("" + aClass.getClass().getClassLoader()); - - - } - - private Object defineClass(Method method, ClassLoader loader, Object[] objects) throws InvocationTargetException, IllegalAccessException { - method.setAccessible(true); - try { - return method.invoke(loader, objects); - } finally { - method.setAccessible(false); - } - } - - - @Test - public void testJdkClassClassLoader() throws IOException { - URL url = new URL("http://www.nave.com"); - - - HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); - - logger.info(urlConnection.toString()); - logger.info("" + urlConnection.getClass().getClassLoader()); - ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); - ClassLoader parent = systemClassLoader.getParent(); - logger.info("parent:" + parent); - logger.info("pparent:" + parent.getParent()); - - logger.info("" + String.class.getClassLoader()); - logger.info("" + TestBootstrapClass.class.getClassLoader()); - - - urlConnection.disconnect(); - - - } - - @Test - public void testReflection() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - java.lang.ClassLoader contextClassLoader = java.lang.Thread.currentThread().getContextClassLoader(); - java.lang.Class interceptorRegistry = contextClassLoader.loadClass("com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry"); - java.lang.reflect.Method getInterceptorMethod = interceptorRegistry.getMethod("getInterceptor", new java.lang.Class[]{int.class}); - java.lang.Object interceptor = getInterceptorMethod.invoke(interceptorRegistry, Integer.valueOf(1)); - - - java.lang.reflect.Method beforeMethod = interceptor.getClass().getMethod("before", java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class); - beforeMethod.invoke(interceptor, null, null, null, null, null); - - } - -} - +package com.nhn.pinpoint.profiler.javaassist; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.ProtectionDomain; + +/** + * @author emeroad + */ +public class TestBootstrapClass { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void test() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, CannotCompileException { + + Class cl = Class.forName("java.lang.ClassLoader"); + + Method defineClass1 = cl.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); + + Method defineClass2 = cl.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class, ProtectionDomain.class}); + + ClassPool cp = new ClassPool(); + cp.appendSystemPath(); + CtClass ctClass = cp.makeClass("com.test.Test"); + byte[] bytes = ctClass.toBytecode(); + + + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + logger.info(systemClassLoader.getClass().getName()); + + defineClass(defineClass1, systemClassLoader, new Object[]{"com.test.Test", bytes, 0, bytes.length}); + Class aClass = systemClassLoader.loadClass("com.test.Test"); + + logger.info("{}", aClass.getClass().getClassLoader()); + + + } + + private Object defineClass(Method method, ClassLoader loader, Object[] objects) throws InvocationTargetException, IllegalAccessException { + method.setAccessible(true); + try { + return method.invoke(loader, objects); + } finally { + method.setAccessible(false); + } + } + + + @Test + public void testJdkClassClassLoader() throws IOException { + URL url = new URL("http://www.nave.com"); + + + HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); + + logger.info(urlConnection.toString()); + logger.info("{}", urlConnection.getClass().getClassLoader()); + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + ClassLoader parent = systemClassLoader.getParent(); + logger.info("parent:{}", parent); + logger.info("pparent:{}", parent.getParent()); + + logger.info("{}", String.class.getClassLoader()); + logger.info("{}", TestBootstrapClass.class.getClassLoader()); + + + urlConnection.disconnect(); + + + } + + @Test + public void testReflection() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + java.lang.ClassLoader contextClassLoader = java.lang.Thread.currentThread().getContextClassLoader(); + java.lang.Class interceptorRegistry = contextClassLoader.loadClass("com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry"); + java.lang.reflect.Method getInterceptorMethod = interceptorRegistry.getMethod("getInterceptor", new java.lang.Class[]{int.class}); + java.lang.Object interceptor = getInterceptorMethod.invoke(interceptorRegistry, Integer.valueOf(1)); + + + java.lang.reflect.Method beforeMethod = interceptor.getClass().getMethod("before", java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class); + beforeMethod.invoke(interceptor, null, null, null, null, null); + + } + +} + diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestClass.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestClass.java index 082b64c49105..011034c46c99 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestClass.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/javaassist/TestClass.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.profiler.javaassist; - -import java.util.List; - -/** - * @author emeroad - */ -public class TestClass { - private int a; - private List b; - private String[] stringArray; - - - public int getA() { - return a; - } - - public void setA(int a) { - this.a = a; - } - - public int inlineClass(final int a) { - Comparable c = new Comparable() { - @Override - public int compareTo(Object o) { - return a; - } - }; - return c.compareTo(null); - } - - private class InnerClass { - private String str; - - public String getStr() { - return str; - } - - public void setStr(String str) { - this.str = str; - } - } - - public void setB(List b) { - this.b = b; - } - - public void setStringArray(String[] stringArray) { - this.stringArray = stringArray; - } -} +package com.nhn.pinpoint.profiler.javaassist; + +import java.util.List; + +/** + * @author emeroad + */ +public class TestClass { + private int a; + private List b; + private String[] stringArray; + + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int inlineClass(final int a) { + Comparable c = new Comparable() { + @Override + public int compareTo(Object o) { + return a; + } + }; + return c.compareTo(null); + } + + private class InnerClass { + private String str; + + public String getStr() { + return str; + } + + public void setStr(String str) { + this.str = str; + } + } + + public void setB(List b) { + this.b = b; + } + + public void setStringArray(String[] stringArray) { + this.stringArray = stringArray; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/BasePinpointTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/BasePinpointTest.java index 64f8d1969799..d2277b7cc51a 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/BasePinpointTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/BasePinpointTest.java @@ -1,26 +1,48 @@ -package com.nhn.pinpoint.profiler.junit4; - -import java.util.List; - -import org.junit.runner.RunWith; - -import com.nhn.pinpoint.bootstrap.context.ReadableStorage; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.profiler.util.TestClassLoader; - -/** - * @author hyungil.jeong - */ -@RunWith(value=PinpointJUnit4ClassRunner.class) -@PinpointTestClassLoader(TestClassLoader.class) -public abstract class BasePinpointTest { - private ThreadLocal traceHolder = new ThreadLocal(); - - protected final List getCurrentSpanEvents() { - return this.traceHolder.get().getSpanEventList(); - } - - final void setCurrentStorage(ReadableStorage spanStorage) { - traceHolder.set(spanStorage); - } -} +package com.nhn.pinpoint.profiler.junit4; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.thrift.TBase; +import org.junit.runner.RunWith; + +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.profiler.context.Span; +import com.nhn.pinpoint.profiler.context.SpanEvent; +import com.nhn.pinpoint.profiler.sender.PeekableDataSender; +import com.nhn.pinpoint.profiler.util.TestClassLoader; + +/** + * @author hyungil.jeong + */ +@RunWith(value = PinpointJUnit4ClassRunner.class) +@PinpointTestClassLoader(TestClassLoader.class) +public abstract class BasePinpointTest { + private ThreadLocal>> traceHolder = new ThreadLocal>>(); + + protected final List getCurrentSpanEvents() { + List spanEvents = new ArrayList(); + for (TBase span : this.traceHolder.get()) { + if (span instanceof SpanEvent) { + SpanEvent spanEvent = (SpanEvent)span; + spanEvents.add(new SpanEventBo(spanEvent.getSpan(), spanEvent)); + } + } + return spanEvents; + } + + protected final List getCurrentRootSpans() { + List rootSpans = new ArrayList(); + for (TBase span : this.traceHolder.get()) { + if (span instanceof Span) { + rootSpans.add(new SpanBo((Span)span)); + } + } + return rootSpans; + } + + final void setCurrentHolder(PeekableDataSender> dataSender) { + traceHolder.set(dataSender); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/IsRootSpan.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/IsRootSpan.java new file mode 100644 index 000000000000..a63829780ba2 --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/IsRootSpan.java @@ -0,0 +1,15 @@ +package com.nhn.pinpoint.profiler.junit4; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author hyungil.jeong + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface IsRootSpan { + boolean value() default true; +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointJUnit4ClassRunner.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointJUnit4ClassRunner.java index aff1cc685a9b..a156bf94bfc3 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointJUnit4ClassRunner.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointJUnit4ClassRunner.java @@ -1,178 +1,205 @@ -package com.nhn.pinpoint.profiler.junit4; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.junit.runner.notification.RunNotifier; -import org.junit.runners.BlockJUnit4ClassRunner; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.InitializationError; -import org.junit.runners.model.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.Trace; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.profiler.DummyInstrumentation; -import com.nhn.pinpoint.profiler.context.DefaultTrace; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; -import com.nhn.pinpoint.profiler.util.MockAgent; -import com.nhn.pinpoint.profiler.util.TestClassLoader; - -/** - * @author hyungil.jeong - */ -public final class PinpointJUnit4ClassRunner extends BlockJUnit4ClassRunner { - - private static final Logger logger = LoggerFactory.getLogger(PinpointJUnit4ClassRunner.class); - private static final Class defaultTestClassLoader = TestClassLoader.class; - - private final TestClassLoader testClassLoader; - private final TestContext testContext; - private final DefaultAgent testAgent; - - public PinpointJUnit4ClassRunner(Class clazz) throws InitializationError { - super(clazz); - if (logger.isDebugEnabled()) { - logger.debug("PinpointJUnit4ClassRunner constructor called with [" + clazz + "]."); - } - this.testAgent = createTestAgent(); - this.testClassLoader = getTestClassLoader(clazz); - this.testClassLoader.initialize(); - try { - this.testContext = new TestContext(this.testClassLoader, clazz); - } catch (ClassNotFoundException e) { - throw new InitializationError(e); - } - // 테스트 대상을 TestClassLoader로 로드된 테스트 객체로 바꿔치기 한다. - // JUnit Runner에서 내부적으로 getTestClass()를 호출하여 사용하는데 이게 final이어서 override 불가. - try { - // PinpointJunit4ClassRunner -> BlockJUnit4ClassRunner -> ParentRunner.fTestClass - Field testClassField = this.getClass().getSuperclass().getSuperclass().getDeclaredField("fTestClass"); - testClassField.setAccessible(true); - testClassField.set(this, this.testContext.getTestClass()); - } catch (Exception e) { - // InitializationError로 퉁치자. - throw new InitializationError(e); - } - } - - private DefaultAgent createTestAgent() throws InitializationError { - PLoggerFactory.initialize(new Slf4jLoggerBinder()); - - ProfilerConfig profilerConfig = new ProfilerConfig(); - - String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); - try { - profilerConfig.readConfigFile(path); - } catch (IOException e) { - throw new InitializationError("Unable to read pinpoint.config"); - } - - profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); - return new MockAgent("", new DummyInstrumentation(), profilerConfig); - } - - private Class findPinpointTestClassLoaderAnnotationForClass(Class testClass) { - if (testClass == null || testClass.equals(Object.class)) { - return null; - } - if (testClass.isAnnotationPresent(PinpointTestClassLoader.class)) { - return testClass; - } - return findPinpointTestClassLoaderAnnotationForClass(testClass.getSuperclass()); - } - - private TestClassLoader getTestClassLoader(Class testClass) throws InitializationError { - Class classWithPinpointTestClassLoaderAnnotationSpecified = findPinpointTestClassLoaderAnnotationForClass(testClass); - if (classWithPinpointTestClassLoaderAnnotationSpecified == null) { - if (logger.isInfoEnabled()) { - logger.info(String.format("@PinpointTestClassLoader not found for class [%s]", testClass)); - } - return createTestClassLoader(defaultTestClassLoader); - } else { - PinpointTestClassLoader pinpointTestClassLoader = classWithPinpointTestClassLoaderAnnotationSpecified.getAnnotation(PinpointTestClassLoader.class); - if (logger.isTraceEnabled()) { - logger.trace(String.format("Retrieved @PinpointTestClassLoader [%s] for class [%s]", pinpointTestClassLoader, testClass)); - } - return createTestClassLoader(pinpointTestClassLoader.value()); - } - } - - private TestClassLoader createTestClassLoader(Class testClassLoader) throws InitializationError { - try { - Constructor c = testClassLoader.getConstructor(DefaultAgent.class); - T classLoader = c.newInstance(this.testAgent); - return classLoader; - } catch (Exception e) { - // 어떤 exception이 발생하던 결국 InitializationError. - throw new InitializationError("Error instantiating Test"); - } - } - - @Override - protected void runChild(FrameworkMethod method, RunNotifier notifier) { - TraceContext traceContext = this.testAgent.getTraceContext(); - beginTracing(traceContext); - ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(this.testClassLoader); - super.runChild(method, notifier); - } finally { - Thread.currentThread().setContextClassLoader(originalClassLoader); - endTracing(traceContext); - } - } - - // TODO refine root trace parameters for test - private void beginTracing(TraceContext traceContext) { - Trace trace = traceContext.newTraceObject(); - trace.markBeforeTime(); - trace.recordServiceType(ServiceType.TEST); - } - - private void endTracing(TraceContext traceContext) { - try { - Trace trace = traceContext.currentRawTraceObject(); - try { - trace.markAfterTime(); - } finally { - trace.traceRootBlockEnd(); - } - } finally { - traceContext.detachTraceObject(); - } - } - - @Override - protected Statement methodInvoker(FrameworkMethod method, Object test) { - // TestContext의 baseTestClass는 BasePinpointTest이므로, 캐스팅해도 된다. - @SuppressWarnings("unchecked") - Class baseTestClass = (Class)this.testContext.getBaseTestClass(); - if (baseTestClass.isInstance(test)) { - DefaultTrace currentTrace = (DefaultTrace)this.testAgent.getTraceContext().currentRawTraceObject(); - Method[] methods = baseTestClass.getDeclaredMethods(); - for (Method m : methods) { - if (m.getName().equals("setCurrentStorage")) { - try { - m.setAccessible(true); - m.invoke(test, currentTrace.getStorage()); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - } - } - return super.methodInvoker(method, test); - } - -} +package com.nhn.pinpoint.profiler.junit4; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.thrift.TBase; +import org.junit.internal.runners.model.EachTestNotifier; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.context.Trace; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.DefaultAgent; +import com.nhn.pinpoint.profiler.DummyInstrumentation; +import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; +import com.nhn.pinpoint.profiler.sender.PeekableDataSender; +import com.nhn.pinpoint.profiler.util.MockAgent; +import com.nhn.pinpoint.profiler.util.TestClassLoader; + +/** + * @author hyungil.jeong + */ +public final class PinpointJUnit4ClassRunner extends BlockJUnit4ClassRunner { + + private static final Logger logger = LoggerFactory.getLogger(PinpointJUnit4ClassRunner.class); + private static final Class defaultTestClassLoader = TestClassLoader.class; + + private final TestClassLoader testClassLoader; + private final TestContext testContext; + private final DefaultAgent testAgent; + private final PeekableDataSender> testDataSender; + + public PinpointJUnit4ClassRunner(Class clazz) throws InitializationError { + super(clazz); + if (logger.isDebugEnabled()) { + logger.debug("PinpointJUnit4ClassRunner constructor called with [" + clazz + "]."); + } + MockAgent testAgent = createTestAgent(); + this.testAgent = testAgent; + this.testDataSender = testAgent.getPeekableSpanDataSender(); + this.testClassLoader = getTestClassLoader(clazz); + this.testClassLoader.initialize(); + try { + this.testContext = new TestContext(this.testClassLoader, clazz); + } catch (ClassNotFoundException e) { + throw new InitializationError(e); + } + // 테스트 대상을 TestClassLoader로 로드된 테스트 객체로 바꿔치기 한다. + // JUnit Runner에서 내부적으로 getTestClass()를 호출하여 사용하는데 이게 final이어서 override 불가. + try { + // PinpointJunit4ClassRunner -> BlockJUnit4ClassRunner -> ParentRunner.fTestClass + Field testClassField = this.getClass().getSuperclass().getSuperclass().getDeclaredField("fTestClass"); + testClassField.setAccessible(true); + testClassField.set(this, this.testContext.getTestClass()); + } catch (Exception e) { + // InitializationError로 퉁치자. + throw new InitializationError(e); + } + } + + private MockAgent createTestAgent() throws InitializationError { + PLoggerFactory.initialize(new Slf4jLoggerBinder()); + + ProfilerConfig profilerConfig = new ProfilerConfig(); + + String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); + try { + profilerConfig.readConfigFile(path); + } catch (IOException e) { + throw new InitializationError("Unable to read pinpoint.config"); + } + + profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); + return new MockAgent("", new DummyInstrumentation(), profilerConfig); + } + + private Class findPinpointTestClassLoaderAnnotationForClass(Class testClass) { + if (testClass == null || testClass.equals(Object.class)) { + return null; + } + if (testClass.isAnnotationPresent(PinpointTestClassLoader.class)) { + return testClass; + } + return findPinpointTestClassLoaderAnnotationForClass(testClass.getSuperclass()); + } + + private TestClassLoader getTestClassLoader(Class testClass) throws InitializationError { + Class classWithPinpointTestClassLoaderAnnotationSpecified = findPinpointTestClassLoaderAnnotationForClass(testClass); + if (classWithPinpointTestClassLoaderAnnotationSpecified == null) { + if (logger.isInfoEnabled()) { + logger.info(String.format("@PinpointTestClassLoader not found for class [%s]", testClass)); + } + return createTestClassLoader(defaultTestClassLoader); + } else { + PinpointTestClassLoader pinpointTestClassLoader = classWithPinpointTestClassLoaderAnnotationSpecified.getAnnotation(PinpointTestClassLoader.class); + if (logger.isTraceEnabled()) { + logger.trace(String.format("Retrieved @PinpointTestClassLoader [%s] for class [%s]", pinpointTestClassLoader, testClass)); + } + return createTestClassLoader(pinpointTestClassLoader.value()); + } + } + + private TestClassLoader createTestClassLoader(Class testClassLoader) throws InitializationError { + try { + Constructor c = testClassLoader.getConstructor(DefaultAgent.class); + T classLoader = c.newInstance(this.testAgent); + return classLoader; + } catch (Exception e) { + // 어떤 exception이 발생하던 결국 InitializationError. + throw new InitializationError("Error instantiating Test"); + } + } + + @Override + protected void runChild(FrameworkMethod method, RunNotifier notifier) { + beginTracing(method); + final Thread thread = Thread.currentThread(); + final ClassLoader originalClassLoader = thread.getContextClassLoader(); + try { + thread.setContextClassLoader(this.testClassLoader); + super.runChild(method, notifier); + } finally { + thread.setContextClassLoader(originalClassLoader); + endTracing(method, notifier); + } + } + + private void beginTracing(FrameworkMethod method) { + if (shouldCreateNewTraceObject(method)) { + TraceContext traceContext = this.testAgent.getTraceContext(); + Trace trace = traceContext.newTraceObject(); + trace.markBeforeTime(); + trace.recordServiceType(ServiceType.TEST); + } + } + + private void endTracing(FrameworkMethod method, RunNotifier notifier) { + if (shouldCreateNewTraceObject(method)) { + TraceContext traceContext = this.testAgent.getTraceContext(); + try { + Trace trace = traceContext.currentRawTraceObject(); + if (trace == null) { + // Trace is already detached from the ThreadLocal storage. + // Happens when root trace method is tested without @IsRootSpan. + EachTestNotifier testMethodNotifier = new EachTestNotifier(notifier, super.describeChild(method)); + String traceObjectAlreadyDetachedMessage = "Trace object already detached. If you're testing a trace root, please add @IsRootSpan to the test method"; + testMethodNotifier.addFailure(new IllegalStateException(traceObjectAlreadyDetachedMessage)); + } else { + try { + trace.markAfterTime(); + } finally { + trace.traceRootBlockEnd(); + } + } + } finally { + traceContext.detachTraceObject(); + } + } + } + + private boolean shouldCreateNewTraceObject(FrameworkMethod method) { + IsRootSpan isRootSpan = method.getAnnotation(IsRootSpan.class); + if (isRootSpan == null || !isRootSpan.value()) { + return true; + } + return false; + } + + @Override + protected Statement methodInvoker(FrameworkMethod method, Object test) { + // TestContext의 baseTestClass는 BasePinpointTest이므로, 캐스팅해도 된다. + @SuppressWarnings("unchecked") + Class baseTestClass = (Class)this.testContext.getBaseTestClass(); + if (baseTestClass.isInstance(test)) { + Method[] methods = baseTestClass.getDeclaredMethods(); + for (Method m : methods) { + if (m.getName().equals("setCurrentHolder")) { + try { + // 각 테스트 메소드 마다 PeekableDataSender를 reset 함. + this.testDataSender.clear(); + m.setAccessible(true); + m.invoke(test, this.testDataSender); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + } + return super.methodInvoker(method, test); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointTestClassLoader.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointTestClassLoader.java index 722985af1315..ebc27a2a1834 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointTestClassLoader.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/PinpointTestClassLoader.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.profiler.junit4; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.nhn.pinpoint.profiler.util.TestClassLoader; - -/** - * - * @author Hyun Jeong - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface PinpointTestClassLoader { - - Class loader() default TestClassLoader.class; - - Class value() default TestClassLoader.class; - -} +package com.nhn.pinpoint.profiler.junit4; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.nhn.pinpoint.profiler.util.TestClassLoader; + +/** + * + * @author Hyun Jeong + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface PinpointTestClassLoader { + + Class loader() default TestClassLoader.class; + + Class value() default TestClassLoader.class; + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/TestContext.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/TestContext.java index d2aca7559fb8..74404ae94b86 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/TestContext.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/junit4/TestContext.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.profiler.junit4; - -import org.junit.runners.model.TestClass; - -import com.nhn.pinpoint.profiler.util.TestClassLoader; - -/** - * @author hyungil.jeong - */ -public class TestContext { - - private final TestClass testClass; - private final Object baseTestClass; - - TestContext(final T testClassLoader, Class clazz) throws ClassNotFoundException { - this.testClass = new TestClass(testClassLoader.loadClass(clazz.getName())); - this.baseTestClass = testClassLoader.loadClass(BasePinpointTest.class.getName()); - } - - public TestClass getTestClass() { - return this.testClass; - } - - public Object getBaseTestClass() { - return this.baseTestClass; - } -} +package com.nhn.pinpoint.profiler.junit4; + +import org.junit.runners.model.TestClass; + +import com.nhn.pinpoint.profiler.util.TestClassLoader; + +/** + * @author hyungil.jeong + */ +public class TestContext { + + private final TestClass testClass; + private final Object baseTestClass; + + TestContext(final T testClassLoader, Class clazz) throws ClassNotFoundException { + this.testClass = new TestClass(testClassLoader.loadClass(clazz.getName())); + this.baseTestClass = testClassLoader.loadClass(BasePinpointTest.class.getName()); + } + + public TestClass getTestClass() { + return this.testClass; + } + + public Object getBaseTestClass() { + return this.baseTestClass; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/logger/JdkLoggerTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/logger/JdkLoggerTest.java index 5fa700c0a906..c45cc89fc884 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/logger/JdkLoggerTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/logger/JdkLoggerTest.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.profiler.logger; - -import org.junit.Test; - -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author emeroad - */ -public class JdkLoggerTest { - @Test - public void test() { - Logger logger = Logger.getLogger(this.getClass().getName()); - - logger.info("tset"); - // format은 역시 안되네. - logger.log(Level.INFO, "Test %s", "sdfsdf"); - - logger.log(Level.INFO, "Test ", new Exception()); - - logger.logp(Level.INFO, JdkLoggerTest.class.getName(), "test()", "tsdd"); - - // logging.properties 에 fine으로 되어 있으므로 출력안되야 됨. - logger.finest("로그가 나오는지?"); - - } -} +package com.nhn.pinpoint.profiler.logger; + +import org.junit.Test; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author emeroad + */ +public class JdkLoggerTest { + @Test + public void test() { + Logger logger = Logger.getLogger(this.getClass().getName()); + + logger.info("tset"); + // format은 역시 안되네. + logger.log(Level.INFO, "Test %s", "sdfsdf"); + + logger.log(Level.INFO, "Test ", new Exception()); + + logger.logp(Level.INFO, JdkLoggerTest.class.getName(), "test()", "tsdd"); + + // logging.properties 에 fine으로 되어 있으므로 출력안되야 됨. + logger.finest("로그가 나오는지?"); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/AgentIdentifierCompareTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/AgentIdentifierCompareTest.java index 7193733a0334..c540c215df7a 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/AgentIdentifierCompareTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/AgentIdentifierCompareTest.java @@ -1,32 +1,36 @@ -package com.nhn.pinpoint.profiler.metadata; - -import org.junit.Test; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * @author emeroad - */ -public class AgentIdentifierCompareTest { - @Test - public void test() { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - long l = System.currentTimeMillis(); - Date date = new Date(l); - System.out.println(simpleDateFormat.format(date)); - - int max = Integer.MAX_VALUE; - Date maxAfter = new Date(l+max); - System.out.println(simpleDateFormat.format(maxAfter)); -// Agent의 identifer대신에 서버시작시간 - 실행시간을 구해서 int type으로 전달하는건 좋은 생각아 아님 -// int max를 더하더라도 최대 한달 정도가 한계임, unsigned type으로 해도 두달 그냥 사이즈 빼서 가변 인코딩 long으로 보내야 함. -// 2013-05-25 15:39:09 -// 2013-04-30 19:07:45 - - - - - } -} +package com.nhn.pinpoint.profiler.metadata; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author emeroad + */ +public class AgentIdentifierCompareTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void test() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + long l = System.currentTimeMillis(); + Date date = new Date(l); + logger.debug(simpleDateFormat.format(date)); + + int max = Integer.MAX_VALUE; + Date maxAfter = new Date(l+max); + logger.debug(simpleDateFormat.format(maxAfter)); +// Agent의 identifer대신에 서버시작시간 - 실행시간을 구해서 int type으로 전달하는건 좋은 생각아 아님 +// int max를 더하더라도 최대 한달 정도가 한계임, unsigned type으로 해도 두달 그냥 사이즈 빼서 가변 인코딩 long으로 보내야 함. +// 2013-05-25 15:39:09 +// 2013-04-30 19:07:45 + + + + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/LRUCacheTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/LRUCacheTest.java index 1f1aed0b868a..c694a6ab6774 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/LRUCacheTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/LRUCacheTest.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.profiler.metadata; - -import junit.framework.Assert; -import org.junit.Test; - -import java.util.Random; - -/** - * @author emeroad - */ -public class LRUCacheTest { - @Test - public void testPut() throws Exception { - long cacheSize = 100; - LRUCache cache = new LRUCache((int) cacheSize); - Random random = new Random(); - for (int i = 0; i < 1000; i++) { - cache.put(String.valueOf(random.nextInt(100000))); - } - - long size = cache.getSize(); - Assert.assertEquals(size, cacheSize); - - } - - @Test - public void testGetSize() throws Exception { - LRUCache cache = new LRUCache(2); - Assert.assertEquals(cache.getSize(), 0); - - String sqlObject = "test"; - - boolean hit = cache.put(sqlObject); - Assert.assertTrue(hit); - Assert.assertEquals(cache.getSize(), 1); - - boolean hit2 = cache.put(sqlObject); - Assert.assertFalse(hit2); - Assert.assertEquals(cache.getSize(), 1); -// "23 123"; -// "DCArMlhwQO 7" - cache.put("23 123"); - cache.put("DCArMlhwQO 7"); - cache.put("3"); - cache.put("4"); - Assert.assertEquals(cache.getSize(), 2); - - - } -} +package com.nhn.pinpoint.profiler.metadata; + +import junit.framework.Assert; +import org.junit.Test; + +import java.util.Random; + +/** + * @author emeroad + */ +public class LRUCacheTest { + @Test + public void testPut() throws Exception { + long cacheSize = 100; + LRUCache cache = new LRUCache((int) cacheSize); + Random random = new Random(); + for (int i = 0; i < 1000; i++) { + cache.put(String.valueOf(random.nextInt(100000))); + } + + long size = cache.getSize(); + Assert.assertEquals(size, cacheSize); + + } + + @Test + public void testGetSize() throws Exception { + LRUCache cache = new LRUCache(2); + Assert.assertEquals(cache.getSize(), 0); + + String sqlObject = "test"; + + boolean hit = cache.put(sqlObject); + Assert.assertTrue(hit); + Assert.assertEquals(cache.getSize(), 1); + + boolean hit2 = cache.put(sqlObject); + Assert.assertFalse(hit2); + Assert.assertEquals(cache.getSize(), 1); +// "23 123"; +// "DCArMlhwQO 7" + cache.put("23 123"); + cache.put("DCArMlhwQO 7"); + cache.put("3"); + cache.put("4"); + Assert.assertEquals(cache.getSize(), 2); + + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/SimpleCacheTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/SimpleCacheTest.java index 0dc29bb42298..bdffc7b3f50b 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/SimpleCacheTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/metadata/SimpleCacheTest.java @@ -1,42 +1,42 @@ -package com.nhn.pinpoint.profiler.metadata; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class SimpleCacheTest { - - - @Test - public void startKey0() { - SimpleCache cache = new SimpleCache(1024, 0); - Result test = cache.put("test"); - Assert.assertEquals(0, test.getId()); - } - - @Test - public void startKey1() { - SimpleCache cache = new SimpleCache(1); - Result test = cache.put("test"); - Assert.assertEquals(-1, test.getId()); - } - - @Test - public void put() { - SimpleCache cache = new SimpleCache(); - Result test = cache.put("test"); - Assert.assertEquals(-1, test.getId()); - Assert.assertTrue(test.isNewValue()); - - Result recheck = cache.put("test"); - Assert.assertEquals(test.getId(), recheck.getId()); - Assert.assertFalse(recheck.isNewValue()); - - Result newValue = cache.put("new"); - Assert.assertEquals(1, newValue.getId()); - Assert.assertTrue(newValue.isNewValue()); - - } -} +package com.nhn.pinpoint.profiler.metadata; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class SimpleCacheTest { + + + @Test + public void startKey0() { + SimpleCache cache = new SimpleCache(1024, 0); + Result test = cache.put("test"); + Assert.assertEquals(0, test.getId()); + } + + @Test + public void startKey1() { + SimpleCache cache = new SimpleCache(1); + Result test = cache.put("test"); + Assert.assertEquals(-1, test.getId()); + } + + @Test + public void put() { + SimpleCache cache = new SimpleCache(); + Result test = cache.put("test"); + Assert.assertEquals(-1, test.getId()); + Assert.assertTrue(test.isNewValue()); + + Result recheck = cache.put("test"); + Assert.assertEquals(test.getId(), recheck.getId()); + Assert.assertFalse(recheck.isNewValue()); + + Result newValue = cache.put("new"); + Assert.assertEquals(1, newValue.getId()); + Assert.assertTrue(newValue.isNewValue()); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifierIntegrationTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifierIntegrationTest.java index ad37451befd8..8ced6c675a67 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifierIntegrationTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/FrontCacheGetFutureModifierIntegrationTest.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.profiler.modifier.arcus; - -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; -import net.spy.memcached.ArcusClient; -import net.spy.memcached.ConnectionFactoryBuilder; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.MockitoAnnotations; - -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -/** - * @author harebox - */ -public class FrontCacheGetFutureModifierIntegrationTest extends BasePinpointTest { - - @Before - public void setUp() throws Exception { -// MockitoAnnotations.initMocks(this); - } - - @Test - @Ignore - // FIXME 테스트 깨짐 - public void frontCacheShouldBeTraced() throws Exception { - // given: front-cache-enabled ArcusClient - ConnectionFactoryBuilder cfb = new ConnectionFactoryBuilder(); - cfb.setMaxFrontCacheElements(100); - cfb.setFrontCacheExpireTime(100); - ArcusClient client = ArcusClient.createArcusClient("dev.arcuscloud.nhncorp.com:17288", "dev1.6", cfb); - - // when - try { - client.set("hello", 0, "world"); - client.asyncGet("hello").get(); - client.asyncGet("hello").get(); - } catch (Exception e) { - e.printStackTrace(); - fail(); - } finally { - client.shutdown(); - } - - // then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(5)); - - final SpanEventBo getFutureSpan = spanEvents.get(2); - final SpanEventBo frontCacheGetFutureSpan = spanEvents.get(4); - - assertNotNull(getFutureSpan.getEndPoint()); - assertNull(frontCacheGetFutureSpan.getEndPoint()); - assertThat(frontCacheGetFutureSpan.getDestinationId(), is("front")); - } -} +package com.nhn.pinpoint.profiler.modifier.arcus; + +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; +import net.spy.memcached.ArcusClient; +import net.spy.memcached.ConnectionFactoryBuilder; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.MockitoAnnotations; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +/** + * @author harebox + */ +public class FrontCacheGetFutureModifierIntegrationTest extends BasePinpointTest { + + @Before + public void setUp() throws Exception { +// MockitoAnnotations.initMocks(this); + } + + @Test + @Ignore + // FIXME 테스트 깨짐 + public void frontCacheShouldBeTraced() throws Exception { + // given: front-cache-enabled ArcusClient + ConnectionFactoryBuilder cfb = new ConnectionFactoryBuilder(); + cfb.setMaxFrontCacheElements(100); + cfb.setFrontCacheExpireTime(100); + ArcusClient client = ArcusClient.createArcusClient("dev.arcuscloud.nhncorp.com:17288", "dev1.6", cfb); + + // when + try { + client.set("hello", 0, "world"); + client.asyncGet("hello").get(); + client.asyncGet("hello").get(); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } finally { + client.shutdown(); + } + + // then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(5)); + + final SpanEventBo getFutureSpan = spanEvents.get(2); + final SpanEventBo frontCacheGetFutureSpan = spanEvents.get(4); + + assertNotNull(getFutureSpan.getEndPoint()); + assertNull(frontCacheGetFutureSpan.getEndPoint()); + assertThat(frontCacheGetFutureSpan.getDestinationId(), is("front")); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java index d922f3287c8f..5c42fc744699 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; - -import junit.framework.Assert; -import net.spy.memcached.ops.OperationState; -import org.junit.Test; - -public class BaseOperationTransitionStateInterceptorTest { - - @Test - public void testComplete() throws Exception { - // 타입비교를 Arcus의 경우 TIMEDOUT state가 별도로 추가되어 정적 타입비교를 할수 있는 상황이 아님. - // toString()을 호출하여, 문자열 비교를 해야 함. - String complete = OperationState.COMPLETE.toString(); - Assert.assertEquals("COMPLETE", complete); - } - - @Test - public void existArcusTimeoutState() throws Exception { - // 클래스가 강제 로딩되서 다른 test에 영향을 줄수 있음. - if (!isArcusExist()) { - // arcus만의 state체크를 위한 것이므로 없으면 패스한다. - return; - } - // Arcus OperationState.timedout에 변경이 있는지 체크한다. - OperationState[] values = OperationState.values(); - for (OperationState value : values) { - if (value.toString().equals("TIMEDOUT")) { - return; - } - } - - Assert.fail("OperationState.TIMEDOUT state not found"); - } - - private boolean isArcusExist() { - try { - Class.forName("net.spy.memcached.ArcusClient"); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } -} +package com.nhn.pinpoint.profiler.modifier.arcus.interceptor; + +import junit.framework.Assert; +import net.spy.memcached.ops.OperationState; +import org.junit.Test; + +public class BaseOperationTransitionStateInterceptorTest { + + @Test + public void testComplete() throws Exception { + // 타입비교를 Arcus의 경우 TIMEDOUT state가 별도로 추가되어 정적 타입비교를 할수 있는 상황이 아님. + // toString()을 호출하여, 문자열 비교를 해야 함. + String complete = OperationState.COMPLETE.toString(); + Assert.assertEquals("COMPLETE", complete); + } + + @Test + public void existArcusTimeoutState() throws Exception { + // 클래스가 강제 로딩되서 다른 test에 영향을 줄수 있음. + if (!isArcusExist()) { + // arcus만의 state체크를 위한 것이므로 없으면 패스한다. + return; + } + // Arcus OperationState.timedout에 변경이 있는지 체크한다. + OperationState[] values = OperationState.values(); + for (OperationState value : values) { + if (value.toString().equals("TIMEDOUT")) { + return; + } + } + + Assert.fail("OperationState.TIMEDOUT state not found"); + } + + private boolean isArcusExist() { + try { + Class.forName("net.spy.memcached.ArcusClient"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParserTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParserTest.java index b0a92bb14941..fd7d09cc9429 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParserTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/JDBCUrlParserTest.java @@ -1,166 +1,166 @@ -package com.nhn.pinpoint.profiler.modifier.db; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.URI; - -/** - * @author emeroad - */ -public class JDBCUrlParserTest { - - private Logger logger = LoggerFactory.getLogger(JDBCUrlParserTest.class); - private JDBCUrlParser jdbcUrlParser = new JDBCUrlParser(); - - @Test - public void testURIParse() throws Exception { - - URI uri = URI.create("jdbc:mysql:replication://10.98.133.22:3306/test_lucy_db"); - logger.debug(uri.toString()); - logger.debug(uri.getScheme()); - - // URI로 파싱하는건 제한적임 한계가 있음. - try { - URI oracleRac = URI.create("jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" + - "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + - "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))" + - "(CONNECT_DATA=(SERVICE_NAME=service)))"); - - logger.debug(oracleRac.toString()); - logger.debug(oracleRac.getScheme()); - Assert.fail(); - } catch (Exception e) { - } - } - - @Test - public void mysqlParse1() { - - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://ip_address:3306/database_name?useUnicode=yes&characterEncoding=UTF-8"); - Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); - Assert.assertEquals(dbInfo.getHost().get(0), ("ip_address:3306")); - Assert.assertEquals(dbInfo.getDatabaseId(), "database_name"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://ip_address:3306/database_name"); - } - - @Test - public void mysqlParse2() { - - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://10.98.133.22:3306/test_lucy_db"); - Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); - Assert.assertEquals(dbInfo.getHost().get(0), "10.98.133.22:3306"); - - Assert.assertEquals(dbInfo.getDatabaseId(), "test_lucy_db"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://10.98.133.22:3306/test_lucy_db"); - logger.info(dbInfo.toString()); - logger.info(dbInfo.getMultipleHost()); - } - - @Test - public void mysqlParse3() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://61.74.71.31/log?useUnicode=yes&characterEncoding=UTF-8"); - Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); - Assert.assertEquals(dbInfo.getHost().get(0), "61.74.71.31"); - Assert.assertEquals(dbInfo.getDatabaseId(), "log"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://61.74.71.31/log"); - logger.info(dbInfo.toString()); - } - - @Test - public void mysqlParseCookierunMaster() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://10.115.8.209:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-COMMITTED'"); - Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); - Assert.assertEquals(dbInfo.getHost().get(0), "10.115.8.209:5605"); - Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://10.115.8.209:5605/db_cookierun"); - logger.info(dbInfo.toString()); - } - - - @Test - public void mysqlParseCookierunSlave() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql:loadbalance://10.118.222.35:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); - Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); - Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); - Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql:loadbalance://10.118.222.35:5605/db_cookierun"); - logger.info(dbInfo.toString()); - } - - @Test - public void mysqlParseCookierunSlave2() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); - Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); - Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); - Assert.assertEquals(dbInfo.getHost().get(1), "10.118.222.36:5605"); - Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun"); - logger.info(dbInfo.toString()); - } - - - - @Test - public void oracleParser1() { - // jdbc:oracle:thin:@hostname:port:SID -// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:@hostname:port:SID"); - Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); - Assert.assertEquals(dbInfo.getHost().get(0), "hostname:port"); - Assert.assertEquals(dbInfo.getDatabaseId(), "SID"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:oracle:thin:@hostname:port:SID"); - logger.info(dbInfo.toString()); - } - - @Test - public void oracleParser2() { - // jdbc:oracle:thin:@hostname:port:SID -// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"); - Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); - Assert.assertEquals(dbInfo.getHost().get(0), "localhost:1521"); - Assert.assertEquals(dbInfo.getDatabaseId(), "XE"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"); - logger.info(dbInfo.toString()); - } - - @Test - public void oracleParserServiceName() { - // jdbc:oracle:thin:@hostname:port:SID -// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:@hostname:port/serviceName"); - Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); - Assert.assertEquals(dbInfo.getHost().get(0), "hostname:port"); - Assert.assertEquals(dbInfo.getDatabaseId(), "serviceName"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:oracle:thin:@hostname:port/serviceName"); - logger.info(dbInfo.toString()); - } - - @Test - public void oracleRacParser1() { -// "jdbc:oracle:thin:@(Description1=(LOAD_BALANCE=on)" + -// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + -// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))" + -// "(CONNECT_DATA=(SERVICE_NAME=service)))" - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" + - "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + - "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1522))" + - "(CONNECT_DATA=(SERVICE_NAME=service)))"; - DatabaseInfo dbInfo = jdbcUrlParser.parse(rac); - Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); - Assert.assertEquals(dbInfo.getHost().get(0), "1.2.3.4:1521"); - Assert.assertEquals(dbInfo.getHost().get(1), "1.2.3.5:1522"); - - Assert.assertEquals(dbInfo.getDatabaseId(), "service"); - Assert.assertEquals(dbInfo.getUrl(), rac); - logger.info(dbInfo.toString()); - } - - - -} +package com.nhn.pinpoint.profiler.modifier.db; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URI; + +/** + * @author emeroad + */ +public class JDBCUrlParserTest { + + private Logger logger = LoggerFactory.getLogger(JDBCUrlParserTest.class); + private JDBCUrlParser jdbcUrlParser = new JDBCUrlParser(); + + @Test + public void testURIParse() throws Exception { + + URI uri = URI.create("jdbc:mysql:replication://10.98.133.22:3306/test_lucy_db"); + logger.debug(uri.toString()); + logger.debug(uri.getScheme()); + + // URI로 파싱하는건 제한적임 한계가 있음. + try { + URI oracleRac = URI.create("jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" + + "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + + "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))" + + "(CONNECT_DATA=(SERVICE_NAME=service)))"); + + logger.debug(oracleRac.toString()); + logger.debug(oracleRac.getScheme()); + Assert.fail(); + } catch (Exception e) { + } + } + + @Test + public void mysqlParse1() { + + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://ip_address:3306/database_name?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); + Assert.assertEquals(dbInfo.getHost().get(0), ("ip_address:3306")); + Assert.assertEquals(dbInfo.getDatabaseId(), "database_name"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://ip_address:3306/database_name"); + } + + @Test + public void mysqlParse2() { + + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://10.98.133.22:3306/test_lucy_db"); + Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); + Assert.assertEquals(dbInfo.getHost().get(0), "10.98.133.22:3306"); + + Assert.assertEquals(dbInfo.getDatabaseId(), "test_lucy_db"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://10.98.133.22:3306/test_lucy_db"); + logger.info(dbInfo.toString()); + logger.info(dbInfo.getMultipleHost()); + } + + @Test + public void mysqlParse3() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://61.74.71.31/log?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); + Assert.assertEquals(dbInfo.getHost().get(0), "61.74.71.31"); + Assert.assertEquals(dbInfo.getDatabaseId(), "log"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://61.74.71.31/log"); + logger.info(dbInfo.toString()); + } + + @Test + public void mysqlParseCookierunMaster() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://10.115.8.209:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-COMMITTED'"); + Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); + Assert.assertEquals(dbInfo.getHost().get(0), "10.115.8.209:5605"); + Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql://10.115.8.209:5605/db_cookierun"); + logger.info(dbInfo.toString()); + } + + + @Test + public void mysqlParseCookierunSlave() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql:loadbalance://10.118.222.35:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); + Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); + Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql:loadbalance://10.118.222.35:5605/db_cookierun"); + logger.info(dbInfo.toString()); + } + + @Test + public void mysqlParseCookierunSlave2() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertEquals(dbInfo.getType(), ServiceType.MYSQL); + Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); + Assert.assertEquals(dbInfo.getHost().get(1), "10.118.222.36:5605"); + Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun"); + logger.info(dbInfo.toString()); + } + + + + @Test + public void oracleParser1() { + // jdbc:oracle:thin:@hostname:port:SID +// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:@hostname:port:SID"); + Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); + Assert.assertEquals(dbInfo.getHost().get(0), "hostname:port"); + Assert.assertEquals(dbInfo.getDatabaseId(), "SID"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:oracle:thin:@hostname:port:SID"); + logger.info(dbInfo.toString()); + } + + @Test + public void oracleParser2() { + // jdbc:oracle:thin:@hostname:port:SID +// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"); + Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); + Assert.assertEquals(dbInfo.getHost().get(0), "localhost:1521"); + Assert.assertEquals(dbInfo.getDatabaseId(), "XE"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"); + logger.info(dbInfo.toString()); + } + + @Test + public void oracleParserServiceName() { + // jdbc:oracle:thin:@hostname:port:SID +// "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:@hostname:port/serviceName"); + Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); + Assert.assertEquals(dbInfo.getHost().get(0), "hostname:port"); + Assert.assertEquals(dbInfo.getDatabaseId(), "serviceName"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:oracle:thin:@hostname:port/serviceName"); + logger.info(dbInfo.toString()); + } + + @Test + public void oracleRacParser1() { +// "jdbc:oracle:thin:@(Description1=(LOAD_BALANCE=on)" + +// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + +// "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))" + +// "(CONNECT_DATA=(SERVICE_NAME=service)))" + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" + + "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + + "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1522))" + + "(CONNECT_DATA=(SERVICE_NAME=service)))"; + DatabaseInfo dbInfo = jdbcUrlParser.parse(rac); + Assert.assertEquals(dbInfo.getType(), ServiceType.ORACLE); + Assert.assertEquals(dbInfo.getHost().get(0), "1.2.3.4:1521"); + Assert.assertEquals(dbInfo.getHost().get(1), "1.2.3.5:1522"); + + Assert.assertEquals(dbInfo.getDatabaseId(), "service"); + Assert.assertEquals(dbInfo.getUrl(), rac); + logger.info(dbInfo.toString()); + } + + + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParserTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParserTest.java index 672854ecad55..6ad8b0333d16 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParserTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionStringParserTest.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.profiler.modifier.db.cubrid; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class CubridConnectionStringParserTest { - - private final ConnectionStringParser parser = new CubridConnectionStringParser(); - @Test - public void testParse() { - String cubrid = "jdbc:cubrid:10.99.196.126:34001:nrdwapw:::?charset=utf-8:"; - - DatabaseInfo dbInfo = parser.parse(cubrid); - - Assert.assertEquals(dbInfo.getType(), ServiceType.CUBRID); - Assert.assertEquals(dbInfo.getHost().get(0), "10.99.196.126:34001"); - Assert.assertEquals(dbInfo.getDatabaseId(), "nrdwapw"); - Assert.assertEquals(dbInfo.getUrl(), "jdbc:cubrid:10.99.196.126:34001:nrdwapw:::"); - } - - @Test - public void testNullParse() { - - DatabaseInfo dbInfo = parser.parse(null); - - Assert.assertEquals(dbInfo.getType(), ServiceType.CUBRID); - Assert.assertEquals(dbInfo.getHost().get(0), "error"); - Assert.assertEquals(dbInfo.getDatabaseId(), "error"); - Assert.assertEquals(dbInfo.getUrl(), null); - -// Assert.assertEquals(dbInfo.getUrl(), cubrid); - } -} +package com.nhn.pinpoint.profiler.modifier.db.cubrid; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class CubridConnectionStringParserTest { + + private final ConnectionStringParser parser = new CubridConnectionStringParser(); + @Test + public void testParse() { + String cubrid = "jdbc:cubrid:10.99.196.126:34001:nrdwapw:::?charset=utf-8:"; + + DatabaseInfo dbInfo = parser.parse(cubrid); + + Assert.assertEquals(dbInfo.getType(), ServiceType.CUBRID); + Assert.assertEquals(dbInfo.getHost().get(0), "10.99.196.126:34001"); + Assert.assertEquals(dbInfo.getDatabaseId(), "nrdwapw"); + Assert.assertEquals(dbInfo.getUrl(), "jdbc:cubrid:10.99.196.126:34001:nrdwapw:::"); + } + + @Test + public void testNullParse() { + + DatabaseInfo dbInfo = parser.parse(null); + + Assert.assertEquals(dbInfo.getType(), ServiceType.CUBRID); + Assert.assertEquals(dbInfo.getHost().get(0), "error"); + Assert.assertEquals(dbInfo.getDatabaseId(), "error"); + Assert.assertEquals(dbInfo.getUrl(), null); + +// Assert.assertEquals(dbInfo.getUrl(), cubrid); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionTest.java index 64d6377a2d48..1e1f7507ceac 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/cubrid/CubridConnectionTest.java @@ -1,208 +1,183 @@ -package com.nhn.pinpoint.profiler.modifier.db.cubrid; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; -import com.nhn.pinpoint.profiler.util.MockAgent; -import com.nhn.pinpoint.profiler.util.TestClassLoader; -import cubrid.jdbc.driver.CUBRIDDriver; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.sql.*; -import java.util.Properties; - -/** - * @author emeroad - */ -public class CubridConnectionTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private TestClassLoader loader; - - @Test - public void executeQueryAndexecuteUpdate() throws SQLException { - CUBRIDDriver driver = new CUBRIDDriver(); - Properties properties = new Properties(); - properties.setProperty("user", "dba"); - properties.setProperty("password", "nhn!@#123"); - Connection connect = driver.connect("jdbc:cubrid:10.101.57.233:30102:pinpoint:::", properties); - - PreparedStatement preparedStatement = connect.prepareStatement("select 1 from db_root where 1=?"); - preparedStatement.setInt(1, 1); - ResultSet resultSet = preparedStatement.executeQuery(); - if (resultSet.next()) { - System.out.println("---" + resultSet.getObject(1)); - } - } - - @Before - public void setUp() throws Exception { - PLoggerFactory.initialize(new Slf4jLoggerBinder()); - - ProfilerConfig profilerConfig = new ProfilerConfig(); - // profiler config를 setter를 열어두는것도 괜찮을듯 하다. - String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); - profilerConfig.readConfigFile(path); - - profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); - DefaultAgent agent = new MockAgent("", profilerConfig); - loader = new TestClassLoader(agent); - // agent가 로드한 모든 Modifier를 자동으로 찾도록 변경함. - - - loader.initialize(); - } - - @Test - public void testModify() throws Exception { - - Driver driver = loadClass(); - - Properties properties = new Properties(); - properties.setProperty("user", "dba"); - properties.setProperty("password", "nhn!@#123"); - Connection connection = driver.connect("jdbc:cubrid:10.101.57.233:30102:pinpoint:::", properties); - - logger.info("Connection class name:{}", connection.getClass().getName()); - logger.info("Connection class cl:{}", connection.getClass().getClassLoader()); - - DatabaseInfo url = ((DatabaseInfoTraceValue)connection).__getTraceDatabaseInfo(); - Assert.assertNotNull(url); - - statement(connection); - - preparedStatement(connection); - - preparedStatement2(connection); - - preparedStatement3(connection); - - preparedStatement4(connection); - - preparedStatement5(connection); - - preparedStatement6(connection); - - preparedStatement7(connection); - - preparedStatement8(connection); - - - connection.close(); - DatabaseInfo clearUrl = ((DatabaseInfoTraceValue)connection).__getTraceDatabaseInfo(); - Assert.assertNull(clearUrl); - - } - - private Driver loadClass() throws ClassNotFoundException, InstantiationException, IllegalAccessException { - Class driverClazz = (Class) loader.loadClass("cubrid.jdbc.driver.CUBRIDDriver"); - - Driver driver = driverClazz.newInstance(); - logger.info("Driver class name:{}", driverClazz.getName()); - logger.info("Driver class cl:{}", driverClazz.getClassLoader()); - - - Class version = loader.loadClass("com.nhn.pinpoint.common.Version"); - Assert.assertSame("check classLoader", this.getClass().getClassLoader(), version.getClassLoader()); - logger.debug("common cl:{}", version.getClassLoader()); - return driver; - } - - - private void statement(Connection connection) throws SQLException { - Statement statement = connection.createStatement(); - statement.executeQuery("select 1"); - statement.close(); - } - - private void preparedStatement(Connection connection) throws SQLException { - PreparedStatement preparedStatement = connection.prepareStatement("select 1"); - logger.info("PreparedStatement className:" + preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - - private void preparedStatement2(Connection connection) throws SQLException { - PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ?"); - preparedStatement.setInt(1, 1); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement3(Connection connection) throws SQLException { - connection.setAutoCommit(false); - - PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ? or id = ? or id = ?"); - preparedStatement.setInt(1, 1); - preparedStatement.setInt(2, 2); - preparedStatement.setString(3, "3"); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - - connection.commit(); - - - connection.setAutoCommit(true); - } - - private void preparedStatement4(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - PreparedStatement preparedStatement = connection.prepareStatement("select 1", Statement.RETURN_GENERATED_KEYS); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement5(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - PreparedStatement preparedStatement = connection.prepareStatement("select 1", new String[]{"test"}); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement6(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - int[] columnIndex = {1,2,3}; - PreparedStatement preparedStatement = connection.prepareStatement("select 1", columnIndex); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement7(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement8(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS -// ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT - PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - -} +package com.nhn.pinpoint.profiler.modifier.db.cubrid; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; + +import com.nhn.pinpoint.common.util.PropertyUtils; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; + +import cubrid.jdbc.driver.CUBRIDDriver; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.Properties; + +/** + * @author emeroad + */ +public class CubridConnectionTest extends BasePinpointTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static Properties db; + + @BeforeClass + public static void beforeClass() throws Exception { + db = PropertyUtils.loadPropertyFromClassPath("database.properties"); + } + + @Test + public void executeQueryAndExecuteUpdate() throws SQLException { + Connection connection = connectDB(); + + PreparedStatement preparedStatement = connection.prepareStatement("select 1 from db_root where 1=?"); + preparedStatement.setInt(1, 1); + ResultSet resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + logger.debug("---{}", resultSet.getObject(1)); + } + connection.close(); + } + + private Connection connectDB() throws SQLException { + String url = db.getProperty("cubrid.url"); + String user = db.getProperty("cubrid.user"); + String password = db.getProperty("cubrid.password"); + + Driver driver = new CUBRIDDriver(); + Properties properties = new Properties(); + properties.setProperty("user", user); + properties.setProperty("password", password); + return driver.connect(url, properties); + } + + + @Test + public void testModify() throws Exception { + + Connection connection = connectDB(); + + logger.info("Connection class name:{}", connection.getClass().getName()); + logger.info("Connection class cl:{}", connection.getClass().getClassLoader()); + + DatabaseInfo url = ((DatabaseInfoTraceValue) connection).__getTraceDatabaseInfo(); + Assert.assertNotNull(url); + + statement(connection); + + preparedStatement(connection); + + preparedStatement2(connection); + + preparedStatement3(connection); + + preparedStatement4(connection); + + preparedStatement5(connection); + + preparedStatement6(connection); + + preparedStatement7(connection); + + preparedStatement8(connection); + + + connection.close(); + DatabaseInfo clearUrl = ((DatabaseInfoTraceValue) connection).__getTraceDatabaseInfo(); + Assert.assertNull(clearUrl); + + } + + + private void statement(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + statement.executeQuery("select 1"); + statement.close(); + } + + private void preparedStatement(Connection connection) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("select 1"); + logger.info("PreparedStatement className:" + preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + + private void preparedStatement2(Connection connection) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ?"); + preparedStatement.setInt(1, 1); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement3(Connection connection) throws SQLException { + connection.setAutoCommit(false); + + PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ? or id = ? or id = ?"); + preparedStatement.setInt(1, 1); + preparedStatement.setInt(2, 2); + preparedStatement.setString(3, "3"); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + + connection.commit(); + + + connection.setAutoCommit(true); + } + + private void preparedStatement4(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", Statement.RETURN_GENERATED_KEYS); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement5(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", new String[]{"test"}); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement6(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + int[] columnIndex = {1, 2, 3}; + PreparedStatement preparedStatement = connection.prepareStatement("select 1", columnIndex); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement7(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement8(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS +// ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT + PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtilsTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtilsTest.java index bc6ac1cd9323..e737db54fec1 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtilsTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/interceptor/BindValueUtilsTest.java @@ -1,93 +1,93 @@ -package com.nhn.pinpoint.profiler.modifier.db.interceptor; - -import junit.framework.Assert; -import org.junit.Test; - -public class BindValueUtilsTest { - - @Test - public void testBindValueToString() throws Exception { - String[] bindValue = {"a", "b"}; - String result = BindValueUtils.bindValueToString(bindValue); - Assert.assertEquals("a, b", result); - } - - @Test - public void testBindValueToString_limit1() throws Exception { - String[] bindValue = {"a", "b"}; - String result = BindValueUtils.bindValueToString(bindValue, 0); - Assert.assertEquals("...(2)", result); - } - - @Test - public void testBindValueToString_limit2() throws Exception { - String[] bindValue = {"a", "b"}; - String result = BindValueUtils.bindValueToString(bindValue, 1); - Assert.assertEquals("a, ...(2)", result); - } - - @Test - public void testBindValueToString_limit3() throws Exception { - String[] bindValue = {"abc", "b"}; - String result = BindValueUtils.bindValueToString(bindValue, 1); - Assert.assertEquals("a...(3), ...(2)", result); - } - - @Test - public void testBindValueToString_limit4() throws Exception { - String[] bindValue = {"abc", "b", "c"}; - String result = BindValueUtils.bindValueToString(bindValue, 1); - Assert.assertEquals("a...(3), ...(3)", result); - } - - - @Test - public void testBindValueToString_limit5() throws Exception { - String[] bindValue = {"abc", "b", "c"}; - String result = BindValueUtils.bindValueToString(bindValue, 1024); - Assert.assertEquals("abc, b, c", result); - } - - @Test - public void testBindValueToString_limit6() throws Exception { - String[] bindValue = {"a", "b", "1234567891012"}; - // limit를 3번째 문자열 길이보다는 작게한다. - String result = BindValueUtils.bindValueToString(bindValue, 10); - Assert.assertEquals("a, b, 1234567891...(13)", result); - } - - @Test - public void testBindValueToString_limit7() throws Exception { - String[] bindValue = {"a", "12345678901", "c"}; - // limit를 2번째 문자열 길이보다는 작게한다. - String result = BindValueUtils.bindValueToString(bindValue, 10); - Assert.assertEquals("a, 1234567890...(11), ...(3)", result); - } - - @Test - public void testBindValueToString_null() throws Exception { - String result = BindValueUtils.bindValueToString(null, 10); - Assert.assertEquals("", result); - } - - @Test - public void testBindValueToString_native() throws Exception { - String[] bindValue = {"a", "b"}; - String result = BindValueUtils.bindValueToString(bindValue, -1); - Assert.assertEquals("...(2)", result); - } - - @Test - public void testBindValueToString_singleLargeString() throws Exception { - String[] bindValue = {"123456"}; - String result = BindValueUtils.bindValueToString(bindValue, 5); - Assert.assertEquals("12345...(6)", result); - } - - @Test - public void testBindValueToString_twoLargeString() throws Exception { - String[] bindValue = {"123456", "123456"}; - String result = BindValueUtils.bindValueToString(bindValue, 5); - Assert.assertEquals("12345...(6), ...(2)", result); - } +package com.nhn.pinpoint.profiler.modifier.db.interceptor; + +import junit.framework.Assert; +import org.junit.Test; + +public class BindValueUtilsTest { + + @Test + public void testBindValueToString() throws Exception { + String[] bindValue = {"a", "b"}; + String result = BindValueUtils.bindValueToString(bindValue); + Assert.assertEquals("a, b", result); + } + + @Test + public void testBindValueToString_limit1() throws Exception { + String[] bindValue = {"a", "b"}; + String result = BindValueUtils.bindValueToString(bindValue, 0); + Assert.assertEquals("...(2)", result); + } + + @Test + public void testBindValueToString_limit2() throws Exception { + String[] bindValue = {"a", "b"}; + String result = BindValueUtils.bindValueToString(bindValue, 1); + Assert.assertEquals("a, ...(2)", result); + } + + @Test + public void testBindValueToString_limit3() throws Exception { + String[] bindValue = {"abc", "b"}; + String result = BindValueUtils.bindValueToString(bindValue, 1); + Assert.assertEquals("a...(3), ...(2)", result); + } + + @Test + public void testBindValueToString_limit4() throws Exception { + String[] bindValue = {"abc", "b", "c"}; + String result = BindValueUtils.bindValueToString(bindValue, 1); + Assert.assertEquals("a...(3), ...(3)", result); + } + + + @Test + public void testBindValueToString_limit5() throws Exception { + String[] bindValue = {"abc", "b", "c"}; + String result = BindValueUtils.bindValueToString(bindValue, 1024); + Assert.assertEquals("abc, b, c", result); + } + + @Test + public void testBindValueToString_limit6() throws Exception { + String[] bindValue = {"a", "b", "1234567891012"}; + // limit를 3번째 문자열 길이보다는 작게한다. + String result = BindValueUtils.bindValueToString(bindValue, 10); + Assert.assertEquals("a, b, 1234567891...(13)", result); + } + + @Test + public void testBindValueToString_limit7() throws Exception { + String[] bindValue = {"a", "12345678901", "c"}; + // limit를 2번째 문자열 길이보다는 작게한다. + String result = BindValueUtils.bindValueToString(bindValue, 10); + Assert.assertEquals("a, 1234567890...(11), ...(3)", result); + } + + @Test + public void testBindValueToString_null() throws Exception { + String result = BindValueUtils.bindValueToString(null, 10); + Assert.assertEquals("", result); + } + + @Test + public void testBindValueToString_native() throws Exception { + String[] bindValue = {"a", "b"}; + String result = BindValueUtils.bindValueToString(bindValue, -1); + Assert.assertEquals("...(2)", result); + } + + @Test + public void testBindValueToString_singleLargeString() throws Exception { + String[] bindValue = {"123456"}; + String result = BindValueUtils.bindValueToString(bindValue, 5); + Assert.assertEquals("12345...(6)", result); + } + + @Test + public void testBindValueToString_twoLargeString() throws Exception { + String[] bindValue = {"123456", "123456"}; + String result = BindValueUtils.bindValueToString(bindValue, 5); + Assert.assertEquals("12345...(6), ...(2)", result); + } } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionStringParserTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionStringParserTest.java new file mode 100644 index 000000000000..3c494a901f73 --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionStringParserTest.java @@ -0,0 +1,117 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.modifier.db.ConnectionStringParser; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JtdsConnectionStringParserTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testParse1() throws Exception { +// jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] +// jdbc:jtds:sqlserver://server/db;user=userName;password=password + String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433;DatabaseName=CAFECHAT;sendStringParametersAsUnicode=false;useLOBs=false;loginTimeout=3"; + ConnectionStringParser parser = new JtdsConnectionStringParser(); + DatabaseInfo info = parser.parse(url); + logger.debug("{}", info); + + Assert.assertEquals(info.getType(), ServiceType.MSSQL); + Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); + Assert.assertEquals(info.getDatabaseId(), "CAFECHAT"); + Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx:1433"); + + } + + @Test + public void testParse2() throws Exception { + String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT;sendStringParametersAsUnicode=false;useLOBs=false;loginTimeout=3"; + ConnectionStringParser parser = new JtdsConnectionStringParser(); + DatabaseInfo info = parser.parse(url); + logger.debug("{}", info); + + Assert.assertEquals(info.getType(), ServiceType.MSSQL); + Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); + Assert.assertEquals(info.getDatabaseId(), "CAFECHAT"); + Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT"); + + } + + @Test + public void testParse3() throws Exception { + String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT"; + ConnectionStringParser parser = new JtdsConnectionStringParser(); + DatabaseInfo info = parser.parse(url); + logger.debug("{}", info); + + Assert.assertEquals(info.getType(), ServiceType.MSSQL); + Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); + Assert.assertEquals(info.getDatabaseId(), "CAFECHAT"); + Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT"); + } + + @Test + public void testParse4() throws Exception { + String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433"; + ConnectionStringParser parser = new JtdsConnectionStringParser(); + DatabaseInfo info = parser.parse(url); + logger.debug("{}", info); + + Assert.assertEquals(info.getType(), ServiceType.MSSQL); + Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); + Assert.assertEquals(info.getDatabaseId(), ""); + Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx:1433"); + } + + + @Test + public void testParse5() throws Exception { +// jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] +// jdbc:jtds:sqlserver://server/db;user=userName;password=password + String url = "jdbc:jtds:sqlserver://10.xx.xx.xx;DatabaseName=CAFECHAT"; + ConnectionStringParser parser = new JtdsConnectionStringParser(); + DatabaseInfo info = parser.parse(url); + logger.debug("{}", info); + + Assert.assertEquals(info.getType(), ServiceType.MSSQL); + Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx"); + Assert.assertEquals(info.getDatabaseId(), "CAFECHAT"); + Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx"); + + } + + @Test + public void testParse6() throws Exception { +// jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] +// jdbc:jtds:sqlserver://server/db;user=userName;password=password + String url = "jdbc:jtds:sqlserver://10.xx.xx.xx"; + ConnectionStringParser parser = new JtdsConnectionStringParser(); + DatabaseInfo info = parser.parse(url); + logger.debug("{}", info); + + Assert.assertEquals(info.getType(), ServiceType.MSSQL); + Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx"); + Assert.assertEquals(info.getDatabaseId(), ""); + Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx"); + + } + + + @Test + public void testParse7() throws Exception { + String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT;abc=1;bcd=2"; + ConnectionStringParser parser = new JtdsConnectionStringParser(); + DatabaseInfo info = parser.parse(url); + logger.debug("{}", info); + + Assert.assertEquals(info.getType(), ServiceType.MSSQL); + Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); + Assert.assertEquals(info.getDatabaseId(), "CAFECHAT"); + Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT"); + } +} \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionTest.java new file mode 100644 index 000000000000..a8ccdd41b29e --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/jtds/JtdsConnectionTest.java @@ -0,0 +1,187 @@ +package com.nhn.pinpoint.profiler.modifier.db.jtds; + +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.common.util.PropertyUtils; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.List; +import java.util.Properties; + +/** + * @author emeroad + */ +public class JtdsConnectionTest extends BasePinpointTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static Properties db; + + @BeforeClass + public static void beforeClass() throws Exception { + db = PropertyUtils.loadPropertyFromClassPath("database.properties"); + } + + @Test + public void executeQueryAndExecuteUpdate() throws SQLException { + Connection connection = connectDB(); + + PreparedStatement preparedStatement = connection.prepareStatement("select 1 "); +// preparedStatement.setInt(1, 1); + ResultSet resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + logger.debug("---{}", resultSet.getObject(1)); + } + connection.close(); + } + + private Connection connectDB() throws SQLException { + String url = db.getProperty("mssqlserver.url"); + String user = db.getProperty("mssqlserver.user"); + String password = db.getProperty("mssqlserver.password"); + + Driver driver = new net.sourceforge.jtds.jdbc.Driver(); + Properties properties = new Properties(); + properties.setProperty("user", user); + properties.setProperty("password", password); + return driver.connect(url, properties); + } + + + @Test + public void testModify() throws Exception { + + Connection connection = connectDB(); + + logger.info("Connection class name:{}", connection.getClass().getName()); + logger.info("Connection class cl:{}", connection.getClass().getClassLoader()); + + DatabaseInfo url = ((DatabaseInfoTraceValue) connection).__getTraceDatabaseInfo(); + Assert.assertNotNull(url); + List currentSpanEvents = getCurrentSpanEvents(); + logger.debug("spanEvent:{}", currentSpanEvents.remove(0)); + logger.debug("{}", currentSpanEvents); + + statement(connection); + logger.debug("spanEvent:{}", currentSpanEvents.remove(0)); + logger.debug("{}", currentSpanEvents); + + preparedStatement(connection); + + preparedStatement2(connection); + + preparedStatement3(connection); + + preparedStatement4(connection); + + preparedStatement5(connection); + + preparedStatement6(connection); + + preparedStatement7(connection); + + preparedStatement8(connection); + + + connection.close(); + DatabaseInfo clearUrl = ((DatabaseInfoTraceValue) connection).__getTraceDatabaseInfo(); + Assert.assertNull(clearUrl); + + } + + + private void statement(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + statement.executeQuery("select 1"); + statement.close(); + } + + private void preparedStatement(Connection connection) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("select 1"); + logger.info("PreparedStatement className:" + preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + + private void preparedStatement2(Connection connection) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ?"); + preparedStatement.setInt(1, 1); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement3(Connection connection) throws SQLException { + connection.setAutoCommit(false); + + PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ? or id = ? or id = ?"); + preparedStatement.setInt(1, 1); + preparedStatement.setInt(2, 2); + preparedStatement.setString(3, "3"); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + + connection.commit(); + + + connection.setAutoCommit(true); + } + + private void preparedStatement4(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", Statement.RETURN_GENERATED_KEYS); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement5(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", new String[]{"test"}); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement6(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + int[] columnIndex = {1}; + PreparedStatement preparedStatement = connection.prepareStatement("select 1", columnIndex); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement7(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement8(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS +// ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT + PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplModifierTest.java index a471ce0476fb..7c117de54568 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplModifierTest.java @@ -1,271 +1,230 @@ -package com.nhn.pinpoint.profiler.modifier.db.mysql; - -import com.mysql.jdbc.JDBC4PreparedStatement; -import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; - -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; - - -import com.nhn.pinpoint.profiler.util.MockAgent; -import com.nhn.pinpoint.profiler.util.TestClassLoader; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.sql.*; -import java.util.Properties; - -/** - * @author emeroad - */ -public class MySQLConnectionImplModifierTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private TestClassLoader loader; - - - @Before - public void setUp() throws Exception { - PLoggerFactory.initialize(new Slf4jLoggerBinder()); - - ProfilerConfig profilerConfig = new ProfilerConfig(); - // profiler config를 setter를 열어두는것도 괜찮을듯 하다. - String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); - profilerConfig.readConfigFile(path); - - profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); - DefaultAgent agent = new MockAgent("", profilerConfig); - loader = new TestClassLoader(agent); - // agent가 로드한 모든 Modifier를 자동으로 찾도록 변경함. - - - loader.initialize(); - } - - @Test - public void testModify() throws Exception { - - Driver driver = loadClass(); - - Properties properties = new Properties(); - properties.setProperty("user", "lucytest"); - properties.setProperty("password", "testlucy"); - Connection connection = driver.connect("jdbc:mysql://10.98.133.22:3306/hippo", properties); - - logger.info("Connection class name:{}", connection.getClass().getName()); - logger.info("Connection class cl:{}", connection.getClass().getClassLoader()); - - DatabaseInfo url = ((DatabaseInfoTraceValue)connection).__getTraceDatabaseInfo(); - Assert.assertNotNull(url); - - statement(connection); - - preparedStatement(connection); - - preparedStatement2(connection); - - preparedStatement3(connection); - - connection.close(); - DatabaseInfo clearUrl = ((DatabaseInfoTraceValue)connection).__getTraceDatabaseInfo(); - Assert.assertNull(clearUrl); - - } - - private Driver loadClass() throws ClassNotFoundException, InstantiationException, IllegalAccessException { - Class driverClazz = (Class) loader.loadClass("com.mysql.jdbc.NonRegisteringDriver"); -// Driver nonRegisteringDriver = new NonRegisteringDriver(); -// Class driverClazz = (Class) nonRegisteringDriver.getClass(); - - Driver driver = driverClazz.newInstance(); - logger.info("Driver class name:{}", driverClazz.getName()); - logger.info("Driver class cl:{}", driverClazz.getClassLoader()); - - - Class aClass = loader.loadClass("com.mysql.jdbc.StringUtils"); -// 이게 loader와 동일하게 로드 되는게 정확한건지 애매함. 하위에 로드되는게 좋을것 같은데. -// Assert.assertNotSame("check classLoader", aClass.getClassLoader(), loader); - logger.debug("mysql cl:{}", aClass.getClassLoader()); - - Class version = loader.loadClass("com.nhn.pinpoint.common.Version"); - Assert.assertSame("check classLoader", this.getClass().getClassLoader(), version.getClassLoader()); - logger.debug("common cl:{}", version.getClassLoader()); - return driver; - } - - @Test - public void loadBalancedUrlModify() throws Exception { - - Driver driver = loadClass(); - - Properties properties = new Properties(); - properties.setProperty("user", "lucytest"); - properties.setProperty("password", "testlucy"); - Connection connection = driver.connect("jdbc:mysql:loadbalance://10.98.133.23:3306,10.98.133.22:3306/hippo", properties); - - logger.info("Connection class name:{}", connection.getClass().getName()); - logger.info("Connection class cl:{}", connection.getClass().getClassLoader()); - // loadbalanced 타입을때 가져올수 있는 reflection을 쓰지 않으면 - // 그리고 LoadBalancingConnectionProxy으로 캐스팅할 경우 classLoader가 달라서 문제가 생김. 일단 그냥둔다. - InvocationHandler invocationHandler = Proxy.getInvocationHandler(connection); - Class aClass = invocationHandler.getClass(); - - Field current = aClass.getDeclaredField("currentConn"); - current.setAccessible(true); - Object internalConnection = current.get(invocationHandler); - - - DatabaseInfo url = ((DatabaseInfoTraceValue)internalConnection).__getTraceDatabaseInfo(); - Assert.assertNotNull(url); - - statement(connection); - - preparedStatement(connection); - - preparedStatement2(connection); - - preparedStatement3(connection); - - preparedStatement4(connection); - - preparedStatement5(connection); - - preparedStatement6(connection); - - preparedStatement7(connection); - - preparedStatement8(connection); - - connection.close(); - DatabaseInfo clearUrl = ((DatabaseInfoTraceValue)internalConnection).__getTraceDatabaseInfo(); - Assert.assertNull(clearUrl); - - } - - private void statement(Connection connection) throws SQLException { - Statement statement = connection.createStatement(); - statement.executeQuery("select 1"); - statement.close(); - } - - private void preparedStatement(Connection connection) throws SQLException { - PreparedStatement preparedStatement = connection.prepareStatement("select 1"); - logger.info("PreparedStatement className:" + preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement2(Connection connection) throws SQLException { - PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ?"); - preparedStatement.setInt(1, 1); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement3(Connection connection) throws SQLException { - connection.setAutoCommit(false); - - PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ? or id = ? or id = ?"); - preparedStatement.setInt(1, 1); - preparedStatement.setInt(2, 2); - preparedStatement.setString(3, "3"); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - - connection.commit(); - - - connection.setAutoCommit(true); - } - - - private void preparedStatement4(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - PreparedStatement preparedStatement = connection.prepareStatement("select 1", Statement.RETURN_GENERATED_KEYS); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement5(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - PreparedStatement preparedStatement = connection.prepareStatement("select 1", new String[]{"test"}); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement6(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - int[] columnIndex = {1,2,3}; - PreparedStatement preparedStatement = connection.prepareStatement("select 1", columnIndex); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatement7(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - private void preparedStatementError(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement("select 8 from invalidTable", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - resultSet = preparedStatement.executeQuery(); - } finally { - if (resultSet != null) { - resultSet.close(); - } - if (preparedStatement != null) { - preparedStatement.close(); - } - - } - } - - private void preparedStatement8(Connection connection) throws SQLException { -// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS -// ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT - PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); - logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); - ResultSet resultSet = preparedStatement.executeQuery(); - resultSet.close(); - preparedStatement.close(); - } - - - @Test - public void test() throws NoSuchMethodException { -// setNClob(int parameterIndex, NClob value) - JDBC4PreparedStatement.class.getDeclaredMethod("setNClob", new Class[]{int.class, NClob.class}); -// JDBC4PreparedStatement.class.getDeclaredMethod("addBatch", null); - JDBC4PreparedStatement.class.getMethod("addBatch"); - - } -} +package com.nhn.pinpoint.profiler.modifier.db.mysql; + +import com.mysql.jdbc.JDBC4PreparedStatement; +import com.mysql.jdbc.NonRegisteringDriver; +import com.nhn.pinpoint.bootstrap.context.DatabaseInfo; +import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue; +import com.nhn.pinpoint.common.util.PropertyUtils; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.sql.*; +import java.util.Properties; + +/** + * @author emeroad + */ +public class MySQLConnectionImplModifierTest extends BasePinpointTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static Properties db; + + @BeforeClass + public static void beforeClass() throws Exception { + db = PropertyUtils.loadPropertyFromClassPath("database.properties"); + } + + @Test + public void testModify() throws Exception { + + Connection connection = connectDB(db.getProperty("mysql.url")); + + logger.info("Connection class name:{}", connection.getClass().getName()); + logger.info("Connection class cl:{}", connection.getClass().getClassLoader()); + + DatabaseInfo url = ((DatabaseInfoTraceValue) connection).__getTraceDatabaseInfo(); + Assert.assertNotNull(url); + + statement(connection); + + preparedStatement(connection); + + preparedStatement2(connection); + + preparedStatement3(connection); + + connection.close(); + + DatabaseInfo clearUrl = ((DatabaseInfoTraceValue) connection).__getTraceDatabaseInfo(); + Assert.assertNull(clearUrl); + + } + + private Connection connectDB(String url) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException { + String user = db.getProperty("mysql.user"); + String password = db.getProperty("mysql.password"); + + Driver driver = new NonRegisteringDriver(); + Properties properties = new Properties(); + properties.setProperty("user", user); + properties.setProperty("password", password); + return driver.connect(url, properties); + } + + @Test + public void loadBalancedUrlModify() throws Exception { + + Connection connection = connectDB(db.getProperty("mysql.url.loadbalance")); + + logger.info("Connection class name:{}", connection.getClass().getName()); + logger.info("Connection class cl:{}", connection.getClass().getClassLoader()); + // loadbalanced 타입을때 가져올수 있는 reflection을 쓰지 않으면 + // 그리고 LoadBalancingConnectionProxy으로 캐스팅할 경우 classLoader가 달라서 문제가 생김. 일단 그냥둔다. + InvocationHandler invocationHandler = Proxy.getInvocationHandler(connection); + Class aClass = invocationHandler.getClass(); + + Field current = aClass.getDeclaredField("currentConn"); + current.setAccessible(true); + Object internalConnection = current.get(invocationHandler); + + + DatabaseInfo url = ((DatabaseInfoTraceValue) internalConnection).__getTraceDatabaseInfo(); + Assert.assertNotNull(url); + + statement(connection); + + preparedStatement(connection); + + preparedStatement2(connection); + + preparedStatement3(connection); + + preparedStatement4(connection); + + preparedStatement5(connection); + + preparedStatement6(connection); + + preparedStatement7(connection); + + preparedStatement8(connection); + + connection.close(); + DatabaseInfo clearUrl = ((DatabaseInfoTraceValue) internalConnection).__getTraceDatabaseInfo(); + Assert.assertNull(clearUrl); + + } + + private void statement(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + statement.executeQuery("select 1"); + statement.close(); + } + + private void preparedStatement(Connection connection) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("select 1"); + logger.info("PreparedStatement className:" + preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement2(Connection connection) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ?"); + preparedStatement.setInt(1, 1); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement3(Connection connection) throws SQLException { + connection.setAutoCommit(false); + + PreparedStatement preparedStatement = connection.prepareStatement("select * from member where id = ? or id = ? or id = ?"); + preparedStatement.setInt(1, 1); + preparedStatement.setInt(2, 2); + preparedStatement.setString(3, "3"); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + + connection.commit(); + + connection.setAutoCommit(true); + } + + + private void preparedStatement4(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", Statement.RETURN_GENERATED_KEYS); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement5(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", new String[]{"test"}); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement6(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + int[] columnIndex = {1, 2, 3}; + PreparedStatement preparedStatement = connection.prepareStatement("select 1", columnIndex); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatement7(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + private void preparedStatementError(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + try { + preparedStatement = connection.prepareStatement("select 8 from invalidTable", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + resultSet = preparedStatement.executeQuery(); + } finally { + if (resultSet != null) { + resultSet.close(); + } + if (preparedStatement != null) { + preparedStatement.close(); + } + + } + } + + private void preparedStatement8(Connection connection) throws SQLException { +// Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS +// ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT + PreparedStatement preparedStatement = connection.prepareStatement("select 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); + logger.info("PreparedStatement className:{}", preparedStatement.getClass().getName()); + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.close(); + preparedStatement.close(); + } + + + @Test + public void test() throws NoSuchMethodException { +// setNClob(int parameterIndex, NClob value) + JDBC4PreparedStatement.class.getDeclaredMethod("setNClob", new Class[]{int.class, NClob.class}); +// JDBC4PreparedStatement.class.getDeclaredMethod("addBatch", null); + JDBC4PreparedStatement.class.getMethod("addBatch"); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplTest.java index 8a931a9deefe..f79b837cd61c 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/mysql/MySQLConnectionImplTest.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.profiler.modifier.db.mysql; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; -import com.nhn.pinpoint.profiler.util.MockAgent; -import com.nhn.pinpoint.profiler.util.TestClassLoader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class MySQLConnectionImplTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private TestClassLoader loader; - -// @Before - public void setUp() throws Exception { - PLoggerFactory.initialize(new Slf4jLoggerBinder()); - - ProfilerConfig profilerConfig = new ProfilerConfig(); - // profiler config를 setter를 열어두는것도 괜찮을듯 하다. - String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); - profilerConfig.readConfigFile(path); - - profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); - DefaultAgent agent = new MockAgent("", profilerConfig); - loader = new TestClassLoader(agent); - // agent가 로드한 모든 Modifier를 자동으로 찾도록 변경함. - - - loader.initialize(); - } - -// @Test - public void test() throws Throwable { -// 간접 참조로 실행할 경우의 샘플용으로 commit함. -// loader.runTest("com.nhn.pinpoint.profiler.modifier.db.mysql.MySQLConnectionImplModifierTest", "testModify"); - } - - -} +package com.nhn.pinpoint.profiler.modifier.db.mysql; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.DefaultAgent; +import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; +import com.nhn.pinpoint.profiler.util.MockAgent; +import com.nhn.pinpoint.profiler.util.TestClassLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class MySQLConnectionImplTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private TestClassLoader loader; + +// @Before + public void setUp() throws Exception { + PLoggerFactory.initialize(new Slf4jLoggerBinder()); + + ProfilerConfig profilerConfig = new ProfilerConfig(); + // profiler config를 setter를 열어두는것도 괜찮을듯 하다. + String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); + profilerConfig.readConfigFile(path); + + profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); + DefaultAgent agent = new MockAgent("", profilerConfig); + loader = new TestClassLoader(agent); + // agent가 로드한 모든 Modifier를 자동으로 찾도록 변경함. + + + loader.initialize(); + } + +// @Test + public void test() throws Throwable { +// 간접 참조로 실행할 경우의 샘플용으로 commit함. +// loader.runTest("com.nhn.pinpoint.profiler.modifier.db.mysql.MySQLConnectionImplModifierTest", "testModify"); + } + + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParserTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParserTest.java index 8966924caad8..355cb33b85a7 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParserTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorParserTest.java @@ -1,174 +1,174 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.Description; -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.KeyValue; -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleConnectionStringException; -import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleNetConnectionDescriptorParser; -import junit.framework.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * @author emeroad - */ -public class OracleNetConnectionDescriptorParserTest { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void simple() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" - + "(CONNECT_DATA=(SERVICE_NAME=service)))"; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - KeyValue keyValue = parser.parse(); - - logger.info(keyValue.toString()); - - Description des = new Description(keyValue); - Assert.assertEquals(des.getServiceName(), "service"); - } - - @Test - public void emptyValue() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=)" - + "(CONNECT_DATA=(SERVICE_NAME=)))"; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - KeyValue keyValue = parser.parse(); - logger.info(keyValue.toString()); - - Description des = new Description(keyValue); - Assert.assertEquals(des.getServiceName(), null); - - } - - @Test - public void parse() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" + - "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + - "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1522))" + - "(CONNECT_DATA=(SERVICE_NAME=service)))"; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - KeyValue keyValue = parser.parse(); - Description description = new Description(keyValue); - - Description value = new Description(); - value.setServiceName("service"); - value.addAddress("tcp", "1.2.3.4", "1521"); - value.addAddress("tcp", "1.2.3.5", "1522"); - Assert.assertEquals(description, value); - - } - - @Test - public void parse2() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + - "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + - "(ADDRESS = (PROTOCOL = TCP ) (HOST = 1.2.3.5) ( PORT = 1522 ))" + - " ( CONNECT_DATA = ( SERVICE_NAME = service ) ) )"; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - KeyValue keyValue = parser.parse(); - Description description = new Description(keyValue); - - Description value = new Description(); - value.setServiceName("service"); - value.addAddress("tcp", "1.2.3.4", "1521"); - value.addAddress("tcp", "1.2.3.5", "1522"); - Assert.assertEquals(description, value); - - } - - @Test - public void parse3() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + - "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + - "(ADDRESS = (PROTOCOL = TCP ) (HOST = 1.2.3.5) ( PORT = 1522 ))" + - "(ADDRESS = (PROTOCOL = TCP ) (HOST = 1.2.3.6) ( PORT = 1523 ))" + - " ( CONNECT_DATA = ( SERVICE_NAME = service ) ) )"; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - KeyValue keyValue = parser.parse(); - Description description = new Description(keyValue); - - Description value = new Description(); - value.setServiceName("service"); - value.addAddress("tcp", "1.2.3.4", "1521"); - value.addAddress("tcp", "1.2.3.5", "1522"); - value.addAddress("tcp", "1.2.3.6", "1523"); - Assert.assertEquals(description, value); - - } - - @Test - public void parse4() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + - "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + - " ( CONNECT_DATA = ( SID = sid ) ) )"; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - KeyValue keyValue = parser.parse(); - Description description = new Description(keyValue); - - Description value = new Description(); - value.setSid("sid"); - value.addAddress("tcp", "1.2.3.4", "1521"); - Assert.assertEquals(description, value); - - } - - @Test - public void parseEofError() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + - "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + -// " ( CONNECT_DATA = ( SID = sid ) ) )"; - " ( CONNECT_DATA = ( SID = sid ) ) "; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - try { - KeyValue keyValue = parser.parse(); - Assert.fail(); - } catch (OracleConnectionStringException e) { - logger.info("Expected error", e); - } - - - } - - - @Test - public void parseSyntaxError() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + - "(ADDRESS = ( PROTOCOL = TCP) HOST = 1.2.3.4 ) (PORT = 1521 ))" + - " ( CONNECT_DATA = ( SID = sid ) ) )"; - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - try { - KeyValue keyValue = parser.parse(); - Assert.fail(); - } catch (OracleConnectionStringException e) { - logger.info("Expected error", e); - } - } - - @Test - public void parseSyntaxError2() { - String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + - "(ADDRESS = ( PROTOCOL = TCP) (HOST = 1.2.3.4 ) ( = 1521 ))" + - " ( CONNECT_DATA = ( SID = sid ) ) )"; - // port 제거 - - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); - try { - KeyValue keyValue = parser.parse(); - Assert.fail(); - } catch (OracleConnectionStringException e) { - logger.info("Expected error", e); - } - } - -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.Description; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.KeyValue; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleConnectionStringException; +import com.nhn.pinpoint.profiler.modifier.db.oracle.parser.OracleNetConnectionDescriptorParser; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * @author emeroad + */ +public class OracleNetConnectionDescriptorParserTest { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void simple() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" + + "(CONNECT_DATA=(SERVICE_NAME=service)))"; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + KeyValue keyValue = parser.parse(); + + logger.info(keyValue.toString()); + + Description des = new Description(keyValue); + Assert.assertEquals(des.getServiceName(), "service"); + } + + @Test + public void emptyValue() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=)" + + "(CONNECT_DATA=(SERVICE_NAME=)))"; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + KeyValue keyValue = parser.parse(); + logger.info(keyValue.toString()); + + Description des = new Description(keyValue); + Assert.assertEquals(des.getServiceName(), null); + + } + + @Test + public void parse() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)" + + "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + + "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1522))" + + "(CONNECT_DATA=(SERVICE_NAME=service)))"; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + KeyValue keyValue = parser.parse(); + Description description = new Description(keyValue); + + Description value = new Description(); + value.setServiceName("service"); + value.addAddress("tcp", "1.2.3.4", "1521"); + value.addAddress("tcp", "1.2.3.5", "1522"); + Assert.assertEquals(description, value); + + } + + @Test + public void parse2() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + + "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + + "(ADDRESS = (PROTOCOL = TCP ) (HOST = 1.2.3.5) ( PORT = 1522 ))" + + " ( CONNECT_DATA = ( SERVICE_NAME = service ) ) )"; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + KeyValue keyValue = parser.parse(); + Description description = new Description(keyValue); + + Description value = new Description(); + value.setServiceName("service"); + value.addAddress("tcp", "1.2.3.4", "1521"); + value.addAddress("tcp", "1.2.3.5", "1522"); + Assert.assertEquals(description, value); + + } + + @Test + public void parse3() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + + "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + + "(ADDRESS = (PROTOCOL = TCP ) (HOST = 1.2.3.5) ( PORT = 1522 ))" + + "(ADDRESS = (PROTOCOL = TCP ) (HOST = 1.2.3.6) ( PORT = 1523 ))" + + " ( CONNECT_DATA = ( SERVICE_NAME = service ) ) )"; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + KeyValue keyValue = parser.parse(); + Description description = new Description(keyValue); + + Description value = new Description(); + value.setServiceName("service"); + value.addAddress("tcp", "1.2.3.4", "1521"); + value.addAddress("tcp", "1.2.3.5", "1522"); + value.addAddress("tcp", "1.2.3.6", "1523"); + Assert.assertEquals(description, value); + + } + + @Test + public void parse4() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + + "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + + " ( CONNECT_DATA = ( SID = sid ) ) )"; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + KeyValue keyValue = parser.parse(); + Description description = new Description(keyValue); + + Description value = new Description(); + value.setSid("sid"); + value.addAddress("tcp", "1.2.3.4", "1521"); + Assert.assertEquals(description, value); + + } + + @Test + public void parseEofError() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + + "(ADDRESS = ( PROTOCOL = TCP)(HOST = 1.2.3.4 ) (PORT = 1521 ))" + +// " ( CONNECT_DATA = ( SID = sid ) ) )"; + " ( CONNECT_DATA = ( SID = sid ) ) "; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + try { + KeyValue keyValue = parser.parse(); + Assert.fail(); + } catch (OracleConnectionStringException e) { + logger.info("Expected error", e); + } + + + } + + + @Test + public void parseSyntaxError() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + + "(ADDRESS = ( PROTOCOL = TCP) HOST = 1.2.3.4 ) (PORT = 1521 ))" + + " ( CONNECT_DATA = ( SID = sid ) ) )"; + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + try { + KeyValue keyValue = parser.parse(); + Assert.fail(); + } catch (OracleConnectionStringException e) { + logger.info("Expected error", e); + } + } + + @Test + public void parseSyntaxError2() { + String rac = "jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE = off )" + + "(ADDRESS = ( PROTOCOL = TCP) (HOST = 1.2.3.4 ) ( = 1521 ))" + + " ( CONNECT_DATA = ( SID = sid ) ) )"; + // port 제거 + + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(rac); + try { + KeyValue keyValue = parser.parse(); + Assert.fail(); + } catch (OracleConnectionStringException e) { + logger.info("Expected error", e); + } + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizerTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizerTest.java index a0ca4e812c9a..3bbb34739e74 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizerTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/db/oracle/parser/OracleNetConnectionDescriptorTokenizerTest.java @@ -1,112 +1,112 @@ -package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; - - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class OracleNetConnectionDescriptorTokenizerTest { - - @Test - public void trimLeft() { - assertTrimLeft("123", "123"); - assertTrimLeft(" 123", "123"); - assertTrimLeft(" 123 ", "123 "); - - assertTrimLeft(" 1 23 ", "1 23 "); - - assertTrimLeft(" 1 23 ", "1 23 "); - - assertTrimLeft("", ""); - assertTrimLeft(" ", ""); - - assertTrimLeft("12 ", "12 "); - - assertTrimLeft("12 ", "12 "); - } - - - - private void assertTrimLeft(String token, String result) { - OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); - int leftTrimIndex = tokenizer.trimLeft(); - Assert.assertEquals(wrap(result), wrap(token.substring(leftTrimIndex))); - } - - - - @Test - public void trimRight() { - assertTrimRight("123", "123"); - assertTrimRight("123 ", "123"); - assertTrimRight("123 ", "123"); - - assertTrimRight("1 23 ", "1 23"); - assertTrimRight(" 1 23 ", " 1 23"); - - assertTrimRight("", ""); - assertTrimRight(" ", ""); - } - - private void assertTrimRight(String token, String result) { - OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); - int rightTrimIndex = tokenizer.trimRight(token.length()); - Assert.assertEquals(wrap(result), wrap(token.substring(0, rightTrimIndex))); - } - - @Test - public void parseLiteral() { - AssertParseLiteral("abc", "abc"); - AssertParseLiteral(" abc", "abc"); - AssertParseLiteral(" abc", "abc"); - - AssertParseLiteral("abc ", "abc"); - AssertParseLiteral("abc ", "abc"); - - AssertParseLiteral("a c", "a c"); - AssertParseLiteral(" a c", "a c"); - AssertParseLiteral(" a c ", "a c"); - - } - - @Test - public void simpleParse() { - assertCompareToken("a=b", "a", "=", "b"); - - assertCompareToken("a = b", "a", "=", "b"); - - assertCompareToken(" a = b ", "a", "=", "b"); - - } - - private void assertCompareToken(String token, String... parsedTokens) { - OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); - tokenizer.parse(); - - int index = 0; - while(true) { - Token t = tokenizer.nextToken(); - // EOF 오브젝트가 추가되서 테스트가 깨짐. - if (t != null && t == OracleNetConnectionDescriptorTokenizer.TOKEN_EOF_OBJECT) { - return; - } - - if (t == null) { - break; - } - Assert.assertEquals(t.getToken(), parsedTokens[index++]); - } - } - - private void AssertParseLiteral(String token, String result) { - OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); - String literal = tokenizer.parseLiteral(); - Assert.assertEquals(wrap(result), wrap(literal)); - } - - private String wrap(String str) { - return "\"" + str + "\""; - } -} +package com.nhn.pinpoint.profiler.modifier.db.oracle.parser; + + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class OracleNetConnectionDescriptorTokenizerTest { + + @Test + public void trimLeft() { + assertTrimLeft("123", "123"); + assertTrimLeft(" 123", "123"); + assertTrimLeft(" 123 ", "123 "); + + assertTrimLeft(" 1 23 ", "1 23 "); + + assertTrimLeft(" 1 23 ", "1 23 "); + + assertTrimLeft("", ""); + assertTrimLeft(" ", ""); + + assertTrimLeft("12 ", "12 "); + + assertTrimLeft("12 ", "12 "); + } + + + + private void assertTrimLeft(String token, String result) { + OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); + int leftTrimIndex = tokenizer.trimLeft(); + Assert.assertEquals(wrap(result), wrap(token.substring(leftTrimIndex))); + } + + + + @Test + public void trimRight() { + assertTrimRight("123", "123"); + assertTrimRight("123 ", "123"); + assertTrimRight("123 ", "123"); + + assertTrimRight("1 23 ", "1 23"); + assertTrimRight(" 1 23 ", " 1 23"); + + assertTrimRight("", ""); + assertTrimRight(" ", ""); + } + + private void assertTrimRight(String token, String result) { + OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); + int rightTrimIndex = tokenizer.trimRight(token.length()); + Assert.assertEquals(wrap(result), wrap(token.substring(0, rightTrimIndex))); + } + + @Test + public void parseLiteral() { + AssertParseLiteral("abc", "abc"); + AssertParseLiteral(" abc", "abc"); + AssertParseLiteral(" abc", "abc"); + + AssertParseLiteral("abc ", "abc"); + AssertParseLiteral("abc ", "abc"); + + AssertParseLiteral("a c", "a c"); + AssertParseLiteral(" a c", "a c"); + AssertParseLiteral(" a c ", "a c"); + + } + + @Test + public void simpleParse() { + assertCompareToken("a=b", "a", "=", "b"); + + assertCompareToken("a = b", "a", "=", "b"); + + assertCompareToken(" a = b ", "a", "=", "b"); + + } + + private void assertCompareToken(String token, String... parsedTokens) { + OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); + tokenizer.parse(); + + int index = 0; + while(true) { + Token t = tokenizer.nextToken(); + // EOF 오브젝트가 추가되서 테스트가 깨짐. + if (t != null && t == OracleNetConnectionDescriptorTokenizer.TOKEN_EOF_OBJECT) { + return; + } + + if (t == null) { + break; + } + Assert.assertEquals(t.getToken(), parsedTokens[index++]); + } + } + + private void AssertParseLiteral(String token, String result) { + OracleNetConnectionDescriptorTokenizer tokenizer = new OracleNetConnectionDescriptorTokenizer(token); + String literal = tokenizer.parseLiteral(); + Assert.assertEquals(wrap(result), wrap(literal)); + } + + private String wrap(String str) { + return "\"" + str + "\""; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/mapping/MappingTableTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/mapping/MappingTableTest.java deleted file mode 100644 index 21bf7c8aa775..000000000000 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/mapping/MappingTableTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.nhn.pinpoint.profiler.modifier.mapping; - -import org.junit.Test; - -/** - * @author emeroad - */ -public class MappingTableTest { - @Test - public void testLookupMethodDescriptor() throws Exception { - // 2147483647 - // xxxxxxxx - yyy xxxx는 class 명, yyy는 함수명매칭하자. 하자. - int maxValue = Integer.MAX_VALUE; - int i = 2147483647 / 100; - System.out.println(i); - - - } -} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifierTest.java index 3fe4b462c89b..d84e6adeef3f 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapClientImplModifierTest.java @@ -1,287 +1,287 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import static org.hamcrest.CoreMatchers.*; - -import java.sql.SQLException; -import java.util.List; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import com.ibatis.sqlmap.client.SqlMapClient; -import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl; -import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate; -import com.ibatis.sqlmap.engine.scope.SessionScope; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.bo.AnnotationBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; - -/** - * @author Hyun Jeong - */ -public class SqlMapClientImplModifierTest extends BasePinpointTest { - - public class MockSqlMapExecutorDelegate extends SqlMapExecutorDelegate { - @Override - public SessionScope beginSessionScope() { - return mockSessionScope; - } - } - - @Mock - private MockSqlMapExecutorDelegate mockSqlMapExecutorDelegate; - @Mock - private SessionScope mockSessionScope; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(this.mockSessionScope); - } - - @Test - public void exceptionsThrownShouldBeTraced() throws Exception { - // Given - when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(null); - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - try { - sqlMapClient.insert("insertShouldThrowNPE"); - fail("sqlMapClient.insert should throw NullPointerException"); - } catch (NullPointerException e) { - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - final SpanEventBo exceptionSpanEventBo = spanEvents.get(0); - assertThat(exceptionSpanEventBo.hasException(), is(true)); - assertThat(exceptionSpanEventBo.getExceptionId(), not(0)); - } - } - - @Test(expected=NullPointerException.class) - public void test() throws SQLException { - // Given - when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(null); - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.insert("insertShouldThrowNPE"); - } - - @Test - public void nullParametersShouldNotBeTraced() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.insert(null); - sqlMapClient.queryForList(null); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo insertSpanEventBo = spanEvents.get(0); - final SpanEventBo queryForListSpanEventBo = spanEvents.get(1); - assertThat(insertSpanEventBo.getApiId(), not(0)); - assertThat(queryForListSpanEventBo.getApiId(), not(0)); - assertThat(insertSpanEventBo.getApiId(), not(queryForListSpanEventBo.getApiId())); - - // Check Parameter - assertNull(insertSpanEventBo.getAnnotationBoList()); - assertNull(queryForListSpanEventBo.getAnnotationBoList()); - } - - @Test - public void sameApiCallsShouldHaveTheSameApiId() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.insert("insertA"); - sqlMapClient.insert("insertB"); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo insertASpanEventBo = spanEvents.get(0); - final SpanEventBo insertBSpanEventBo = spanEvents.get(1); - assertThat(insertASpanEventBo.getApiId(), not(0)); - assertThat(insertBSpanEventBo.getApiId(), not(0)); - assertThat(insertASpanEventBo.getApiId(), is(insertBSpanEventBo.getApiId())); - - } - - @Test - public void insertShouldBeTraced() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.insert("insertId"); - sqlMapClient.insert("insertId", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo insertWith1ArgSpanEventBo = spanEvents.get(0); - final SpanEventBo insertWith2ArgSpanEventBo = spanEvents.get(1); - assertThat(insertWith1ArgSpanEventBo.getApiId(), not(0)); - assertThat(insertWith2ArgSpanEventBo.getApiId(), not(0)); - assertThat(insertWith1ArgSpanEventBo.getApiId(), not(insertWith2ArgSpanEventBo.getApiId())); - - // Check Parameter - final List insertWith1ArgAnnotations = insertWith1ArgSpanEventBo.getAnnotationBoList(); - assertThat(insertWith1ArgAnnotations.size(), is(1)); - final AnnotationBo insertWith1ArgParameterAnnotation = insertWith1ArgAnnotations.get(0); - assertThat(insertWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - final List insertWith2ArgAnnotations = insertWith2ArgSpanEventBo.getAnnotationBoList(); - assertThat(insertWith2ArgAnnotations.size(), is(1)); - final AnnotationBo insertWith2ArgAnnotation = insertWith2ArgAnnotations.get(0); - assertThat(insertWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - } - - @Test - public void deleteShouldBeTraced() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.delete("deleteId"); - sqlMapClient.delete("deleteId", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo deleteWith1ArgSpanEvent = spanEvents.get(0); - final SpanEventBo deleteWith2ArgSpanEvent = spanEvents.get(1); - assertThat(deleteWith1ArgSpanEvent.getApiId(), not(0)); - assertThat(deleteWith2ArgSpanEvent.getApiId(), not(0)); - assertThat(deleteWith1ArgSpanEvent.getApiId(), not(deleteWith2ArgSpanEvent.getApiId())); - - // Check Parameter - final List deleteWith1ArgAnnotations = deleteWith1ArgSpanEvent.getAnnotationBoList(); - assertThat(deleteWith1ArgAnnotations.size(), is(1)); - final AnnotationBo deleteWith1ArgParameterAnnotation = deleteWith1ArgAnnotations.get(0); - assertThat(deleteWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - final List deleteWith2ArgAnnotations = deleteWith2ArgSpanEvent.getAnnotationBoList(); - assertThat(deleteWith2ArgAnnotations.size(), is(1)); - final AnnotationBo deleteWith2ArgAnnotation = deleteWith2ArgAnnotations.get(0); - assertThat(deleteWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Test - public void updateShouldBeTraced() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.update("updateId"); - sqlMapClient.update("updateId", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo updateWith1ArgSpanEvent = spanEvents.get(0); - final SpanEventBo updateWith2ArgSpanEvent = spanEvents.get(1); - assertThat(updateWith1ArgSpanEvent.getApiId(), not(0)); - assertThat(updateWith2ArgSpanEvent.getApiId(), not(0)); - assertThat(updateWith1ArgSpanEvent.getApiId(), not(updateWith2ArgSpanEvent.getApiId())); - - // Check Parameter - final List updateWith1ArgAnnotations = updateWith1ArgSpanEvent.getAnnotationBoList(); - assertThat(updateWith1ArgAnnotations.size(), is(1)); - final AnnotationBo updateWith1ArgParameterAnnotation = updateWith1ArgAnnotations.get(0); - assertThat(updateWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - final List updateWith2ArgAnnotations = updateWith2ArgSpanEvent.getAnnotationBoList(); - assertThat(updateWith2ArgAnnotations.size(), is(1)); - final AnnotationBo updateWith2ArgAnnotation = updateWith2ArgAnnotations.get(0); - assertThat(updateWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - } - - @Test - public void queryForListShouldBeTraced() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.queryForList("abc"); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); - assertThat(apiCallSpanEventBo.getApiId(), not(0)); - - // Check Parameter - final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); - assertThat(annotationBoList.size(), is(1)); - - final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); - assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Test - public void queryForObjectShouldBeTraced() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.queryForObject("abrgrgfdaghertah", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); - assertThat(apiCallSpanEventBo.getApiId(), not(0)); - - // Check Parameter - final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); - assertThat(annotationBoList.size(), is(1)); - - final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); - assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void transactionsShouldBeTraced() throws Exception { - // Given - SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - // When - sqlMapClient.startTransaction(); - sqlMapClient.commitTransaction(); - sqlMapClient.endTransaction(); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(3)); - - // Check Method - final SpanEventBo startTransactionSpanEventBo = spanEvents.get(0); - final SpanEventBo commitTransactionSpanEventBo = spanEvents.get(1); - final SpanEventBo endTransactionSpanEventBo = spanEvents.get(2); - - assertThat(startTransactionSpanEventBo.getApiId(), not(0)); - assertThat(commitTransactionSpanEventBo.getApiId(), not(0)); - assertThat(endTransactionSpanEventBo.getApiId(), not(0)); - - assertThat(startTransactionSpanEventBo.getApiId(), not(commitTransactionSpanEventBo.getApiId())); - assertThat(commitTransactionSpanEventBo.getApiId(), not(endTransactionSpanEventBo.getApiId())); - assertThat(endTransactionSpanEventBo.getApiId(), not(startTransactionSpanEventBo.getApiId())); - - // Check Parameter - assertNull(startTransactionSpanEventBo.getAnnotationBoList()); - assertNull(commitTransactionSpanEventBo.getAnnotationBoList()); - assertNull(endTransactionSpanEventBo.getAnnotationBoList()); - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import static org.hamcrest.CoreMatchers.*; + +import java.sql.SQLException; +import java.util.List; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import com.ibatis.sqlmap.client.SqlMapClient; +import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl; +import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate; +import com.ibatis.sqlmap.engine.scope.SessionScope; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.bo.AnnotationBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; + +/** + * @author Hyun Jeong + */ +public class SqlMapClientImplModifierTest extends BasePinpointTest { + + public class MockSqlMapExecutorDelegate extends SqlMapExecutorDelegate { + @Override + public SessionScope beginSessionScope() { + return mockSessionScope; + } + } + + @Mock + private MockSqlMapExecutorDelegate mockSqlMapExecutorDelegate; + @Mock + private SessionScope mockSessionScope; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(this.mockSessionScope); + } + + @Test + public void exceptionsThrownShouldBeTraced() throws Exception { + // Given + when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(null); + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + try { + sqlMapClient.insert("insertShouldThrowNPE"); + fail("sqlMapClient.insert should throw NullPointerException"); + } catch (NullPointerException e) { + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + final SpanEventBo exceptionSpanEventBo = spanEvents.get(0); + assertThat(exceptionSpanEventBo.hasException(), is(true)); + assertThat(exceptionSpanEventBo.getExceptionId(), not(0)); + } + } + + @Test(expected=NullPointerException.class) + public void test() throws SQLException { + // Given + when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(null); + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.insert("insertShouldThrowNPE"); + } + + @Test + public void nullParametersShouldNotBeTraced() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.insert(null); + sqlMapClient.queryForList(null); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo insertSpanEventBo = spanEvents.get(0); + final SpanEventBo queryForListSpanEventBo = spanEvents.get(1); + assertThat(insertSpanEventBo.getApiId(), not(0)); + assertThat(queryForListSpanEventBo.getApiId(), not(0)); + assertThat(insertSpanEventBo.getApiId(), not(queryForListSpanEventBo.getApiId())); + + // Check Parameter + assertNull(insertSpanEventBo.getAnnotationBoList()); + assertNull(queryForListSpanEventBo.getAnnotationBoList()); + } + + @Test + public void sameApiCallsShouldHaveTheSameApiId() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.insert("insertA"); + sqlMapClient.insert("insertB"); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo insertASpanEventBo = spanEvents.get(0); + final SpanEventBo insertBSpanEventBo = spanEvents.get(1); + assertThat(insertASpanEventBo.getApiId(), not(0)); + assertThat(insertBSpanEventBo.getApiId(), not(0)); + assertThat(insertASpanEventBo.getApiId(), is(insertBSpanEventBo.getApiId())); + + } + + @Test + public void insertShouldBeTraced() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.insert("insertId"); + sqlMapClient.insert("insertId", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo insertWith1ArgSpanEventBo = spanEvents.get(0); + final SpanEventBo insertWith2ArgSpanEventBo = spanEvents.get(1); + assertThat(insertWith1ArgSpanEventBo.getApiId(), not(0)); + assertThat(insertWith2ArgSpanEventBo.getApiId(), not(0)); + assertThat(insertWith1ArgSpanEventBo.getApiId(), not(insertWith2ArgSpanEventBo.getApiId())); + + // Check Parameter + final List insertWith1ArgAnnotations = insertWith1ArgSpanEventBo.getAnnotationBoList(); + assertThat(insertWith1ArgAnnotations.size(), is(1)); + final AnnotationBo insertWith1ArgParameterAnnotation = insertWith1ArgAnnotations.get(0); + assertThat(insertWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + final List insertWith2ArgAnnotations = insertWith2ArgSpanEventBo.getAnnotationBoList(); + assertThat(insertWith2ArgAnnotations.size(), is(1)); + final AnnotationBo insertWith2ArgAnnotation = insertWith2ArgAnnotations.get(0); + assertThat(insertWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + } + + @Test + public void deleteShouldBeTraced() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.delete("deleteId"); + sqlMapClient.delete("deleteId", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo deleteWith1ArgSpanEvent = spanEvents.get(0); + final SpanEventBo deleteWith2ArgSpanEvent = spanEvents.get(1); + assertThat(deleteWith1ArgSpanEvent.getApiId(), not(0)); + assertThat(deleteWith2ArgSpanEvent.getApiId(), not(0)); + assertThat(deleteWith1ArgSpanEvent.getApiId(), not(deleteWith2ArgSpanEvent.getApiId())); + + // Check Parameter + final List deleteWith1ArgAnnotations = deleteWith1ArgSpanEvent.getAnnotationBoList(); + assertThat(deleteWith1ArgAnnotations.size(), is(1)); + final AnnotationBo deleteWith1ArgParameterAnnotation = deleteWith1ArgAnnotations.get(0); + assertThat(deleteWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + final List deleteWith2ArgAnnotations = deleteWith2ArgSpanEvent.getAnnotationBoList(); + assertThat(deleteWith2ArgAnnotations.size(), is(1)); + final AnnotationBo deleteWith2ArgAnnotation = deleteWith2ArgAnnotations.get(0); + assertThat(deleteWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Test + public void updateShouldBeTraced() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.update("updateId"); + sqlMapClient.update("updateId", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo updateWith1ArgSpanEvent = spanEvents.get(0); + final SpanEventBo updateWith2ArgSpanEvent = spanEvents.get(1); + assertThat(updateWith1ArgSpanEvent.getApiId(), not(0)); + assertThat(updateWith2ArgSpanEvent.getApiId(), not(0)); + assertThat(updateWith1ArgSpanEvent.getApiId(), not(updateWith2ArgSpanEvent.getApiId())); + + // Check Parameter + final List updateWith1ArgAnnotations = updateWith1ArgSpanEvent.getAnnotationBoList(); + assertThat(updateWith1ArgAnnotations.size(), is(1)); + final AnnotationBo updateWith1ArgParameterAnnotation = updateWith1ArgAnnotations.get(0); + assertThat(updateWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + final List updateWith2ArgAnnotations = updateWith2ArgSpanEvent.getAnnotationBoList(); + assertThat(updateWith2ArgAnnotations.size(), is(1)); + final AnnotationBo updateWith2ArgAnnotation = updateWith2ArgAnnotations.get(0); + assertThat(updateWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + } + + @Test + public void queryForListShouldBeTraced() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.queryForList("abc"); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); + assertThat(apiCallSpanEventBo.getApiId(), not(0)); + + // Check Parameter + final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); + assertThat(annotationBoList.size(), is(1)); + + final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); + assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Test + public void queryForObjectShouldBeTraced() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.queryForObject("abrgrgfdaghertah", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); + assertThat(apiCallSpanEventBo.getApiId(), not(0)); + + // Check Parameter + final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); + assertThat(annotationBoList.size(), is(1)); + + final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); + assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void transactionsShouldBeTraced() throws Exception { + // Given + SqlMapClient sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + // When + sqlMapClient.startTransaction(); + sqlMapClient.commitTransaction(); + sqlMapClient.endTransaction(); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(3)); + + // Check Method + final SpanEventBo startTransactionSpanEventBo = spanEvents.get(0); + final SpanEventBo commitTransactionSpanEventBo = spanEvents.get(1); + final SpanEventBo endTransactionSpanEventBo = spanEvents.get(2); + + assertThat(startTransactionSpanEventBo.getApiId(), not(0)); + assertThat(commitTransactionSpanEventBo.getApiId(), not(0)); + assertThat(endTransactionSpanEventBo.getApiId(), not(0)); + + assertThat(startTransactionSpanEventBo.getApiId(), not(commitTransactionSpanEventBo.getApiId())); + assertThat(commitTransactionSpanEventBo.getApiId(), not(endTransactionSpanEventBo.getApiId())); + assertThat(endTransactionSpanEventBo.getApiId(), not(startTransactionSpanEventBo.getApiId())); + + // Check Parameter + assertNull(startTransactionSpanEventBo.getAnnotationBoList()); + assertNull(commitTransactionSpanEventBo.getAnnotationBoList()); + assertNull(endTransactionSpanEventBo.getAnnotationBoList()); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifierTest.java index 0773a97de8b6..76925f010a13 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/ibatis/SqlMapSessionImplModifierTest.java @@ -1,306 +1,306 @@ -package com.nhn.pinpoint.profiler.modifier.orm.ibatis; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import static org.hamcrest.CoreMatchers.*; - -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import com.ibatis.sqlmap.client.SqlMapSession; -import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl; -import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate; -import com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl; -import com.ibatis.sqlmap.engine.scope.SessionScope; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.bo.AnnotationBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; - -/** - * @author Hyun Jeong - */ -public class SqlMapSessionImplModifierTest extends BasePinpointTest { - - public class MockSqlMapExecutorDelegate extends SqlMapExecutorDelegate { - @Override - public SessionScope beginSessionScope() { - return mockSessionScope; - } - } - - private SqlMapClientImpl sqlMapClient; - - @Mock - private MockSqlMapExecutorDelegate mockSqlMapExecutorDelegate; - @Mock - private SessionScope mockSessionScope; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(this.mockSessionScope); - this.sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); - } - - @After - public void cleanUp() throws Exception { - this.sqlMapClient = null; - } - - @Test - public void exceptionsThrownShouldBeTraced() throws Exception { - // Given - final String exceptionInsertId = "insertShouldThrowNPE"; - when(this.mockSqlMapExecutorDelegate.insert(mockSessionScope, exceptionInsertId, null)).thenThrow(new NullPointerException()); - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - try { - sqlMapSession.insert(exceptionInsertId); - fail("sqlMapSession.insert() should throw NullPointerException"); - } catch (NullPointerException e) { - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - final SpanEventBo exceptionSpanEventBo = spanEvents.get(0); - assertThat(exceptionSpanEventBo.hasException(), is(true)); - assertThat(exceptionSpanEventBo.getExceptionId(), not(0)); - } - } - - @Test - public void nullParametersShouldNotBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.insert(null); - sqlMapSession.queryForList(null); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo insertSpanEventBo = spanEvents.get(0); - final SpanEventBo queryForListSpanEventBo = spanEvents.get(1); - assertThat(insertSpanEventBo.getApiId(), not(0)); - assertThat(queryForListSpanEventBo.getApiId(), not(0)); - assertThat(insertSpanEventBo.getApiId(), not(queryForListSpanEventBo.getApiId())); - - // Check Parameter - assertNull(insertSpanEventBo.getAnnotationBoList()); - assertNull(queryForListSpanEventBo.getAnnotationBoList()); - } - - @Test - public void sameApiCallsShouldHaveTheSameApiId() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.insert("insertA"); - sqlMapSession.insert("insertB"); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo insertASpanEventBo = spanEvents.get(0); - final SpanEventBo insertBSpanEventBo = spanEvents.get(1); - assertThat(insertASpanEventBo.getApiId(), not(0)); - assertThat(insertBSpanEventBo.getApiId(), not(0)); - assertThat(insertASpanEventBo.getApiId(), is(insertBSpanEventBo.getApiId())); - - } - - @Test - public void insertShouldBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.insert("insertId"); - sqlMapSession.insert("insertId", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo insertWith1ArgSpanEventBo = spanEvents.get(0); - final SpanEventBo insertWith2ArgSpanEventBo = spanEvents.get(1); - assertThat(insertWith1ArgSpanEventBo.getApiId(), not(0)); - assertThat(insertWith2ArgSpanEventBo.getApiId(), not(0)); - assertThat(insertWith1ArgSpanEventBo.getApiId(), not(insertWith2ArgSpanEventBo.getApiId())); - - // Check Parameter - final List insertWith1ArgAnnotations = insertWith1ArgSpanEventBo.getAnnotationBoList(); - assertThat(insertWith1ArgAnnotations.size(), is(1)); - final AnnotationBo insertWith1ArgParameterAnnotation = insertWith1ArgAnnotations.get(0); - assertThat(insertWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - final List insertWith2ArgAnnotations = insertWith2ArgSpanEventBo.getAnnotationBoList(); - assertThat(insertWith2ArgAnnotations.size(), is(1)); - final AnnotationBo insertWith2ArgAnnotation = insertWith2ArgAnnotations.get(0); - assertThat(insertWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - } - - @Test - public void deleteShouldBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.delete("deleteId"); - sqlMapSession.delete("deleteId", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo deleteWith1ArgSpanEvent = spanEvents.get(0); - final SpanEventBo deleteWith2ArgSpanEvent = spanEvents.get(1); - assertThat(deleteWith1ArgSpanEvent.getApiId(), not(0)); - assertThat(deleteWith2ArgSpanEvent.getApiId(), not(0)); - assertThat(deleteWith1ArgSpanEvent.getApiId(), not(deleteWith2ArgSpanEvent.getApiId())); - - // Check Parameter - final List deleteWith1ArgAnnotations = deleteWith1ArgSpanEvent.getAnnotationBoList(); - assertThat(deleteWith1ArgAnnotations.size(), is(1)); - final AnnotationBo deleteWith1ArgParameterAnnotation = deleteWith1ArgAnnotations.get(0); - assertThat(deleteWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - final List deleteWith2ArgAnnotations = deleteWith2ArgSpanEvent.getAnnotationBoList(); - assertThat(deleteWith2ArgAnnotations.size(), is(1)); - final AnnotationBo deleteWith2ArgAnnotation = deleteWith2ArgAnnotations.get(0); - assertThat(deleteWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Test - public void updateShouldBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.update("updateId"); - sqlMapSession.update("updateId", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo updateWith1ArgSpanEvent = spanEvents.get(0); - final SpanEventBo updateWith2ArgSpanEvent = spanEvents.get(1); - assertThat(updateWith1ArgSpanEvent.getApiId(), not(0)); - assertThat(updateWith2ArgSpanEvent.getApiId(), not(0)); - assertThat(updateWith1ArgSpanEvent.getApiId(), not(updateWith2ArgSpanEvent.getApiId())); - - // Check Parameter - final List updateWith1ArgAnnotations = updateWith1ArgSpanEvent.getAnnotationBoList(); - assertThat(updateWith1ArgAnnotations.size(), is(1)); - final AnnotationBo updateWith1ArgParameterAnnotation = updateWith1ArgAnnotations.get(0); - assertThat(updateWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - final List updateWith2ArgAnnotations = updateWith2ArgSpanEvent.getAnnotationBoList(); - assertThat(updateWith2ArgAnnotations.size(), is(1)); - final AnnotationBo updateWith2ArgAnnotation = updateWith2ArgAnnotations.get(0); - assertThat(updateWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - - } - - @Test - public void queryForListShouldBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.queryForList("abc"); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); - assertThat(apiCallSpanEventBo.getApiId(), not(0)); - - // Check Parameter - final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); - assertThat(annotationBoList.size(), is(1)); - - final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); - assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Test - public void queryForObjectShouldBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.queryForObject("abrgrgfdaghertah", new Object()); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); - assertThat(apiCallSpanEventBo.getApiId(), not(0)); - - // Check Parameter - final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); - assertThat(annotationBoList.size(), is(1)); - - final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); - assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void transactionsShouldBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.startTransaction(); - sqlMapSession.commitTransaction(); - sqlMapSession.endTransaction(); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(3)); - - // Check Method - final SpanEventBo startTransactionSpanEventBo = spanEvents.get(0); - final SpanEventBo commitTransactionSpanEventBo = spanEvents.get(1); - final SpanEventBo endTransactionSpanEventBo = spanEvents.get(2); - - assertThat(startTransactionSpanEventBo.getApiId(), not(0)); - assertThat(commitTransactionSpanEventBo.getApiId(), not(0)); - assertThat(endTransactionSpanEventBo.getApiId(), not(0)); - - assertThat(startTransactionSpanEventBo.getApiId(), not(commitTransactionSpanEventBo.getApiId())); - assertThat(commitTransactionSpanEventBo.getApiId(), not(endTransactionSpanEventBo.getApiId())); - assertThat(endTransactionSpanEventBo.getApiId(), not(startTransactionSpanEventBo.getApiId())); - - // Check Parameter - assertNull(startTransactionSpanEventBo.getAnnotationBoList()); - assertNull(commitTransactionSpanEventBo.getAnnotationBoList()); - assertNull(endTransactionSpanEventBo.getAnnotationBoList()); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void closeShouldBeTraced() throws Exception { - // Given - SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); - // When - sqlMapSession.close(); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo closeSpanEventBo = spanEvents.get(0); - assertThat(closeSpanEventBo.getApiId(), not(0)); - - // Check Parameter - assertNull(closeSpanEventBo.getAnnotationBoList()); - } -} +package com.nhn.pinpoint.profiler.modifier.orm.ibatis; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import static org.hamcrest.CoreMatchers.*; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import com.ibatis.sqlmap.client.SqlMapSession; +import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl; +import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate; +import com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl; +import com.ibatis.sqlmap.engine.scope.SessionScope; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.bo.AnnotationBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; + +/** + * @author Hyun Jeong + */ +public class SqlMapSessionImplModifierTest extends BasePinpointTest { + + public class MockSqlMapExecutorDelegate extends SqlMapExecutorDelegate { + @Override + public SessionScope beginSessionScope() { + return mockSessionScope; + } + } + + private SqlMapClientImpl sqlMapClient; + + @Mock + private MockSqlMapExecutorDelegate mockSqlMapExecutorDelegate; + @Mock + private SessionScope mockSessionScope; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(this.mockSqlMapExecutorDelegate.beginSessionScope()).thenReturn(this.mockSessionScope); + this.sqlMapClient = new SqlMapClientImpl(this.mockSqlMapExecutorDelegate); + } + + @After + public void cleanUp() throws Exception { + this.sqlMapClient = null; + } + + @Test + public void exceptionsThrownShouldBeTraced() throws Exception { + // Given + final String exceptionInsertId = "insertShouldThrowNPE"; + when(this.mockSqlMapExecutorDelegate.insert(mockSessionScope, exceptionInsertId, null)).thenThrow(new NullPointerException()); + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + try { + sqlMapSession.insert(exceptionInsertId); + fail("sqlMapSession.insert() should throw NullPointerException"); + } catch (NullPointerException e) { + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + final SpanEventBo exceptionSpanEventBo = spanEvents.get(0); + assertThat(exceptionSpanEventBo.hasException(), is(true)); + assertThat(exceptionSpanEventBo.getExceptionId(), not(0)); + } + } + + @Test + public void nullParametersShouldNotBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.insert(null); + sqlMapSession.queryForList(null); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo insertSpanEventBo = spanEvents.get(0); + final SpanEventBo queryForListSpanEventBo = spanEvents.get(1); + assertThat(insertSpanEventBo.getApiId(), not(0)); + assertThat(queryForListSpanEventBo.getApiId(), not(0)); + assertThat(insertSpanEventBo.getApiId(), not(queryForListSpanEventBo.getApiId())); + + // Check Parameter + assertNull(insertSpanEventBo.getAnnotationBoList()); + assertNull(queryForListSpanEventBo.getAnnotationBoList()); + } + + @Test + public void sameApiCallsShouldHaveTheSameApiId() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.insert("insertA"); + sqlMapSession.insert("insertB"); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo insertASpanEventBo = spanEvents.get(0); + final SpanEventBo insertBSpanEventBo = spanEvents.get(1); + assertThat(insertASpanEventBo.getApiId(), not(0)); + assertThat(insertBSpanEventBo.getApiId(), not(0)); + assertThat(insertASpanEventBo.getApiId(), is(insertBSpanEventBo.getApiId())); + + } + + @Test + public void insertShouldBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.insert("insertId"); + sqlMapSession.insert("insertId", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo insertWith1ArgSpanEventBo = spanEvents.get(0); + final SpanEventBo insertWith2ArgSpanEventBo = spanEvents.get(1); + assertThat(insertWith1ArgSpanEventBo.getApiId(), not(0)); + assertThat(insertWith2ArgSpanEventBo.getApiId(), not(0)); + assertThat(insertWith1ArgSpanEventBo.getApiId(), not(insertWith2ArgSpanEventBo.getApiId())); + + // Check Parameter + final List insertWith1ArgAnnotations = insertWith1ArgSpanEventBo.getAnnotationBoList(); + assertThat(insertWith1ArgAnnotations.size(), is(1)); + final AnnotationBo insertWith1ArgParameterAnnotation = insertWith1ArgAnnotations.get(0); + assertThat(insertWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + final List insertWith2ArgAnnotations = insertWith2ArgSpanEventBo.getAnnotationBoList(); + assertThat(insertWith2ArgAnnotations.size(), is(1)); + final AnnotationBo insertWith2ArgAnnotation = insertWith2ArgAnnotations.get(0); + assertThat(insertWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + } + + @Test + public void deleteShouldBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.delete("deleteId"); + sqlMapSession.delete("deleteId", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo deleteWith1ArgSpanEvent = spanEvents.get(0); + final SpanEventBo deleteWith2ArgSpanEvent = spanEvents.get(1); + assertThat(deleteWith1ArgSpanEvent.getApiId(), not(0)); + assertThat(deleteWith2ArgSpanEvent.getApiId(), not(0)); + assertThat(deleteWith1ArgSpanEvent.getApiId(), not(deleteWith2ArgSpanEvent.getApiId())); + + // Check Parameter + final List deleteWith1ArgAnnotations = deleteWith1ArgSpanEvent.getAnnotationBoList(); + assertThat(deleteWith1ArgAnnotations.size(), is(1)); + final AnnotationBo deleteWith1ArgParameterAnnotation = deleteWith1ArgAnnotations.get(0); + assertThat(deleteWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + final List deleteWith2ArgAnnotations = deleteWith2ArgSpanEvent.getAnnotationBoList(); + assertThat(deleteWith2ArgAnnotations.size(), is(1)); + final AnnotationBo deleteWith2ArgAnnotation = deleteWith2ArgAnnotations.get(0); + assertThat(deleteWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Test + public void updateShouldBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.update("updateId"); + sqlMapSession.update("updateId", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo updateWith1ArgSpanEvent = spanEvents.get(0); + final SpanEventBo updateWith2ArgSpanEvent = spanEvents.get(1); + assertThat(updateWith1ArgSpanEvent.getApiId(), not(0)); + assertThat(updateWith2ArgSpanEvent.getApiId(), not(0)); + assertThat(updateWith1ArgSpanEvent.getApiId(), not(updateWith2ArgSpanEvent.getApiId())); + + // Check Parameter + final List updateWith1ArgAnnotations = updateWith1ArgSpanEvent.getAnnotationBoList(); + assertThat(updateWith1ArgAnnotations.size(), is(1)); + final AnnotationBo updateWith1ArgParameterAnnotation = updateWith1ArgAnnotations.get(0); + assertThat(updateWith1ArgParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + final List updateWith2ArgAnnotations = updateWith2ArgSpanEvent.getAnnotationBoList(); + assertThat(updateWith2ArgAnnotations.size(), is(1)); + final AnnotationBo updateWith2ArgAnnotation = updateWith2ArgAnnotations.get(0); + assertThat(updateWith2ArgAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + + } + + @Test + public void queryForListShouldBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.queryForList("abc"); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); + assertThat(apiCallSpanEventBo.getApiId(), not(0)); + + // Check Parameter + final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); + assertThat(annotationBoList.size(), is(1)); + + final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); + assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Test + public void queryForObjectShouldBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.queryForObject("abrgrgfdaghertah", new Object()); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo apiCallSpanEventBo = spanEvents.get(0); + assertThat(apiCallSpanEventBo.getApiId(), not(0)); + + // Check Parameter + final List annotationBoList = apiCallSpanEventBo.getAnnotationBoList(); + assertThat(annotationBoList.size(), is(1)); + + final AnnotationBo parameterAnnotationBo = annotationBoList.get(0); + assertThat(parameterAnnotationBo.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void transactionsShouldBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.startTransaction(); + sqlMapSession.commitTransaction(); + sqlMapSession.endTransaction(); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(3)); + + // Check Method + final SpanEventBo startTransactionSpanEventBo = spanEvents.get(0); + final SpanEventBo commitTransactionSpanEventBo = spanEvents.get(1); + final SpanEventBo endTransactionSpanEventBo = spanEvents.get(2); + + assertThat(startTransactionSpanEventBo.getApiId(), not(0)); + assertThat(commitTransactionSpanEventBo.getApiId(), not(0)); + assertThat(endTransactionSpanEventBo.getApiId(), not(0)); + + assertThat(startTransactionSpanEventBo.getApiId(), not(commitTransactionSpanEventBo.getApiId())); + assertThat(commitTransactionSpanEventBo.getApiId(), not(endTransactionSpanEventBo.getApiId())); + assertThat(endTransactionSpanEventBo.getApiId(), not(startTransactionSpanEventBo.getApiId())); + + // Check Parameter + assertNull(startTransactionSpanEventBo.getAnnotationBoList()); + assertNull(commitTransactionSpanEventBo.getAnnotationBoList()); + assertNull(endTransactionSpanEventBo.getAnnotationBoList()); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void closeShouldBeTraced() throws Exception { + // Given + SqlMapSession sqlMapSession = new SqlMapSessionImpl(this.sqlMapClient); + // When + sqlMapSession.close(); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo closeSpanEventBo = spanEvents.get(0); + assertThat(closeSpanEventBo.getApiId(), not(0)); + + // Check Parameter + assertNull(closeSpanEventBo.getAnnotationBoList()); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifierTest.java index a39126f465fa..90a71f451880 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/DefaultSqlSessionModifierTest.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis; - -import static org.mockito.Mockito.*; - -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.reflection.factory.ObjectFactory; -import org.apache.ibatis.session.Configuration; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.defaults.DefaultSqlSession; -import org.apache.ibatis.transaction.Transaction; -import org.junit.Test; -import org.mockito.Mock; - -/** - * @author Hyun Jeong - */ -public class DefaultSqlSessionModifierTest extends MyBatisClientModifierTest { - - @Mock - private Configuration configuration; - @Mock - private Executor executor; - - @Override - protected SqlSession getSqlSession() { - return new DefaultSqlSession(this.configuration, this.executor); - } - - @Override - @Test - public void selectMapShouldBeTraced() throws Exception { - ObjectFactory objectFactory = mock(ObjectFactory.class); - when(this.configuration.getObjectFactory()).thenReturn(objectFactory); - super.selectMapShouldBeTraced(); - } - - @Override - @Test - public void getConnectionShouldBeTraced() throws Exception { - Transaction mockTransaction = mock(Transaction.class); - when(this.executor.getTransaction()).thenReturn(mockTransaction); - } -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis; + +import static org.mockito.Mockito.*; + +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.reflection.factory.ObjectFactory; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.defaults.DefaultSqlSession; +import org.apache.ibatis.transaction.Transaction; +import org.junit.Test; +import org.mockito.Mock; + +/** + * @author Hyun Jeong + */ +public class DefaultSqlSessionModifierTest extends MyBatisClientModifierTest { + + @Mock + private Configuration configuration; + @Mock + private Executor executor; + + @Override + protected SqlSession getSqlSession() { + return new DefaultSqlSession(this.configuration, this.executor); + } + + @Override + @Test + public void selectMapShouldBeTraced() throws Exception { + ObjectFactory objectFactory = mock(ObjectFactory.class); + when(this.configuration.getObjectFactory()).thenReturn(objectFactory); + super.selectMapShouldBeTraced(); + } + + @Override + @Test + public void getConnectionShouldBeTraced() throws Exception { + Transaction mockTransaction = mock(Transaction.class); + when(this.executor.getTransaction()).thenReturn(mockTransaction); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifierTest.java index dad8266b9a61..4c94fb7ecc9c 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/MyBatisClientModifierTest.java @@ -1,276 +1,276 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.ibatis.session.SqlSession; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.MockitoAnnotations; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.bo.AnnotationBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; - -/** - * @author Hyun Jeong - */ -public abstract class MyBatisClientModifierTest extends BasePinpointTest { - - public static final int NOT_CACHED = 0; - - protected abstract SqlSession getSqlSession(); - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - } - - @After - public void cleanUp() throws Exception { - getSqlSession().close(); - } - - @Test - public void nullParameterShouldNotBeTraced() throws Exception { - // When - getSqlSession().insert(null); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo insertSpanEventBo = spanEvents.get(0); - assertThat(insertSpanEventBo.getApiId(), not(NOT_CACHED)); - - // Check Parameter - assertNull(insertSpanEventBo.getAnnotationBoList()); - } - - @Test - public void selectOneShouldBeTraced() throws Exception { - // When - getSqlSession().selectOne("selectOne"); - getSqlSession().selectOne("selectOne", null); - // Then - assertNOperations(2); - } - - @Test - public void selectListShouldBeTraced() throws Exception { - // When - getSqlSession().selectList("selectList"); - getSqlSession().selectList("selectList", null); - getSqlSession().selectList("selectList", null, null); - // Then - assertNOperations(3); - } - - @Test - public void selectMapShouldBeTraced() throws Exception { - // Given - // When - getSqlSession().selectMap("selectMap", null); - getSqlSession().selectMap("selectMap", null, null); - getSqlSession().selectMap("selectMap", null, null, null); - // Then - assertNOperations(3); - } - - @Test - public void selectShouldBeTraced() throws Exception { - // When - getSqlSession().select("select", null); - getSqlSession().select("select", null, null); - getSqlSession().select("select", null, null, null); - // Then - assertNOperations(3); - } - - @Test - public void insertShouldBeTraced() throws Exception { - // When - getSqlSession().insert("insert"); - getSqlSession().insert("insert", new Object()); - // Then - assertNOperations(2); - } - - @Test - public void updateShouldBeTraced() throws Exception { - // When - getSqlSession().update("update"); - getSqlSession().update("update", new Object()); - // Then - assertNOperations(2); - } - - @Test - public void deleteShouldBeTraced() throws Exception { - // When - getSqlSession().delete("delete"); - getSqlSession().delete("delete", new Object()); - // Then - assertNOperations(2); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void commitShouldBeTraced() throws Exception { - // When - getSqlSession().commit(); - getSqlSession().commit(true); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo commitWith0ArgSpanEvent = spanEvents.get(0); - final SpanEventBo commitWith1ArgSpanEvent = spanEvents.get(1); - assertThat(commitWith0ArgSpanEvent.getApiId(), not(NOT_CACHED)); - assertThat(commitWith1ArgSpanEvent.getApiId(), not(NOT_CACHED)); - assertThat(commitWith0ArgSpanEvent.getApiId(), not(commitWith1ArgSpanEvent.getApiId())); - - // Check Parameter - assertNull(commitWith0ArgSpanEvent.getAnnotationBoList()); - assertThat(commitWith1ArgSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void rollbackShouldBeTraced() throws Exception { - // When - getSqlSession().rollback(); - getSqlSession().rollback(true); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(2)); - - // Check Method - final SpanEventBo rollbackWith0ArgSpanEvent = spanEvents.get(0); - final SpanEventBo rollbackWith1ArgSpanEvent = spanEvents.get(1); - assertThat(rollbackWith0ArgSpanEvent.getApiId(), not(NOT_CACHED)); - assertThat(rollbackWith1ArgSpanEvent.getApiId(), not(NOT_CACHED)); - assertThat(rollbackWith0ArgSpanEvent.getApiId(), not(rollbackWith1ArgSpanEvent.getApiId())); - - // Check Parameter - assertNull(rollbackWith0ArgSpanEvent.getAnnotationBoList()); - assertThat(rollbackWith1ArgSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void flushStatementsShouldBeTraced() throws Exception { - // When - getSqlSession().flushStatements(); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo flushStatementsSpanEvent = spanEvents.get(0); - assertThat(flushStatementsSpanEvent.getApiId(), not(NOT_CACHED)); - - // Check Parameter - assertNull(flushStatementsSpanEvent.getAnnotationBoList()); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void closeShouldBeTraced() throws Exception { - // When - getSqlSession().close(); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo closeSpanEvent = spanEvents.get(0); - assertThat(closeSpanEvent.getApiId(), not(NOT_CACHED)); - - // Check Parameter - assertNull(closeSpanEvent.getAnnotationBoList()); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void getConfigurationShouldBeTraced() throws Exception { - // When - getSqlSession().getConfiguration(); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo getConfigurationSpanEvent = spanEvents.get(0); - assertThat(getConfigurationSpanEvent.getApiId(), not(NOT_CACHED)); - - // Check Parameter - assertNull(getConfigurationSpanEvent.getAnnotationBoList()); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void getMapperShouldBeTraced() throws Exception { - // Given - class SomeBean {} - // When - getSqlSession().getMapper(SomeBean.class); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo getConnectionSpanEvent = spanEvents.get(0); - assertThat(getConnectionSpanEvent.getApiId(), not(NOT_CACHED)); - - // Check Parameter - assertThat(getConnectionSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Test - public void getConnectionShouldBeTraced() throws Exception { - // When - getSqlSession().getConnection(); - // Then - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - - // Check Method - final SpanEventBo getConnectionSpanEvent = spanEvents.get(0); - assertThat(getConnectionSpanEvent.getApiId(), not(NOT_CACHED)); - - // Check Parameter - assertNull(getConnectionSpanEvent.getAnnotationBoList()); - } - - private void assertNOperations(int numOperations) { - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(numOperations)); - - final Set uniqueApiIds = new HashSet(); - for (int n = 0; n < numOperations; ++n) { - final SpanEventBo apiSpanEvent = spanEvents.get(n); - uniqueApiIds.add(apiSpanEvent.getApiId()); - // Check Method - assertThat(apiSpanEvent.getApiId(), not(NOT_CACHED)); - // Check Parameter - final List apiAnnotations = apiSpanEvent.getAnnotationBoList(); - assertThat(apiAnnotations.size(), is(1)); - final AnnotationBo apiParameterAnnotation = apiAnnotations.get(0); - assertThat(apiParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); - } - assertThat(uniqueApiIds.size(), is(numOperations)); - } - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.ibatis.session.SqlSession; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.MockitoAnnotations; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.bo.AnnotationBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; + +/** + * @author Hyun Jeong + */ +public abstract class MyBatisClientModifierTest extends BasePinpointTest { + + public static final int NOT_CACHED = 0; + + protected abstract SqlSession getSqlSession(); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @After + public void cleanUp() throws Exception { + getSqlSession().close(); + } + + @Test + public void nullParameterShouldNotBeTraced() throws Exception { + // When + getSqlSession().insert(null); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo insertSpanEventBo = spanEvents.get(0); + assertThat(insertSpanEventBo.getApiId(), not(NOT_CACHED)); + + // Check Parameter + assertNull(insertSpanEventBo.getAnnotationBoList()); + } + + @Test + public void selectOneShouldBeTraced() throws Exception { + // When + getSqlSession().selectOne("selectOne"); + getSqlSession().selectOne("selectOne", null); + // Then + assertNOperations(2); + } + + @Test + public void selectListShouldBeTraced() throws Exception { + // When + getSqlSession().selectList("selectList"); + getSqlSession().selectList("selectList", null); + getSqlSession().selectList("selectList", null, null); + // Then + assertNOperations(3); + } + + @Test + public void selectMapShouldBeTraced() throws Exception { + // Given + // When + getSqlSession().selectMap("selectMap", null); + getSqlSession().selectMap("selectMap", null, null); + getSqlSession().selectMap("selectMap", null, null, null); + // Then + assertNOperations(3); + } + + @Test + public void selectShouldBeTraced() throws Exception { + // When + getSqlSession().select("select", null); + getSqlSession().select("select", null, null); + getSqlSession().select("select", null, null, null); + // Then + assertNOperations(3); + } + + @Test + public void insertShouldBeTraced() throws Exception { + // When + getSqlSession().insert("insert"); + getSqlSession().insert("insert", new Object()); + // Then + assertNOperations(2); + } + + @Test + public void updateShouldBeTraced() throws Exception { + // When + getSqlSession().update("update"); + getSqlSession().update("update", new Object()); + // Then + assertNOperations(2); + } + + @Test + public void deleteShouldBeTraced() throws Exception { + // When + getSqlSession().delete("delete"); + getSqlSession().delete("delete", new Object()); + // Then + assertNOperations(2); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void commitShouldBeTraced() throws Exception { + // When + getSqlSession().commit(); + getSqlSession().commit(true); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo commitWith0ArgSpanEvent = spanEvents.get(0); + final SpanEventBo commitWith1ArgSpanEvent = spanEvents.get(1); + assertThat(commitWith0ArgSpanEvent.getApiId(), not(NOT_CACHED)); + assertThat(commitWith1ArgSpanEvent.getApiId(), not(NOT_CACHED)); + assertThat(commitWith0ArgSpanEvent.getApiId(), not(commitWith1ArgSpanEvent.getApiId())); + + // Check Parameter + assertNull(commitWith0ArgSpanEvent.getAnnotationBoList()); + assertThat(commitWith1ArgSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void rollbackShouldBeTraced() throws Exception { + // When + getSqlSession().rollback(); + getSqlSession().rollback(true); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(2)); + + // Check Method + final SpanEventBo rollbackWith0ArgSpanEvent = spanEvents.get(0); + final SpanEventBo rollbackWith1ArgSpanEvent = spanEvents.get(1); + assertThat(rollbackWith0ArgSpanEvent.getApiId(), not(NOT_CACHED)); + assertThat(rollbackWith1ArgSpanEvent.getApiId(), not(NOT_CACHED)); + assertThat(rollbackWith0ArgSpanEvent.getApiId(), not(rollbackWith1ArgSpanEvent.getApiId())); + + // Check Parameter + assertNull(rollbackWith0ArgSpanEvent.getAnnotationBoList()); + assertThat(rollbackWith1ArgSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void flushStatementsShouldBeTraced() throws Exception { + // When + getSqlSession().flushStatements(); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo flushStatementsSpanEvent = spanEvents.get(0); + assertThat(flushStatementsSpanEvent.getApiId(), not(NOT_CACHED)); + + // Check Parameter + assertNull(flushStatementsSpanEvent.getAnnotationBoList()); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void closeShouldBeTraced() throws Exception { + // When + getSqlSession().close(); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo closeSpanEvent = spanEvents.get(0); + assertThat(closeSpanEvent.getApiId(), not(NOT_CACHED)); + + // Check Parameter + assertNull(closeSpanEvent.getAnnotationBoList()); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void getConfigurationShouldBeTraced() throws Exception { + // When + getSqlSession().getConfiguration(); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo getConfigurationSpanEvent = spanEvents.get(0); + assertThat(getConfigurationSpanEvent.getApiId(), not(NOT_CACHED)); + + // Check Parameter + assertNull(getConfigurationSpanEvent.getAnnotationBoList()); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void getMapperShouldBeTraced() throws Exception { + // Given + class SomeBean {} + // When + getSqlSession().getMapper(SomeBean.class); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo getConnectionSpanEvent = spanEvents.get(0); + assertThat(getConnectionSpanEvent.getApiId(), not(NOT_CACHED)); + + // Check Parameter + assertThat(getConnectionSpanEvent.getAnnotationBoList().get(0).getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Test + public void getConnectionShouldBeTraced() throws Exception { + // When + getSqlSession().getConnection(); + // Then + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + + // Check Method + final SpanEventBo getConnectionSpanEvent = spanEvents.get(0); + assertThat(getConnectionSpanEvent.getApiId(), not(NOT_CACHED)); + + // Check Parameter + assertNull(getConnectionSpanEvent.getAnnotationBoList()); + } + + private void assertNOperations(int numOperations) { + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(numOperations)); + + final Set uniqueApiIds = new HashSet(); + for (int n = 0; n < numOperations; ++n) { + final SpanEventBo apiSpanEvent = spanEvents.get(n); + uniqueApiIds.add(apiSpanEvent.getApiId()); + // Check Method + assertThat(apiSpanEvent.getApiId(), not(NOT_CACHED)); + // Check Parameter + final List apiAnnotations = apiSpanEvent.getAnnotationBoList(); + assertThat(apiAnnotations.size(), is(1)); + final AnnotationBo apiParameterAnnotation = apiAnnotations.get(0); + assertThat(apiParameterAnnotation.getKey(), is(AnnotationKey.CACHE_ARGS0.getCode())); + } + assertThat(uniqueApiIds.size(), is(numOperations)); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifierTest.java index 2ab00abd6a94..0f51ef918360 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/orm/mybatis/SqlSessionTemplateModifierTest.java @@ -1,123 +1,123 @@ -package com.nhn.pinpoint.profiler.modifier.orm.mybatis; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; - -import java.util.List; - -import javax.sql.DataSource; - -import org.apache.ibatis.mapping.Environment; -import org.apache.ibatis.session.Configuration; -import org.apache.ibatis.session.ExecutorType; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; -import org.apache.ibatis.transaction.TransactionFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.Mock; -import org.mybatis.spring.SqlSessionTemplate; - -import com.nhn.pinpoint.common.bo.SpanEventBo; - -/** - * @author Hyun Jeong - */ -public class SqlSessionTemplateModifierTest extends MyBatisClientModifierTest { - - private static final ExecutorType executorType = ExecutorType.SIMPLE; - - private SqlSessionTemplate sqlSessionTemplate; - - @Mock - private SqlSessionFactory sqlSessionFactory; - - @Mock - private SqlSession sqlSession; - - @Override - protected SqlSession getSqlSession() { - return this.sqlSessionTemplate; - } - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - setUpSqlSessionFactory(); - setUpSqlSession(); - this.sqlSessionTemplate = new SqlSessionTemplate(this.sqlSessionFactory, executorType); - } - - private void setUpSqlSessionFactory() throws Exception { - Configuration configuration = mock(Configuration.class); - TransactionFactory transactionFactory = mock(TransactionFactory.class); - DataSource dataSource = mock(DataSource.class); - Environment environment = new Environment("test", transactionFactory, dataSource); - when(this.sqlSessionFactory.getConfiguration()).thenReturn(configuration); - when(configuration.getEnvironment()).thenReturn(environment); - } - - private void setUpSqlSession() throws Exception { - when(this.sqlSessionFactory.openSession(executorType)).thenReturn(this.sqlSession); - } - - @Override - @After - public void cleanUp() throws Exception { - // Should not manually close SqlSessionTemplate - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Override - @Test - public void commitShouldBeTraced() throws Exception { - try { - super.commitShouldBeTraced(); - fail("SqlSessionTemplate cannot manually call commit."); - } catch (UnsupportedOperationException e) { - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - final SpanEventBo commitSpanEventBo = spanEvents.get(0); - assertThat(commitSpanEventBo.hasException(), is(true)); - assertThat(commitSpanEventBo.getExceptionId(), not(NOT_CACHED)); - } - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Override - @Test - public void rollbackShouldBeTraced() throws Exception { - try { - super.rollbackShouldBeTraced(); - fail("SqlSessionTemplate cannot manually call rollback."); - } catch (UnsupportedOperationException e) { - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - final SpanEventBo rollbackSpanEventBo = spanEvents.get(0); - assertThat(rollbackSpanEventBo.hasException(), is(true)); - assertThat(rollbackSpanEventBo.getExceptionId(), not(NOT_CACHED)); - } - } - - @Ignore // 쿼리 작업만 tracing 하도록 변경 - @Override - @Test - public void closeShouldBeTraced() throws Exception { - try { - super.closeShouldBeTraced(); - } catch (UnsupportedOperationException e) { - final List spanEvents = getCurrentSpanEvents(); - assertThat(spanEvents.size(), is(1)); - final SpanEventBo closeSpanEventBo = spanEvents.get(0); - assertThat(closeSpanEventBo.hasException(), is(true)); - assertThat(closeSpanEventBo.getExceptionId(), not(NOT_CACHED)); - } - } - - -} +package com.nhn.pinpoint.profiler.modifier.orm.mybatis; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; + +import java.util.List; + +import javax.sql.DataSource; + +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.transaction.TransactionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mock; +import org.mybatis.spring.SqlSessionTemplate; + +import com.nhn.pinpoint.common.bo.SpanEventBo; + +/** + * @author Hyun Jeong + */ +public class SqlSessionTemplateModifierTest extends MyBatisClientModifierTest { + + private static final ExecutorType executorType = ExecutorType.SIMPLE; + + private SqlSessionTemplate sqlSessionTemplate; + + @Mock + private SqlSessionFactory sqlSessionFactory; + + @Mock + private SqlSession sqlSession; + + @Override + protected SqlSession getSqlSession() { + return this.sqlSessionTemplate; + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + setUpSqlSessionFactory(); + setUpSqlSession(); + this.sqlSessionTemplate = new SqlSessionTemplate(this.sqlSessionFactory, executorType); + } + + private void setUpSqlSessionFactory() throws Exception { + Configuration configuration = mock(Configuration.class); + TransactionFactory transactionFactory = mock(TransactionFactory.class); + DataSource dataSource = mock(DataSource.class); + Environment environment = new Environment("test", transactionFactory, dataSource); + when(this.sqlSessionFactory.getConfiguration()).thenReturn(configuration); + when(configuration.getEnvironment()).thenReturn(environment); + } + + private void setUpSqlSession() throws Exception { + when(this.sqlSessionFactory.openSession(executorType)).thenReturn(this.sqlSession); + } + + @Override + @After + public void cleanUp() throws Exception { + // Should not manually close SqlSessionTemplate + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Override + @Test + public void commitShouldBeTraced() throws Exception { + try { + super.commitShouldBeTraced(); + fail("SqlSessionTemplate cannot manually call commit."); + } catch (UnsupportedOperationException e) { + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + final SpanEventBo commitSpanEventBo = spanEvents.get(0); + assertThat(commitSpanEventBo.hasException(), is(true)); + assertThat(commitSpanEventBo.getExceptionId(), not(NOT_CACHED)); + } + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Override + @Test + public void rollbackShouldBeTraced() throws Exception { + try { + super.rollbackShouldBeTraced(); + fail("SqlSessionTemplate cannot manually call rollback."); + } catch (UnsupportedOperationException e) { + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + final SpanEventBo rollbackSpanEventBo = spanEvents.get(0); + assertThat(rollbackSpanEventBo.hasException(), is(true)); + assertThat(rollbackSpanEventBo.getExceptionId(), not(NOT_CACHED)); + } + } + + @Ignore // 쿼리 작업만 tracing 하도록 변경 + @Override + @Test + public void closeShouldBeTraced() throws Exception { + try { + super.closeShouldBeTraced(); + } catch (UnsupportedOperationException e) { + final List spanEvents = getCurrentSpanEvents(); + assertThat(spanEvents.size(), is(1)); + final SpanEventBo closeSpanEventBo = spanEvents.get(0); + assertThat(closeSpanEventBo.hasException(), is(true)); + assertThat(closeSpanEventBo.getExceptionId(), not(NOT_CACHED)); + } + } + + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/tomcat/InvokeMethodInterceptorTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/tomcat/InvokeMethodInterceptorTest.java index ee33f8f13a35..0c4784031e9a 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/tomcat/InvokeMethodInterceptorTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/tomcat/InvokeMethodInterceptorTest.java @@ -1,115 +1,115 @@ -package com.nhn.pinpoint.profiler.modifier.tomcat; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.Enumeration; -import java.util.UUID; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.nhn.pinpoint.bootstrap.context.Header; -import com.nhn.pinpoint.profiler.context.MockTraceContextFactory; -import com.nhn.pinpoint.bootstrap.context.TraceContext; -import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.StandardHostValveInvokeInterceptor; - -/** - * @author emeroad - */ -public class InvokeMethodInterceptorTest { - @BeforeClass - public static void before() { - PLoggerFactory.initialize(new Slf4jLoggerBinder()); - } - - @Test - public void testHeaderNOTExists() { - - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - - when(request.getRequestURI()).thenReturn("/hellotest.nhn"); - when(request.getRemoteAddr()).thenReturn("10.0.0.1"); - when(request.getHeader(Header.HTTP_TRACE_ID.toString())).thenReturn(null); - when(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString())).thenReturn(null); - when(request.getHeader(Header.HTTP_SPAN_ID.toString())).thenReturn(null); - when(request.getHeader(Header.HTTP_SAMPLED.toString())).thenReturn(null); - when(request.getHeader(Header.HTTP_FLAGS.toString())).thenReturn(null); - - Enumeration enumeration = mock(Enumeration.class); - when(request.getParameterNames()).thenReturn(enumeration); - - StandardHostValveInvokeInterceptor interceptor = new StandardHostValveInvokeInterceptor(); - TraceContext traceContext = new MockTraceContextFactory().create(); - interceptor.setTraceContext(traceContext); - - interceptor.before("target", new Object[]{request, response}); - interceptor.after("target", new Object[]{request, response}, new Object(), null); - - interceptor.before("target", new Object[]{request, response}); - interceptor.after("target", new Object[]{request, response}, new Object(), null); - } - - @Test - public void testInvalidHeaderExists() { - - // TODO 결과값 검증 필요. - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - - when(request.getRequestURI()).thenReturn("/hellotest.nhn"); - when(request.getRemoteAddr()).thenReturn("10.0.0.1"); - when(request.getHeader(Header.HTTP_TRACE_ID.toString())).thenReturn("TRACEID"); - when(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString())).thenReturn("PARENTSPANID"); - when(request.getHeader(Header.HTTP_SPAN_ID.toString())).thenReturn("SPANID"); - when(request.getHeader(Header.HTTP_SAMPLED.toString())).thenReturn("false"); - when(request.getHeader(Header.HTTP_FLAGS.toString())).thenReturn("0"); - - Enumeration enumeration = mock(Enumeration.class); - when(request.getParameterNames()).thenReturn(enumeration); - - TraceContext traceContext = new MockTraceContextFactory().create(); - StandardHostValveInvokeInterceptor interceptor = new StandardHostValveInvokeInterceptor(); - interceptor.setTraceContext(traceContext); - interceptor.before("target", new Object[]{request, response}); - interceptor.after("target", new Object[]{request, response}, new Object(), null); - - interceptor.before("target", new Object[]{request, response}); - interceptor.after("target", new Object[]{request, response}, new Object(), null); - } - - @Test - public void testValidHeaderExists() { - - // TODO 결과값 검증 필요. - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - - when(request.getRequestURI()).thenReturn("/hellotest.nhn"); - when(request.getRemoteAddr()).thenReturn("10.0.0.1"); - when(request.getHeader(Header.HTTP_TRACE_ID.toString())).thenReturn(UUID.randomUUID().toString()); - when(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString())).thenReturn("PARENTSPANID"); - when(request.getHeader(Header.HTTP_SPAN_ID.toString())).thenReturn("SPANID"); - when(request.getHeader(Header.HTTP_SAMPLED.toString())).thenReturn("false"); - when(request.getHeader(Header.HTTP_FLAGS.toString())).thenReturn("0"); - - Enumeration enumeration = mock(Enumeration.class); - when(request.getParameterNames()).thenReturn(enumeration); - - TraceContext traceContext = new MockTraceContextFactory().create(); - StandardHostValveInvokeInterceptor interceptor = new StandardHostValveInvokeInterceptor(); - interceptor.setTraceContext(traceContext); - - interceptor.before("target", new Object[]{request, response}); - interceptor.after("target", new Object[]{request, response}, new Object(), null); - - interceptor.before("target", new Object[]{request, response}); - interceptor.after("target", new Object[]{request, response}, new Object(), null); - } -} +package com.nhn.pinpoint.profiler.modifier.tomcat; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Enumeration; +import java.util.UUID; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.nhn.pinpoint.bootstrap.context.Header; +import com.nhn.pinpoint.profiler.context.MockTraceContextFactory; +import com.nhn.pinpoint.bootstrap.context.TraceContext; +import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; +import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.nhn.pinpoint.profiler.modifier.tomcat.interceptor.StandardHostValveInvokeInterceptor; + +/** + * @author emeroad + */ +public class InvokeMethodInterceptorTest { + @BeforeClass + public static void before() { + PLoggerFactory.initialize(new Slf4jLoggerBinder()); + } + + @Test + public void testHeaderNOTExists() { + + HttpServletRequest request = mock(HttpServletRequest.class); + HttpServletResponse response = mock(HttpServletResponse.class); + + when(request.getRequestURI()).thenReturn("/hellotest.nhn"); + when(request.getRemoteAddr()).thenReturn("10.0.0.1"); + when(request.getHeader(Header.HTTP_TRACE_ID.toString())).thenReturn(null); + when(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString())).thenReturn(null); + when(request.getHeader(Header.HTTP_SPAN_ID.toString())).thenReturn(null); + when(request.getHeader(Header.HTTP_SAMPLED.toString())).thenReturn(null); + when(request.getHeader(Header.HTTP_FLAGS.toString())).thenReturn(null); + + Enumeration enumeration = mock(Enumeration.class); + when(request.getParameterNames()).thenReturn(enumeration); + + StandardHostValveInvokeInterceptor interceptor = new StandardHostValveInvokeInterceptor(); + TraceContext traceContext = new MockTraceContextFactory().create(); + interceptor.setTraceContext(traceContext); + + interceptor.before("target", new Object[]{request, response}); + interceptor.after("target", new Object[]{request, response}, new Object(), null); + + interceptor.before("target", new Object[]{request, response}); + interceptor.after("target", new Object[]{request, response}, new Object(), null); + } + + @Test + public void testInvalidHeaderExists() { + + // TODO 결과값 검증 필요. + HttpServletRequest request = mock(HttpServletRequest.class); + HttpServletResponse response = mock(HttpServletResponse.class); + + when(request.getRequestURI()).thenReturn("/hellotest.nhn"); + when(request.getRemoteAddr()).thenReturn("10.0.0.1"); + when(request.getHeader(Header.HTTP_TRACE_ID.toString())).thenReturn("TRACEID"); + when(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString())).thenReturn("PARENTSPANID"); + when(request.getHeader(Header.HTTP_SPAN_ID.toString())).thenReturn("SPANID"); + when(request.getHeader(Header.HTTP_SAMPLED.toString())).thenReturn("false"); + when(request.getHeader(Header.HTTP_FLAGS.toString())).thenReturn("0"); + + Enumeration enumeration = mock(Enumeration.class); + when(request.getParameterNames()).thenReturn(enumeration); + + TraceContext traceContext = new MockTraceContextFactory().create(); + StandardHostValveInvokeInterceptor interceptor = new StandardHostValveInvokeInterceptor(); + interceptor.setTraceContext(traceContext); + interceptor.before("target", new Object[]{request, response}); + interceptor.after("target", new Object[]{request, response}, new Object(), null); + + interceptor.before("target", new Object[]{request, response}); + interceptor.after("target", new Object[]{request, response}, new Object(), null); + } + + @Test + public void testValidHeaderExists() { + + // TODO 결과값 검증 필요. + HttpServletRequest request = mock(HttpServletRequest.class); + HttpServletResponse response = mock(HttpServletResponse.class); + + when(request.getRequestURI()).thenReturn("/hellotest.nhn"); + when(request.getRemoteAddr()).thenReturn("10.0.0.1"); + when(request.getHeader(Header.HTTP_TRACE_ID.toString())).thenReturn(UUID.randomUUID().toString()); + when(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString())).thenReturn("PARENTSPANID"); + when(request.getHeader(Header.HTTP_SPAN_ID.toString())).thenReturn("SPANID"); + when(request.getHeader(Header.HTTP_SAMPLED.toString())).thenReturn("false"); + when(request.getHeader(Header.HTTP_FLAGS.toString())).thenReturn("0"); + + Enumeration enumeration = mock(Enumeration.class); + when(request.getParameterNames()).thenReturn(enumeration); + + TraceContext traceContext = new MockTraceContextFactory().create(); + StandardHostValveInvokeInterceptor interceptor = new StandardHostValveInvokeInterceptor(); + interceptor.setTraceContext(traceContext); + + interceptor.before("target", new Object[]{request, response}); + interceptor.after("target", new Object[]{request, response}, new Object(), null); + + interceptor.before("target", new Object[]{request, response}); + interceptor.after("target", new Object[]{request, response}, new Object(), null); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/tomcat/StandardHostValveInvokeModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/tomcat/StandardHostValveInvokeModifierTest.java new file mode 100644 index 000000000000..69277324b1f6 --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/tomcat/StandardHostValveInvokeModifierTest.java @@ -0,0 +1,137 @@ +package com.nhn.pinpoint.profiler.modifier.tomcat; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.util.Enumeration; +import java.util.List; + +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.catalina.core.StandardHost; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import com.nhn.pinpoint.bootstrap.context.Header; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.util.TransactionIdUtils; +import com.nhn.pinpoint.profiler.junit4.BasePinpointTest; +import com.nhn.pinpoint.profiler.junit4.IsRootSpan; + +/** + * @author hyungil.jeong + */ +public class StandardHostValveInvokeModifierTest extends BasePinpointTest { + + private static final ServiceType SERVICE_TYPE = ServiceType.TOMCAT; + private static final String REQUEST_URI = "testRequestUri"; + private static final String SERVER_NAME = "serverForTest"; + private static final int SERVER_PORT = 19999; + private static final String REMOTE_ADDRESS = "1.1.1.1"; + private static final Enumeration EMPTY_PARAM_KEYS = new Enumeration() { + @Override + public boolean hasMoreElements() { + return false; + } + + @Override + public String nextElement() { + return null; + } + }; + + private StandardHost host; + + @Mock + private Request mockRequest; + @Mock + private Response mockResponse; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + initMockRequest(); + // StandardHost's default constructor sets StandardHostValve as the first item in the pipeline. + host = new StandardHost(); + } + + private void initMockRequest() { + when(mockRequest.getRequestURI()).thenReturn(REQUEST_URI); + when(mockRequest.getServerName()).thenReturn(SERVER_NAME); + when(mockRequest.getServerPort()).thenReturn(SERVER_PORT); + when(mockRequest.getRemoteAddr()).thenReturn(REMOTE_ADDRESS); + when(mockRequest.getParameterNames()).thenReturn(EMPTY_PARAM_KEYS); + } + + @Test + @IsRootSpan + public void invokeShouldBeTraced() throws Exception { + // Given + // When + host.invoke(mockRequest, mockResponse); + // Then + final List rootSpans = getCurrentRootSpans(); + assertEquals(rootSpans.size(), 1); + + final SpanBo rootSpan = rootSpans.get(0); + assertEquals(rootSpan.getParentSpanId(), -1); + assertEquals(rootSpan.getServiceType(), SERVICE_TYPE); + assertEquals(rootSpan.getRpc(), REQUEST_URI); + assertEquals(rootSpan.getEndPoint(), SERVER_NAME + ":" + SERVER_PORT); + assertEquals(rootSpan.getRemoteAddr(), REMOTE_ADDRESS); + } + + @Test + @IsRootSpan + public void invokeShouldTraceExceptions() throws Exception { + // Given + when(mockRequest.getContext()).thenThrow(new RuntimeException("expected exception.")); + // When + try { + host.invoke(mockRequest, mockResponse); + assertTrue(false); + } catch (RuntimeException e) { + // Then + final List rootSpans = getCurrentRootSpans(); + assertEquals(rootSpans.size(), 1); + + final SpanBo rootSpan = rootSpans.get(0); + assertEquals(rootSpan.getParentSpanId(), -1); + assertEquals(rootSpan.getServiceType(), SERVICE_TYPE); + assertTrue(rootSpan.hasException()); + } + } + + @Test + @IsRootSpan + public void invokeShouldContinueTracingFromRequest() throws Exception { + // Given + // Set Transaction ID from remote source. + final String sourceAgentId = "agentId"; + final long sourceAgentStartTime = 1234567890123L; + final long sourceTransactionSequence = 12345678L; + final String sourceTransactionId = TransactionIdUtils.formatString(sourceAgentId, sourceAgentStartTime, sourceTransactionSequence); + when(mockRequest.getHeader(Header.HTTP_TRACE_ID.toString())).thenReturn(sourceTransactionId); + // Set parent Span ID from remote source. + final long sourceParentId = 99999; + when(mockRequest.getHeader(Header.HTTP_PARENT_SPAN_ID.toString())).thenReturn(String.valueOf(sourceParentId)); + // When + host.invoke(mockRequest, mockResponse); + // Then + final List rootSpans = getCurrentRootSpans(); + assertEquals(rootSpans.size(), 1); + + final SpanBo rootSpan = rootSpans.get(0); + // Check Transaction ID from remote source. + assertEquals(rootSpan.getTransactionId(), sourceTransactionId); + assertEquals(rootSpan.getTraceAgentId(), sourceAgentId); + assertEquals(rootSpan.getTraceAgentStartTime(), sourceAgentStartTime); + assertEquals(rootSpan.getTraceTransactionSequence(), sourceTransactionSequence); + // Check parent Span ID from remote source. + assertEquals(rootSpan.getParentSpanId(), sourceParentId); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistryTest.java index 167e288f2008..7da68da1de24 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistryTest.java @@ -21,8 +21,12 @@ import com.nhn.pinpoint.thrift.dto.TAgentStat._Fields; import com.nhn.pinpoint.profiler.monitor.codahale.MetricHistogramMonitor; import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MetricMonitorRegistryTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + MetricMonitorRegistry registry = new MetricMonitorRegistry(); @@ -111,18 +115,18 @@ public void mapper() { MetricRegistry r = registry.getRegistry(); Map map = r.getGauges(); // for (Entry each : map.entrySet()) { -// System.out.println(each.getKey() + " : " + each.getValue().getValue().getClass()); +// logger.debug(each.getKey() + " : " + each.getValue().getValue().getClass()); // } // for (Entry<_Fields, FieldMetaData> each : TAgentStat.metaDataMap.entrySet()) { - System.out.println(toMetricName(each.getKey().name())); + logger.debug(toMetricName(each.getKey().name())); Gauge value = map.get(toMetricName(each.getKey().name())); if (value != null) { agentStat.setFieldValue(each.getKey(), value.getValue()); } } - - System.out.println(agentStat); + + logger.debug("{}", agentStat); } } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetricTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetricTest.java index 5a5bccafa8c9..3f3be0f27805 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetricTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/DefaultRpcMetricTest.java @@ -1,31 +1,31 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.ServiceType; -import junit.framework.Assert; -import org.junit.Test; - -import java.util.List; - - -public class DefaultRpcMetricTest { - - @Test - public void testAddResponseTime() throws Exception { - - HistogramSchema schema = ServiceType.HTTP_CLIENT.getHistogramSchema(); - DefaultRpcMetric metric = new DefaultRpcMetric(ServiceType.HTTP_CLIENT); - metric.addResponseTime("test1", schema.getFastSlot().getSlotTime()); - - metric.addResponseTime("test2", schema.getSlowSlot().getSlotTime()); - metric.addResponseTime("test2", schema.getSlowSlot().getSlotTime()); - - metric.addResponseTime("test3", schema.getErrorSlot().getSlotTime()); - metric.addResponseTime("test3", schema.getErrorSlot().getSlotTime()); - metric.addResponseTime("test3", schema.getErrorSlot().getSlotTime()); - - List snapshotList = metric.createSnapshotList(); - Assert.assertEquals(snapshotList.size(), 3); - - } +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.ServiceType; +import junit.framework.Assert; +import org.junit.Test; + +import java.util.List; + + +public class DefaultRpcMetricTest { + + @Test + public void testAddResponseTime() throws Exception { + + HistogramSchema schema = ServiceType.HTTP_CLIENT.getHistogramSchema(); + DefaultRpcMetric metric = new DefaultRpcMetric(ServiceType.HTTP_CLIENT); + metric.addResponseTime("test1", schema.getFastSlot().getSlotTime()); + + metric.addResponseTime("test2", schema.getSlowSlot().getSlotTime()); + metric.addResponseTime("test2", schema.getSlowSlot().getSlotTime()); + + metric.addResponseTime("test3", schema.getErrorSlot().getSlotTime()); + metric.addResponseTime("test3", schema.getErrorSlot().getSlotTime()); + metric.addResponseTime("test3", schema.getErrorSlot().getSlotTime()); + + List snapshotList = metric.createSnapshotList(); + Assert.assertEquals(snapshotList.size(), 3); + + } } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramTest.java index 2018d969309d..787e11588b38 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/HistogramTest.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.ServiceType; -import org.junit.Assert; -import org.junit.Test; - - -public class HistogramTest { - - @Test - public void testAddResponseTime() throws Exception { - HistogramSchema schema = ServiceType.TOMCAT.getHistogramSchema(); - LongAdderHistogram histogram = new LongAdderHistogram(ServiceType.TOMCAT); - histogram.addResponseTime(1000); - - histogram.addResponseTime(3000); - histogram.addResponseTime(3000); - - histogram.addResponseTime(5000); - histogram.addResponseTime(5000); - histogram.addResponseTime(5000); - - histogram.addResponseTime(6000); - histogram.addResponseTime(6000); - histogram.addResponseTime(6000); - histogram.addResponseTime(6000); - - histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); - histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); - histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); - histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); - histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); - - - HistogramSnapshot snapshot = histogram.createSnapshot(); - Assert.assertEquals(snapshot.getFastCount(), 1); - Assert.assertEquals(snapshot.getNormalCount(), 2); - Assert.assertEquals(snapshot.getSlowCount(), 3); - Assert.assertEquals(snapshot.getVerySlowCount(), 4); - Assert.assertEquals(snapshot.getErrorCount(), 5); - } - +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.ServiceType; +import org.junit.Assert; +import org.junit.Test; + + +public class HistogramTest { + + @Test + public void testAddResponseTime() throws Exception { + HistogramSchema schema = ServiceType.TOMCAT.getHistogramSchema(); + LongAdderHistogram histogram = new LongAdderHistogram(ServiceType.TOMCAT); + histogram.addResponseTime(1000); + + histogram.addResponseTime(3000); + histogram.addResponseTime(3000); + + histogram.addResponseTime(5000); + histogram.addResponseTime(5000); + histogram.addResponseTime(5000); + + histogram.addResponseTime(6000); + histogram.addResponseTime(6000); + histogram.addResponseTime(6000); + histogram.addResponseTime(6000); + + histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); + histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); + histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); + histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); + histogram.addResponseTime(schema.getErrorSlot().getSlotTime()); + + + HistogramSnapshot snapshot = histogram.createSnapshot(); + Assert.assertEquals(snapshot.getFastCount(), 1); + Assert.assertEquals(snapshot.getNormalCount(), 2); + Assert.assertEquals(snapshot.getSlowCount(), 3); + Assert.assertEquals(snapshot.getVerySlowCount(), 4); + Assert.assertEquals(snapshot.getErrorCount(), 5); + } + } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistryTest.java index 64bad69f9b7d..819189536df5 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/MetricRegistryTest.java @@ -1,35 +1,35 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.ServiceType; -import junit.framework.Assert; -import org.junit.Test; - -public class MetricRegistryTest { - - @Test - public void testSuccess() { - MetricRegistry metricRegistry = new MetricRegistry(ServiceType.TOMCAT); - RpcMetric rpcMetric = metricRegistry.getRpcMetric(ServiceType.HTTP_CLIENT); - - - } - - @Test - public void testFalse() { - MetricRegistry metricRegistry = null; - try { - metricRegistry = new MetricRegistry(ServiceType.ARCUS); - Assert.fail(); - } catch (Exception e) { - } - - metricRegistry = new MetricRegistry(ServiceType.TOMCAT); - try { - metricRegistry.getRpcMetric(ServiceType.IBATIS); - Assert.fail(); - } catch (Exception e) { - } - - } - +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.ServiceType; +import junit.framework.Assert; +import org.junit.Test; + +public class MetricRegistryTest { + + @Test + public void testSuccess() { + MetricRegistry metricRegistry = new MetricRegistry(ServiceType.TOMCAT); + RpcMetric rpcMetric = metricRegistry.getRpcMetric(ServiceType.HTTP_CLIENT); + + + } + + @Test + public void testFalse() { + MetricRegistry metricRegistry = null; + try { + metricRegistry = new MetricRegistry(ServiceType.ARCUS); + Assert.fail(); + } catch (Exception e) { + } + + metricRegistry = new MetricRegistry(ServiceType.TOMCAT); + try { + metricRegistry.getRpcMetric(ServiceType.IBATIS); + Assert.fail(); + } catch (Exception e) { + } + + } + } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/WasStaticAcceptHistogramTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/WasStaticAcceptHistogramTest.java index e47f3fd95c46..9d4416b36e07 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/WasStaticAcceptHistogramTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/metric/WasStaticAcceptHistogramTest.java @@ -1,71 +1,74 @@ -package com.nhn.pinpoint.profiler.monitor.metric; - -import com.nhn.pinpoint.common.ServiceType; -import junit.framework.Assert; -import org.junit.Test; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class WasStaticAcceptHistogramTest { - - @Test - public void testLookUp() throws Exception { - StaticAcceptHistogram table = new StaticAcceptHistogram(); - Assert.assertTrue(table.addResponseTime("abc", ServiceType.TOMCAT.getCode(), 1000)); - Assert.assertTrue(table.addResponseTime("abc", ServiceType.BLOC.getCode(), 1000)); - Assert.assertTrue(table.addResponseTime("abc", ServiceType.STAND_ALONE.getCode(), 1000)); - Assert.assertTrue(table.addResponseTime("abc", ServiceType.BLOC.getCode(), 1000)); - - Assert.assertFalse(table.addResponseTime("abc", ServiceType.ARCUS.getCode(), 1000)); - } - - - public void performanceTest () throws InterruptedException { -// 63519 static table -// 72350 dynamic table -// 로 static table 빠름. - // InthashMap ConcurrentHashMap의 성능 차이 비교; - // 차이는 미비한데. 이중구조로 할지 아니면. single data로 할지. - // dynamic table의 경우 추가 ResponseKey객체도 추가로 생성함. - final StaticAcceptHistogram table = new StaticAcceptHistogram(); - execute(new Runnable() { - @Override - public void run() { - table.addResponseTime("test", ServiceType.TOMCAT.getCode(), 1000); - } - }); - - final DynamicAcceptHistogram hashTable = new DynamicAcceptHistogram(); - execute(new Runnable() { - @Override - public void run() { - hashTable.addResponseTime("test", ServiceType.TOMCAT.getCode(), 1000); - } - }); - - } - - private void execute(final Runnable runnable) throws InterruptedException { - long l = System.currentTimeMillis(); - ExecutorService executors = Executors.newFixedThreadPool(20); - for(int x = 0; x< 100; x++) { - final int count = 1000000; - final CountDownLatch latch = new CountDownLatch(count); - for (int i = 0; i < count; i++) { - executors.execute(new Runnable() { - @Override - public void run() { - runnable.run(); - latch.countDown(); - } - }); - } - latch.await(); - } - System.out.println(System.currentTimeMillis() - l); - executors.shutdown(); - } - +package com.nhn.pinpoint.profiler.monitor.metric; + +import com.nhn.pinpoint.common.ServiceType; +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class WasStaticAcceptHistogramTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testLookUp() throws Exception { + StaticAcceptHistogram table = new StaticAcceptHistogram(); + Assert.assertTrue(table.addResponseTime("abc", ServiceType.TOMCAT.getCode(), 1000)); + Assert.assertTrue(table.addResponseTime("abc", ServiceType.BLOC.getCode(), 1000)); + Assert.assertTrue(table.addResponseTime("abc", ServiceType.STAND_ALONE.getCode(), 1000)); + Assert.assertTrue(table.addResponseTime("abc", ServiceType.BLOC.getCode(), 1000)); + + Assert.assertFalse(table.addResponseTime("abc", ServiceType.ARCUS.getCode(), 1000)); + } + + + public void performanceTest () throws InterruptedException { +// 63519 static table +// 72350 dynamic table +// 로 static table 빠름. + // InthashMap ConcurrentHashMap의 성능 차이 비교; + // 차이는 미비한데. 이중구조로 할지 아니면. single data로 할지. + // dynamic table의 경우 추가 ResponseKey객체도 추가로 생성함. + final StaticAcceptHistogram table = new StaticAcceptHistogram(); + execute(new Runnable() { + @Override + public void run() { + table.addResponseTime("test", ServiceType.TOMCAT.getCode(), 1000); + } + }); + + final DynamicAcceptHistogram hashTable = new DynamicAcceptHistogram(); + execute(new Runnable() { + @Override + public void run() { + hashTable.addResponseTime("test", ServiceType.TOMCAT.getCode(), 1000); + } + }); + + } + + private void execute(final Runnable runnable) throws InterruptedException { + long l = System.currentTimeMillis(); + ExecutorService executors = Executors.newFixedThreadPool(20); + for(int x = 0; x< 100; x++) { + final int count = 1000000; + final CountDownLatch latch = new CountDownLatch(count); + for (int i = 0; i < count; i++) { + executors.execute(new Runnable() { + @Override + public void run() { + runnable.run(); + latch.countDown(); + } + }); + } + latch.await(); + } + logger.debug("{}", System.currentTimeMillis() - l); + executors.shutdown(); + } + } \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactoryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactoryTest.java index f13ff7e05dca..9fb50c214796 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactoryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactoryTest.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.profiler.sampler; - -import com.nhn.pinpoint.bootstrap.sampler.Sampler; -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class SamplerFactoryTest { - @Test - public void createSamplerSamplingRate0() { - SamplerFactory samplerFactory = new SamplerFactory(); - Sampler sampler = samplerFactory.createSampler(true, 0); - boolean sampling = sampler.isSampling(); - Assert.assertFalse(sampling); - } - - @Test - public void createSamplerSamplingRate_Negative() { - SamplerFactory samplerFactory = new SamplerFactory(); - Sampler sampler = samplerFactory.createSampler(true, -1); - boolean sampling = sampler.isSampling(); - Assert.assertFalse(sampling); - } -} +package com.nhn.pinpoint.profiler.sampler; + +import com.nhn.pinpoint.bootstrap.sampler.Sampler; +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class SamplerFactoryTest { + @Test + public void createSamplerSamplingRate0() { + SamplerFactory samplerFactory = new SamplerFactory(); + Sampler sampler = samplerFactory.createSampler(true, 0); + boolean sampling = sampler.isSampling(); + Assert.assertFalse(sampling); + } + + @Test + public void createSamplerSamplingRate_Negative() { + SamplerFactory samplerFactory = new SamplerFactory(); + Sampler sampler = samplerFactory.createSampler(true, -1); + boolean sampling = sampler.isSampling(); + Assert.assertFalse(sampling); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java index b3a97e50c3e2..c63bb997b463 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java @@ -1,45 +1,50 @@ -package com.nhn.pinpoint.profiler.sampler; - - -import com.nhn.pinpoint.profiler.sampler.SamplingRateSampler; -import org.junit.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class SimpleSamplerTest { - @Test - public void test() { - SamplingRateSampler simpleSampler = new SamplingRateSampler(1); - assertChoice(simpleSampler); - assertChoice(simpleSampler); - assertChoice(simpleSampler); - assertChoice(simpleSampler); - - SamplingRateSampler simpleSampler2 = new SamplingRateSampler(2); - assertChoice(simpleSampler2); - assertDrop(simpleSampler2); - assertChoice(simpleSampler2); - assertDrop(simpleSampler2); - } - - @Test - public void mod() { - int i = 0 % 101; - System.out.println("" + i); - - int j = Math.abs(-102) % 101; - System.out.println("" + j); - } - - private void assertDrop(SamplingRateSampler simpleSampler) { - boolean sample = simpleSampler.isSampling(); - Assert.assertFalse(sample); - } - - private void assertChoice(SamplingRateSampler simpleSampler) { - boolean sample = simpleSampler.isSampling(); - Assert.assertTrue(sample); - } -} +package com.nhn.pinpoint.profiler.sampler; + + +import com.nhn.pinpoint.profiler.sampler.SamplingRateSampler; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class SimpleSamplerTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void test() { + SamplingRateSampler simpleSampler = new SamplingRateSampler(1); + assertChoice(simpleSampler); + assertChoice(simpleSampler); + assertChoice(simpleSampler); + assertChoice(simpleSampler); + + SamplingRateSampler simpleSampler2 = new SamplingRateSampler(2); + assertChoice(simpleSampler2); + assertDrop(simpleSampler2); + assertChoice(simpleSampler2); + assertDrop(simpleSampler2); + } + + @Test + public void mod() { + int i = 0 % 101; + logger.debug("{}", i); + + int j = Math.abs(-102) % 101; + logger.debug("{}", j); + } + + private void assertDrop(SamplingRateSampler simpleSampler) { + boolean sample = simpleSampler.isSampling(); + Assert.assertFalse(sample); + } + + private void assertChoice(SamplingRateSampler simpleSampler) { + boolean sample = simpleSampler.isSampling(); + Assert.assertTrue(sample); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/CountingDataSender.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/CountingDataSender.java index c5346368d2bc..2e600b35ad31 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/CountingDataSender.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/CountingDataSender.java @@ -1,118 +1,118 @@ -package com.nhn.pinpoint.profiler.sender; - -import com.nhn.pinpoint.profiler.context.Span; -import com.nhn.pinpoint.profiler.context.SpanChunk; -import com.nhn.pinpoint.rpc.FutureListener; -import com.nhn.pinpoint.rpc.ResponseMessage; -import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; -import org.apache.thrift.TBase; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class CountingDataSender implements EnhancedDataSender { - - private final AtomicInteger requestCounter = new AtomicInteger(); - private final AtomicInteger requestRetryCounter = new AtomicInteger(); - private final AtomicInteger requestResponseListenerCounter = new AtomicInteger(); - private final AtomicInteger senderCounter = new AtomicInteger(); - - private final AtomicInteger spanCounter = new AtomicInteger(); - private final AtomicInteger spanChunkCounter = new AtomicInteger(); - - - @Override - public boolean request(TBase data) { - requestCounter.incrementAndGet(); - return false; - } - - @Override - public boolean request(TBase data, int retry) { - requestRetryCounter.incrementAndGet(); - return false; - } - - @Override - public boolean request(TBase data, FutureListener listener) { - return false; - } - - @Override - public boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - return false; - } - - @Override - public boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - return false; - } - - @Override - public boolean send(TBase data) { - senderCounter.incrementAndGet(); - if (data instanceof Span) { - this.spanCounter.incrementAndGet(); - } else if (data instanceof SpanChunk) { - this.spanChunkCounter.incrementAndGet(); - } - return false; - } - - @Override - public void stop() { - this.requestCounter.set(0); - this.requestRetryCounter.set(0); - this.requestResponseListenerCounter.set(0); - this.senderCounter.set(0); - this.spanCounter.set(0); - this.spanChunkCounter.set(0); - } - - @Override - public boolean isNetworkAvailable() { - return false; - } - - public int getRequestCounter() { - return requestCounter.get(); - } - - public int getRequestRetryCounter() { - return requestRetryCounter.get(); - } - - public int getRequestResponseListenerCounter() { - return requestResponseListenerCounter.get(); - } - - public int getSenderCounter() { - return senderCounter.get(); - } - - public int getSpanChunkCounter() { - return spanChunkCounter.get(); - } - - public int getSpanCounter() { - return spanCounter.get(); - } - - public int getTotalCount() { - return requestCounter.get() + requestRetryCounter.get() + requestResponseListenerCounter.get() + senderCounter.get(); - } - - @Override - public String toString() { - return "CountingDataSender{" + - "requestCounter=" + requestCounter + - ", requestRetryCounter=" + requestRetryCounter + - ", requestResponseListenerCounter=" + requestResponseListenerCounter + - ", senderCounter=" + senderCounter + - ", spanCounter=" + spanCounter + - ", spanChunkCounter=" + spanChunkCounter + - '}'; - } -} +package com.nhn.pinpoint.profiler.sender; + +import com.nhn.pinpoint.profiler.context.Span; +import com.nhn.pinpoint.profiler.context.SpanChunk; +import com.nhn.pinpoint.rpc.FutureListener; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.rpc.client.PinpointSocketReconnectEventListener; +import org.apache.thrift.TBase; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class CountingDataSender implements EnhancedDataSender { + + private final AtomicInteger requestCounter = new AtomicInteger(); + private final AtomicInteger requestRetryCounter = new AtomicInteger(); + private final AtomicInteger requestResponseListenerCounter = new AtomicInteger(); + private final AtomicInteger senderCounter = new AtomicInteger(); + + private final AtomicInteger spanCounter = new AtomicInteger(); + private final AtomicInteger spanChunkCounter = new AtomicInteger(); + + + @Override + public boolean request(TBase data) { + requestCounter.incrementAndGet(); + return false; + } + + @Override + public boolean request(TBase data, int retry) { + requestRetryCounter.incrementAndGet(); + return false; + } + + @Override + public boolean request(TBase data, FutureListener listener) { + return false; + } + + @Override + public boolean addReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + return false; + } + + @Override + public boolean removeReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + return false; + } + + @Override + public boolean send(TBase data) { + senderCounter.incrementAndGet(); + if (data instanceof Span) { + this.spanCounter.incrementAndGet(); + } else if (data instanceof SpanChunk) { + this.spanChunkCounter.incrementAndGet(); + } + return false; + } + + @Override + public void stop() { + this.requestCounter.set(0); + this.requestRetryCounter.set(0); + this.requestResponseListenerCounter.set(0); + this.senderCounter.set(0); + this.spanCounter.set(0); + this.spanChunkCounter.set(0); + } + + @Override + public boolean isNetworkAvailable() { + return false; + } + + public int getRequestCounter() { + return requestCounter.get(); + } + + public int getRequestRetryCounter() { + return requestRetryCounter.get(); + } + + public int getRequestResponseListenerCounter() { + return requestResponseListenerCounter.get(); + } + + public int getSenderCounter() { + return senderCounter.get(); + } + + public int getSpanChunkCounter() { + return spanChunkCounter.get(); + } + + public int getSpanCounter() { + return spanCounter.get(); + } + + public int getTotalCount() { + return requestCounter.get() + requestRetryCounter.get() + requestResponseListenerCounter.get() + senderCounter.get(); + } + + @Override + public String toString() { + return "CountingDataSender{" + + "requestCounter=" + requestCounter + + ", requestRetryCounter=" + requestRetryCounter + + ", requestResponseListenerCounter=" + requestResponseListenerCounter + + ", senderCounter=" + senderCounter + + ", spanCounter=" + spanCounter + + ", spanChunkCounter=" + spanChunkCounter + + '}'; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/PeekableDataSender.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/PeekableDataSender.java index 9e3080564d7d..013d7855a572 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/PeekableDataSender.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/PeekableDataSender.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.profiler.sender; - -import java.util.Iterator; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -import org.apache.thrift.TBase; - -/** - * @author hyungil.jeong - */ -public class PeekableDataSender> implements DataSender, Iterable { - - private final Queue queue = new ConcurrentLinkedQueue(); - - public T peek() { - return this.queue.peek(); - } - - public T poll() { - return this.queue.poll(); - } - - public int size() { - return this.queue.size(); - } - - public void clear() { - this.queue.clear(); - } - - @Override - public Iterator iterator() { - return this.queue.iterator(); - } - - @Override - public boolean send(TBase data) { - // deepCopy 안 함. 실제로도 네트워크 전송이 늦게되면 다른 datasender 들도 - // send 할 객체들의 레퍼런스를 그대로 가지고 있기 때문. - @SuppressWarnings("unchecked") - T dataToAdd = (T)data; - return this.queue.offer(dataToAdd); - } - - @Override - public void stop() { - } - - @Override - public boolean isNetworkAvailable() { - return false; - } - - @Override - public String toString() { - return this.queue.toString(); - } - -} +package com.nhn.pinpoint.profiler.sender; + +import java.util.Iterator; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.apache.thrift.TBase; + +/** + * @author hyungil.jeong + */ +public class PeekableDataSender> implements DataSender, Iterable { + + private final Queue queue = new ConcurrentLinkedQueue(); + + public T peek() { + return this.queue.peek(); + } + + public T poll() { + return this.queue.poll(); + } + + public int size() { + return this.queue.size(); + } + + public void clear() { + this.queue.clear(); + } + + @Override + public Iterator iterator() { + return this.queue.iterator(); + } + + @Override + public boolean send(TBase data) { + // deepCopy 안 함. 실제로도 네트워크 전송이 늦게되면 다른 datasender 들도 + // send 할 객체들의 레퍼런스를 그대로 가지고 있기 때문. + @SuppressWarnings("unchecked") + T dataToAdd = (T)data; + return this.queue.offer(dataToAdd); + } + + @Override + public void stop() { + } + + @Override + public boolean isNetworkAvailable() { + return false; + } + + @Override + public String toString() { + return this.queue.toString(); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/RetryQueueTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/RetryQueueTest.java index 9cd3502054d7..ea7a4f44f369 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/RetryQueueTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/RetryQueueTest.java @@ -1,56 +1,56 @@ -package com.nhn.pinpoint.profiler.sender; - -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class RetryQueueTest { - @Test - public void size() { - - RetryQueue retryQueue = new RetryQueue(1, 1); - retryQueue.add(new RetryMessage(0, new byte[0])); - retryQueue.add(new RetryMessage(0, new byte[0])); - - Assert.assertEquals(1, retryQueue.size()); - - } - - @Test - public void size2() { - - RetryQueue retryQueue = new RetryQueue(1, 1); - RetryMessage retryMessage = retryQueue.get(); - Assert.assertNull(retryMessage); - } - - @Test - public void maxRetryTest() { - - RetryQueue retryQueue = new RetryQueue(3, 2); - RetryMessage retryMessage = new RetryMessage(0, new byte[0]); - retryMessage.fail(); - retryMessage.fail(); - - - retryQueue.add(retryMessage); - retryQueue.add(retryMessage); - - Assert.assertEquals(retryQueue.size(), 0); - } - - @Test - public void add() { - - RetryQueue retryQueue = new RetryQueue(3, 2); - retryQueue.add(new RetryMessage(0, new byte[0])); - // 하나 넣고.실패한 메시지 넣으면 반이상이라서 버려야됨. - RetryMessage retryMessage = new RetryMessage(0, new byte[0]); - retryMessage.fail(); - retryQueue.add(retryMessage); - - Assert.assertEquals(retryQueue.size(), 1); - } -} +package com.nhn.pinpoint.profiler.sender; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class RetryQueueTest { + @Test + public void size() { + + RetryQueue retryQueue = new RetryQueue(1, 1); + retryQueue.add(new RetryMessage(0, new byte[0])); + retryQueue.add(new RetryMessage(0, new byte[0])); + + Assert.assertEquals(1, retryQueue.size()); + + } + + @Test + public void size2() { + + RetryQueue retryQueue = new RetryQueue(1, 1); + RetryMessage retryMessage = retryQueue.get(); + Assert.assertNull(retryMessage); + } + + @Test + public void maxRetryTest() { + + RetryQueue retryQueue = new RetryQueue(3, 2); + RetryMessage retryMessage = new RetryMessage(0, new byte[0]); + retryMessage.fail(); + retryMessage.fail(); + + + retryQueue.add(retryMessage); + retryQueue.add(retryMessage); + + Assert.assertEquals(retryQueue.size(), 0); + } + + @Test + public void add() { + + RetryQueue retryQueue = new RetryQueue(3, 2); + retryQueue.add(new RetryMessage(0, new byte[0])); + // 하나 넣고.실패한 메시지 넣으면 반이상이라서 버려야됨. + RetryMessage retryMessage = new RetryMessage(0, new byte[0]); + retryMessage.fail(); + retryQueue.add(retryMessage); + + Assert.assertEquals(retryQueue.size(), 1); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderReconnectTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderReconnectTest.java index fd87844b4a49..a87272601ef2 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderReconnectTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderReconnectTest.java @@ -1,123 +1,123 @@ -package com.nhn.pinpoint.profiler.sender; - -import java.util.Collections; -import java.util.Map; - -import com.nhn.pinpoint.thrift.dto.TApiMetaData; -import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.client.MessageListener; -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import com.nhn.pinpoint.rpc.server.PinpointServerSocket; -import com.nhn.pinpoint.rpc.server.ServerMessageListener; -import com.nhn.pinpoint.rpc.server.ServerStreamChannel; -import com.nhn.pinpoint.rpc.server.SocketChannel; - -import net.sf.cglib.proxy.Factory; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class TcpDataSenderReconnectTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final int PORT = 10050; - public static final String HOST = "127.0.0.1"; - - private int send; - - public PinpointServerSocket serverStart() { - PinpointServerSocket server = new PinpointServerSocket(); - server.setMessageListener(new ServerMessageListener() { - - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - logger.info("handleSend:{}", sendPacket); - send++; - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - logger.info("handleRequest:{}", requestPacket); - } - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.info("handleStreamPacket:{}", streamPacket); - } - - @Override - public int handleEnableWorker(Map properties) { - return 0; - } - }); - server.bind(HOST, PORT); - return server; - } - - - @Test - public void connectAndSend() throws InterruptedException { - PinpointServerSocket old = serverStart(); - - PinpointSocketFactory socketFactory = createPinpointSocketFactory(); - PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); - - TcpDataSender sender = new TcpDataSender(socket); - Thread.sleep(500); - old.close(); - - Thread.sleep(500); - logger.info("Server start------------------"); - PinpointServerSocket pinpointServerSocket = serverStart(); - - Thread.sleep(5000); - logger.info("sendMessage------------------"); - sender.send(new TApiMetaData("test", System.currentTimeMillis(), 1, "TestApi")); - - Thread.sleep(500); - logger.info("sender stop------------------"); - sender.stop(); - - pinpointServerSocket.close(); - socket.close(); - socketFactory.release(); - } - - private PinpointSocketFactory createPinpointSocketFactory() { - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setTimeoutMillis(1000 * 5); - pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); - - return pinpointSocketFactory; - } - - - private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { - MessageListener messageListener = new CommandDispatcher(); - - PinpointSocket socket = null; - for (int i = 0; i < 3; i++) { - try { - socket = factory.connect(host, port, messageListener); - logger.info("tcp connect success:{}/{}", host, port); - return socket; - } catch (PinpointSocketException e) { - logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); - } - } - logger.warn("change background tcp connect mode {}/{} ", host, port); - socket = factory.scheduledConnect(host, port, messageListener); - - return socket; - } -} +package com.nhn.pinpoint.profiler.sender; + +import java.util.Collections; +import java.util.Map; + +import com.nhn.pinpoint.thrift.dto.TApiMetaData; +import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.client.MessageListener; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import com.nhn.pinpoint.rpc.server.ServerMessageListener; +import com.nhn.pinpoint.rpc.server.ServerStreamChannel; +import com.nhn.pinpoint.rpc.server.SocketChannel; + +import net.sf.cglib.proxy.Factory; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class TcpDataSenderReconnectTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final int PORT = 10050; + public static final String HOST = "127.0.0.1"; + + private int send; + + public PinpointServerSocket serverStart() { + PinpointServerSocket server = new PinpointServerSocket(); + server.setMessageListener(new ServerMessageListener() { + + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.info("handleSend:{}", sendPacket); + send++; + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.info("handleRequest:{}", requestPacket); + } + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.info("handleStreamPacket:{}", streamPacket); + } + + @Override + public int handleEnableWorker(Map properties) { + return 0; + } + }); + server.bind(HOST, PORT); + return server; + } + + + @Test + public void connectAndSend() throws InterruptedException { + PinpointServerSocket old = serverStart(); + + PinpointSocketFactory socketFactory = createPinpointSocketFactory(); + PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); + + TcpDataSender sender = new TcpDataSender(socket); + Thread.sleep(500); + old.close(); + + Thread.sleep(500); + logger.info("Server start------------------"); + PinpointServerSocket pinpointServerSocket = serverStart(); + + Thread.sleep(5000); + logger.info("sendMessage------------------"); + sender.send(new TApiMetaData("test", System.currentTimeMillis(), 1, "TestApi")); + + Thread.sleep(500); + logger.info("sender stop------------------"); + sender.stop(); + + pinpointServerSocket.close(); + socket.close(); + socketFactory.release(); + } + + private PinpointSocketFactory createPinpointSocketFactory() { + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setTimeoutMillis(1000 * 5); + pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); + + return pinpointSocketFactory; + } + + + private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { + MessageListener messageListener = new CommandDispatcher(); + + PinpointSocket socket = null; + for (int i = 0; i < 3; i++) { + try { + socket = factory.connect(host, port, messageListener); + logger.info("tcp connect success:{}/{}", host, port); + return socket; + } catch (PinpointSocketException e) { + logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); + } + } + logger.warn("change background tcp connect mode {}/{} ", host, port); + socket = factory.scheduledConnect(host, port, messageListener); + + return socket; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderTest.java index 6271202444fe..f14d81261776 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/TcpDataSenderTest.java @@ -1,136 +1,136 @@ -package com.nhn.pinpoint.profiler.sender; - -import com.nhn.pinpoint.thrift.dto.TApiMetaData; -import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.client.MessageListener; -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import com.nhn.pinpoint.rpc.server.PinpointServerSocket; -import com.nhn.pinpoint.rpc.server.ServerMessageListener; -import com.nhn.pinpoint.rpc.server.ServerStreamChannel; -import com.nhn.pinpoint.rpc.server.SocketChannel; - -import junit.framework.Assert; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - */ -public class TcpDataSenderTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final int PORT = 10050; - public static final String HOST = "127.0.0.1"; - - private PinpointServerSocket server; - private CountDownLatch sendLatch; - - @Before - public void serverStart() { - server = new PinpointServerSocket(); - server.setMessageListener(new ServerMessageListener() { - - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - logger.info("handleSend:{}", sendPacket); - if (sendLatch != null) { - sendLatch.countDown(); - } - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - logger.info("handleRequest:{}", requestPacket); - } - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.info("handleStreamPacket:{}", streamPacket); - } - - @Override - public int handleEnableWorker(Map arg0) { - return 0; - } - }); - server.bind(HOST, PORT); - } - - @After - public void serverShutdown() { - if (server != null) { - server.close(); - } - } - - @Test - public void connectAndSend() throws InterruptedException { - this.sendLatch = new CountDownLatch(2); - - PinpointSocketFactory socketFactory = createPinpointSocketFactory(); - PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); - - TcpDataSender sender = new TcpDataSender(socket); - try { - sender.send(new TApiMetaData("test", System.currentTimeMillis(), 1, "TestApi")); - sender.send(new TApiMetaData("test", System.currentTimeMillis(), 1, "TestApi")); - - - boolean received = sendLatch.await(1000, TimeUnit.MILLISECONDS); - Assert.assertTrue(received); - } finally { - sender.stop(); - - if (socket != null) { - socket.close(); - } - - if (socketFactory != null) { - socketFactory.release(); - } - } - } - - private PinpointSocketFactory createPinpointSocketFactory() { - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setTimeoutMillis(1000 * 5); - pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); - - return pinpointSocketFactory; - } - - - private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { - MessageListener messageListener = new CommandDispatcher(); - - PinpointSocket socket = null; - for (int i = 0; i < 3; i++) { - try { - socket = factory.connect(host, port, messageListener); - logger.info("tcp connect success:{}/{}", host, port); - return socket; - } catch (PinpointSocketException e) { - logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); - } - } - logger.warn("change background tcp connect mode {}/{} ", host, port); - socket = factory.scheduledConnect(host, port, messageListener); - - return socket; - } -} +package com.nhn.pinpoint.profiler.sender; + +import com.nhn.pinpoint.thrift.dto.TApiMetaData; +import com.nhn.pinpoint.profiler.receiver.CommandDispatcher; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.client.MessageListener; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import com.nhn.pinpoint.rpc.server.ServerMessageListener; +import com.nhn.pinpoint.rpc.server.ServerStreamChannel; +import com.nhn.pinpoint.rpc.server.SocketChannel; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + */ +public class TcpDataSenderTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final int PORT = 10050; + public static final String HOST = "127.0.0.1"; + + private PinpointServerSocket server; + private CountDownLatch sendLatch; + + @Before + public void serverStart() { + server = new PinpointServerSocket(); + server.setMessageListener(new ServerMessageListener() { + + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.info("handleSend:{}", sendPacket); + if (sendLatch != null) { + sendLatch.countDown(); + } + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.info("handleRequest:{}", requestPacket); + } + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.info("handleStreamPacket:{}", streamPacket); + } + + @Override + public int handleEnableWorker(Map arg0) { + return 0; + } + }); + server.bind(HOST, PORT); + } + + @After + public void serverShutdown() { + if (server != null) { + server.close(); + } + } + + @Test + public void connectAndSend() throws InterruptedException { + this.sendLatch = new CountDownLatch(2); + + PinpointSocketFactory socketFactory = createPinpointSocketFactory(); + PinpointSocket socket = createPinpointSocket(HOST, PORT, socketFactory); + + TcpDataSender sender = new TcpDataSender(socket); + try { + sender.send(new TApiMetaData("test", System.currentTimeMillis(), 1, "TestApi")); + sender.send(new TApiMetaData("test", System.currentTimeMillis(), 1, "TestApi")); + + + boolean received = sendLatch.await(1000, TimeUnit.MILLISECONDS); + Assert.assertTrue(received); + } finally { + sender.stop(); + + if (socket != null) { + socket.close(); + } + + if (socketFactory != null) { + socketFactory.release(); + } + } + } + + private PinpointSocketFactory createPinpointSocketFactory() { + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setTimeoutMillis(1000 * 5); + pinpointSocketFactory.setProperties(Collections.EMPTY_MAP); + + return pinpointSocketFactory; + } + + + private PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { + MessageListener messageListener = new CommandDispatcher(); + + PinpointSocket socket = null; + for (int i = 0; i < 3; i++) { + try { + socket = factory.connect(host, port, messageListener); + logger.info("tcp connect success:{}/{}", host, port); + return socket; + } catch (PinpointSocketException e) { + logger.warn("tcp connect fail:{}/{} try reconnect, retryCount:{}", host, port, i); + } + } + logger.warn("change background tcp connect mode {}/{} ", host, port); + socket = factory.scheduledConnect(host, port, messageListener); + + return socket; + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpDataSenderTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpDataSenderTest.java index 367bcbb3687b..fccd0a0df5ee 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpDataSenderTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpDataSenderTest.java @@ -1,89 +1,89 @@ -package com.nhn.pinpoint.profiler.sender; - -import com.nhn.pinpoint.thrift.dto.TAgentInfo; -import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinderInitializer; -import junit.framework.Assert; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.thrift.TBase; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * @author emeroad - */ -public class UdpDataSenderTest { - @BeforeClass - public static void before() { - Slf4jLoggerBinderInitializer.beforeClass(); - } - - @AfterClass - public static void after() { - Slf4jLoggerBinderInitializer.afterClass(); - } - - - - @Test - public void sendAndFlushChck() throws InterruptedException { - UdpDataSender sender = new UdpDataSender("localhost", 9009, "test", 128, 1000, 1024*64*100); - - TAgentInfo agentInfo = new TAgentInfo(); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.send(agentInfo); - sender.stop(); - } - - @Test - public void sendAndLarge() throws InterruptedException { - String random = RandomStringUtils.randomAlphabetic(UdpDataSender.UDP_MAX_PACKET_LENGTH); - TAgentInfo agentInfo = new TAgentInfo(); - agentInfo.setAgentId(random); - boolean limit = sendMessage_getLimit(agentInfo); - Assert.assertTrue("limit overflow",limit); - - boolean noLimit = sendMessage_getLimit(new TAgentInfo()); - Assert.assertFalse("success", noLimit); - - - } - - private boolean sendMessage_getLimit(TBase tbase) throws InterruptedException { - final AtomicBoolean limitCounter = new AtomicBoolean(false); - final CountDownLatch latch = new CountDownLatch(1); - - UdpDataSender sender = new UdpDataSender("localhost", 9009, "test", 128, 1000, 1024*64*100) { - @Override - protected boolean isLimit(int interBufferSize) { - boolean limit = super.isLimit(interBufferSize); - limitCounter.set(limit); - latch.countDown(); - return limit; - } - }; - try { - sender.send(tbase); - latch.await(5000, TimeUnit.MILLISECONDS); - } finally { - sender.stop(); - } - return limitCounter.get(); - } - -} +package com.nhn.pinpoint.profiler.sender; + +import com.nhn.pinpoint.thrift.dto.TAgentInfo; +import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinderInitializer; +import junit.framework.Assert; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.thrift.TBase; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author emeroad + */ +public class UdpDataSenderTest { + @BeforeClass + public static void before() { + Slf4jLoggerBinderInitializer.beforeClass(); + } + + @AfterClass + public static void after() { + Slf4jLoggerBinderInitializer.afterClass(); + } + + + + @Test + public void sendAndFlushChck() throws InterruptedException { + UdpDataSender sender = new UdpDataSender("localhost", 9009, "test", 128, 1000, 1024*64*100); + + TAgentInfo agentInfo = new TAgentInfo(); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.send(agentInfo); + sender.stop(); + } + + @Test + public void sendAndLarge() throws InterruptedException { + String random = RandomStringUtils.randomAlphabetic(UdpDataSender.UDP_MAX_PACKET_LENGTH); + TAgentInfo agentInfo = new TAgentInfo(); + agentInfo.setAgentId(random); + boolean limit = sendMessage_getLimit(agentInfo); + Assert.assertTrue("limit overflow",limit); + + boolean noLimit = sendMessage_getLimit(new TAgentInfo()); + Assert.assertFalse("success", noLimit); + + + } + + private boolean sendMessage_getLimit(TBase tbase) throws InterruptedException { + final AtomicBoolean limitCounter = new AtomicBoolean(false); + final CountDownLatch latch = new CountDownLatch(1); + + UdpDataSender sender = new UdpDataSender("localhost", 9009, "test", 128, 1000, 1024*64*100) { + @Override + protected boolean isLimit(int interBufferSize) { + boolean limit = super.isLimit(interBufferSize); + limitCounter.set(limit); + latch.countDown(); + return limit; + } + }; + try { + sender.send(tbase); + latch.await(5000, TimeUnit.MILLISECONDS); + } finally { + sender.stop(); + } + return limitCounter.get(); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpSocketTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpSocketTest.java index e35081cc6d5d..0f71669593b4 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpSocketTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/UdpSocketTest.java @@ -1,178 +1,178 @@ -package com.nhn.pinpoint.profiler.sender; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetSocketAddress; -import java.net.SocketException; - -/** - * @author emeroad - */ -public class UdpSocketTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - // 기본포트와 충돌나서 + 5함 - private int PORT = 10000; - // The correct maximum UDP message size is 65507, as determined by the following formula: - // 0xffff - (sizeof(IP Header) + sizeof(UDP Header)) = 65535-(20+8) = 65507 - private static int AcceptedSize = 65507; - - - private DatagramSocket receiver; - private DatagramSocket sender; - - @Before - public void setUp() throws SocketException { - receiver = new DatagramSocket(PORT); - sender = new DatagramSocket(); - sender.connect(new InetSocketAddress("localhost", PORT)); - } - - @After - public void setDown() throws InterruptedException { - close(sender); - close(receiver); - // testcase가 연속적으로 돌면 포트 충돌이 발생하여 증가시킴 - PORT++; - } - - private void close(DatagramSocket socket) { - if (socket == null) { - return; - } - socket.close(); - - } - - private DatagramPacket newDatagramPacket(int size) { - return new DatagramPacket(new byte[size], size); - } - - @Test - public void testChunkSize() throws IOException { - - DatagramPacket packet1 = newDatagramPacket(1000); - sender.send(packet1); - - DatagramPacket packet2 = newDatagramPacket(500); - sender.send(packet2); - - DatagramPacket r1 = newDatagramPacket(2000); - receiver.receive(r1); - Assert.assertEquals(r1.getLength(), 1000); - - DatagramPacket r2 = newDatagramPacket(2000); - receiver.receive(r2); - Assert.assertEquals(r2.getLength(), 500); - - } - - @Test - public void testDatagramSendFail() { - int size = 70000; - DatagramPacket packet1 = newDatagramPacket(size); - try { - sender.send(packet1); - Assert.fail("실패해야 정상인데 성공."); - } catch (IOException e) { - logger.info("메시지가 너무 크다. " + e.getMessage(), e); - } - } - - @Test - public void testDatagramMaxSend() throws IOException { - - DatagramPacket packet1 = newDatagramPacket(AcceptedSize); - sender.send(packet1); - - DatagramPacket r1 = newDatagramPacket(AcceptedSize); - receiver.receive(r1); - Assert.assertEquals(r1.getLength(), AcceptedSize); - } - - - @Test - public void testMaxBytes() throws IOException { - - DatagramPacket packet1 = newDatagramPacket(50000); - sender.send(packet1); - - - DatagramPacket r1 = newDatagramPacket(50000); - receiver.receive(r1); - - logger.info(String.valueOf(r1.getLength())); - - - } - - // 원격지 테스트시 풀어서 확인한다. - //@Test - public void testRemoteReceive() { - while (true) { - DatagramPacket datagramPacket = newDatagramPacket(70000); - try { - receiver.receive(datagramPacket); - logger.info("data size:" + datagramPacket.getLength()); - } catch (IOException e) { - logger.warn("receive error:" + e.getMessage(), e); - } - } - } - - // @Test - public void testRemoteSend() throws IOException, InterruptedException { - DatagramSocket so = new DatagramSocket(); - so.connect(new InetSocketAddress("10.66.18.78", PORT)); - - so.send(newDatagramPacket(1500)); - - so.send(newDatagramPacket(10000)); - - so.send(newDatagramPacket(20000)); - - so.send(newDatagramPacket(50000)); - - so.send(newDatagramPacket(60000)); - - - so.send(newDatagramPacket(AcceptedSize)); - - try { - so.send(newDatagramPacket(AcceptedSize + 1)); - Assert.fail("실패"); - } catch (IOException e) { - } - - try { - so.send(newDatagramPacket(70000)); - Assert.fail("실패"); - } catch (IOException e) { - } - - so.close(); - } - - // @Test - public void createUdpSocket() throws IOException { - DatagramSocket so = new DatagramSocket(); -// so.bind(new InetSocketAddress("localhost", 8081)); -// DatagramSocket receiver = new DatagramSocket(new InetSocketAddress("localhost", 8082)); -// receiver.bind(new InetSocketAddress("localhost", 8082)); - - so.connect(new InetSocketAddress("localhost", 8082)); - so.send(new DatagramPacket(new byte[10], 10)); - -// receiver.receive(newDatagramPacket(1000)); - so.close(); - } -} +package com.nhn.pinpoint.profiler.sender; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetSocketAddress; +import java.net.SocketException; + +/** + * @author emeroad + */ +public class UdpSocketTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + // 기본포트와 충돌나서 + 5함 + private int PORT = 10000; + // The correct maximum UDP message size is 65507, as determined by the following formula: + // 0xffff - (sizeof(IP Header) + sizeof(UDP Header)) = 65535-(20+8) = 65507 + private static int AcceptedSize = 65507; + + + private DatagramSocket receiver; + private DatagramSocket sender; + + @Before + public void setUp() throws SocketException { + receiver = new DatagramSocket(PORT); + sender = new DatagramSocket(); + sender.connect(new InetSocketAddress("localhost", PORT)); + } + + @After + public void setDown() throws InterruptedException { + close(sender); + close(receiver); + // testcase가 연속적으로 돌면 포트 충돌이 발생하여 증가시킴 + PORT++; + } + + private void close(DatagramSocket socket) { + if (socket == null) { + return; + } + socket.close(); + + } + + private DatagramPacket newDatagramPacket(int size) { + return new DatagramPacket(new byte[size], size); + } + + @Test + public void testChunkSize() throws IOException { + + DatagramPacket packet1 = newDatagramPacket(1000); + sender.send(packet1); + + DatagramPacket packet2 = newDatagramPacket(500); + sender.send(packet2); + + DatagramPacket r1 = newDatagramPacket(2000); + receiver.receive(r1); + Assert.assertEquals(r1.getLength(), 1000); + + DatagramPacket r2 = newDatagramPacket(2000); + receiver.receive(r2); + Assert.assertEquals(r2.getLength(), 500); + + } + + @Test + public void testDatagramSendFail() { + int size = 70000; + DatagramPacket packet1 = newDatagramPacket(size); + try { + sender.send(packet1); + Assert.fail("실패해야 정상인데 성공."); + } catch (IOException e) { + logger.info("메시지가 너무 크다. " + e.getMessage(), e); + } + } + + @Test + public void testDatagramMaxSend() throws IOException { + + DatagramPacket packet1 = newDatagramPacket(AcceptedSize); + sender.send(packet1); + + DatagramPacket r1 = newDatagramPacket(AcceptedSize); + receiver.receive(r1); + Assert.assertEquals(r1.getLength(), AcceptedSize); + } + + + @Test + public void testMaxBytes() throws IOException { + + DatagramPacket packet1 = newDatagramPacket(50000); + sender.send(packet1); + + + DatagramPacket r1 = newDatagramPacket(50000); + receiver.receive(r1); + + logger.info(String.valueOf(r1.getLength())); + + + } + + // 원격지 테스트시 풀어서 확인한다. + //@Test + public void testRemoteReceive() { + while (true) { + DatagramPacket datagramPacket = newDatagramPacket(70000); + try { + receiver.receive(datagramPacket); + logger.info("data size:" + datagramPacket.getLength()); + } catch (IOException e) { + logger.warn("receive error:" + e.getMessage(), e); + } + } + } + + // @Test + public void testRemoteSend() throws IOException, InterruptedException { + DatagramSocket so = new DatagramSocket(); + so.connect(new InetSocketAddress("10.66.18.78", PORT)); + + so.send(newDatagramPacket(1500)); + + so.send(newDatagramPacket(10000)); + + so.send(newDatagramPacket(20000)); + + so.send(newDatagramPacket(50000)); + + so.send(newDatagramPacket(60000)); + + + so.send(newDatagramPacket(AcceptedSize)); + + try { + so.send(newDatagramPacket(AcceptedSize + 1)); + Assert.fail("실패"); + } catch (IOException e) { + } + + try { + so.send(newDatagramPacket(70000)); + Assert.fail("실패"); + } catch (IOException e) { + } + + so.close(); + } + + // @Test + public void createUdpSocket() throws IOException { + DatagramSocket so = new DatagramSocket(); +// so.bind(new InetSocketAddress("localhost", 8081)); +// DatagramSocket receiver = new DatagramSocket(new InetSocketAddress("localhost", 8082)); +// receiver.bind(new InetSocketAddress("localhost", 8082)); + + so.connect(new InetSocketAddress("localhost", 8082)); + so.send(new DatagramPacket(new byte[10], 10)); + +// receiver.receive(newDatagramPacket(1000)); + so.close(); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/ArrayUtilsTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/ArrayUtilsTest.java index dd647057ed82..4251c5d2ed01 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/ArrayUtilsTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/ArrayUtilsTest.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.profiler.util; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class ArrayUtilsTest { - private final Logger logger = LoggerFactory.getLogger(ArrayUtilsTest.class.getName()); - - @Test - public void dropToStringSmall() { - byte[] bytes = new byte[] {1, 2, 3, 4}; - - String small = ArrayUtils.dropToString(bytes, 3); - Assert.assertEquals("[1, 2, 3, ...(1)]", small); - } - - @Test - public void dropToStringEqual() { - byte[] bytes = new byte[] {1, 2, 3, 4}; - - String equals = ArrayUtils.dropToString(bytes, 4); - Assert.assertEquals("[1, 2, 3, 4]", equals); - - } - - @Test - public void dropToStringLarge() { - byte[] bytes = new byte[] {1, 2, 3, 4}; - - String large = ArrayUtils.dropToString(bytes, 11); - Assert.assertEquals("[1, 2, 3, 4]", large); - - } - - - @Test - public void dropToStringOneAndZero() { - byte[] bytes = new byte[] {1, 2, 3, 4}; - - String one = ArrayUtils.dropToString(bytes, 1); - Assert.assertEquals("[1, ...(3)]", one); - - String zero = ArrayUtils.dropToString(bytes, 0); - Assert.assertEquals("[...(4)]", zero); - } - - - @Test - public void dropToStringSingle() { - byte[] bytes = new byte[] {1}; - - String small = ArrayUtils.dropToString(bytes, 1); - logger.info(small); - Assert.assertEquals("[1]", small); - } - - @Test - public void dropToStringNegative() { - byte[] bytes = new byte[] {1}; - - try { - ArrayUtils.dropToString(bytes, -1); - Assert.fail(); - } catch (Exception e) { - } - } -} +package com.nhn.pinpoint.profiler.util; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class ArrayUtilsTest { + private final Logger logger = LoggerFactory.getLogger(ArrayUtilsTest.class.getName()); + + @Test + public void dropToStringSmall() { + byte[] bytes = new byte[] {1, 2, 3, 4}; + + String small = ArrayUtils.dropToString(bytes, 3); + Assert.assertEquals("[1, 2, 3, ...(1)]", small); + } + + @Test + public void dropToStringEqual() { + byte[] bytes = new byte[] {1, 2, 3, 4}; + + String equals = ArrayUtils.dropToString(bytes, 4); + Assert.assertEquals("[1, 2, 3, 4]", equals); + + } + + @Test + public void dropToStringLarge() { + byte[] bytes = new byte[] {1, 2, 3, 4}; + + String large = ArrayUtils.dropToString(bytes, 11); + Assert.assertEquals("[1, 2, 3, 4]", large); + + } + + + @Test + public void dropToStringOneAndZero() { + byte[] bytes = new byte[] {1, 2, 3, 4}; + + String one = ArrayUtils.dropToString(bytes, 1); + Assert.assertEquals("[1, ...(3)]", one); + + String zero = ArrayUtils.dropToString(bytes, 0); + Assert.assertEquals("[...(4)]", zero); + } + + + @Test + public void dropToStringSingle() { + byte[] bytes = new byte[] {1}; + + String small = ArrayUtils.dropToString(bytes, 1); + logger.info(small); + Assert.assertEquals("[1]", small); + } + + @Test + public void dropToStringNegative() { + byte[] bytes = new byte[] {1}; + + try { + ArrayUtils.dropToString(bytes, -1); + Assert.fail(); + } catch (Exception e) { + } + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/DepthScopeTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/DepthScopeTest.java index 4468f920cf8c..a93c6559adb1 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/DepthScopeTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/DepthScopeTest.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.profiler.util; - -/** - * @author emeroad - */ -import org.junit.Test; -import org.junit.Assert; - -/** - * @author emeroad - */ -public class DepthScopeTest { - @Test - public void pushPop() { - DepthScope scope = new DepthScope("test"); - Assert.assertEquals(scope.push(), 0); - Assert.assertEquals(scope.push(), 1); - Assert.assertEquals(scope.push(), 2); - - Assert.assertEquals(scope.depth(), 3); - - Assert.assertEquals(scope.pop(), 2); - Assert.assertEquals(scope.pop(), 1); - Assert.assertEquals(scope.pop(), 0); - } - - @Test - public void pushPopError() { - DepthScope scope = new DepthScope("test"); - Assert.assertEquals(scope.pop(), -1); - Assert.assertEquals(scope.pop(), -2); - - Assert.assertEquals(scope.push(), -2); - Assert.assertEquals(scope.push(), -1); - - Assert.assertEquals(scope.depth(), 0); - - - } -} - +package com.nhn.pinpoint.profiler.util; + +/** + * @author emeroad + */ +import org.junit.Test; +import org.junit.Assert; + +/** + * @author emeroad + */ +public class DepthScopeTest { + @Test + public void pushPop() { + DepthScope scope = new DepthScope("test"); + Assert.assertEquals(scope.push(), 0); + Assert.assertEquals(scope.push(), 1); + Assert.assertEquals(scope.push(), 2); + + Assert.assertEquals(scope.depth(), 3); + + Assert.assertEquals(scope.pop(), 2); + Assert.assertEquals(scope.pop(), 1); + Assert.assertEquals(scope.pop(), 0); + } + + @Test + public void pushPopError() { + DepthScope scope = new DepthScope("test"); + Assert.assertEquals(scope.pop(), -1); + Assert.assertEquals(scope.pop(), -2); + + Assert.assertEquals(scope.push(), -2); + Assert.assertEquals(scope.push(), -1); + + Assert.assertEquals(scope.depth(), 0); + + + } +} + diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/GoavaCacheTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/GuavaCacheTest.java similarity index 66% rename from profiler/src/test/java/com/navercorp/pinpoint/profiler/util/GoavaCacheTest.java rename to profiler/src/test/java/com/navercorp/pinpoint/profiler/util/GuavaCacheTest.java index 8490e61cac98..0249313a460b 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/GoavaCacheTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/GuavaCacheTest.java @@ -1,25 +1,30 @@ -package com.nhn.pinpoint.profiler.util; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import org.junit.Test; - -/** - * @author emeroad - */ -public class GoavaCacheTest { - @Test - public void test() { - CacheBuilder builder = CacheBuilder.newBuilder(); - builder.concurrencyLevel(8); - builder.maximumSize(1); - builder.initialCapacity(1); - Cache cache = builder.build(); - - cache.put("test1", "1"); - System.out.println(cache.size()); - cache.put("test3", "2"); - System.out.println(cache.size()); - - } -} +package com.nhn.pinpoint.profiler.util; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class GuavaCacheTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void test() { + CacheBuilder builder = CacheBuilder.newBuilder(); + builder.concurrencyLevel(8); + builder.maximumSize(1); + builder.initialCapacity(1); + Cache cache = builder.build(); + + cache.put("test1", "1"); + logger.debug("{}", cache.size()); + cache.put("test3", "2"); + logger.debug("{}", cache.size()); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InetAddressTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InetAddressTest.java index 62533be49fea..ad75b36fdded 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InetAddressTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InetAddressTest.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.profiler.util; - -import java.net.InetAddress; - -/** - * - */ -public class InetAddressTest { - public void test() { -// InetAddresses.forString("127.0.0.1"); -// InetAddresses - } -} +package com.nhn.pinpoint.profiler.util; + +import java.net.InetAddress; + +/** + * + */ +public class InetAddressTest { + public void test() { +// InetAddresses.forString("127.0.0.1"); +// InetAddresses + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InstrumentTranslator.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InstrumentTranslator.java index 87bdaa10db0a..4bdc06bbeb87 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InstrumentTranslator.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/InstrumentTranslator.java @@ -1,83 +1,83 @@ -package com.nhn.pinpoint.profiler.util; - -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.profiler.modifier.Modifier; -import javassist.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class InstrumentTranslator implements Translator { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final DefaultAgent agent; - - private ConcurrentMap modifierMap = new ConcurrentHashMap(); - - private ClassLoader loader; - - public InstrumentTranslator(ClassLoader loader, DefaultAgent agent) { - this.loader = loader; - this.agent = agent; - } - - public Modifier addModifier(Modifier modifier) { - return modifierMap.put(modifier.getTargetClass().replace('/', '.'), modifier); - } - - @Override - public void start(ClassPool pool) throws NotFoundException, CannotCompileException { -// this.pool = pool; - } - - @Override - public void onLoad(ClassPool pool, String classname) throws NotFoundException, CannotCompileException { - logger.debug("loading className:{}", classname); - - try { - // agent가 등록한 Modifier를 찾아서 트랜스 폼 시도를 한다. - String replace = classname.replace('.', '/'); - ClassFileTransformer classFileTransformer = agent.getClassFileTransformer(); - byte[] transform = classFileTransformer.transform(this.loader, replace, null, null, null); - if (transform != null) { - pool.makeClass(new ByteArrayInputStream(transform)); - return; - } - } catch (IOException ex) { - throw new NotFoundException(classname + " not found. Caused:" + ex.getMessage(), ex); - } catch (IllegalClassFormatException ex) { - throw new RuntimeException(classname + " not found. Caused:" + ex.getMessage(), ex); - } - // 자체적으로 등록한 ModifierMap 을 찾는다. - findModifierMap(pool, classname); - - - } - private void findModifierMap(ClassPool pool, String classname) throws NotFoundException, CannotCompileException { - Modifier modifier = modifierMap.get(classname); - if (modifier == null) { - return; - } - logger.info("Modify loader:{}, name:{}, modifier{}", loader, classname, modifier); - - final Thread thread = Thread.currentThread(); - final ClassLoader beforeClassLoader = thread.getContextClassLoader(); - thread.setContextClassLoader(loader); - try { - byte[] modify = modifier.modify(this.loader, classname, null, null); - pool.makeClass(new ByteArrayInputStream(modify)); - } catch (IOException ex) { - throw new NotFoundException(classname + " not found. Caused:" + ex.getMessage(), ex); - } finally { - thread.setContextClassLoader(beforeClassLoader); - } - } -} +package com.nhn.pinpoint.profiler.util; + +import com.nhn.pinpoint.profiler.DefaultAgent; +import com.nhn.pinpoint.profiler.modifier.Modifier; +import javassist.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class InstrumentTranslator implements Translator { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final DefaultAgent agent; + + private ConcurrentMap modifierMap = new ConcurrentHashMap(); + + private ClassLoader loader; + + public InstrumentTranslator(ClassLoader loader, DefaultAgent agent) { + this.loader = loader; + this.agent = agent; + } + + public Modifier addModifier(Modifier modifier) { + return modifierMap.put(modifier.getTargetClass().replace('/', '.'), modifier); + } + + @Override + public void start(ClassPool pool) throws NotFoundException, CannotCompileException { +// this.pool = pool; + } + + @Override + public void onLoad(ClassPool pool, String classname) throws NotFoundException, CannotCompileException { + logger.debug("loading className:{}", classname); + + try { + // agent가 등록한 Modifier를 찾아서 트랜스 폼 시도를 한다. + String replace = classname.replace('.', '/'); + ClassFileTransformer classFileTransformer = agent.getClassFileTransformer(); + byte[] transform = classFileTransformer.transform(this.loader, replace, null, null, null); + if (transform != null) { + pool.makeClass(new ByteArrayInputStream(transform)); + return; + } + } catch (IOException ex) { + throw new NotFoundException(classname + " not found. Caused:" + ex.getMessage(), ex); + } catch (IllegalClassFormatException ex) { + throw new RuntimeException(classname + " not found. Caused:" + ex.getMessage(), ex); + } + // 자체적으로 등록한 ModifierMap 을 찾는다. + findModifierMap(pool, classname); + + + } + private void findModifierMap(ClassPool pool, String classname) throws NotFoundException, CannotCompileException { + Modifier modifier = modifierMap.get(classname); + if (modifier == null) { + return; + } + logger.info("Modify loader:{}, name:{}, modifier{}", loader, classname, modifier); + + final Thread thread = Thread.currentThread(); + final ClassLoader beforeClassLoader = thread.getContextClassLoader(); + thread.setContextClassLoader(loader); + try { + byte[] modify = modifier.modify(this.loader, classname, null, null); + pool.makeClass(new ByteArrayInputStream(modify)); + } catch (IOException ex) { + throw new NotFoundException(classname + " not found. Caused:" + ex.getMessage(), ex); + } finally { + thread.setContextClassLoader(beforeClassLoader); + } + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java index 4295469c82a0..b7b39109bf44 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java @@ -1,125 +1,125 @@ -package com.nhn.pinpoint.profiler.util; - -import javassist.*; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; - -/** - * @author emeroad - */ -public class JavaAssistUtilsTest { - private final Logger logger = LoggerFactory.getLogger(JavaAssistUtilsTest.class.getName()); - private ClassPool pool; - - @Before - public void setUp() throws Exception { - pool = new ClassPool(); - pool.appendSystemPath(); - } - - @Test - public void testGetParameterDescription() throws Exception { - CtClass ctClass = pool.get("java.lang.String"); - CtMethod substring = ctClass.getDeclaredMethod("substring", new CtClass[]{CtClass.intType}); - - String ctDescription = JavaAssistUtils.getParameterDescription(substring.getParameterTypes()); - logger.info(ctDescription); - - String clsDescription = JavaAssistUtils.getParameterDescription(new Class[]{int.class}); - logger.info(clsDescription); - Assert.assertEquals(ctDescription, clsDescription); - - - } - - @Test - public void testGetLineNumber() throws Exception { -// pool.appendClassPath(new ClassClassPath(AbstractHttpClient.class)); - CtClass ctClass = pool.get("org.apache.http.impl.client.AbstractHttpClient"); - CtClass params = pool.get("org.apache.http.params.HttpParams"); - // non-javadoc, see interface HttpClient -// public synchronized final HttpParams getParams() { -// if (defaultParams == null) { -// defaultParams = createHttpParams(); -// } -// return defaultParams; -// } - - CtMethod setParams = ctClass.getDeclaredMethod("setParams", new CtClass[]{params}); - int lineNumber = JavaAssistUtils.getLineNumber(setParams); - logger.info("line:" + lineNumber); - - logger.info(setParams.getName()); - logger.info(setParams.getLongName()); - - String[] paramName = JavaAssistUtils.getParameterVariableName(setParams); - logger.info(Arrays.toString(paramName)); - Assert.assertEquals(paramName.length, 1); - Assert.assertEquals(paramName[0], "params"); - - String[] parameterType = JavaAssistUtils.getParameterType(setParams.getParameterTypes()); - logger.info(Arrays.toString(parameterType)); - - String s = ApiUtils.mergeParameterVariableNameDescription(parameterType, paramName); - logger.info(s); - } - - @Test - public void testVariableNameError1() throws Exception { - CtClass ctClass = pool.get("com.mysql.jdbc.ConnectionImpl"); - CtClass params = pool.get("org.apache.http.params.HttpParams"); - CtMethod setParams = ctClass.getDeclaredMethod("setAutoCommit", new CtClass[]{CtClass.booleanType}); - int lineNumber = JavaAssistUtils.getLineNumber(setParams); - logger.info("line:" + lineNumber); - - logger.info(setParams.getName()); - logger.info(setParams.getLongName()); - - String[] paramName = JavaAssistUtils.getParameterVariableName(setParams); - logger.info(Arrays.toString(paramName)); - Assert.assertEquals(paramName.length, 1); - Assert.assertEquals(paramName[0], "autoCommitFlag"); - - String[] parameterType = JavaAssistUtils.getParameterType(setParams.getParameterTypes()); - logger.info(Arrays.toString(parameterType)); - - String s = ApiUtils.mergeParameterVariableNameDescription(parameterType, paramName); - logger.info(s); - } - - @Test - public void testVariableNameError2() throws Exception { - CtClass ctClass = pool.get("com.mysql.jdbc.StatementImpl"); - CtClass params = pool.get("java.lang.String"); - CtMethod setParams = ctClass.getDeclaredMethod("executeQuery", new CtClass[]{params}); - int lineNumber = JavaAssistUtils.getLineNumber(setParams); - - logger.info(setParams.getName()); - logger.info(setParams.getLongName()); - - String[] paramName = JavaAssistUtils.getParameterVariableName(setParams); - logger.info(Arrays.toString(paramName)); - Assert.assertEquals(paramName.length, 1); - Assert.assertEquals(paramName[0], "sql"); - - String[] parameterType = JavaAssistUtils.getParameterType(setParams.getParameterTypes()); - logger.info(Arrays.toString(parameterType)); - - String s = ApiUtils.mergeParameterVariableNameDescription(parameterType, paramName); - logger.info(s); - } - - - @Test - public void testGetParameterDescription2() throws Exception { - String clsDescription = JavaAssistUtils.getParameterDescription(new Class[]{String.class, Integer.class}); - logger.info(clsDescription); - Assert.assertEquals("(java.lang.String, java.lang.Integer)", clsDescription); - } - -} +package com.nhn.pinpoint.profiler.util; + +import javassist.*; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +/** + * @author emeroad + */ +public class JavaAssistUtilsTest { + private final Logger logger = LoggerFactory.getLogger(JavaAssistUtilsTest.class.getName()); + private ClassPool pool; + + @Before + public void setUp() throws Exception { + pool = new ClassPool(); + pool.appendSystemPath(); + } + + @Test + public void testGetParameterDescription() throws Exception { + CtClass ctClass = pool.get("java.lang.String"); + CtMethod substring = ctClass.getDeclaredMethod("substring", new CtClass[]{CtClass.intType}); + + String ctDescription = JavaAssistUtils.getParameterDescription(substring.getParameterTypes()); + logger.info(ctDescription); + + String clsDescription = JavaAssistUtils.getParameterDescription(new Class[]{int.class}); + logger.info(clsDescription); + Assert.assertEquals(ctDescription, clsDescription); + + + } + + @Test + public void testGetLineNumber() throws Exception { +// pool.appendClassPath(new ClassClassPath(AbstractHttpClient.class)); + CtClass ctClass = pool.get("org.apache.http.impl.client.AbstractHttpClient"); + CtClass params = pool.get("org.apache.http.params.HttpParams"); + // non-javadoc, see interface HttpClient +// public synchronized final HttpParams getParams() { +// if (defaultParams == null) { +// defaultParams = createHttpParams(); +// } +// return defaultParams; +// } + + CtMethod setParams = ctClass.getDeclaredMethod("setParams", new CtClass[]{params}); + int lineNumber = JavaAssistUtils.getLineNumber(setParams); + logger.info("line:" + lineNumber); + + logger.info(setParams.getName()); + logger.info(setParams.getLongName()); + + String[] paramName = JavaAssistUtils.getParameterVariableName(setParams); + logger.info(Arrays.toString(paramName)); + Assert.assertEquals(paramName.length, 1); + Assert.assertEquals(paramName[0], "params"); + + String[] parameterType = JavaAssistUtils.getParameterType(setParams.getParameterTypes()); + logger.info(Arrays.toString(parameterType)); + + String s = ApiUtils.mergeParameterVariableNameDescription(parameterType, paramName); + logger.info(s); + } + + @Test + public void testVariableNameError1() throws Exception { + CtClass ctClass = pool.get("com.mysql.jdbc.ConnectionImpl"); + CtClass params = pool.get("org.apache.http.params.HttpParams"); + CtMethod setParams = ctClass.getDeclaredMethod("setAutoCommit", new CtClass[]{CtClass.booleanType}); + int lineNumber = JavaAssistUtils.getLineNumber(setParams); + logger.info("line:" + lineNumber); + + logger.info(setParams.getName()); + logger.info(setParams.getLongName()); + + String[] paramName = JavaAssistUtils.getParameterVariableName(setParams); + logger.info(Arrays.toString(paramName)); + Assert.assertEquals(paramName.length, 1); + Assert.assertEquals(paramName[0], "autoCommitFlag"); + + String[] parameterType = JavaAssistUtils.getParameterType(setParams.getParameterTypes()); + logger.info(Arrays.toString(parameterType)); + + String s = ApiUtils.mergeParameterVariableNameDescription(parameterType, paramName); + logger.info(s); + } + + @Test + public void testVariableNameError2() throws Exception { + CtClass ctClass = pool.get("com.mysql.jdbc.StatementImpl"); + CtClass params = pool.get("java.lang.String"); + CtMethod setParams = ctClass.getDeclaredMethod("executeQuery", new CtClass[]{params}); + int lineNumber = JavaAssistUtils.getLineNumber(setParams); + + logger.info(setParams.getName()); + logger.info(setParams.getLongName()); + + String[] paramName = JavaAssistUtils.getParameterVariableName(setParams); + logger.info(Arrays.toString(paramName)); + Assert.assertEquals(paramName.length, 1); + Assert.assertEquals(paramName[0], "sql"); + + String[] parameterType = JavaAssistUtils.getParameterType(setParams.getParameterTypes()); + logger.info(Arrays.toString(parameterType)); + + String s = ApiUtils.mergeParameterVariableNameDescription(parameterType, paramName); + logger.info(s); + } + + + @Test + public void testGetParameterDescription2() throws Exception { + String clsDescription = JavaAssistUtils.getParameterDescription(new Class[]{String.class, Integer.class}); + logger.info(clsDescription); + Assert.assertEquals("(java.lang.String, java.lang.Integer)", clsDescription); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/MockAgent.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/MockAgent.java index 9ee15b8239d7..c1fab7d8204d 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/MockAgent.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/MockAgent.java @@ -1,61 +1,73 @@ -package com.nhn.pinpoint.profiler.util; - -import java.lang.instrument.Instrumentation; - -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.profiler.DummyInstrumentation; -import com.nhn.pinpoint.profiler.context.storage.ReadableSpanStorageFactory; -import com.nhn.pinpoint.profiler.context.storage.StorageFactory; -import com.nhn.pinpoint.profiler.sender.DataSender; -import com.nhn.pinpoint.profiler.sender.EnhancedDataSender; -import com.nhn.pinpoint.profiler.sender.LoggingDataSender; -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; - -/** - * @author emeroad - * @author koo.taejin - */ -public class MockAgent extends DefaultAgent { - - public MockAgent(String agentArgs, ProfilerConfig profilerConfig) { - this(agentArgs, new DummyInstrumentation(), profilerConfig); - } - - public MockAgent(String agentArgs, Instrumentation instrumentation, ProfilerConfig profilerConfig) { - super(agentArgs, instrumentation, profilerConfig); - } - - @Override - protected DataSender createUdpDataSender(int port, String threadName, int writeQueueSize, int timeout, int sendBufferSize) { - return new LoggingDataSender(); - } - - @Override - protected StorageFactory createStorageFactory() { - return new ReadableSpanStorageFactory(); - } - - - @Override - protected PinpointSocketFactory createPinpointSocketFactory() { - return null; - } - - @Override - protected PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { - return null; - } - - @Override - protected PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory, boolean useMessageListener) { - return null; - } - - @Override - protected EnhancedDataSender createTcpDataSender(PinpointSocket socket) { - return new LoggingDataSender(); - } - -} +package com.nhn.pinpoint.profiler.util; + +import java.lang.instrument.Instrumentation; + +import org.apache.thrift.TBase; + +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.profiler.DefaultAgent; +import com.nhn.pinpoint.profiler.DummyInstrumentation; +import com.nhn.pinpoint.profiler.context.storage.HoldingSpanStorageFactory; +import com.nhn.pinpoint.profiler.context.storage.StorageFactory; +import com.nhn.pinpoint.profiler.sender.DataSender; +import com.nhn.pinpoint.profiler.sender.EnhancedDataSender; +import com.nhn.pinpoint.profiler.sender.LoggingDataSender; +import com.nhn.pinpoint.profiler.sender.PeekableDataSender; +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; + +/** + * @author emeroad + * @author koo.taejin + * @author hyungil.jeong + */ +public class MockAgent extends DefaultAgent { + + public MockAgent(String agentArgs, ProfilerConfig profilerConfig) { + this(agentArgs, new DummyInstrumentation(), profilerConfig); + } + + public MockAgent(String agentArgs, Instrumentation instrumentation, ProfilerConfig profilerConfig) { + super(agentArgs, instrumentation, profilerConfig); + } + + @Override + protected DataSender createUdpDataSender(int port, String threadName, int writeQueueSize, int timeout, int sendBufferSize) { + return new PeekableDataSender>(); + } + + public PeekableDataSender getPeekableSpanDataSender() { + DataSender spanDataSender = getSpanDataSender(); + if (spanDataSender instanceof PeekableDataSender) { + return (PeekableDataSender)getSpanDataSender(); + } else { + throw new IllegalStateException("UdpDataSender must be an instance of a PeekableDataSender. Found : " + spanDataSender.getClass().getName()); + } + } + + @Override + protected StorageFactory createStorageFactory() { + return new HoldingSpanStorageFactory(getSpanDataSender()); + } + + @Override + protected PinpointSocketFactory createPinpointSocketFactory() { + return null; + } + + @Override + protected PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory) { + return null; + } + + @Override + protected PinpointSocket createPinpointSocket(String host, int port, PinpointSocketFactory factory, boolean useMessageListener) { + return null; + } + + @Override + protected EnhancedDataSender createTcpDataSender(PinpointSocket socket) { + return new LoggingDataSender(); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtilsTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtilsTest.java index e2dc9e480c50..f3b6ac2f544e 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtilsTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PreparedStatementUtilsTest.java @@ -1,28 +1,33 @@ -package com.nhn.pinpoint.profiler.util; - -import org.junit.Assert; -import org.junit.Test; - -import java.lang.reflect.Method; -import java.util.List; - -/** - * @author emeroad - */ -public class PreparedStatementUtilsTest { - @Test - public void testBindSetMethod() { - List bindVariableSetMethod = PreparedStatementUtils.findBindVariableSetMethod(); - for (Method method : bindVariableSetMethod) { - System.out.println(method); - } - } - - @Test - public void testMatch() throws Exception { - Assert.assertTrue(PreparedStatementUtils.isSetter("setNCString")); - Assert.assertTrue(PreparedStatementUtils.isSetter("setInt")); - Assert.assertTrue(PreparedStatementUtils.isSetter("setTestTeTst")); - - } -} +package com.nhn.pinpoint.profiler.util; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * @author emeroad + */ +public class PreparedStatementUtilsTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void testBindSetMethod() { + List bindVariableSetMethod = PreparedStatementUtils.findBindVariableSetMethod(); + for (Method method : bindVariableSetMethod) { + logger.debug("{}", method); + } + } + + @Test + public void testMatch() throws Exception { + Assert.assertTrue(PreparedStatementUtils.isSetter("setNCString")); + Assert.assertTrue(PreparedStatementUtils.isSetter("setInt")); + Assert.assertTrue(PreparedStatementUtils.isSetter("setTestTeTst")); + + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/QueryStringUtilTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/QueryStringUtilTest.java index e66b96e8f951..8d87f80d47cb 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/QueryStringUtilTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/QueryStringUtilTest.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.profiler.util; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class QueryStringUtilTest { - @Test - public void testRemoveAllMultiSpace() throws Exception { - String s = QueryStringUtil.removeAllMultiSpace("a b"); - - Assert.assertEquals("a b", s); - } -} +package com.nhn.pinpoint.profiler.util; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class QueryStringUtilTest { + @Test + public void testRemoveAllMultiSpace() throws Exception { + String s = QueryStringUtil.removeAllMultiSpace("a b"); + + Assert.assertEquals("a b", s); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtilsTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtilsTest.java index b9d8ce6afc08..e774b107f0cf 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtilsTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/RuntimeMXBeanUtilsTest.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.profiler.util; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Date; - -/** - * @author emeroad - */ -public class RuntimeMXBeanUtilsTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - @Test - public void vmStartTime() { - long vmStartTime = RuntimeMXBeanUtils.getVmStartTime(); - logger.debug("vmStartTime:{}", new Date(vmStartTime)); - Assert.assertNotSame(vmStartTime, 0); - } - - @Test - public void pid() { - int pid = RuntimeMXBeanUtils.getPid(); - logger.debug("pid:{}", pid); - Assert.assertTrue(pid > 0); - } -} +package com.nhn.pinpoint.profiler.util; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; + +/** + * @author emeroad + */ +public class RuntimeMXBeanUtilsTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Test + public void vmStartTime() { + long vmStartTime = RuntimeMXBeanUtils.getVmStartTime(); + logger.debug("vmStartTime:{}", new Date(vmStartTime)); + Assert.assertNotSame(vmStartTime, 0); + } + + @Test + public void pid() { + int pid = RuntimeMXBeanUtils.getPid(); + logger.debug("pid:{}", pid); + Assert.assertTrue(pid > 0); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/StringUtilsTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/StringUtilsTest.java index 612c5db42480..473a2672164d 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/StringUtilsTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/StringUtilsTest.java @@ -1,49 +1,49 @@ -package com.nhn.pinpoint.profiler.util; - -import com.nhn.pinpoint.bootstrap.util.StringUtils; -import junit.framework.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class StringUtilsTest { - @Test - public void testDrop1() throws Exception { - String string = "abc"; - String drop = StringUtils.drop(string, 1); - Assert.assertEquals("a...(3)", drop); - } - - @Test - public void testDrop2() throws Exception { - String string = "abc"; - String drop = StringUtils.drop(string, 5); - Assert.assertEquals("abc", drop); - } - - @Test - public void testDrop3() throws Exception { - String string = "abc"; - String drop = StringUtils.drop(string, 3); - Assert.assertEquals("abc", drop); - } - - @Test - public void testDrop4() throws Exception { - String string = "abc"; - String drop = StringUtils.drop(string, 0); - Assert.assertEquals("...(3)", drop); - - } - - @Test - public void testDropNegative() throws Exception { - String string = "abc"; - try { - StringUtils.drop(string, -1); - Assert.fail(); - } catch (Exception e) { - } - } -} +package com.nhn.pinpoint.profiler.util; + +import com.nhn.pinpoint.bootstrap.util.StringUtils; +import junit.framework.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class StringUtilsTest { + @Test + public void testDrop1() throws Exception { + String string = "abc"; + String drop = StringUtils.drop(string, 1); + Assert.assertEquals("a...(3)", drop); + } + + @Test + public void testDrop2() throws Exception { + String string = "abc"; + String drop = StringUtils.drop(string, 5); + Assert.assertEquals("abc", drop); + } + + @Test + public void testDrop3() throws Exception { + String string = "abc"; + String drop = StringUtils.drop(string, 3); + Assert.assertEquals("abc", drop); + } + + @Test + public void testDrop4() throws Exception { + String string = "abc"; + String drop = StringUtils.drop(string, 0); + Assert.assertEquals("...(3)", drop); + + } + + @Test + public void testDropNegative() throws Exception { + String string = "abc"; + try { + StringUtils.drop(string, -1); + Assert.fail(); + } catch (Exception e) { + } + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestClassLoader.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestClassLoader.java index d6719bceff94..84343199b152 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestClassLoader.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestClassLoader.java @@ -1,144 +1,149 @@ -package com.nhn.pinpoint.profiler.util; - -import java.io.IOException; -import java.lang.reflect.Constructor; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.profiler.DefaultAgent; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.interceptor.bci.JavaAssistByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.modifier.Modifier; -import javassist.CannotCompileException; -import javassist.Loader; -import javassist.NotFoundException; - -import org.junit.runners.model.InitializationError; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - * @author hyungil.jeong - */ -public class TestClassLoader extends Loader { - private final Logger logger = LoggerFactory.getLogger(TestClassLoader.class.getName()); - - private final String agentClassName; - - private Agent agent; - private ByteCodeInstrumentor instrumentor; - private InstrumentTranslator instrumentTranslator; - - - public TestClassLoader(String agentClassName) { - this.agentClassName = agentClassName; - } - - public TestClassLoader(DefaultAgent agent) { - if (agent == null) { - throw new NullPointerException("agent must not be null"); - } - - this.agentClassName = agent.getClass().getName(); - this.agent = agent; - this.instrumentor = agent.getByteCodeInstrumentor(); - this.instrumentTranslator = new InstrumentTranslator(this, agent); - } - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - return super.findClass(name); - } - - public void initialize() throws InitializationError { - addDefaultDelegateLoadingOf(); -// loadAgent(); - addTranslator(); - } - - private void loadAgent() throws InitializationError { - try { - Thread.currentThread().setContextClassLoader(this); - Class agentClass = this.loadClass(this.agentClassName); - @SuppressWarnings("unchecked") - Constructor agentConstructor = (Constructor) agentClass.getConstructor(String.class, ProfilerConfig.class); - ProfilerConfig profilerConfig = getProfilerConfig(); - this.agent = agentConstructor.newInstance("", profilerConfig); - this.instrumentor = ((DefaultAgent)agent).getByteCodeInstrumentor(); - this.instrumentTranslator = new InstrumentTranslator(this, ((DefaultAgent)agent)); - } catch (Exception e) { - // 퉁 치자..결국은 InitializationError 이므로... - throw new InitializationError(e); - } - } - - private ProfilerConfig getProfilerConfig() throws InitializationError { - ProfilerConfig profilerConfig = new ProfilerConfig(); - - String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); - try { - profilerConfig.readConfigFile(path); - } catch (IOException e) { - throw new InitializationError("Unable to read pinpoint.config"); - } - - profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); - return profilerConfig; - } - - public Agent getAgent() { - if (this.agent == null) { - throw new IllegalStateException("TestClassLoader is not initialized."); - } - return agent; - } - - public ByteCodeInstrumentor getInstrumentor() { - if (this.instrumentor == null) { - throw new IllegalStateException("TestClassLoader is not initialized."); - } - return instrumentor; - } - - public Modifier addModifier(Modifier modifier) { - if (this.instrumentTranslator == null) { - throw new IllegalStateException("TestClassLoader is not initialized."); - } - return this.instrumentTranslator.addModifier(modifier); - } - - private void addDefaultDelegateLoadingOf() { - this.delegateLoadingOf("com.nhn.pinpoint.bootstrap."); - this.delegateLoadingOf("com.nhn.pinpoint.common."); - this.delegateLoadingOf("junit."); - this.delegateLoadingOf("org.hamcrest."); - this.delegateLoadingOf("org.junit."); - } - - @Override - protected Class loadClassByDelegation(String name) throws ClassNotFoundException { - return super.loadClassByDelegation(name); - } - - private void addTranslator() { - try { - addTranslator(((JavaAssistByteCodeInstrumentor)instrumentor).getClassPool(), instrumentTranslator); - } catch (NotFoundException e) { - throw new RuntimeException(e.getMessage(), e); - } catch (CannotCompileException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - public void runTest(String className, String methodName) throws Throwable { - Class c = loadClass(className); - Object o = c.newInstance(); - try { - c.getDeclaredMethod(methodName).invoke(o); - } catch (java.lang.reflect.InvocationTargetException e) { - throw e.getTargetException(); - } - } -} +package com.nhn.pinpoint.profiler.util; + +import java.io.IOException; +import java.lang.reflect.Constructor; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.config.ProfilerConfig; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.profiler.DefaultAgent; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.interceptor.bci.JavaAssistByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.modifier.Modifier; +import javassist.CannotCompileException; +import javassist.Loader; +import javassist.NotFoundException; + +import org.junit.runners.model.InitializationError; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + * @author hyungil.jeong + */ +public class TestClassLoader extends Loader { + private final Logger logger = LoggerFactory.getLogger(TestClassLoader.class.getName()); + + private final String agentClassName; + + private Agent agent; + private ByteCodeInstrumentor instrumentor; + private InstrumentTranslator instrumentTranslator; + + + public TestClassLoader(String agentClassName) { + this.agentClassName = agentClassName; + } + + public TestClassLoader(DefaultAgent agent) { + if (agent == null) { + throw new NullPointerException("agent must not be null"); + } + + this.agentClassName = agent.getClass().getName(); + this.agent = agent; + this.instrumentor = agent.getByteCodeInstrumentor(); + this.instrumentTranslator = new InstrumentTranslator(this, agent); + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + return super.findClass(name); + } + + public void initialize() throws InitializationError { + addDefaultDelegateLoadingOf(); +// loadAgent(); + addTranslator(); + } + + private void loadAgent() throws InitializationError { + try { + Thread.currentThread().setContextClassLoader(this); + Class agentClass = this.loadClass(this.agentClassName); + @SuppressWarnings("unchecked") + Constructor agentConstructor = (Constructor) agentClass.getConstructor(String.class, ProfilerConfig.class); + ProfilerConfig profilerConfig = getProfilerConfig(); + this.agent = agentConstructor.newInstance("", profilerConfig); + this.instrumentor = ((DefaultAgent)agent).getByteCodeInstrumentor(); + this.instrumentTranslator = new InstrumentTranslator(this, ((DefaultAgent)agent)); + } catch (Exception e) { + // 퉁 치자..결국은 InitializationError 이므로... + throw new InitializationError(e); + } + } + + private ProfilerConfig getProfilerConfig() throws InitializationError { + ProfilerConfig profilerConfig = new ProfilerConfig(); + + String path = MockAgent.class.getClassLoader().getResource("pinpoint.config").getPath(); + try { + profilerConfig.readConfigFile(path); + } catch (IOException e) { + throw new InitializationError("Unable to read pinpoint.config"); + } + + profilerConfig.setApplicationServerType(ServiceType.TEST_STAND_ALONE); + return profilerConfig; + } + + public Agent getAgent() { + if (this.agent == null) { + throw new IllegalStateException("TestClassLoader is not initialized."); + } + return agent; + } + + public ByteCodeInstrumentor getInstrumentor() { + if (this.instrumentor == null) { + throw new IllegalStateException("TestClassLoader is not initialized."); + } + return instrumentor; + } + + public Modifier addModifier(Modifier modifier) { + if (this.instrumentTranslator == null) { + throw new IllegalStateException("TestClassLoader is not initialized."); + } + return this.instrumentTranslator.addModifier(modifier); + } + + private void addDefaultDelegateLoadingOf() { + this.delegateLoadingOf("com.nhn.pinpoint.bootstrap."); + this.delegateLoadingOf("com.nhn.pinpoint.common."); + this.delegateLoadingOf("com.nhn.pinpoint.thrift."); + this.delegateLoadingOf("com.nhn.pinpoint.profiler.context."); + this.delegateLoadingOf("com.nhn.pinpoint.profiler.sender.PeekableDataSender"); + this.delegateLoadingOf("com.nhn.pinpoint.profiler.junit4.IsRootSpan"); + this.delegateLoadingOf("org.apache.thrift.TBase"); + this.delegateLoadingOf("junit."); + this.delegateLoadingOf("org.hamcrest."); + this.delegateLoadingOf("org.junit."); + } + + @Override + protected Class loadClassByDelegation(String name) throws ClassNotFoundException { + return super.loadClassByDelegation(name); + } + + private void addTranslator() { + try { + addTranslator(((JavaAssistByteCodeInstrumentor)instrumentor).getClassPool(), instrumentTranslator); + } catch (NotFoundException e) { + throw new RuntimeException(e.getMessage(), e); + } catch (CannotCompileException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public void runTest(String className, String methodName) throws Throwable { + Class c = loadClass(className); + Object o = c.newInstance(); + try { + c.getDeclaredMethod(methodName).invoke(o); + } catch (java.lang.reflect.InvocationTargetException e) { + throw e.getTargetException(); + } + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestModifier.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestModifier.java index f5de3e0af628..1ed65ffde8ac 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestModifier.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/TestModifier.java @@ -1,54 +1,54 @@ -package com.nhn.pinpoint.profiler.util; - -import com.nhn.pinpoint.bootstrap.Agent; -import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; -import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; -import com.nhn.pinpoint.profiler.modifier.AbstractModifier; - -import java.security.ProtectionDomain; -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -public abstract class TestModifier extends AbstractModifier { - - private String targetClass; - - public final List interceptorList = new ArrayList(); - - public TestModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { - super(byteCodeInstrumentor, agent); - } - - - public void setTargetClass(String targetClass) { - this.targetClass = targetClass; - } - - @Override - public String getTargetClass() { - return targetClass; - } - - public void addInterceptor(Interceptor interceptor) { - this.interceptorList.add(interceptor); - } - - public List getInterceptorList() { - return interceptorList; - } - - public Interceptor getInterceptor(int index) { - return interceptorList.get(index); - } - - - - - @Override - public abstract byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer); - - -} +package com.nhn.pinpoint.profiler.util; + +import com.nhn.pinpoint.bootstrap.Agent; +import com.nhn.pinpoint.bootstrap.interceptor.Interceptor; +import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.nhn.pinpoint.profiler.modifier.AbstractModifier; + +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public abstract class TestModifier extends AbstractModifier { + + private String targetClass; + + public final List interceptorList = new ArrayList(); + + public TestModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + + public void setTargetClass(String targetClass) { + this.targetClass = targetClass; + } + + @Override + public String getTargetClass() { + return targetClass; + } + + public void addInterceptor(Interceptor interceptor) { + this.interceptorList.add(interceptor); + } + + public List getInterceptorList() { + return interceptorList; + } + + public Interceptor getInterceptor(int index) { + return interceptorList.get(index); + } + + + + + @Override + public abstract byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer); + + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverterTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverterTest.java index 34ab8af8bc30..0c326af90813 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverterTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/BindValueConverterTest.java @@ -1,32 +1,36 @@ -package com.nhn.pinpoint.profiler.util.bindvalue; - -import junit.framework.Assert; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Date; - -public class BindValueConverterTest { - @Test - public void testBindValueToString() throws Exception { - Date d = new Date(); - System.out.println(d); - - byte[] bytes = new byte[] {1, 2, 4}; - String s = Arrays.toString(bytes); - System.out.println(s); - } - - @Test - public void testBindValueBoolean() throws Exception { - String setBoolean = BindValueConverter.convert("setBoolean", new Object[]{null, Boolean.TRUE}); - Assert.assertEquals(setBoolean, Boolean.TRUE.toString()); - } - - @Test - public void testBindValueNotSupport() throws Exception { - // 지원되지 않는 api 라도 Exception이 발생하면 안됨. - String setBoolean = BindValueConverter.convert("setXxxx", new Object[]{null, "XXX"}); - Assert.assertEquals(setBoolean, ""); - } -} +package com.nhn.pinpoint.profiler.util.bindvalue; + +import junit.framework.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.Date; + +public class BindValueConverterTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + public void testBindValueToString() throws Exception { + Date d = new Date(); + logger.debug("{}", d); + + byte[] bytes = new byte[] {1, 2, 4}; + String s = Arrays.toString(bytes); + logger.debug(s); + } + + @Test + public void testBindValueBoolean() throws Exception { + String setBoolean = BindValueConverter.convert("setBoolean", new Object[]{null, Boolean.TRUE}); + Assert.assertEquals(setBoolean, Boolean.TRUE.toString()); + } + + @Test + public void testBindValueNotSupport() throws Exception { + // 지원되지 않는 api 라도 Exception이 발생하면 안됨. + String setBoolean = BindValueConverter.convert("setXxxx", new Object[]{null, "XXX"}); + Assert.assertEquals(setBoolean, ""); + } +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/TypesTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/TypesTest.java index ea8713e768cd..9afa342a886d 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/TypesTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/bindvalue/TypesTest.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.profiler.util.bindvalue; - -import com.nhn.pinpoint.profiler.util.bindvalue.Types; -import org.junit.Assert; -import org.junit.Test; - -import java.lang.reflect.Field; -import java.util.Map; - -public class TypesTest { - - @Test - public void testInverse() throws Exception { - Map inverse = Types.inverse(); - Field[] fields = java.sql.Types.class.getFields(); - Assert.assertEquals(inverse.size(), fields.length); - } -} +package com.nhn.pinpoint.profiler.util.bindvalue; + +import com.nhn.pinpoint.profiler.util.bindvalue.Types; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.Map; + +public class TypesTest { + + @Test + public void testInverse() throws Exception { + Map inverse = Types.inverse(); + Field[] fields = java.sql.Types.class.getFields(); + Assert.assertEquals(inverse.size(), fields.length); + } +} diff --git a/profiler/src/test/resources/database.properties b/profiler/src/test/resources/database.properties new file mode 100644 index 000000000000..0a1b6e31d42c --- /dev/null +++ b/profiler/src/test/resources/database.properties @@ -0,0 +1,24 @@ +# oracle +oracle.url=jdbc:oracle:thin:@10.98.133.174:1725:INDEV +oracle.user=lucy +oracle.password=lucy!234 + +# ms sqlserver +mssqlserver.url=jdbc:jtds:sqlserver://10.99.220.85:1433/pinpoint_test +mssqlserver.user=pinpoint_user +mssqlserver.password=pinpoint!234 + +# mysql +#mysql.url=jdbc:mysql://10.98.133.22:3306/hippo +#mysql.url.loadbalance=jdbc:mysql:loadbalance://10.98.133.23:3306,10.98.133.22:3306/hippo +#mysql.user=lucytest +#mysql.password=testlucy +# ʿ. +mysql.url=jdbc:mysql://10.25.149.61:3306/MySQL?characterEncoding=UTF-8 +mysql.user=pinpoint +mysql.password=nhn!@#123 + +# cubrid +cubrid.url=jdbc:cubrid:10.101.57.233:30102:pinpoint::: +cubrid.user=dba +cubrid.password=nhn!@#123 \ No newline at end of file diff --git a/profiler/src/test/resources/log4j.xml b/profiler/src/test/resources/log4j.xml index 4b35f9b33615..b6c9f75d1dd0 100644 --- a/profiler/src/test/resources/log4j.xml +++ b/profiler/src/test/resources/log4j.xml @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/profiler/src/test/resources/udp socket datasize.txt b/profiler/src/test/resources/udp socket datasize.txt index 9359b3da68d8..294d4c08ab65 100644 --- a/profiler/src/test/resources/udp socket datasize.txt +++ b/profiler/src/test/resources/udp socket datasize.txt @@ -1,33 +1,33 @@ -TCP MSS (Maximum Segment Size) and Interface MTU (Maximum Transmission Unit) - -* Data Link - - Ethernet Max MTU: 1500 Bytes - - Min Data Link MTU for IPv4: 68 Bytes - - Min Data Link MTU for IPv6: 576 Bytes - - Path MTU: the smallest MTU in the path (can be discoverd using IPv4 DF bit - ICMP error message) - -* IP - - IPv4 Header: 20 Bytes - - IPv6 Header: 40 Bytes - - Max Datagram Size for IPv4: 65535 Bytes (16 bits total length -> includes header) - - Max Datagram Size for IPv6: 65575 Bytes (16 bits payload length -> dose not include header) - - Min Reassembly Buffer Size for IPv4: 576 Bytes (UDP applications should not generate IP datagrams that exceed this size) - - Min Reassembly Buffer Size for IPv6: 1500 Bytes - -* TCP - - Header: 20 Bytes - - MSS for IPv4: less than or equal to MTU - 40 - - MSS for IPv6: less than or equal to MTU - 60 - - MSS(announced by the peer): less than or equal to 65535 (16 bits) - - Default MSS for IPv4(if not announced by the peer): 576 - 40 = 536 Bytes - - MSS option trys to avoid fragmentation - -* Max Window w/o window scale option: 65535 (16 bits) - -* TCP Send and Receive Buffer (Window Size) - - Advertised TCP window size = available room in the socket receive buffer - - TCP send and receive buffer sizes: 4096 Bytes (old), 8192 ~ 61440 Bytes (new) - - UDP send buffer size: 9000 Bytes, UDP receive buffer size: 40000 Bytes - - Client must set TCP receive buffer size before calling connect function - - Server must set TCP receive buffer size before calling listen function +TCP MSS (Maximum Segment Size) and Interface MTU (Maximum Transmission Unit) + +* Data Link + - Ethernet Max MTU: 1500 Bytes + - Min Data Link MTU for IPv4: 68 Bytes + - Min Data Link MTU for IPv6: 576 Bytes + - Path MTU: the smallest MTU in the path (can be discoverd using IPv4 DF bit - ICMP error message) + +* IP + - IPv4 Header: 20 Bytes + - IPv6 Header: 40 Bytes + - Max Datagram Size for IPv4: 65535 Bytes (16 bits total length -> includes header) + - Max Datagram Size for IPv6: 65575 Bytes (16 bits payload length -> dose not include header) + - Min Reassembly Buffer Size for IPv4: 576 Bytes (UDP applications should not generate IP datagrams that exceed this size) + - Min Reassembly Buffer Size for IPv6: 1500 Bytes + +* TCP + - Header: 20 Bytes + - MSS for IPv4: less than or equal to MTU - 40 + - MSS for IPv6: less than or equal to MTU - 60 + - MSS(announced by the peer): less than or equal to 65535 (16 bits) + - Default MSS for IPv4(if not announced by the peer): 576 - 40 = 536 Bytes + - MSS option trys to avoid fragmentation + +* Max Window w/o window scale option: 65535 (16 bits) + +* TCP Send and Receive Buffer (Window Size) + - Advertised TCP window size = available room in the socket receive buffer + - TCP send and receive buffer sizes: 4096 Bytes (old), 8192 ~ 61440 Bytes (new) + - UDP send buffer size: 9000 Bytes, UDP receive buffer size: 40000 Bytes + - Client must set TCP receive buffer size before calling connect function + - Server must set TCP receive buffer size before calling listen function - TCP socket buffer sizes should be at least three times the MSS (512 or 1460) \ No newline at end of file diff --git a/rpc/build.xml b/rpc/build.xml index 88a567a322e1..56b6a7f023bb 100644 --- a/rpc/build.xml +++ b/rpc/build.xml @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rpc/findbugs-exclude.xml b/rpc/findbugs-exclude.xml index a4b4e8251d57..0193409a64e7 100644 --- a/rpc/findbugs-exclude.xml +++ b/rpc/findbugs-exclude.xml @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteCompleteListenableFuture.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteCompleteListenableFuture.java index 6530b03e1e3e..bdf4e8648b68 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteCompleteListenableFuture.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteCompleteListenableFuture.java @@ -1,38 +1,38 @@ -package com.nhn.pinpoint.rpc; - -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; - -/** - * @author emeroad - */ -public class ChannelWriteCompleteListenableFuture extends DefaultFuture implements ChannelFutureListener { - - private T result; - - public ChannelWriteCompleteListenableFuture() { - this(null, 3000); - } - - public ChannelWriteCompleteListenableFuture(T result) { - this(result, 3000); - } - public ChannelWriteCompleteListenableFuture(T result, long timeoutMillis) { - super(timeoutMillis); - this.result = result; - } - - public ChannelWriteCompleteListenableFuture(long timeoutMillis) { - super(timeoutMillis); - } - - - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (future.isSuccess()) { - this.setResult(result); - } else { - this.setFailure(future.getCause()); - } - } -} +package com.nhn.pinpoint.rpc; + +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; + +/** + * @author emeroad + */ +public class ChannelWriteCompleteListenableFuture extends DefaultFuture implements ChannelFutureListener { + + private T result; + + public ChannelWriteCompleteListenableFuture() { + this(null, 3000); + } + + public ChannelWriteCompleteListenableFuture(T result) { + this(result, 3000); + } + public ChannelWriteCompleteListenableFuture(T result, long timeoutMillis) { + super(timeoutMillis); + this.result = result; + } + + public ChannelWriteCompleteListenableFuture(long timeoutMillis) { + super(timeoutMillis); + } + + + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (future.isSuccess()) { + this.setResult(result); + } else { + this.setFailure(future.getCause()); + } + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteFailListenableFuture.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteFailListenableFuture.java index b3445fe16be3..e983b78614af 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteFailListenableFuture.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ChannelWriteFailListenableFuture.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.rpc; - -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; - -/** - * @author emeroad - */ -public class ChannelWriteFailListenableFuture extends DefaultFuture implements ChannelFutureListener { - - public ChannelWriteFailListenableFuture() { - super(3000); - } - - public ChannelWriteFailListenableFuture(long timeoutMillis) { - super(timeoutMillis); - } - - - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (!future.isSuccess()) { - // io write fail - this.setFailure(future.getCause()); - } - } -} +package com.nhn.pinpoint.rpc; + +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; + +/** + * @author emeroad + */ +public class ChannelWriteFailListenableFuture extends DefaultFuture implements ChannelFutureListener { + + public ChannelWriteFailListenableFuture() { + super(3000); + } + + public ChannelWriteFailListenableFuture(long timeoutMillis) { + super(timeoutMillis); + } + + + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + // io write fail + this.setFailure(future.getCause()); + } + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ClassPreLoader.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ClassPreLoader.java index 18a9c1886fcc..cc36a3697b83 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ClassPreLoader.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ClassPreLoader.java @@ -1,75 +1,75 @@ -package com.nhn.pinpoint.rpc; - -import com.nhn.pinpoint.rpc.client.PinpointSocket; -import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; -import com.nhn.pinpoint.rpc.server.PinpointServerSocket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public final class ClassPreLoader { - - - public static void preload() { - try { - preload(65535); - } catch (Exception e) { - } - } - - public static void preload(int port) { - PinpointServerSocket serverSocket = null; - PinpointSocket socket = null; - PinpointSocketFactory socketFactory = null; - try { - serverSocket = new PinpointServerSocket(); - serverSocket.bind("127.0.0.1", port); - - socketFactory = new PinpointSocketFactory(); - socket = socketFactory.connect("127.0.0.1", port); - socket.sendSync(new byte[0]); - - - } catch (Exception ex) { - - System.err.print("preLoad error Caused:" + ex.getMessage()); - ex.printStackTrace(); - - final Logger logger = LoggerFactory.getLogger(ClassPreLoader.class); - logger.warn("preLoad error Caused:{}", ex.getMessage(), ex); - if (ex instanceof PinpointSocketException) { - throw (PinpointSocketException)ex; - } else { - throw new PinpointSocketException(ex.getMessage(), ex); - } - } finally { - if (socket != null) { - try { - socket.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - if(socketFactory != null) { - try { - socketFactory.release(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (serverSocket != null) { - try { - serverSocket.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - } - } - -} +package com.nhn.pinpoint.rpc; + +import com.nhn.pinpoint.rpc.client.PinpointSocket; +import com.nhn.pinpoint.rpc.client.PinpointSocketFactory; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public final class ClassPreLoader { + + + public static void preload() { + try { + preload(65535); + } catch (Exception e) { + } + } + + public static void preload(int port) { + PinpointServerSocket serverSocket = null; + PinpointSocket socket = null; + PinpointSocketFactory socketFactory = null; + try { + serverSocket = new PinpointServerSocket(); + serverSocket.bind("127.0.0.1", port); + + socketFactory = new PinpointSocketFactory(); + socket = socketFactory.connect("127.0.0.1", port); + socket.sendSync(new byte[0]); + + + } catch (Exception ex) { + + System.err.print("preLoad error Caused:" + ex.getMessage()); + ex.printStackTrace(); + + final Logger logger = LoggerFactory.getLogger(ClassPreLoader.class); + logger.warn("preLoad error Caused:{}", ex.getMessage(), ex); + if (ex instanceof PinpointSocketException) { + throw (PinpointSocketException)ex; + } else { + throw new PinpointSocketException(ex.getMessage(), ex); + } + } finally { + if (socket != null) { + try { + socket.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if(socketFactory != null) { + try { + socketFactory.release(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (serverSocket != null) { + try { + serverSocket.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/DefaultFuture.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/DefaultFuture.java index 3364ce02f880..e62fc90ca384 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/DefaultFuture.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/DefaultFuture.java @@ -1,245 +1,245 @@ -package com.nhn.pinpoint.rpc; - -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.TimerTask; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class DefaultFuture implements TimerTask, Future { - - private static final Logger logger = LoggerFactory.getLogger(DefaultFuture.class); - - private final long timeoutMillis; - private int waiters = 0; - - private boolean ready = false; - - private T result; - private Throwable cause; - - private Timeout timeout; - private FailureEventHandler failureEventHandler; - private FutureListener listener; - - - public DefaultFuture() { - this(3000); - } - - public DefaultFuture(long timeoutMillis) { - this.timeoutMillis = timeoutMillis; - } - - @Override - public synchronized T getResult() { - if (this.cause != null) { - throw new PinpointSocketException(cause); - } - return result; - } - - @Override - public synchronized Throwable getCause() { - return cause; - } - - @Override - public synchronized boolean isReady() { - return ready; - } - - @Override - public synchronized boolean isSuccess() { - return ready && cause == null; - } - - public boolean setResult(T message) { - synchronized (this) { - if (ready) { - return false; - } - this.ready = true; - - this.result = message; - if (waiters > 0) { - notifyAll(); - } - } - cancelTimeout(); - notifyListener(); - return true; - - } - - public boolean setFailure(Throwable cause) { - synchronized (this) { - if (ready) { - return false; - } - this.ready = true; - - this.cause = cause; - - if (waiters > 0) { - notifyAll(); - } - } - - cancelTimeout(); - notifyFailureHandle(); - notifyListener(); - return true; - } - - private boolean fireTimeout() { - synchronized (this) { - if (ready) { - return false; - } - this.ready = true; - - this.cause = new PinpointSocketException("timeout"); - - if (waiters > 0) { - notifyAll(); - } - } - // 이미 timeout 되서 들어오기 때문에 tieout.cancel시킬필요가 없음. - notifyFailureHandle(); - notifyListener(); - return true; - } - - private void cancelTimeout() { - final Timeout timeout = this.timeout; - if (timeout != null) { - timeout.cancel(); - this.timeout = null; - } - } - - private void notifyListener() { - FutureListener listener = this.listener; - if (listener != null) { - fireOnComplete(listener); - this.listener = null; - } - } - - protected void notifyFailureHandle() { - - FailureEventHandler failureEventHandler = this.failureEventHandler; - if (failureEventHandler != null) { - failureEventHandler.fireFailure(); - this.failureEventHandler = null; - } - } - - @Override - public boolean setListener(FutureListener listener) { - if (listener == null) { - throw new NullPointerException("listener"); - } - - boolean alreadyReady = false; - synchronized (this) { - if (ready) { - alreadyReady = true; - } else { - this.listener = listener; - } - - } - - if (alreadyReady) { - fireOnComplete(listener); - } - return !alreadyReady; - } - - private boolean fireOnComplete(FutureListener listener) { - try { - listener.onComplete(this); - return true; - } catch (Throwable th) { - logger.warn("FutureListener.onComplete() fail Caused:{}", th.getMessage(), th); - return false; - } - } - - @Override - public boolean await(long timeoutMillis) { - return await0(timeoutMillis); - } - - @Override - public boolean await() { - return await0(this.timeoutMillis); - } - - private boolean await0(long timeoutMillis) { - if (timeoutMillis < 0) { - throw new IllegalArgumentException("timeoutMillis must not be negative :" + timeoutMillis); - } - - boolean interrupted = false; - - synchronized (this) { - if (ready) { - return true; - } - - try { - this.waiters++; - wait(timeoutMillis); - } catch (InterruptedException e) { - interrupted = true; - } finally { - this.waiters--; - } - } - - if (interrupted) { - Thread.currentThread().interrupt(); - } - return ready; - - } - - - @Override - public void run(Timeout timeout) throws Exception { - if (timeout.isCancelled()) { - return; - } - this.fireTimeout(); - } - - public void setTimeout(Timeout timeout) { - if (timeout == null) { - throw new NullPointerException("timeout"); - } - this.timeout = timeout; - } - - public void setFailureEventHandler(FailureEventHandler failureEventHandler) { - if (failureEventHandler == null) { - throw new NullPointerException("failureEventHandler"); - } - this.failureEventHandler = failureEventHandler; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("DefaultFuture"); - sb.append("{ready=").append(ready); - sb.append(", result=").append(result); - sb.append(", cause=").append(cause); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.rpc; + +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class DefaultFuture implements TimerTask, Future { + + private static final Logger logger = LoggerFactory.getLogger(DefaultFuture.class); + + private final long timeoutMillis; + private int waiters = 0; + + private boolean ready = false; + + private T result; + private Throwable cause; + + private Timeout timeout; + private FailureEventHandler failureEventHandler; + private FutureListener listener; + + + public DefaultFuture() { + this(3000); + } + + public DefaultFuture(long timeoutMillis) { + this.timeoutMillis = timeoutMillis; + } + + @Override + public synchronized T getResult() { + if (this.cause != null) { + throw new PinpointSocketException(cause); + } + return result; + } + + @Override + public synchronized Throwable getCause() { + return cause; + } + + @Override + public synchronized boolean isReady() { + return ready; + } + + @Override + public synchronized boolean isSuccess() { + return ready && cause == null; + } + + public boolean setResult(T message) { + synchronized (this) { + if (ready) { + return false; + } + this.ready = true; + + this.result = message; + if (waiters > 0) { + notifyAll(); + } + } + cancelTimeout(); + notifyListener(); + return true; + + } + + public boolean setFailure(Throwable cause) { + synchronized (this) { + if (ready) { + return false; + } + this.ready = true; + + this.cause = cause; + + if (waiters > 0) { + notifyAll(); + } + } + + cancelTimeout(); + notifyFailureHandle(); + notifyListener(); + return true; + } + + private boolean fireTimeout() { + synchronized (this) { + if (ready) { + return false; + } + this.ready = true; + + this.cause = new PinpointSocketException("timeout"); + + if (waiters > 0) { + notifyAll(); + } + } + // 이미 timeout 되서 들어오기 때문에 tieout.cancel시킬필요가 없음. + notifyFailureHandle(); + notifyListener(); + return true; + } + + private void cancelTimeout() { + final Timeout timeout = this.timeout; + if (timeout != null) { + timeout.cancel(); + this.timeout = null; + } + } + + private void notifyListener() { + FutureListener listener = this.listener; + if (listener != null) { + fireOnComplete(listener); + this.listener = null; + } + } + + protected void notifyFailureHandle() { + + FailureEventHandler failureEventHandler = this.failureEventHandler; + if (failureEventHandler != null) { + failureEventHandler.fireFailure(); + this.failureEventHandler = null; + } + } + + @Override + public boolean setListener(FutureListener listener) { + if (listener == null) { + throw new NullPointerException("listener"); + } + + boolean alreadyReady = false; + synchronized (this) { + if (ready) { + alreadyReady = true; + } else { + this.listener = listener; + } + + } + + if (alreadyReady) { + fireOnComplete(listener); + } + return !alreadyReady; + } + + private boolean fireOnComplete(FutureListener listener) { + try { + listener.onComplete(this); + return true; + } catch (Throwable th) { + logger.warn("FutureListener.onComplete() fail Caused:{}", th.getMessage(), th); + return false; + } + } + + @Override + public boolean await(long timeoutMillis) { + return await0(timeoutMillis); + } + + @Override + public boolean await() { + return await0(this.timeoutMillis); + } + + private boolean await0(long timeoutMillis) { + if (timeoutMillis < 0) { + throw new IllegalArgumentException("timeoutMillis must not be negative :" + timeoutMillis); + } + + boolean interrupted = false; + + synchronized (this) { + if (ready) { + return true; + } + + try { + this.waiters++; + wait(timeoutMillis); + } catch (InterruptedException e) { + interrupted = true; + } finally { + this.waiters--; + } + } + + if (interrupted) { + Thread.currentThread().interrupt(); + } + return ready; + + } + + + @Override + public void run(Timeout timeout) throws Exception { + if (timeout.isCancelled()) { + return; + } + this.fireTimeout(); + } + + public void setTimeout(Timeout timeout) { + if (timeout == null) { + throw new NullPointerException("timeout"); + } + this.timeout = timeout; + } + + public void setFailureEventHandler(FailureEventHandler failureEventHandler) { + if (failureEventHandler == null) { + throw new NullPointerException("failureEventHandler"); + } + this.failureEventHandler = failureEventHandler; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("DefaultFuture"); + sb.append("{ready=").append(ready); + sb.append(", result=").append(result); + sb.append(", cause=").append(cause); + sb.append('}'); + return sb.toString(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/FailureEventHandler.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/FailureEventHandler.java index 3cc8419c6322..4e60f282cbcb 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/FailureEventHandler.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/FailureEventHandler.java @@ -1,9 +1,9 @@ -package com.nhn.pinpoint.rpc; - -/** - * @author emeroad - */ -public interface FailureEventHandler { - - boolean fireFailure(); -} +package com.nhn.pinpoint.rpc; + +/** + * @author emeroad + */ +public interface FailureEventHandler { + + boolean fireFailure(); +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/Future.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/Future.java index 22c2a7a7434d..7d7fdff0cbef 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/Future.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/Future.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.rpc; - -/** - * @author emeroad - */ -public interface Future { - - T getResult(); - - Throwable getCause(); - - boolean isReady(); - - boolean isSuccess(); - - boolean setListener(FutureListener listener); - - boolean await(long timeoutMillis); - - boolean await(); -} +package com.nhn.pinpoint.rpc; + +/** + * @author emeroad + */ +public interface Future { + + T getResult(); + + Throwable getCause(); + + boolean isReady(); + + boolean isSuccess(); + + boolean setListener(FutureListener listener); + + boolean await(long timeoutMillis); + + boolean await(); +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/FutureListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/FutureListener.java index bf960a7e76f2..b20bd13a1a2c 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/FutureListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/FutureListener.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.rpc; - -/** - * @author emeroad - */ -public interface FutureListener { - void onComplete(Future future); -} +package com.nhn.pinpoint.rpc; + +/** + * @author emeroad + */ +public interface FutureListener { + void onComplete(Future future); +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/Message.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/Message.java index 462ff40f4ca9..65e513f3e364 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/Message.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/Message.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.rpc; - -/** - * @author emeroad - */ -public interface Message { - byte[] getMessage(); -} +package com.nhn.pinpoint.rpc; + +/** + * @author emeroad + */ +public interface Message { + byte[] getMessage(); +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/PinpointSocketException.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/PinpointSocketException.java index 061299e387b0..6a33066213ae 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/PinpointSocketException.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/PinpointSocketException.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.rpc; - -/** - * @author emeroad - */ -public class PinpointSocketException extends RuntimeException { - public PinpointSocketException() { - } - - public PinpointSocketException(String message) { - super(message); - } - - public PinpointSocketException(String message, Throwable cause) { - super(message, cause); - } - - public PinpointSocketException(Throwable cause) { - super(cause); - } -} +package com.nhn.pinpoint.rpc; + +/** + * @author emeroad + */ +public class PinpointSocketException extends RuntimeException { + public PinpointSocketException() { + } + + public PinpointSocketException(String message) { + super(message); + } + + public PinpointSocketException(String message, Throwable cause) { + super(message, cause); + } + + public PinpointSocketException(Throwable cause) { + super(cause); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/RequestResponseServerMessageListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/RequestResponseServerMessageListener.java index 5766a649c1f1..693245ecc92a 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/RequestResponseServerMessageListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/RequestResponseServerMessageListener.java @@ -1,49 +1,49 @@ -package com.nhn.pinpoint.rpc; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import com.nhn.pinpoint.rpc.server.ServerMessageListener; -import com.nhn.pinpoint.rpc.server.ServerStreamChannel; -import com.nhn.pinpoint.rpc.server.SocketChannel; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class RequestResponseServerMessageListener implements ServerMessageListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final RequestResponseServerMessageListener LISTENER = new RequestResponseServerMessageListener(); - - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - logger.info("handlerSend {} {}", sendPacket, channel); - - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - logger.info("handlerRequest {}", requestPacket, channel); - channel.sendResponseMessage(requestPacket, requestPacket.getPayload()); - } - - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.info("handlerStream {} {}", streamChannel, streamChannel); - } - - @Override - public int handleEnableWorker(Map properties) { - logger.info("handleEnableWorker {}", properties); - return ControlEnableWorkerConfirmPacket.SUCCESS; - } - -} +package com.nhn.pinpoint.rpc; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.server.ServerMessageListener; +import com.nhn.pinpoint.rpc.server.ServerStreamChannel; +import com.nhn.pinpoint.rpc.server.SocketChannel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class RequestResponseServerMessageListener implements ServerMessageListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final RequestResponseServerMessageListener LISTENER = new RequestResponseServerMessageListener(); + + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.info("handlerSend {} {}", sendPacket, channel); + + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.info("handlerRequest {}", requestPacket, channel); + channel.sendResponseMessage(requestPacket, requestPacket.getPayload()); + } + + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.info("handlerStream {} {}", streamChannel, streamChannel); + } + + @Override + public int handleEnableWorker(Map properties) { + logger.info("handleEnableWorker {}", properties); + return ControlEnableWorkerConfirmPacket.SUCCESS; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ResponseMessage.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ResponseMessage.java index da60d3f3406d..024cda543c8d 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/ResponseMessage.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/ResponseMessage.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.rpc; - -/** - * @author emeroad - */ -public class ResponseMessage implements Message { - private byte[] message; - - public ResponseMessage() { - } - - public void setMessage(byte[] payload) { - if (payload == null) { - throw new NullPointerException("message"); - } - this.message = payload; - } - - @Override - public byte[] getMessage() { - return message; - } -} +package com.nhn.pinpoint.rpc; + +/** + * @author emeroad + */ +public class ResponseMessage implements Message { + private byte[] message; + + public ResponseMessage() { + } + + public void setMessage(byte[] payload) { + if (payload == null) { + throw new NullPointerException("message"); + } + this.message = payload; + } + + @Override + public byte[] getMessage() { + return message; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/StreamCreateResponse.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/StreamCreateResponse.java index a1c42751cc29..2e43eb9df589 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/StreamCreateResponse.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/StreamCreateResponse.java @@ -1,20 +1,20 @@ -package com.nhn.pinpoint.rpc; - -/** - * @author emeroad - */ -public class StreamCreateResponse extends ResponseMessage { - private boolean success; - - public StreamCreateResponse(boolean success) { - this.success = success; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } -} +package com.nhn.pinpoint.rpc; + +/** + * @author emeroad + */ +public class StreamCreateResponse extends ResponseMessage { + private boolean success; + + public StreamCreateResponse(boolean success) { + this.success = success; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/DummyPinpointSocketReconnectEventListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/DummyPinpointSocketReconnectEventListener.java index 1ef6f1a08c45..c565307ab42e 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/DummyPinpointSocketReconnectEventListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/DummyPinpointSocketReconnectEventListener.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.rpc.client; - -public class DummyPinpointSocketReconnectEventListener implements PinpointSocketReconnectEventListener { - - @Override - public void reconnectPerformed(PinpointSocket socket) { - - } - -} +package com.nhn.pinpoint.rpc.client; + +public class DummyPinpointSocketReconnectEventListener implements PinpointSocketReconnectEventListener { + + @Override + public void reconnectPerformed(PinpointSocket socket) { + + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/MessageListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/MessageListener.java index e055bc94fa28..2ef39019166c 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/MessageListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/MessageListener.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.rpc.client; - -import org.jboss.netty.channel.Channel; - -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; - -/** - * @author koo.taejin - */ -public interface MessageListener { - - void handleSend(SendPacket sendPacket, Channel channel); - - void handleRequest(RequestPacket requestPacket, Channel channel); - -} +package com.nhn.pinpoint.rpc.client; + +import org.jboss.netty.channel.Channel; + +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; + +/** + * @author koo.taejin + */ +public interface MessageListener { + + void handleSend(SendPacket sendPacket, Channel channel); + + void handleRequest(RequestPacket requestPacket, Channel channel); + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocket.java index ea04fd688df7..cc9ec2cd0021 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocket.java @@ -1,174 +1,174 @@ -package com.nhn.pinpoint.rpc.client; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.DefaultFuture; -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.ResponseMessage; -import com.nhn.pinpoint.rpc.util.AssertUtils; - - -/** - * @author emeroad - * @author koo.taejin - * @author netspider - */ -public class PinpointSocket { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final MessageListener messageListener; - - private volatile SocketHandler socketHandler; - - private volatile boolean closed; - - private List reconnectEventListeners = new CopyOnWriteArrayList(); - - public PinpointSocket() { - this(new ReconnectStateSocketHandler()); - } - - public PinpointSocket(MessageListener messageListener) { - this(new ReconnectStateSocketHandler(), messageListener); - } - - public PinpointSocket(SocketHandler socketHandler) { - this(socketHandler, SimpleLoggingMessageListener.LISTENER); - } - - public PinpointSocket(SocketHandler socketHandler, MessageListener messageListener) { - AssertUtils.assertNotNull(socketHandler, "socketHandler"); - AssertUtils.assertNotNull(messageListener, "messageListener"); - - this.messageListener = messageListener; - socketHandler.setMessageListener(this.messageListener); - - this.socketHandler = socketHandler; - - socketHandler.setPinpointSocket(this); - } - - - void reconnectSocketHandler(SocketHandler socketHandler) { - AssertUtils.assertNotNull(socketHandler, "socketHandler"); - - if (closed) { - logger.warn("reconnectSocketHandler(). socketHandler force close."); - socketHandler.close(); - return; - } - logger.warn("reconnectSocketHandler:{}", socketHandler); - - // Pinpoint 소켓 내부 객체가 되기전에 listener를 먼저 등록 - socketHandler.setMessageListener(messageListener); - this.socketHandler = socketHandler; - - notifyReconnectEvent(); - } - - // reconnectEventListener의 경우 직접 생성자 호출시에 Dummy를 포함하고 있으며, - // setter를 통해서도 접근을 못하게 하기 때문에 null이 아닌 것이 보장됨 - public boolean addPinpointSocketReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - if (eventListener == null) { - return false; - } - - return this.reconnectEventListeners.add(eventListener); - } - - public boolean removePinpointSocketReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { - if (eventListener == null) { - return false; - } - - return this.reconnectEventListeners.remove(eventListener); - } - - private void notifyReconnectEvent() { - for (PinpointSocketReconnectEventListener eachListener : this.reconnectEventListeners) { - eachListener.reconnectPerformed(this); - } - } - - public void sendSync(byte[] bytes) { - ensureOpen(); - socketHandler.sendSync(bytes); - } - - public Future sendAsync(byte[] bytes) { - ensureOpen(); - return socketHandler.sendAsync(bytes); - } - - public void send(byte[] bytes) { - ensureOpen(); - socketHandler.send(bytes); - } - - - public Future request(byte[] bytes) { - if (socketHandler == null) { - return returnFailureFuture(); - } - return socketHandler.request(bytes); - } - - - public StreamChannel createStreamChannel() { - // 실패를 리턴하는 StreamChannel을 던져야 되는데. StreamChannel을 interface로 변경해야 됨. - // 일단 그냥 ex를 던지도록 하겠음. - ensureOpen(); - return socketHandler.createStreamChannel(); - } - - private Future returnFailureFuture() { - DefaultFuture future = new DefaultFuture(); - future.setFailure(new PinpointSocketException("socketHandler is null")); - return future; - } - - private void ensureOpen() { - if (socketHandler == null) { - throw new PinpointSocketException("socketHandler is null"); - } - } - - /** - * ping packet을 tcp 채널에 write한다. - * write 실패시 PinpointSocketException이 throw 된다. - */ - public void sendPing() { - SocketHandler socketHandler = this.socketHandler; - if (socketHandler == null) { - return; - } - socketHandler.sendPing(); - } - - public void close() { - synchronized (this) { - if (closed) { - return; - } - closed = true; - } - SocketHandler socketHandler = this.socketHandler; - if (socketHandler == null) { - return; - } - socketHandler.close(); - } - - public boolean isClosed() { - return closed; - } - - public boolean isConnected() { - return this.socketHandler.isConnected(); - } -} +package com.nhn.pinpoint.rpc.client; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.DefaultFuture; +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.rpc.util.AssertUtils; + + +/** + * @author emeroad + * @author koo.taejin + * @author netspider + */ +public class PinpointSocket { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final MessageListener messageListener; + + private volatile SocketHandler socketHandler; + + private volatile boolean closed; + + private List reconnectEventListeners = new CopyOnWriteArrayList(); + + public PinpointSocket() { + this(new ReconnectStateSocketHandler()); + } + + public PinpointSocket(MessageListener messageListener) { + this(new ReconnectStateSocketHandler(), messageListener); + } + + public PinpointSocket(SocketHandler socketHandler) { + this(socketHandler, SimpleLoggingMessageListener.LISTENER); + } + + public PinpointSocket(SocketHandler socketHandler, MessageListener messageListener) { + AssertUtils.assertNotNull(socketHandler, "socketHandler"); + AssertUtils.assertNotNull(messageListener, "messageListener"); + + this.messageListener = messageListener; + socketHandler.setMessageListener(this.messageListener); + + this.socketHandler = socketHandler; + + socketHandler.setPinpointSocket(this); + } + + + void reconnectSocketHandler(SocketHandler socketHandler) { + AssertUtils.assertNotNull(socketHandler, "socketHandler"); + + if (closed) { + logger.warn("reconnectSocketHandler(). socketHandler force close."); + socketHandler.close(); + return; + } + logger.warn("reconnectSocketHandler:{}", socketHandler); + + // Pinpoint 소켓 내부 객체가 되기전에 listener를 먼저 등록 + socketHandler.setMessageListener(messageListener); + this.socketHandler = socketHandler; + + notifyReconnectEvent(); + } + + // reconnectEventListener의 경우 직접 생성자 호출시에 Dummy를 포함하고 있으며, + // setter를 통해서도 접근을 못하게 하기 때문에 null이 아닌 것이 보장됨 + public boolean addPinpointSocketReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + if (eventListener == null) { + return false; + } + + return this.reconnectEventListeners.add(eventListener); + } + + public boolean removePinpointSocketReconnectEventListener(PinpointSocketReconnectEventListener eventListener) { + if (eventListener == null) { + return false; + } + + return this.reconnectEventListeners.remove(eventListener); + } + + private void notifyReconnectEvent() { + for (PinpointSocketReconnectEventListener eachListener : this.reconnectEventListeners) { + eachListener.reconnectPerformed(this); + } + } + + public void sendSync(byte[] bytes) { + ensureOpen(); + socketHandler.sendSync(bytes); + } + + public Future sendAsync(byte[] bytes) { + ensureOpen(); + return socketHandler.sendAsync(bytes); + } + + public void send(byte[] bytes) { + ensureOpen(); + socketHandler.send(bytes); + } + + + public Future request(byte[] bytes) { + if (socketHandler == null) { + return returnFailureFuture(); + } + return socketHandler.request(bytes); + } + + + public StreamChannel createStreamChannel() { + // 실패를 리턴하는 StreamChannel을 던져야 되는데. StreamChannel을 interface로 변경해야 됨. + // 일단 그냥 ex를 던지도록 하겠음. + ensureOpen(); + return socketHandler.createStreamChannel(); + } + + private Future returnFailureFuture() { + DefaultFuture future = new DefaultFuture(); + future.setFailure(new PinpointSocketException("socketHandler is null")); + return future; + } + + private void ensureOpen() { + if (socketHandler == null) { + throw new PinpointSocketException("socketHandler is null"); + } + } + + /** + * ping packet을 tcp 채널에 write한다. + * write 실패시 PinpointSocketException이 throw 된다. + */ + public void sendPing() { + SocketHandler socketHandler = this.socketHandler; + if (socketHandler == null) { + return; + } + socketHandler.sendPing(); + } + + public void close() { + synchronized (this) { + if (closed) { + return; + } + closed = true; + } + SocketHandler socketHandler = this.socketHandler; + if (socketHandler == null) { + return; + } + socketHandler.close(); + } + + public boolean isClosed() { + return closed; + } + + public boolean isConnected() { + return this.socketHandler.isConnected(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactory.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactory.java index 4db920a5c4fa..f1774ef84488 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactory.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactory.java @@ -1,386 +1,386 @@ -package com.nhn.pinpoint.rpc.client; - - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.jboss.netty.bootstrap.ClientBootstrap; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineException; -import org.jboss.netty.channel.socket.nio.NioClientBossPool; -import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; -import org.jboss.netty.channel.socket.nio.NioWorkerPool; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.ThreadNameDeterminer; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.Timer; -import org.jboss.netty.util.TimerTask; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.common.util.PinpointThreadFactory; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.util.AssertUtils; -import com.nhn.pinpoint.rpc.util.LoggerFactorySetup; -import com.nhn.pinpoint.rpc.util.TimerFactory; - -/** - * @author emeroad - * @author koo.taejin - */ -public class PinpointSocketFactory { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final String CONNECT_TIMEOUT_MILLIS = "connectTimeoutMillis"; - private static final int DEFAULT_CONNECT_TIMEOUT = 5000; - private static final long DEFAULT_TIMEOUTMILLIS = 3 * 1000; - private static final long DEFAULT_PING_DELAY = 60 * 1000 * 5; - private static final long DEFAULT_ENABLE_WORKER_PACKET_DELAY = 60 * 1000 * 1; - - - private volatile boolean released; - private ClientBootstrap bootstrap; - private Map properties = Collections.emptyMap(); - - private long reconnectDelay = 3 * 1000; - private final Timer timer; - - // 이 값이 짧아야 될 필요가 없음. client에서 server로 가는 핑 주기를 짧게 유지한다고 해서. - // 연결끊김이 빨랑 디텍트 되는게 아님. 오히려 server에서 client의 ping주기를 짧게 해야 디텍트 속도가 빨라짐. - private long pingDelay = DEFAULT_PING_DELAY; - private long enableWorkerPacketDelay = DEFAULT_ENABLE_WORKER_PACKET_DELAY; - private long timeoutMillis = DEFAULT_TIMEOUTMILLIS; - - - static { - LoggerFactorySetup.setupSlf4jLoggerFactory(); - } - - public PinpointSocketFactory() { - this(1, 1); - } - - public PinpointSocketFactory(int bossCount, int workerCount) { - if (bossCount < 1) { - throw new IllegalArgumentException("bossCount is negative: " + bossCount); - } - // timer를 connect timeout으로 쓰므로 먼저 만들어야 됨. - Timer timer = createTimer(); - ClientBootstrap bootstrap = createBootStrap(bossCount, workerCount, timer); - setOptions(bootstrap); - addPipeline(bootstrap); - - this.bootstrap = bootstrap; - this.timer = timer; - } - - private Timer createTimer() { - HashedWheelTimer timer = TimerFactory.createHashedWheelTimer("Pinpoint-SocketFactory-Timer", 100, TimeUnit.MILLISECONDS, 512); - timer.start(); - return timer; - } - - private void addPipeline(ClientBootstrap bootstrap) { - SocketClientPipelineFactory socketClientPipelineFactory = new SocketClientPipelineFactory(this); - bootstrap.setPipelineFactory(socketClientPipelineFactory); - } - - private void setOptions(ClientBootstrap bootstrap) { - // connectTimeout - bootstrap.setOption(CONNECT_TIMEOUT_MILLIS, DEFAULT_CONNECT_TIMEOUT); - // read write timeout이 있어야 되나? nio라서 없어도 되던가? - - // tcp 세팅 - bootstrap.setOption("tcpNoDelay", true); - bootstrap.setOption("keepAlive", true); - // buffer - bootstrap.setOption("sendBufferSize", 1024 * 64); - bootstrap.setOption("receiveBufferSize", 1024 * 64); - - } - - public void setConnectTimeout(int connectTimeout) { - if (connectTimeout < 0) { - throw new IllegalArgumentException("connectTimeout cannot be a negative number"); - } - bootstrap.setOption(CONNECT_TIMEOUT_MILLIS, connectTimeout); - } - - public int getConnectTimeout() { - return (Integer) bootstrap.getOption(CONNECT_TIMEOUT_MILLIS); - } - - public long getReconnectDelay() { - return reconnectDelay; - } - - public void setReconnectDelay(long reconnectDelay) { - if (reconnectDelay < 0) { - throw new IllegalArgumentException("reconnectDelay cannot be a negative number"); - } - this.reconnectDelay = reconnectDelay; - } - - public long getPingDelay() { - return pingDelay; - } - - public void setPingDelay(long pingDelay) { - if (pingDelay < 0) { - throw new IllegalArgumentException("pingDelay cannot be a negative number"); - } - this.pingDelay = pingDelay; - } - - public long getEnableWorkerPacketDelay() { - return enableWorkerPacketDelay; - } - - public void setEnableWorkerPacketDelay(long enableWorkerPacketDelay) { - if (enableWorkerPacketDelay < 0) { - throw new IllegalArgumentException("EnableWorkerPacketDelay cannot be a negative number"); - } - this.enableWorkerPacketDelay = enableWorkerPacketDelay; - } - - public long getTimeoutMillis() { - return timeoutMillis; - } - - public void setTimeoutMillis(long timeoutMillis) { - if (timeoutMillis < 0) { - throw new IllegalArgumentException("timeoutMillis cannot be a negative number"); - } - this.timeoutMillis = timeoutMillis; - } - - private ClientBootstrap createBootStrap(int bossCount, int workerCount, Timer timer) { - // profiler, collector, - logger.debug("createBootStrap boss:{}, worker:{}", bossCount, workerCount); - NioClientSocketChannelFactory nioClientSocketChannelFactory = createChannelFactory(bossCount, workerCount, timer); - return new ClientBootstrap(nioClientSocketChannelFactory); - } - - private NioClientSocketChannelFactory createChannelFactory(int bossCount, int workerCount, Timer timer) { - ExecutorService boss = Executors.newCachedThreadPool(new PinpointThreadFactory("Pinpoint-Client-Boss", true)); - NioClientBossPool bossPool = new NioClientBossPool(boss, bossCount, timer, ThreadNameDeterminer.CURRENT); - - ExecutorService worker = Executors.newCachedThreadPool(new PinpointThreadFactory("Pinpoint-Client-Worker", true)); - NioWorkerPool workerPool = new NioWorkerPool(worker, workerCount, ThreadNameDeterminer.CURRENT); - return new NioClientSocketChannelFactory(bossPool, workerPool); - } - - public PinpointSocket connect(String host, int port) throws PinpointSocketException { - return connect(host, port, SimpleLoggingMessageListener.LISTENER); - } - - public PinpointSocket connect(String host, int port, MessageListener messageListener) throws PinpointSocketException { - AssertUtils.assertNotNull(messageListener); - - SocketAddress address = new InetSocketAddress(host, port); - ChannelFuture connectFuture = bootstrap.connect(address); - SocketHandler socketHandler = getSocketHandler(connectFuture, address); - - PinpointSocket pinpointSocket = new PinpointSocket(socketHandler, messageListener); - traceSocket(pinpointSocket); - return pinpointSocket; - } - - public PinpointSocket reconnect(String host, int port) throws PinpointSocketException { - return reconnect(host, port, SimpleLoggingMessageListener.LISTENER); - } - - public PinpointSocket reconnect(String host, int port, MessageListener messageListener) throws PinpointSocketException { - AssertUtils.assertNotNull(messageListener); - - SocketAddress address = new InetSocketAddress(host, port); - ChannelFuture connectFuture = bootstrap.connect(address); - SocketHandler socketHandler = getSocketHandler(connectFuture, address); - - PinpointSocket pinpointSocket = new PinpointSocket(socketHandler, messageListener); - traceSocket(pinpointSocket); - return pinpointSocket; - } - - private void traceSocket(PinpointSocket pinpointSocket) { - // socket을 닫지 않고 clsoe했을 경우의 추적 로직이 필요함 - // 예외 케이스 이므로 나중에 만들어도 될듯. - } - - public PinpointSocket scheduledConnect(String host, int port) { - return scheduledConnect(host, port, SimpleLoggingMessageListener.LISTENER); - } - - public PinpointSocket scheduledConnect(String host, int port, MessageListener messageListener) { - AssertUtils.assertNotNull(messageListener); - - PinpointSocket pinpointSocket = new PinpointSocket(new ReconnectStateSocketHandler(), messageListener); - SocketAddress address = new InetSocketAddress(host, port); - reconnect(pinpointSocket, address); - return pinpointSocket; - } - - SocketHandler getSocketHandler(ChannelFuture connectFuture, SocketAddress address) { - if (address == null) { - throw new NullPointerException("address"); - } - - SocketHandler socketHandler = getSocketHandler(connectFuture.getChannel()); - socketHandler.setConnectSocketAddress(address); - - connectFuture.awaitUninterruptibly(); - if (!connectFuture.isSuccess()) { - throw new PinpointSocketException("connect fail. " + address, connectFuture.getCause()); - } - socketHandler.open(); - return socketHandler; - } - - public ChannelFuture reconnect(final SocketAddress remoteAddress) { - if (remoteAddress == null) { - throw new NullPointerException("remoteAddress"); - } - - ChannelPipeline pipeline; - final ClientBootstrap bootstrap = this.bootstrap; - try { - pipeline = bootstrap.getPipelineFactory().getPipeline(); - } catch (Exception e) { - throw new ChannelPipelineException("Failed to initialize a pipeline.", e); - } - SocketHandler socketHandler = (PinpointSocketHandler) pipeline.getLast(); - socketHandler.initReconnect(); - - - // Set the options. - Channel ch = bootstrap.getFactory().newChannel(pipeline); - boolean success = false; - try { - ch.getConfig().setOptions(bootstrap.getOptions()); - success = true; - } finally { - if (!success) { - ch.close(); - } - } - - // Connect. - return ch.connect(remoteAddress); - } - - public Timeout newTimeout(TimerTask task, long delay, TimeUnit unit) { - return this.timer.newTimeout(task, delay, unit); - } - - - private SocketHandler getSocketHandler(Channel channel) { - return (SocketHandler) channel.getPipeline().getLast(); - } - - void reconnect(final PinpointSocket pinpointSocket, final SocketAddress socketAddress) { - ConnectEvent connectEvent = new ConnectEvent(pinpointSocket, socketAddress); - timer.newTimeout(connectEvent, reconnectDelay, TimeUnit.MILLISECONDS); - } - - - private class ConnectEvent implements TimerTask { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final PinpointSocket pinpointSocket; - private final SocketAddress socketAddress; - - private ConnectEvent(PinpointSocket pinpointSocket, SocketAddress socketAddress) { - if (pinpointSocket == null) { - throw new NullPointerException("pinpointSocket must not be null"); - } - if (socketAddress == null) { - throw new NullPointerException("socketAddress must not be null"); - } - - this.pinpointSocket = pinpointSocket; - this.socketAddress = socketAddress; - } - - @Override - public void run(Timeout timeout) { - if (timeout.isCancelled()) { - return; - } - // 이벤트는 fire됬지만 close됬을 경우 reconnect를 시도 하지 않음. - if (pinpointSocket.isClosed()) { - logger.debug("pinpointSocket is already closed."); - return; - } - - logger.warn("try reconnect. connectAddress:{}", socketAddress); - final ChannelFuture channelFuture = reconnect(socketAddress); - Channel channel = channelFuture.getChannel(); - final SocketHandler socketHandler = getSocketHandler(channel); - socketHandler.setConnectSocketAddress(socketAddress); - socketHandler.setPinpointSocket(pinpointSocket); - - channelFuture.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (future.isSuccess()) { - Channel channel = future.getChannel(); - logger.warn("reconnect success {}, {}", socketAddress, channel); - socketHandler.open(); - pinpointSocket.reconnectSocketHandler(socketHandler); - } else { - if (!pinpointSocket.isClosed()) { -// 구지 여기서 안찍어도 exceptionCought에서 메시지가 발생하므로 생략 -// if (logger.isWarnEnabled()) { -// Throwable cause = future.getCause(); -// logger.warn("reconnect fail. {} Caused:{}", socketAddress, cause.getMessage()); -// } - reconnect(pinpointSocket, socketAddress); - } else { - logger.info("pinpointSocket is closed. stop reconnect."); - } - } - } - }); - } - } - - - public void release() { - synchronized (this) { - if (released) { - return; - } - released = true; - } - - if (bootstrap != null) { - bootstrap.releaseExternalResources(); - } - Set stop = this.timer.stop(); - if (!stop.isEmpty()) { - logger.info("stop Timeout:{}", stop.size()); - } -// stop 뭔가 취소를 해야 되나?? - } - - Map getProperties() { - return properties; - } - - public void setProperties(Map agentProperties) { - AssertUtils.assertNotNull(properties, "agentProperties must not be null"); - - this.properties = Collections.unmodifiableMap(agentProperties); - } - -} +package com.nhn.pinpoint.rpc.client; + + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.bootstrap.ClientBootstrap; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineException; +import org.jboss.netty.channel.socket.nio.NioClientBossPool; +import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; +import org.jboss.netty.channel.socket.nio.NioWorkerPool; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.ThreadNameDeterminer; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.Timer; +import org.jboss.netty.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.common.util.PinpointThreadFactory; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.util.AssertUtils; +import com.nhn.pinpoint.rpc.util.LoggerFactorySetup; +import com.nhn.pinpoint.rpc.util.TimerFactory; + +/** + * @author emeroad + * @author koo.taejin + */ +public class PinpointSocketFactory { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final String CONNECT_TIMEOUT_MILLIS = "connectTimeoutMillis"; + private static final int DEFAULT_CONNECT_TIMEOUT = 5000; + private static final long DEFAULT_TIMEOUTMILLIS = 3 * 1000; + private static final long DEFAULT_PING_DELAY = 60 * 1000 * 5; + private static final long DEFAULT_ENABLE_WORKER_PACKET_DELAY = 60 * 1000 * 1; + + + private volatile boolean released; + private ClientBootstrap bootstrap; + private Map properties = Collections.emptyMap(); + + private long reconnectDelay = 3 * 1000; + private final Timer timer; + + // 이 값이 짧아야 될 필요가 없음. client에서 server로 가는 핑 주기를 짧게 유지한다고 해서. + // 연결끊김이 빨랑 디텍트 되는게 아님. 오히려 server에서 client의 ping주기를 짧게 해야 디텍트 속도가 빨라짐. + private long pingDelay = DEFAULT_PING_DELAY; + private long enableWorkerPacketDelay = DEFAULT_ENABLE_WORKER_PACKET_DELAY; + private long timeoutMillis = DEFAULT_TIMEOUTMILLIS; + + + static { + LoggerFactorySetup.setupSlf4jLoggerFactory(); + } + + public PinpointSocketFactory() { + this(1, 1); + } + + public PinpointSocketFactory(int bossCount, int workerCount) { + if (bossCount < 1) { + throw new IllegalArgumentException("bossCount is negative: " + bossCount); + } + // timer를 connect timeout으로 쓰므로 먼저 만들어야 됨. + Timer timer = createTimer(); + ClientBootstrap bootstrap = createBootStrap(bossCount, workerCount, timer); + setOptions(bootstrap); + addPipeline(bootstrap); + + this.bootstrap = bootstrap; + this.timer = timer; + } + + private Timer createTimer() { + HashedWheelTimer timer = TimerFactory.createHashedWheelTimer("Pinpoint-SocketFactory-Timer", 100, TimeUnit.MILLISECONDS, 512); + timer.start(); + return timer; + } + + private void addPipeline(ClientBootstrap bootstrap) { + SocketClientPipelineFactory socketClientPipelineFactory = new SocketClientPipelineFactory(this); + bootstrap.setPipelineFactory(socketClientPipelineFactory); + } + + private void setOptions(ClientBootstrap bootstrap) { + // connectTimeout + bootstrap.setOption(CONNECT_TIMEOUT_MILLIS, DEFAULT_CONNECT_TIMEOUT); + // read write timeout이 있어야 되나? nio라서 없어도 되던가? + + // tcp 세팅 + bootstrap.setOption("tcpNoDelay", true); + bootstrap.setOption("keepAlive", true); + // buffer + bootstrap.setOption("sendBufferSize", 1024 * 64); + bootstrap.setOption("receiveBufferSize", 1024 * 64); + + } + + public void setConnectTimeout(int connectTimeout) { + if (connectTimeout < 0) { + throw new IllegalArgumentException("connectTimeout cannot be a negative number"); + } + bootstrap.setOption(CONNECT_TIMEOUT_MILLIS, connectTimeout); + } + + public int getConnectTimeout() { + return (Integer) bootstrap.getOption(CONNECT_TIMEOUT_MILLIS); + } + + public long getReconnectDelay() { + return reconnectDelay; + } + + public void setReconnectDelay(long reconnectDelay) { + if (reconnectDelay < 0) { + throw new IllegalArgumentException("reconnectDelay cannot be a negative number"); + } + this.reconnectDelay = reconnectDelay; + } + + public long getPingDelay() { + return pingDelay; + } + + public void setPingDelay(long pingDelay) { + if (pingDelay < 0) { + throw new IllegalArgumentException("pingDelay cannot be a negative number"); + } + this.pingDelay = pingDelay; + } + + public long getEnableWorkerPacketDelay() { + return enableWorkerPacketDelay; + } + + public void setEnableWorkerPacketDelay(long enableWorkerPacketDelay) { + if (enableWorkerPacketDelay < 0) { + throw new IllegalArgumentException("EnableWorkerPacketDelay cannot be a negative number"); + } + this.enableWorkerPacketDelay = enableWorkerPacketDelay; + } + + public long getTimeoutMillis() { + return timeoutMillis; + } + + public void setTimeoutMillis(long timeoutMillis) { + if (timeoutMillis < 0) { + throw new IllegalArgumentException("timeoutMillis cannot be a negative number"); + } + this.timeoutMillis = timeoutMillis; + } + + private ClientBootstrap createBootStrap(int bossCount, int workerCount, Timer timer) { + // profiler, collector, + logger.debug("createBootStrap boss:{}, worker:{}", bossCount, workerCount); + NioClientSocketChannelFactory nioClientSocketChannelFactory = createChannelFactory(bossCount, workerCount, timer); + return new ClientBootstrap(nioClientSocketChannelFactory); + } + + private NioClientSocketChannelFactory createChannelFactory(int bossCount, int workerCount, Timer timer) { + ExecutorService boss = Executors.newCachedThreadPool(new PinpointThreadFactory("Pinpoint-Client-Boss", true)); + NioClientBossPool bossPool = new NioClientBossPool(boss, bossCount, timer, ThreadNameDeterminer.CURRENT); + + ExecutorService worker = Executors.newCachedThreadPool(new PinpointThreadFactory("Pinpoint-Client-Worker", true)); + NioWorkerPool workerPool = new NioWorkerPool(worker, workerCount, ThreadNameDeterminer.CURRENT); + return new NioClientSocketChannelFactory(bossPool, workerPool); + } + + public PinpointSocket connect(String host, int port) throws PinpointSocketException { + return connect(host, port, SimpleLoggingMessageListener.LISTENER); + } + + public PinpointSocket connect(String host, int port, MessageListener messageListener) throws PinpointSocketException { + AssertUtils.assertNotNull(messageListener); + + SocketAddress address = new InetSocketAddress(host, port); + ChannelFuture connectFuture = bootstrap.connect(address); + SocketHandler socketHandler = getSocketHandler(connectFuture, address); + + PinpointSocket pinpointSocket = new PinpointSocket(socketHandler, messageListener); + traceSocket(pinpointSocket); + return pinpointSocket; + } + + public PinpointSocket reconnect(String host, int port) throws PinpointSocketException { + return reconnect(host, port, SimpleLoggingMessageListener.LISTENER); + } + + public PinpointSocket reconnect(String host, int port, MessageListener messageListener) throws PinpointSocketException { + AssertUtils.assertNotNull(messageListener); + + SocketAddress address = new InetSocketAddress(host, port); + ChannelFuture connectFuture = bootstrap.connect(address); + SocketHandler socketHandler = getSocketHandler(connectFuture, address); + + PinpointSocket pinpointSocket = new PinpointSocket(socketHandler, messageListener); + traceSocket(pinpointSocket); + return pinpointSocket; + } + + private void traceSocket(PinpointSocket pinpointSocket) { + // socket을 닫지 않고 clsoe했을 경우의 추적 로직이 필요함 + // 예외 케이스 이므로 나중에 만들어도 될듯. + } + + public PinpointSocket scheduledConnect(String host, int port) { + return scheduledConnect(host, port, SimpleLoggingMessageListener.LISTENER); + } + + public PinpointSocket scheduledConnect(String host, int port, MessageListener messageListener) { + AssertUtils.assertNotNull(messageListener); + + PinpointSocket pinpointSocket = new PinpointSocket(new ReconnectStateSocketHandler(), messageListener); + SocketAddress address = new InetSocketAddress(host, port); + reconnect(pinpointSocket, address); + return pinpointSocket; + } + + SocketHandler getSocketHandler(ChannelFuture connectFuture, SocketAddress address) { + if (address == null) { + throw new NullPointerException("address"); + } + + SocketHandler socketHandler = getSocketHandler(connectFuture.getChannel()); + socketHandler.setConnectSocketAddress(address); + + connectFuture.awaitUninterruptibly(); + if (!connectFuture.isSuccess()) { + throw new PinpointSocketException("connect fail. " + address, connectFuture.getCause()); + } + socketHandler.open(); + return socketHandler; + } + + public ChannelFuture reconnect(final SocketAddress remoteAddress) { + if (remoteAddress == null) { + throw new NullPointerException("remoteAddress"); + } + + ChannelPipeline pipeline; + final ClientBootstrap bootstrap = this.bootstrap; + try { + pipeline = bootstrap.getPipelineFactory().getPipeline(); + } catch (Exception e) { + throw new ChannelPipelineException("Failed to initialize a pipeline.", e); + } + SocketHandler socketHandler = (PinpointSocketHandler) pipeline.getLast(); + socketHandler.initReconnect(); + + + // Set the options. + Channel ch = bootstrap.getFactory().newChannel(pipeline); + boolean success = false; + try { + ch.getConfig().setOptions(bootstrap.getOptions()); + success = true; + } finally { + if (!success) { + ch.close(); + } + } + + // Connect. + return ch.connect(remoteAddress); + } + + public Timeout newTimeout(TimerTask task, long delay, TimeUnit unit) { + return this.timer.newTimeout(task, delay, unit); + } + + + private SocketHandler getSocketHandler(Channel channel) { + return (SocketHandler) channel.getPipeline().getLast(); + } + + void reconnect(final PinpointSocket pinpointSocket, final SocketAddress socketAddress) { + ConnectEvent connectEvent = new ConnectEvent(pinpointSocket, socketAddress); + timer.newTimeout(connectEvent, reconnectDelay, TimeUnit.MILLISECONDS); + } + + + private class ConnectEvent implements TimerTask { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final PinpointSocket pinpointSocket; + private final SocketAddress socketAddress; + + private ConnectEvent(PinpointSocket pinpointSocket, SocketAddress socketAddress) { + if (pinpointSocket == null) { + throw new NullPointerException("pinpointSocket must not be null"); + } + if (socketAddress == null) { + throw new NullPointerException("socketAddress must not be null"); + } + + this.pinpointSocket = pinpointSocket; + this.socketAddress = socketAddress; + } + + @Override + public void run(Timeout timeout) { + if (timeout.isCancelled()) { + return; + } + // 이벤트는 fire됬지만 close됬을 경우 reconnect를 시도 하지 않음. + if (pinpointSocket.isClosed()) { + logger.debug("pinpointSocket is already closed."); + return; + } + + logger.warn("try reconnect. connectAddress:{}", socketAddress); + final ChannelFuture channelFuture = reconnect(socketAddress); + Channel channel = channelFuture.getChannel(); + final SocketHandler socketHandler = getSocketHandler(channel); + socketHandler.setConnectSocketAddress(socketAddress); + socketHandler.setPinpointSocket(pinpointSocket); + + channelFuture.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (future.isSuccess()) { + Channel channel = future.getChannel(); + logger.warn("reconnect success {}, {}", socketAddress, channel); + socketHandler.open(); + pinpointSocket.reconnectSocketHandler(socketHandler); + } else { + if (!pinpointSocket.isClosed()) { +// 구지 여기서 안찍어도 exceptionCought에서 메시지가 발생하므로 생략 +// if (logger.isWarnEnabled()) { +// Throwable cause = future.getCause(); +// logger.warn("reconnect fail. {} Caused:{}", socketAddress, cause.getMessage()); +// } + reconnect(pinpointSocket, socketAddress); + } else { + logger.info("pinpointSocket is closed. stop reconnect."); + } + } + } + }); + } + } + + + public void release() { + synchronized (this) { + if (released) { + return; + } + released = true; + } + + if (bootstrap != null) { + bootstrap.releaseExternalResources(); + } + Set stop = this.timer.stop(); + if (!stop.isEmpty()) { + logger.info("stop Timeout:{}", stop.size()); + } +// stop 뭔가 취소를 해야 되나?? + } + + Map getProperties() { + return properties; + } + + public void setProperties(Map agentProperties) { + AssertUtils.assertNotNull(properties, "agentProperties must not be null"); + + this.properties = Collections.unmodifiableMap(agentProperties); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketHandler.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketHandler.java index 47add2e7ff5b..64902cf70caf 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketHandler.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketHandler.java @@ -1,592 +1,592 @@ -package com.nhn.pinpoint.rpc.client; - -import java.net.SocketAddress; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelHandler; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.Timer; -import org.jboss.netty.util.TimerTask; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.ChannelWriteCompleteListenableFuture; -import com.nhn.pinpoint.rpc.ChannelWriteFailListenableFuture; -import com.nhn.pinpoint.rpc.DefaultFuture; -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.ResponseMessage; -import com.nhn.pinpoint.rpc.control.ProtocolException; -import com.nhn.pinpoint.rpc.packet.ClientClosePacket; -import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; -import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerPacket; -import com.nhn.pinpoint.rpc.packet.Packet; -import com.nhn.pinpoint.rpc.packet.PacketType; -import com.nhn.pinpoint.rpc.packet.PingPacket; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.ResponsePacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import com.nhn.pinpoint.rpc.util.AssertUtils; -import com.nhn.pinpoint.rpc.util.ControlMessageEnDeconderUtils; -import com.nhn.pinpoint.rpc.util.MapUtils; -import com.nhn.pinpoint.rpc.util.TimerFactory; - -/** - * @author emeroad - * @author netspider - * @author koo.taejin - */ -public class PinpointSocketHandler extends SimpleChannelHandler implements SocketHandler { - - private static final long DEFAULT_PING_DELAY = 60 * 1000 * 5; - private static final long DEFAULT_TIMEOUTMILLIS = 3 * 1000; - - private static final long DEFAULT_ENABLE_WORKER_PACKET_DELAY = 60 * 1000 * 1; - private static final int DEFAULT_ENABLE_WORKER_PACKET_RETRY_COUNT = 3; - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final State state = new State(); - - private volatile Channel channel; - private volatile MessageListener messageListener = SimpleLoggingMessageListener.LISTENER; - - private long timeoutMillis = DEFAULT_TIMEOUTMILLIS; - private long pingDelay = DEFAULT_PING_DELAY; - - private long enableWorkerPacketDelay = DEFAULT_ENABLE_WORKER_PACKET_DELAY; - private int enableWorkerPacketRetryCount = DEFAULT_ENABLE_WORKER_PACKET_RETRY_COUNT; - - private final Timer channelTimer; - - private final PinpointSocketFactory pinpointSocketFactory; - private SocketAddress connectSocketAddress; - private volatile PinpointSocket pinpointSocket; - - private final RequestManager requestManager; - private final StreamChannelManager streamChannelManager; - - private final ChannelFutureListener pingWriteFailFutureListener = new WriteFailFutureListener(this.logger, "ping write fail.", "ping write success."); - private final ChannelFutureListener sendWriteFailFutureListener = new WriteFailFutureListener(this.logger, "send() write fail.", "send() write fail."); - private final ChannelFutureListener enableWorkerWriteFailFutureListener = new WriteFailFutureListener(this.logger, "enableWorker write fail.", "enableWorker write success."); - - public PinpointSocketHandler(PinpointSocketFactory pinpointSocketFactory) { - this(pinpointSocketFactory, DEFAULT_PING_DELAY, DEFAULT_ENABLE_WORKER_PACKET_DELAY, DEFAULT_TIMEOUTMILLIS); - } - - public PinpointSocketHandler(PinpointSocketFactory pinpointSocketFactory, long pingDelay, long enableWorkerPacketDelay, long timeoutMillis) { - if (pinpointSocketFactory == null) { - throw new NullPointerException("pinpointSocketFactory must not be null"); - } - - HashedWheelTimer timer = TimerFactory.createHashedWheelTimer("Pinpoint-SocketHandler-Timer", 100, TimeUnit.MILLISECONDS, 512); - timer.start(); - this.channelTimer = timer; - this.pinpointSocketFactory = pinpointSocketFactory; - this.requestManager = new RequestManager(timer); - this.streamChannelManager = new StreamChannelManager(); - this.pingDelay = pingDelay; - this.enableWorkerPacketDelay = enableWorkerPacketDelay; - this.timeoutMillis = timeoutMillis; - } - - public Timer getChannelTimer() { - return channelTimer; - } - - public void setPinpointSocket(PinpointSocket pinpointSocket) { - if (pinpointSocket == null) { - throw new NullPointerException("pinpointSocket must not be null"); - } - - this.pinpointSocket = pinpointSocket; - } - - public void setConnectSocketAddress(SocketAddress connectSocketAddress) { - if (connectSocketAddress == null) { - throw new NullPointerException("connectSocketAddress must not be null"); - } - this.connectSocketAddress = connectSocketAddress; - } - - @Override - public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { - Channel channel = e.getChannel(); - if (logger.isDebugEnabled()) { - logger.debug("channelOpen() state:{} {}", state.getString(), channel); - } - this.channel = channel; - } - - public void open() { - logger.info("open() change state=RUN"); - if (!state.changeRun()) { - throw new IllegalStateException("invalid open state:" + state.getString()); - } - } - - @Override - public void setMessageListener(MessageListener messageListener) { - AssertUtils.assertNotNull(messageListener, "messageListener"); - - logger.info("{} registered Listner({}).", toString(), messageListener); - - if (messageListener != SimpleLoggingMessageListener.LISTENER) { - this.messageListener = messageListener; - - // MessageListener 등록시 EnableWorkerPacket전달 - sendEnableWorkerPacket(); - - RegisterEnableWorkerPacketJob job = new RegisterEnableWorkerPacketJob(enableWorkerPacketRetryCount); - reservationEnableWorkerPacketJob(job); - } - } - - @Override - public void initReconnect() { - logger.info("initReconnect() change state=INIT_RECONNECT"); - state.setState(State.INIT_RECONNECT); - } - - @Override - public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { - if (logger.isDebugEnabled()) { - logger.debug("channelConnected() state:{} {}", state.getString(), channel); - } - registerPing(); - - } - - private void registerPing() { - final PingTask pingTask = new PingTask(); - newPingTimeout(pingTask); - } - - private void newPingTimeout(TimerTask pingTask) { - this.channelTimer.newTimeout(pingTask, pingDelay, TimeUnit.MILLISECONDS); - } - - private class PingTask implements TimerTask { - @Override - public void run(Timeout timeout) throws Exception { - if (timeout.isCancelled()) { - newPingTimeout(this); - return; - } - if (isClosed()) { - return; - } - writePing(); - newPingTimeout(this); - } - } - - void writePing() { - if (!isRun()) { - return; - } - logger.debug("writePing {}", channel); - ChannelFuture write = this.channel.write(PingPacket.PING_PACKET); - write.addListener(pingWriteFailFutureListener); - } - - private class RegisterEnableWorkerPacketJob implements TimerTask { - - private final int maxRetryCount; - private final AtomicInteger currentCount; - - public RegisterEnableWorkerPacketJob(int maxRetryCount) { - this.maxRetryCount = maxRetryCount; - this.currentCount = new AtomicInteger(0); - } - - @Override - public void run(Timeout timeout) throws Exception { - if (timeout.isCancelled()) { - reservationEnableWorkerPacketJob(this); - return; - } - if (isClosed()) { - return; - } - - if (state.getState() == State.RUN) { - incrementCurrentRetryCount(); - - sendEnableWorkerPacket(); - reservationEnableWorkerPacketJob(this); - } - } - - public int getMaxRetryCount() { - return maxRetryCount; - } - - public int getCurrentRetryCount() { - return currentCount.get(); - } - - public void incrementCurrentRetryCount() { - currentCount.incrementAndGet(); - } - - } - - private void reservationEnableWorkerPacketJob(RegisterEnableWorkerPacketJob task) { - if (task.getCurrentRetryCount() >= task.getMaxRetryCount()) { - return; - } - - this.channelTimer.newTimeout(task, enableWorkerPacketDelay, TimeUnit.MILLISECONDS); - } - - void sendEnableWorkerPacket() { - if (!isRun()) { - return; - } - - logger.debug("write EnableWorkerPacket {}", channel); - - try { - Map properties = this.pinpointSocketFactory.getProperties(); - byte[] payload = ControlMessageEnDeconderUtils.encode(properties); - ControlEnableWorkerPacket packet = new ControlEnableWorkerPacket(payload); - final ChannelFuture write = this.channel.write(packet); - write.addListener(enableWorkerWriteFailFutureListener); - } catch (ProtocolException e) { - logger.warn(e.getMessage(), e); - } - } - - public void sendPing() { - if (!isRun()) { - return; - } - logger.debug("sendPing {}", channel); - ChannelFuture write = this.channel.write(PingPacket.PING_PACKET); - write.awaitUninterruptibly(); - if (!write.isSuccess()) { - Throwable cause = write.getCause(); - throw new PinpointSocketException("send ping fail. Caused:" + cause.getMessage(), cause); - } - logger.debug("sendPing success {}", channel); - } - - - - public void send(byte[] bytes) { - if (bytes == null) { - throw new NullPointerException("bytes"); - } - ChannelFuture future = send0(bytes); - future.addListener(sendWriteFailFutureListener); - } - - public Future sendAsync(byte[] bytes) { - if (bytes == null) { - throw new NullPointerException("bytes"); - } - - ChannelFuture channelFuture = send0(bytes); - final ChannelWriteCompleteListenableFuture future = new ChannelWriteCompleteListenableFuture(timeoutMillis); - channelFuture.addListener(future); - return future ; - } - - public void sendSync(byte[] bytes) { - if (bytes == null) { - throw new NullPointerException("bytes"); - } - ChannelFuture write = send0(bytes); - await(write); - } - - private void await(ChannelFuture channelFuture) { - try { - channelFuture.await(timeoutMillis, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - if (channelFuture.isDone()) { - boolean success = channelFuture.isSuccess(); - if (success) { - return; - } else { - final Throwable cause = channelFuture.getCause(); - throw new PinpointSocketException(cause); - } - } else { - boolean cancel = channelFuture.cancel(); - if (cancel) { - // 3초에도 io가 안끝나면 일단 timeout인가? - throw new PinpointSocketException("io timeout"); - } else { - // 성공했으니. 위와 로직이 동일할듯. - boolean success = channelFuture.isSuccess(); - if (success) { - return; - } else { - final Throwable cause = channelFuture.getCause(); - throw new PinpointSocketException(cause); - } - } - } - } - - private ChannelFuture send0(byte[] bytes) { - ensureOpen(); - SendPacket send = new SendPacket(bytes); - - return this.channel.write(send); - } - - public Future request(byte[] bytes) { - if (bytes == null) { - throw new NullPointerException("bytes"); - } - - boolean run = isRun(); - if (!run) { - DefaultFuture closedException = new DefaultFuture(); - closedException.setFailure(new PinpointSocketException("invalid state:" + state.getString() + " channel:" + channel)); - return closedException; - } - - RequestPacket request = new RequestPacket(bytes); - - final Channel channel = this.channel; - final ChannelWriteFailListenableFuture messageFuture = this.requestManager.register(request, this.timeoutMillis); - - ChannelFuture write = channel.write(request); - write.addListener(messageFuture); - - return messageFuture; - } - - - public StreamChannel createStreamChannel() { - ensureOpen(); - - final Channel channel = this.channel; - return this.streamChannelManager.createStreamChannel(channel); - } - - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - final Object message = e.getMessage(); - if (message instanceof Packet) { - final Packet packet = (Packet) message; - final short packetType = packet.getPacketType(); - switch (packetType) { - case PacketType.APPLICATION_RESPONSE: - this.requestManager.messageReceived((ResponsePacket) message, e.getChannel()); - return; - // connector로 들어오는 request 메시지를 핸들링을 해야 함. - case PacketType.APPLICATION_REQUEST: - this.messageListener.handleRequest((RequestPacket) message, e.getChannel()); - return; - case PacketType.APPLICATION_SEND: - this.messageListener.handleSend((SendPacket) message, e.getChannel()); - return; - case PacketType.APPLICATION_STREAM_CREATE: - case PacketType.APPLICATION_STREAM_CLOSE: - case PacketType.APPLICATION_STREAM_CREATE_SUCCESS: - case PacketType.APPLICATION_STREAM_CREATE_FAIL: - case PacketType.APPLICATION_STREAM_RESPONSE: - this.streamChannelManager.messageReceived((StreamPacket) message, e.getChannel()); - return; - case PacketType.CONTROL_SERVER_CLOSE: - messageReceivedServerClosed(e.getChannel()); - return; - case PacketType.CONTROL_ENABLE_WORKER_CONFIRM: - messageReceivedEnableWorkerConfirm((ControlEnableWorkerConfirmPacket)message, e.getChannel()); - return; - default: - logger.warn("unexpectedMessage received:{} address:{}", message, e.getRemoteAddress()); - } - } else { - logger.warn("invalid messageReceived:{}", message); - } - } - - private void messageReceivedServerClosed(Channel channel) { - logger.info("ServerClosed Packet received. {}", channel); - // reconnect 상태로 변경한다. - state.setState(State.RECONNECT); - } - - private void messageReceivedEnableWorkerConfirm(ControlEnableWorkerConfirmPacket message, Channel channel) { - int code = getRegisterAgentConfirmPacketCode(message.getPayload()); - - logger.info("EnableWorkerConfirm Packet({}) code={} received. {}", message, code, channel); - // reconnect 상태로 변경한다. - - if (code == ControlEnableWorkerConfirmPacket.SUCCESS || code == ControlEnableWorkerConfirmPacket.ALREADY_REGISTER) { - state.changeRunDuplexCommunication(); - } else { - logger.warn("Invalid EnableWorkerConfirm Packet ({}) code={} received. {}", message, code, channel); - } - } - - private int getRegisterAgentConfirmPacketCode(byte[] payload) { - Map result = null; - try { - result = (Map) ControlMessageEnDeconderUtils.decode(payload); - } catch (ProtocolException e) { - logger.warn(e.getMessage(), e); - } - - int code = MapUtils.getInteger(result, "code", -1); - - return code; - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { - Throwable cause = e.getCause(); - if (state.getState() == State.INIT_RECONNECT) { - // 재접속시 stackTrace는 제거하였음. 로그가 너무 많이 나옴. - logger.info("exceptionCaught() reconnect fail. state:{} {} Caused:{}", state.getString(), e.getChannel(), cause.getMessage()); - } else { - logger.warn("exceptionCaught() UnexpectedError happened. state:{} {} Caused:{}", state.getString(), e.getChannel(), cause.getMessage(), cause); - } - // error가 발생하였을 경우의 동작을 더 정확히 해야 될듯함. -// 아래처럼 하면 상대방이 그냥 죽었을때 reconnet가 안됨. -// state.setClosed(); -// Channel channel = e.getChannel(); -// if (channel.isConnected()) { -// channel.close(); -// } - - } - - @Override - public void channelClosed(final ChannelHandlerContext ctx, final ChannelStateEvent e) throws Exception { - final int currentState = state.getState(); - if (currentState == State.CLOSED) { - logger.debug("channelClosed() normal. state:{} {}", state.getString(currentState), e.getChannel()); - return; - } else if(currentState == State.INIT_RECONNECT){ - logger.debug("channelClosed() reconnect fail. state:{} {}", state.getString(currentState), e.getChannel()); - } else if (state.isRun(currentState) || currentState == State.RECONNECT) { - // 여기서 부터 비정상 closed라고 볼수 있다. - if (state.isRun(currentState)) { - logger.debug("change state=reconnect"); - state.setState(State.RECONNECT); - } - logger.info("channelClosed() UnexpectedChannelClosed. state:{} try reconnect channel:{}, connectSocketAddress:{}", state.getString(), e.getChannel(), connectSocketAddress); - - this.pinpointSocketFactory.reconnect(this.pinpointSocket, this.connectSocketAddress); - return; - } else { - logger.info("channelClosed() UnexpectedChannelClosed. state:{} {}", state.getString(currentState), e.getChannel()); - } - releaseResource(); - } - - private void ensureOpen() { - final int currentState = state.getState(); - if (state.isRun(currentState)) { - return; - } - if (currentState == State.CLOSED) { - throw new PinpointSocketException("already closed"); - } else if(currentState == State.RECONNECT) { - throw new PinpointSocketException("reconnecting..."); - } - logger.info("invalid socket state:{}", state.getString(currentState)); - throw new PinpointSocketException("invalid socket state:" + currentState); - } - - - boolean isRun() { - return state.isRun(); - } - - boolean isClosed() { - return state.isClosed(); - } - - public void close() { - logger.debug("close() call"); - int currentState = this.state.getState(); - if (currentState == State.CLOSED) { - logger.debug("already close()"); - return; - } - logger.debug("close() start"); - if (!this.state.changeClosed(currentState)) { - logger.info("close() invalid state"); - return; - } - logger.debug("close() state change complete"); - // hand shake close - final Channel channel = this.channel; - // close packet을 먼저 날리고 resource를 정리해야 되나? - // resource 정리시 request response 메시지에 대한 에러 처리나, stream 채널의 정리가 필요하니 반대로 해야 되나?? 이게 맞는거 같긴한데. timer가 헤깔리네. - // 헤깔리니. 일단 만들고 추후 수정. - sendClosedPacket(channel); - releaseResource(); - logger.debug("channel.close()"); - - ChannelFuture channelFuture = channel.close(); - channelFuture.addListener(new WriteFailFutureListener(logger, "close() event fail.", "close() event success.")); - channelFuture.awaitUninterruptibly(); - logger.debug("close() complete"); - } - - private void releaseResource() { - logger.debug("releaseResource()"); - this.requestManager.close(); - this.streamChannelManager.close(); - this.channelTimer.stop(); - } - - private void sendClosedPacket(Channel channel) { - if (!channel.isConnected()) { - logger.debug("channel already closed. skip sendClosedPacket() {}", channel); - return; - } - logger.debug("write ClientClosePacket"); - ClientClosePacket clientClosePacket = new ClientClosePacket(); - ChannelFuture write = channel.write(clientClosePacket); - write.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (!future.isSuccess()) { - logger.warn("ClientClosePacket write fail. channel:{}", future.getCause(), future.getCause()); - } else { - logger.debug("ClientClosePacket write success. channel:{}", future.getChannel()); - } - } - }); - write.awaitUninterruptibly(3000, TimeUnit.MILLISECONDS); - } - - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("PinpointSocketHandler{"); - sb.append("channel=").append(channel); - sb.append('}'); - return sb.toString(); - } - - @Override - public boolean isConnected() { - return this.state.isRun(); - } - -} +package com.nhn.pinpoint.rpc.client; + +import java.net.SocketAddress; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.Timer; +import org.jboss.netty.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.ChannelWriteCompleteListenableFuture; +import com.nhn.pinpoint.rpc.ChannelWriteFailListenableFuture; +import com.nhn.pinpoint.rpc.DefaultFuture; +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.rpc.control.ProtocolException; +import com.nhn.pinpoint.rpc.packet.ClientClosePacket; +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerPacket; +import com.nhn.pinpoint.rpc.packet.Packet; +import com.nhn.pinpoint.rpc.packet.PacketType; +import com.nhn.pinpoint.rpc.packet.PingPacket; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.ResponsePacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.util.AssertUtils; +import com.nhn.pinpoint.rpc.util.ControlMessageEnDeconderUtils; +import com.nhn.pinpoint.rpc.util.MapUtils; +import com.nhn.pinpoint.rpc.util.TimerFactory; + +/** + * @author emeroad + * @author netspider + * @author koo.taejin + */ +public class PinpointSocketHandler extends SimpleChannelHandler implements SocketHandler { + + private static final long DEFAULT_PING_DELAY = 60 * 1000 * 5; + private static final long DEFAULT_TIMEOUTMILLIS = 3 * 1000; + + private static final long DEFAULT_ENABLE_WORKER_PACKET_DELAY = 60 * 1000 * 1; + private static final int DEFAULT_ENABLE_WORKER_PACKET_RETRY_COUNT = 3; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final State state = new State(); + + private volatile Channel channel; + private volatile MessageListener messageListener = SimpleLoggingMessageListener.LISTENER; + + private long timeoutMillis = DEFAULT_TIMEOUTMILLIS; + private long pingDelay = DEFAULT_PING_DELAY; + + private long enableWorkerPacketDelay = DEFAULT_ENABLE_WORKER_PACKET_DELAY; + private int enableWorkerPacketRetryCount = DEFAULT_ENABLE_WORKER_PACKET_RETRY_COUNT; + + private final Timer channelTimer; + + private final PinpointSocketFactory pinpointSocketFactory; + private SocketAddress connectSocketAddress; + private volatile PinpointSocket pinpointSocket; + + private final RequestManager requestManager; + private final StreamChannelManager streamChannelManager; + + private final ChannelFutureListener pingWriteFailFutureListener = new WriteFailFutureListener(this.logger, "ping write fail.", "ping write success."); + private final ChannelFutureListener sendWriteFailFutureListener = new WriteFailFutureListener(this.logger, "send() write fail.", "send() write fail."); + private final ChannelFutureListener enableWorkerWriteFailFutureListener = new WriteFailFutureListener(this.logger, "enableWorker write fail.", "enableWorker write success."); + + public PinpointSocketHandler(PinpointSocketFactory pinpointSocketFactory) { + this(pinpointSocketFactory, DEFAULT_PING_DELAY, DEFAULT_ENABLE_WORKER_PACKET_DELAY, DEFAULT_TIMEOUTMILLIS); + } + + public PinpointSocketHandler(PinpointSocketFactory pinpointSocketFactory, long pingDelay, long enableWorkerPacketDelay, long timeoutMillis) { + if (pinpointSocketFactory == null) { + throw new NullPointerException("pinpointSocketFactory must not be null"); + } + + HashedWheelTimer timer = TimerFactory.createHashedWheelTimer("Pinpoint-SocketHandler-Timer", 100, TimeUnit.MILLISECONDS, 512); + timer.start(); + this.channelTimer = timer; + this.pinpointSocketFactory = pinpointSocketFactory; + this.requestManager = new RequestManager(timer); + this.streamChannelManager = new StreamChannelManager(); + this.pingDelay = pingDelay; + this.enableWorkerPacketDelay = enableWorkerPacketDelay; + this.timeoutMillis = timeoutMillis; + } + + public Timer getChannelTimer() { + return channelTimer; + } + + public void setPinpointSocket(PinpointSocket pinpointSocket) { + if (pinpointSocket == null) { + throw new NullPointerException("pinpointSocket must not be null"); + } + + this.pinpointSocket = pinpointSocket; + } + + public void setConnectSocketAddress(SocketAddress connectSocketAddress) { + if (connectSocketAddress == null) { + throw new NullPointerException("connectSocketAddress must not be null"); + } + this.connectSocketAddress = connectSocketAddress; + } + + @Override + public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + Channel channel = e.getChannel(); + if (logger.isDebugEnabled()) { + logger.debug("channelOpen() state:{} {}", state.getString(), channel); + } + this.channel = channel; + } + + public void open() { + logger.info("open() change state=RUN"); + if (!state.changeRun()) { + throw new IllegalStateException("invalid open state:" + state.getString()); + } + } + + @Override + public void setMessageListener(MessageListener messageListener) { + AssertUtils.assertNotNull(messageListener, "messageListener"); + + logger.info("{} registered Listner({}).", toString(), messageListener); + + if (messageListener != SimpleLoggingMessageListener.LISTENER) { + this.messageListener = messageListener; + + // MessageListener 등록시 EnableWorkerPacket전달 + sendEnableWorkerPacket(); + + RegisterEnableWorkerPacketJob job = new RegisterEnableWorkerPacketJob(enableWorkerPacketRetryCount); + reservationEnableWorkerPacketJob(job); + } + } + + @Override + public void initReconnect() { + logger.info("initReconnect() change state=INIT_RECONNECT"); + state.setState(State.INIT_RECONNECT); + } + + @Override + public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + if (logger.isDebugEnabled()) { + logger.debug("channelConnected() state:{} {}", state.getString(), channel); + } + registerPing(); + + } + + private void registerPing() { + final PingTask pingTask = new PingTask(); + newPingTimeout(pingTask); + } + + private void newPingTimeout(TimerTask pingTask) { + this.channelTimer.newTimeout(pingTask, pingDelay, TimeUnit.MILLISECONDS); + } + + private class PingTask implements TimerTask { + @Override + public void run(Timeout timeout) throws Exception { + if (timeout.isCancelled()) { + newPingTimeout(this); + return; + } + if (isClosed()) { + return; + } + writePing(); + newPingTimeout(this); + } + } + + void writePing() { + if (!isRun()) { + return; + } + logger.debug("writePing {}", channel); + ChannelFuture write = this.channel.write(PingPacket.PING_PACKET); + write.addListener(pingWriteFailFutureListener); + } + + private class RegisterEnableWorkerPacketJob implements TimerTask { + + private final int maxRetryCount; + private final AtomicInteger currentCount; + + public RegisterEnableWorkerPacketJob(int maxRetryCount) { + this.maxRetryCount = maxRetryCount; + this.currentCount = new AtomicInteger(0); + } + + @Override + public void run(Timeout timeout) throws Exception { + if (timeout.isCancelled()) { + reservationEnableWorkerPacketJob(this); + return; + } + if (isClosed()) { + return; + } + + if (state.getState() == State.RUN) { + incrementCurrentRetryCount(); + + sendEnableWorkerPacket(); + reservationEnableWorkerPacketJob(this); + } + } + + public int getMaxRetryCount() { + return maxRetryCount; + } + + public int getCurrentRetryCount() { + return currentCount.get(); + } + + public void incrementCurrentRetryCount() { + currentCount.incrementAndGet(); + } + + } + + private void reservationEnableWorkerPacketJob(RegisterEnableWorkerPacketJob task) { + if (task.getCurrentRetryCount() >= task.getMaxRetryCount()) { + return; + } + + this.channelTimer.newTimeout(task, enableWorkerPacketDelay, TimeUnit.MILLISECONDS); + } + + void sendEnableWorkerPacket() { + if (!isRun()) { + return; + } + + logger.debug("write EnableWorkerPacket {}", channel); + + try { + Map properties = this.pinpointSocketFactory.getProperties(); + byte[] payload = ControlMessageEnDeconderUtils.encode(properties); + ControlEnableWorkerPacket packet = new ControlEnableWorkerPacket(payload); + final ChannelFuture write = this.channel.write(packet); + write.addListener(enableWorkerWriteFailFutureListener); + } catch (ProtocolException e) { + logger.warn(e.getMessage(), e); + } + } + + public void sendPing() { + if (!isRun()) { + return; + } + logger.debug("sendPing {}", channel); + ChannelFuture write = this.channel.write(PingPacket.PING_PACKET); + write.awaitUninterruptibly(); + if (!write.isSuccess()) { + Throwable cause = write.getCause(); + throw new PinpointSocketException("send ping fail. Caused:" + cause.getMessage(), cause); + } + logger.debug("sendPing success {}", channel); + } + + + + public void send(byte[] bytes) { + if (bytes == null) { + throw new NullPointerException("bytes"); + } + ChannelFuture future = send0(bytes); + future.addListener(sendWriteFailFutureListener); + } + + public Future sendAsync(byte[] bytes) { + if (bytes == null) { + throw new NullPointerException("bytes"); + } + + ChannelFuture channelFuture = send0(bytes); + final ChannelWriteCompleteListenableFuture future = new ChannelWriteCompleteListenableFuture(timeoutMillis); + channelFuture.addListener(future); + return future ; + } + + public void sendSync(byte[] bytes) { + if (bytes == null) { + throw new NullPointerException("bytes"); + } + ChannelFuture write = send0(bytes); + await(write); + } + + private void await(ChannelFuture channelFuture) { + try { + channelFuture.await(timeoutMillis, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + if (channelFuture.isDone()) { + boolean success = channelFuture.isSuccess(); + if (success) { + return; + } else { + final Throwable cause = channelFuture.getCause(); + throw new PinpointSocketException(cause); + } + } else { + boolean cancel = channelFuture.cancel(); + if (cancel) { + // 3초에도 io가 안끝나면 일단 timeout인가? + throw new PinpointSocketException("io timeout"); + } else { + // 성공했으니. 위와 로직이 동일할듯. + boolean success = channelFuture.isSuccess(); + if (success) { + return; + } else { + final Throwable cause = channelFuture.getCause(); + throw new PinpointSocketException(cause); + } + } + } + } + + private ChannelFuture send0(byte[] bytes) { + ensureOpen(); + SendPacket send = new SendPacket(bytes); + + return this.channel.write(send); + } + + public Future request(byte[] bytes) { + if (bytes == null) { + throw new NullPointerException("bytes"); + } + + boolean run = isRun(); + if (!run) { + DefaultFuture closedException = new DefaultFuture(); + closedException.setFailure(new PinpointSocketException("invalid state:" + state.getString() + " channel:" + channel)); + return closedException; + } + + RequestPacket request = new RequestPacket(bytes); + + final Channel channel = this.channel; + final ChannelWriteFailListenableFuture messageFuture = this.requestManager.register(request, this.timeoutMillis); + + ChannelFuture write = channel.write(request); + write.addListener(messageFuture); + + return messageFuture; + } + + + public StreamChannel createStreamChannel() { + ensureOpen(); + + final Channel channel = this.channel; + return this.streamChannelManager.createStreamChannel(channel); + } + + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + final Object message = e.getMessage(); + if (message instanceof Packet) { + final Packet packet = (Packet) message; + final short packetType = packet.getPacketType(); + switch (packetType) { + case PacketType.APPLICATION_RESPONSE: + this.requestManager.messageReceived((ResponsePacket) message, e.getChannel()); + return; + // connector로 들어오는 request 메시지를 핸들링을 해야 함. + case PacketType.APPLICATION_REQUEST: + this.messageListener.handleRequest((RequestPacket) message, e.getChannel()); + return; + case PacketType.APPLICATION_SEND: + this.messageListener.handleSend((SendPacket) message, e.getChannel()); + return; + case PacketType.APPLICATION_STREAM_CREATE: + case PacketType.APPLICATION_STREAM_CLOSE: + case PacketType.APPLICATION_STREAM_CREATE_SUCCESS: + case PacketType.APPLICATION_STREAM_CREATE_FAIL: + case PacketType.APPLICATION_STREAM_RESPONSE: + this.streamChannelManager.messageReceived((StreamPacket) message, e.getChannel()); + return; + case PacketType.CONTROL_SERVER_CLOSE: + messageReceivedServerClosed(e.getChannel()); + return; + case PacketType.CONTROL_ENABLE_WORKER_CONFIRM: + messageReceivedEnableWorkerConfirm((ControlEnableWorkerConfirmPacket)message, e.getChannel()); + return; + default: + logger.warn("unexpectedMessage received:{} address:{}", message, e.getRemoteAddress()); + } + } else { + logger.warn("invalid messageReceived:{}", message); + } + } + + private void messageReceivedServerClosed(Channel channel) { + logger.info("ServerClosed Packet received. {}", channel); + // reconnect 상태로 변경한다. + state.setState(State.RECONNECT); + } + + private void messageReceivedEnableWorkerConfirm(ControlEnableWorkerConfirmPacket message, Channel channel) { + int code = getRegisterAgentConfirmPacketCode(message.getPayload()); + + logger.info("EnableWorkerConfirm Packet({}) code={} received. {}", message, code, channel); + // reconnect 상태로 변경한다. + + if (code == ControlEnableWorkerConfirmPacket.SUCCESS || code == ControlEnableWorkerConfirmPacket.ALREADY_REGISTER) { + state.changeRunDuplexCommunication(); + } else { + logger.warn("Invalid EnableWorkerConfirm Packet ({}) code={} received. {}", message, code, channel); + } + } + + private int getRegisterAgentConfirmPacketCode(byte[] payload) { + Map result = null; + try { + result = (Map) ControlMessageEnDeconderUtils.decode(payload); + } catch (ProtocolException e) { + logger.warn(e.getMessage(), e); + } + + int code = MapUtils.getInteger(result, "code", -1); + + return code; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + Throwable cause = e.getCause(); + if (state.getState() == State.INIT_RECONNECT) { + // 재접속시 stackTrace는 제거하였음. 로그가 너무 많이 나옴. + logger.info("exceptionCaught() reconnect fail. state:{} {} Caused:{}", state.getString(), e.getChannel(), cause.getMessage()); + } else { + logger.warn("exceptionCaught() UnexpectedError happened. state:{} {} Caused:{}", state.getString(), e.getChannel(), cause.getMessage(), cause); + } + // error가 발생하였을 경우의 동작을 더 정확히 해야 될듯함. +// 아래처럼 하면 상대방이 그냥 죽었을때 reconnet가 안됨. +// state.setClosed(); +// Channel channel = e.getChannel(); +// if (channel.isConnected()) { +// channel.close(); +// } + + } + + @Override + public void channelClosed(final ChannelHandlerContext ctx, final ChannelStateEvent e) throws Exception { + final int currentState = state.getState(); + if (currentState == State.CLOSED) { + logger.debug("channelClosed() normal. state:{} {}", state.getString(currentState), e.getChannel()); + return; + } else if(currentState == State.INIT_RECONNECT){ + logger.debug("channelClosed() reconnect fail. state:{} {}", state.getString(currentState), e.getChannel()); + } else if (state.isRun(currentState) || currentState == State.RECONNECT) { + // 여기서 부터 비정상 closed라고 볼수 있다. + if (state.isRun(currentState)) { + logger.debug("change state=reconnect"); + state.setState(State.RECONNECT); + } + logger.info("channelClosed() UnexpectedChannelClosed. state:{} try reconnect channel:{}, connectSocketAddress:{}", state.getString(), e.getChannel(), connectSocketAddress); + + this.pinpointSocketFactory.reconnect(this.pinpointSocket, this.connectSocketAddress); + return; + } else { + logger.info("channelClosed() UnexpectedChannelClosed. state:{} {}", state.getString(currentState), e.getChannel()); + } + releaseResource(); + } + + private void ensureOpen() { + final int currentState = state.getState(); + if (state.isRun(currentState)) { + return; + } + if (currentState == State.CLOSED) { + throw new PinpointSocketException("already closed"); + } else if(currentState == State.RECONNECT) { + throw new PinpointSocketException("reconnecting..."); + } + logger.info("invalid socket state:{}", state.getString(currentState)); + throw new PinpointSocketException("invalid socket state:" + currentState); + } + + + boolean isRun() { + return state.isRun(); + } + + boolean isClosed() { + return state.isClosed(); + } + + public void close() { + logger.debug("close() call"); + int currentState = this.state.getState(); + if (currentState == State.CLOSED) { + logger.debug("already close()"); + return; + } + logger.debug("close() start"); + if (!this.state.changeClosed(currentState)) { + logger.info("close() invalid state"); + return; + } + logger.debug("close() state change complete"); + // hand shake close + final Channel channel = this.channel; + // close packet을 먼저 날리고 resource를 정리해야 되나? + // resource 정리시 request response 메시지에 대한 에러 처리나, stream 채널의 정리가 필요하니 반대로 해야 되나?? 이게 맞는거 같긴한데. timer가 헤깔리네. + // 헤깔리니. 일단 만들고 추후 수정. + sendClosedPacket(channel); + releaseResource(); + logger.debug("channel.close()"); + + ChannelFuture channelFuture = channel.close(); + channelFuture.addListener(new WriteFailFutureListener(logger, "close() event fail.", "close() event success.")); + channelFuture.awaitUninterruptibly(); + logger.debug("close() complete"); + } + + private void releaseResource() { + logger.debug("releaseResource()"); + this.requestManager.close(); + this.streamChannelManager.close(); + this.channelTimer.stop(); + } + + private void sendClosedPacket(Channel channel) { + if (!channel.isConnected()) { + logger.debug("channel already closed. skip sendClosedPacket() {}", channel); + return; + } + logger.debug("write ClientClosePacket"); + ClientClosePacket clientClosePacket = new ClientClosePacket(); + ChannelFuture write = channel.write(clientClosePacket); + write.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + logger.warn("ClientClosePacket write fail. channel:{}", future.getCause(), future.getCause()); + } else { + logger.debug("ClientClosePacket write success. channel:{}", future.getChannel()); + } + } + }); + write.awaitUninterruptibly(3000, TimeUnit.MILLISECONDS); + } + + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("PinpointSocketHandler{"); + sb.append("channel=").append(channel); + sb.append('}'); + return sb.toString(); + } + + @Override + public boolean isConnected() { + return this.state.isRun(); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketReconnectEventListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketReconnectEventListener.java index 26edfd57aaa3..52bc5c58c591 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketReconnectEventListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/PinpointSocketReconnectEventListener.java @@ -1,9 +1,9 @@ -package com.nhn.pinpoint.rpc.client; - -public interface PinpointSocketReconnectEventListener { - - // 현재는 Reconnect를 제외한 별다른 Event가 없음 - // 이후에 별다른 Event가 있을 경우 Event와 함께 넘겨주면 좋을듯함 - void reconnectPerformed(PinpointSocket socket); - -} +package com.nhn.pinpoint.rpc.client; + +public interface PinpointSocketReconnectEventListener { + + // 현재는 Reconnect를 제외한 별다른 Event가 없음 + // 이후에 별다른 Event가 있을 경우 Event와 함께 넘겨주면 좋을듯함 + void reconnectPerformed(PinpointSocket socket); + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/ReconnectStateSocketHandler.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/ReconnectStateSocketHandler.java index ddd153323c2a..44ec9a38cfe7 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/ReconnectStateSocketHandler.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/ReconnectStateSocketHandler.java @@ -1,85 +1,85 @@ -package com.nhn.pinpoint.rpc.client; - -import com.nhn.pinpoint.rpc.DefaultFuture; -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.ResponseMessage; - -import java.net.SocketAddress; - -/** - * @author emeroad - * @author netspider - */ -public class ReconnectStateSocketHandler implements SocketHandler { - - - @Override - public void setConnectSocketAddress(SocketAddress connectSocketAddress) { - } - - @Override - public void open() { - throw new IllegalStateException(); - } - - @Override - public void setMessageListener(MessageListener messageListener) { - } - - @Override - public void initReconnect() { - //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public void setPinpointSocket(PinpointSocket pinpointSocket) { - } - - @Override - public void sendSync(byte[] bytes) { - throw newReconnectException(); - } - - @Override - public Future sendAsync(byte[] bytes) { - return reconnectFailureFuture(); - } - - private DefaultFuture reconnectFailureFuture() { - DefaultFuture reconnect = new DefaultFuture(); - reconnect.setFailure(newReconnectException()); - return reconnect; - } - - @Override - public void close() { - } - - @Override - public void send(byte[] bytes) { - } - - private PinpointSocketException newReconnectException() { - return new PinpointSocketException("reconnecting..."); - } - - @Override - public Future request(byte[] bytes) { - return reconnectFailureFuture(); - } - - @Override - public StreamChannel createStreamChannel() { - throw new UnsupportedOperationException(); - } - - @Override - public void sendPing() { - } - - @Override - public boolean isConnected() { - return false; - } -} +package com.nhn.pinpoint.rpc.client; + +import com.nhn.pinpoint.rpc.DefaultFuture; +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.ResponseMessage; + +import java.net.SocketAddress; + +/** + * @author emeroad + * @author netspider + */ +public class ReconnectStateSocketHandler implements SocketHandler { + + + @Override + public void setConnectSocketAddress(SocketAddress connectSocketAddress) { + } + + @Override + public void open() { + throw new IllegalStateException(); + } + + @Override + public void setMessageListener(MessageListener messageListener) { + } + + @Override + public void initReconnect() { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void setPinpointSocket(PinpointSocket pinpointSocket) { + } + + @Override + public void sendSync(byte[] bytes) { + throw newReconnectException(); + } + + @Override + public Future sendAsync(byte[] bytes) { + return reconnectFailureFuture(); + } + + private DefaultFuture reconnectFailureFuture() { + DefaultFuture reconnect = new DefaultFuture(); + reconnect.setFailure(newReconnectException()); + return reconnect; + } + + @Override + public void close() { + } + + @Override + public void send(byte[] bytes) { + } + + private PinpointSocketException newReconnectException() { + return new PinpointSocketException("reconnecting..."); + } + + @Override + public Future request(byte[] bytes) { + return reconnectFailureFuture(); + } + + @Override + public StreamChannel createStreamChannel() { + throw new UnsupportedOperationException(); + } + + @Override + public void sendPing() { + } + + @Override + public boolean isConnected() { + return false; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/RequestManager.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/RequestManager.java index e4c361de1332..e30fac10db29 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/RequestManager.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/RequestManager.java @@ -1,147 +1,147 @@ -package com.nhn.pinpoint.rpc.client; - -import com.nhn.pinpoint.rpc.*; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.ResponsePacket; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.Timer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class RequestManager { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final AtomicInteger requestId = new AtomicInteger(1); - - private final ConcurrentMap> requestMap = new ConcurrentHashMap>(); - // Timer를 factory로 옮겨야 되나? - private final Timer timer; - - - - public RequestManager(Timer timer) { - if (timer == null) { - throw new NullPointerException("timer must not be null"); - } - this.timer = timer; - } - - - private FailureEventHandler createFailureEventHandler(final int requestId) { - FailureEventHandler failureEventHandler = new FailureEventHandler() { - @Override - public boolean fireFailure() { - DefaultFuture future = removeMessageFuture(requestId); - if (future != null) { - // 정확하게 지워짐. - return true; - } - return false; - } - }; - return failureEventHandler; - } - - - private void addTimeoutTask(long timeoutMillis, DefaultFuture future) { - if (future == null) { - throw new NullPointerException("future"); - } - try { - Timeout timeout = timer.newTimeout(future, timeoutMillis, TimeUnit.MILLISECONDS); - future.setTimeout(timeout); - } catch (IllegalStateException e) { - // timer가 shutdown되었을 경우인데. 이것은 socket이 closed되었다는 의미뿐이 없을거임.. - future.setFailure(new PinpointSocketException("socket closed")) ; - } - } - - private int getNextRequestId() { - return this.requestId.getAndIncrement(); - } - - - public void messageReceived(ResponsePacket responsePacket, Channel channel) { - final int requestId = responsePacket.getRequestId(); - final DefaultFuture future = removeMessageFuture(requestId); - if (future == null) { - logger.warn("future not found:{}, channel:{}", responsePacket, channel); - return; - } else { - logger.debug("responsePacket arrived packet:{}, channel:{}", responsePacket, channel); - } - - ResponseMessage response = new ResponseMessage(); - response.setMessage(responsePacket.getPayload()); - future.setResult(response); - } - - public DefaultFuture removeMessageFuture(int requestId) { - return this.requestMap.remove(requestId); - } - - public void messageReceived(RequestPacket requestPacket, Channel channel) { - logger.error("unexpectedMessage received:{} address:{}", requestPacket, channel.getRemoteAddress()); - } - - - - public ChannelWriteFailListenableFuture register(RequestPacket requestPacket, long timeoutMillis) { - // shutdown check - final int requestId = getNextRequestId(); - requestPacket.setRequestId(requestId); - - final ChannelWriteFailListenableFuture future = new ChannelWriteFailListenableFuture(timeoutMillis); - - final DefaultFuture old = this.requestMap.put(requestId, future); - if (old != null) { - throw new PinpointSocketException("unexpected error. old future exist:" + old + " id:" + requestId); - } - // future가 실패하였을 경우 requestMap에서 빠르게 지울수 있도록 핸들을 넣는다. - FailureEventHandler removeTable = createFailureEventHandler(requestId); - future.setFailureEventHandler(removeTable); - - addTimeoutTask(timeoutMillis, future); - return future; - } - - - public void close() { - logger.debug("close()"); - final PinpointSocketException closed = new PinpointSocketException("socket closed"); - - // close의 동시성 타이밍을 좀더 좋게 맞출수는 없나? -// final Timer timer = this.timer; -// if (timer != null) { -// Set stop = timer.stop(); -// for (Timeout timeout : stop) { -// DefaultFuture future = (DefaultFuture)timeout.getTask(); -// future.setFailure(closed); -// } -// } - int requestFailCount = 0; - for (Map.Entry> entry : requestMap.entrySet()) { - if(entry.getValue().setFailure(closed)) { - requestFailCount++; - } - } - this.requestMap.clear(); - if (requestFailCount > 0) { - logger.info("requestManager failCount:{}", requestFailCount); - } - - } - -} - +package com.nhn.pinpoint.rpc.client; + +import com.nhn.pinpoint.rpc.*; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.ResponsePacket; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.Timer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class RequestManager { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final AtomicInteger requestId = new AtomicInteger(1); + + private final ConcurrentMap> requestMap = new ConcurrentHashMap>(); + // Timer를 factory로 옮겨야 되나? + private final Timer timer; + + + + public RequestManager(Timer timer) { + if (timer == null) { + throw new NullPointerException("timer must not be null"); + } + this.timer = timer; + } + + + private FailureEventHandler createFailureEventHandler(final int requestId) { + FailureEventHandler failureEventHandler = new FailureEventHandler() { + @Override + public boolean fireFailure() { + DefaultFuture future = removeMessageFuture(requestId); + if (future != null) { + // 정확하게 지워짐. + return true; + } + return false; + } + }; + return failureEventHandler; + } + + + private void addTimeoutTask(long timeoutMillis, DefaultFuture future) { + if (future == null) { + throw new NullPointerException("future"); + } + try { + Timeout timeout = timer.newTimeout(future, timeoutMillis, TimeUnit.MILLISECONDS); + future.setTimeout(timeout); + } catch (IllegalStateException e) { + // timer가 shutdown되었을 경우인데. 이것은 socket이 closed되었다는 의미뿐이 없을거임.. + future.setFailure(new PinpointSocketException("socket closed")) ; + } + } + + private int getNextRequestId() { + return this.requestId.getAndIncrement(); + } + + + public void messageReceived(ResponsePacket responsePacket, Channel channel) { + final int requestId = responsePacket.getRequestId(); + final DefaultFuture future = removeMessageFuture(requestId); + if (future == null) { + logger.warn("future not found:{}, channel:{}", responsePacket, channel); + return; + } else { + logger.debug("responsePacket arrived packet:{}, channel:{}", responsePacket, channel); + } + + ResponseMessage response = new ResponseMessage(); + response.setMessage(responsePacket.getPayload()); + future.setResult(response); + } + + public DefaultFuture removeMessageFuture(int requestId) { + return this.requestMap.remove(requestId); + } + + public void messageReceived(RequestPacket requestPacket, Channel channel) { + logger.error("unexpectedMessage received:{} address:{}", requestPacket, channel.getRemoteAddress()); + } + + + + public ChannelWriteFailListenableFuture register(RequestPacket requestPacket, long timeoutMillis) { + // shutdown check + final int requestId = getNextRequestId(); + requestPacket.setRequestId(requestId); + + final ChannelWriteFailListenableFuture future = new ChannelWriteFailListenableFuture(timeoutMillis); + + final DefaultFuture old = this.requestMap.put(requestId, future); + if (old != null) { + throw new PinpointSocketException("unexpected error. old future exist:" + old + " id:" + requestId); + } + // future가 실패하였을 경우 requestMap에서 빠르게 지울수 있도록 핸들을 넣는다. + FailureEventHandler removeTable = createFailureEventHandler(requestId); + future.setFailureEventHandler(removeTable); + + addTimeoutTask(timeoutMillis, future); + return future; + } + + + public void close() { + logger.debug("close()"); + final PinpointSocketException closed = new PinpointSocketException("socket closed"); + + // close의 동시성 타이밍을 좀더 좋게 맞출수는 없나? +// final Timer timer = this.timer; +// if (timer != null) { +// Set stop = timer.stop(); +// for (Timeout timeout : stop) { +// DefaultFuture future = (DefaultFuture)timeout.getTask(); +// future.setFailure(closed); +// } +// } + int requestFailCount = 0; + for (Map.Entry> entry : requestMap.entrySet()) { + if(entry.getValue().setFailure(closed)) { + requestFailCount++; + } + } + this.requestMap.clear(); + if (requestFailCount > 0) { + logger.info("requestManager failCount:{}", requestFailCount); + } + + } + +} + diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SimpleLoggingMessageListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SimpleLoggingMessageListener.java index 45366967e81b..d0ef51219ea9 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SimpleLoggingMessageListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SimpleLoggingMessageListener.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.rpc.client; - -import org.jboss.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.ResponsePacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; - -public class SimpleLoggingMessageListener implements MessageListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final SimpleLoggingMessageListener LISTENER = new SimpleLoggingMessageListener(); - - @Override - public void handleSend(SendPacket sendPacket, Channel channel) { - logger.info("handlerSend {} {}", sendPacket, channel); - } - - @Override - public void handleRequest(RequestPacket requestPacket, Channel channel) { - channel.write(new ResponsePacket(requestPacket.getRequestId(), new byte[0])); - logger.info("handlerRequest {} {}", requestPacket, channel); - } - -} +package com.nhn.pinpoint.rpc.client; + +import org.jboss.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.ResponsePacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; + +public class SimpleLoggingMessageListener implements MessageListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final SimpleLoggingMessageListener LISTENER = new SimpleLoggingMessageListener(); + + @Override + public void handleSend(SendPacket sendPacket, Channel channel) { + logger.info("handlerSend {} {}", sendPacket, channel); + } + + @Override + public void handleRequest(RequestPacket requestPacket, Channel channel) { + channel.write(new ResponsePacket(requestPacket.getRequestId(), new byte[0])); + logger.info("handlerRequest {} {}", requestPacket, channel); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketClientPipelineFactory.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketClientPipelineFactory.java index f21e331d58c6..43049fd470e8 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketClientPipelineFactory.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketClientPipelineFactory.java @@ -1,42 +1,42 @@ -package com.nhn.pinpoint.rpc.client; - - -import com.nhn.pinpoint.rpc.codec.PacketDecoder; -import com.nhn.pinpoint.rpc.codec.PacketEncoder; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.handler.timeout.WriteTimeoutHandler; - -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - * @author koo.taejin - */ -public class SocketClientPipelineFactory implements ChannelPipelineFactory { - - private final PinpointSocketFactory pinpointSocketFactory; - - public SocketClientPipelineFactory(PinpointSocketFactory pinpointSocketFactory) { - if (pinpointSocketFactory == null) { - throw new NullPointerException("pinpointSocketFactory must not be null"); - } - this.pinpointSocketFactory = pinpointSocketFactory; - } - - - @Override - public ChannelPipeline getPipeline() throws Exception { - ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("encoder", new PacketEncoder()); - pipeline.addLast("decoder", new PacketDecoder()); - long pingDelay = pinpointSocketFactory.getPingDelay(); - long enableWorkerPacketDelay = pinpointSocketFactory.getEnableWorkerPacketDelay(); - long timeoutMillis = pinpointSocketFactory.getTimeoutMillis(); - PinpointSocketHandler pinpointSocketHandler = new PinpointSocketHandler(pinpointSocketFactory, pingDelay, enableWorkerPacketDelay, timeoutMillis); - pipeline.addLast("writeTimeout", new WriteTimeoutHandler(pinpointSocketHandler.getChannelTimer(), 3000, TimeUnit.MILLISECONDS)); - pipeline.addLast("socketHandler", pinpointSocketHandler); - return pipeline; - } -} +package com.nhn.pinpoint.rpc.client; + + +import com.nhn.pinpoint.rpc.codec.PacketDecoder; +import com.nhn.pinpoint.rpc.codec.PacketEncoder; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.handler.timeout.WriteTimeoutHandler; + +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + * @author koo.taejin + */ +public class SocketClientPipelineFactory implements ChannelPipelineFactory { + + private final PinpointSocketFactory pinpointSocketFactory; + + public SocketClientPipelineFactory(PinpointSocketFactory pinpointSocketFactory) { + if (pinpointSocketFactory == null) { + throw new NullPointerException("pinpointSocketFactory must not be null"); + } + this.pinpointSocketFactory = pinpointSocketFactory; + } + + + @Override + public ChannelPipeline getPipeline() throws Exception { + ChannelPipeline pipeline = Channels.pipeline(); + pipeline.addLast("encoder", new PacketEncoder()); + pipeline.addLast("decoder", new PacketDecoder()); + long pingDelay = pinpointSocketFactory.getPingDelay(); + long enableWorkerPacketDelay = pinpointSocketFactory.getEnableWorkerPacketDelay(); + long timeoutMillis = pinpointSocketFactory.getTimeoutMillis(); + PinpointSocketHandler pinpointSocketHandler = new PinpointSocketHandler(pinpointSocketFactory, pingDelay, enableWorkerPacketDelay, timeoutMillis); + pipeline.addLast("writeTimeout", new WriteTimeoutHandler(pinpointSocketHandler.getChannelTimer(), 3000, TimeUnit.MILLISECONDS)); + pipeline.addLast("socketHandler", pinpointSocketHandler); + return pipeline; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketHandler.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketHandler.java index e75bd8175d97..50f01e3f053d 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketHandler.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/SocketHandler.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.rpc.client; - -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.ResponseMessage; - -import java.net.SocketAddress; - -/** - * @author emeroad - * @author netspider - */ -public interface SocketHandler { - - void setConnectSocketAddress(SocketAddress address); - - void open(); - - void initReconnect(); - - void setPinpointSocket(PinpointSocket pinpointSocket); - - void sendSync(byte[] bytes); - - Future sendAsync(byte[] bytes); - - void close(); - - void send(byte[] bytes); - - Future request(byte[] bytes); - - StreamChannel createStreamChannel(); - - void sendPing(); - - boolean isConnected(); - - void setMessageListener(MessageListener messageListener); -} +package com.nhn.pinpoint.rpc.client; + +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.ResponseMessage; + +import java.net.SocketAddress; + +/** + * @author emeroad + * @author netspider + */ +public interface SocketHandler { + + void setConnectSocketAddress(SocketAddress address); + + void open(); + + void initReconnect(); + + void setPinpointSocket(PinpointSocket pinpointSocket); + + void sendSync(byte[] bytes); + + Future sendAsync(byte[] bytes); + + void close(); + + void send(byte[] bytes); + + Future request(byte[] bytes); + + StreamChannel createStreamChannel(); + + void sendPing(); + + boolean isConnected(); + + void setMessageListener(MessageListener messageListener); +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/State.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/State.java index 27ba85e4d78d..e4d5acd36252 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/State.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/State.java @@ -1,113 +1,113 @@ -package com.nhn.pinpoint.rpc.client; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - * @author koo.taejin - */ -public class State { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - // 프로파일러에서 동작하는 것들은 최대한 가볍게 함 - - // 0 핸드쉐이크 안함.. 1은 동작중, 2는 closed - public static final int INIT_RECONNECT = -1; - public static final int INIT = 0; - public static final int RUN = 1; - public static final int RUN_DUPLEX_COMMUNICATION = 2; - public static final int CLOSED = 3; -// 이 상태가 있어야 되나? - public static final int RECONNECT = 4; - - - private final AtomicInteger state = new AtomicInteger(INIT); - - public int getState() { - return this.state.get(); - } - - public boolean isRun() { - int code = state.get(); - return code == RUN || code == RUN_DUPLEX_COMMUNICATION; - } - - public boolean isRun(int code) { - return code == RUN || code == RUN_DUPLEX_COMMUNICATION; - } - - public boolean isClosed() { - return state.get() == CLOSED; - } - - public boolean changeRun() { - logger.debug("State Will Be Changed {}.", getString(RUN)); - final int current = state.get(); - if (current == INIT) { - return this.state.compareAndSet(INIT, RUN); - } else if(current == INIT_RECONNECT) { - return this.state.compareAndSet(INIT_RECONNECT, RUN); - } - throw new IllegalStateException("InvalidState current:" + getString(current) + " change:" + getString(RUN)); - } - - public boolean changeRunDuplexCommunication() { - logger.debug("State Will Be Changed {}.", getString(RUN_DUPLEX_COMMUNICATION)); - final int current = state.get(); - if (current == INIT) { - return this.state.compareAndSet(INIT, RUN_DUPLEX_COMMUNICATION); - } else if(current == INIT_RECONNECT) { - return this.state.compareAndSet(INIT_RECONNECT, RUN_DUPLEX_COMMUNICATION); - } else if (current == RUN) { - return this.state.compareAndSet(RUN, RUN_DUPLEX_COMMUNICATION); - } else if (current == RUN_DUPLEX_COMMUNICATION) { - return true; - } - throw new IllegalStateException("InvalidState current:" + getString(current) + " change:" + getString(RUN_DUPLEX_COMMUNICATION)); - } - - public boolean changeClosed(int before) { - logger.debug("State Will Be Changed {} -> {}.", getString(before), getString(CLOSED)); - return this.state.compareAndSet(before, CLOSED); - } - - public boolean changeClosed() { - logger.debug("State Will Be Changed {}.", getString(CLOSED)); - return this.state.compareAndSet(RUN, CLOSED); - } - - public void setClosed() { - this.state.set(CLOSED); - } - - public void setState(int state) { - logger.debug("State Will Be Changed {}.", getString(state)); - this.state.set(state); - } - - public String getString(int stateCode) { - switch (stateCode) { - case INIT: - return "INIT"; - case RUN: - return "RUN"; - case RUN_DUPLEX_COMMUNICATION: - return "RUN_DUPLEX_COMMUNICATION"; - case CLOSED: - return "CLOSED"; - case RECONNECT: - return "RECONNECT"; - case INIT_RECONNECT: - return "INIT_RECONNECT"; - } - return "UNKNOWN"; - } - - public String getString() { - return getString(state.get()); - } -} +package com.nhn.pinpoint.rpc.client; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + * @author koo.taejin + */ +public class State { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + // 프로파일러에서 동작하는 것들은 최대한 가볍게 함 + + // 0 핸드쉐이크 안함.. 1은 동작중, 2는 closed + public static final int INIT_RECONNECT = -1; + public static final int INIT = 0; + public static final int RUN = 1; + public static final int RUN_DUPLEX_COMMUNICATION = 2; + public static final int CLOSED = 3; +// 이 상태가 있어야 되나? + public static final int RECONNECT = 4; + + + private final AtomicInteger state = new AtomicInteger(INIT); + + public int getState() { + return this.state.get(); + } + + public boolean isRun() { + int code = state.get(); + return code == RUN || code == RUN_DUPLEX_COMMUNICATION; + } + + public boolean isRun(int code) { + return code == RUN || code == RUN_DUPLEX_COMMUNICATION; + } + + public boolean isClosed() { + return state.get() == CLOSED; + } + + public boolean changeRun() { + logger.debug("State Will Be Changed {}.", getString(RUN)); + final int current = state.get(); + if (current == INIT) { + return this.state.compareAndSet(INIT, RUN); + } else if(current == INIT_RECONNECT) { + return this.state.compareAndSet(INIT_RECONNECT, RUN); + } + throw new IllegalStateException("InvalidState current:" + getString(current) + " change:" + getString(RUN)); + } + + public boolean changeRunDuplexCommunication() { + logger.debug("State Will Be Changed {}.", getString(RUN_DUPLEX_COMMUNICATION)); + final int current = state.get(); + if (current == INIT) { + return this.state.compareAndSet(INIT, RUN_DUPLEX_COMMUNICATION); + } else if(current == INIT_RECONNECT) { + return this.state.compareAndSet(INIT_RECONNECT, RUN_DUPLEX_COMMUNICATION); + } else if (current == RUN) { + return this.state.compareAndSet(RUN, RUN_DUPLEX_COMMUNICATION); + } else if (current == RUN_DUPLEX_COMMUNICATION) { + return true; + } + throw new IllegalStateException("InvalidState current:" + getString(current) + " change:" + getString(RUN_DUPLEX_COMMUNICATION)); + } + + public boolean changeClosed(int before) { + logger.debug("State Will Be Changed {} -> {}.", getString(before), getString(CLOSED)); + return this.state.compareAndSet(before, CLOSED); + } + + public boolean changeClosed() { + logger.debug("State Will Be Changed {}.", getString(CLOSED)); + return this.state.compareAndSet(RUN, CLOSED); + } + + public void setClosed() { + this.state.set(CLOSED); + } + + public void setState(int state) { + logger.debug("State Will Be Changed {}.", getString(state)); + this.state.set(state); + } + + public String getString(int stateCode) { + switch (stateCode) { + case INIT: + return "INIT"; + case RUN: + return "RUN"; + case RUN_DUPLEX_COMMUNICATION: + return "RUN_DUPLEX_COMMUNICATION"; + case CLOSED: + return "CLOSED"; + case RECONNECT: + return "RECONNECT"; + case INIT_RECONNECT: + return "INIT_RECONNECT"; + } + return "UNKNOWN"; + } + + public String getString() { + return getString(state.get()); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannel.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannel.java index a6a10800e0cf..433001344568 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannel.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannel.java @@ -1,219 +1,219 @@ -package com.nhn.pinpoint.rpc.client; - -import com.nhn.pinpoint.rpc.DefaultFuture; -import com.nhn.pinpoint.rpc.FailureEventHandler; -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.StreamCreateResponse; -import com.nhn.pinpoint.rpc.packet.*; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class StreamChannel { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private static final int NONE = 0; - // OPEN 호출 - private static final int OPEN = 1; - // OPEN 결과 대기 - private static final int OPEN_AWAIT = 2; - // 동작중 - private static final int RUN = 3; - // 닫힘 - private static final int CLOSED = 4; - - private final AtomicInteger state = new AtomicInteger(NONE); - - private final int channelId; - - private StreamChannelManager streamChannelManager; - - private StreamChannelMessageListener streamChannelMessageListener; - - private DefaultFuture openLatch; - private Channel channel; - - public StreamChannel(int channelId) { - this.channelId = channelId; - } - - public int getChannelId() { - return channelId; - } - - public void setChannel(Channel channel) { - this.channel = channel; - } - - public Future open(byte[] bytes) { - if (!state.compareAndSet(NONE, OPEN)) { - throw new IllegalStateException("invalid state:" + state.get()); - } - StreamCreatePacket streamCreatePacket = new StreamCreatePacket(channelId, bytes); - - this.openLatch = new DefaultFuture(); - openLatch.setFailureEventHandler(new FailureEventHandler() { - @Override - public boolean fireFailure() { - streamChannelManager.closeChannel(channelId); - return false; - } - }); - ChannelFuture channelFuture = this.channel.write(streamCreatePacket); - channelFuture.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (!future.isSuccess()) { - future.setFailure(future.getCause()); - } - } - }); - - - if (!state.compareAndSet(OPEN, OPEN_AWAIT)) { - throw new IllegalStateException("invalid state"); - } - return openLatch; - } - - - public boolean receiveStreamPacket(StreamPacket packet) { - final short packetType = packet.getPacketType(); - switch (packetType) { - case PacketType.APPLICATION_STREAM_CREATE_SUCCESS: - logger.debug("APPLICATION_STREAM_CREATE_SUCCESS {}", channel); - StreamCreateResponse success = new StreamCreateResponse(true); - success.setMessage(packet.getPayload()); - return openChannel(RUN, success); - - case PacketType.APPLICATION_STREAM_CREATE_FAIL: - logger.debug("APPLICATION_STREAM_CREATE_FAIL {}", channel); - StreamCreateResponse failResult = new StreamCreateResponse(false); - failResult.setMessage(packet.getPayload()); - return openChannel(CLOSED, failResult); - - case PacketType.APPLICATION_STREAM_RESPONSE: { - logger.debug("APPLICATION_STREAM_RESPONSE {}", channel); - - StreamResponsePacket streamResponsePacket = (StreamResponsePacket) packet; - StreamChannelMessageListener streamChannelMessageListener = this.streamChannelMessageListener; - if (streamChannelMessageListener != null) { - streamChannelMessageListener.handleStreamResponse(this, streamResponsePacket.getPayload()); - } - return true; - } - case PacketType.APPLICATION_STREAM_CLOSE: { - logger.debug("APPLICATION_STREAM_CLOSE {}", channel); - - this.closeInternal(); - - StreamClosePacket streamClosePacket = (StreamClosePacket) packet; - StreamChannelMessageListener streamChannelMessageListener = this.streamChannelMessageListener; - if (streamChannelMessageListener != null) { - streamChannelMessageListener.handleClose(this, streamClosePacket.getPayload()); - } - - return true; - } - } - return false; - } - - private boolean openChannel(int channelState, StreamCreateResponse streamCreateResponse) { - if (state.compareAndSet(OPEN_AWAIT, channelState)) { - notifyOpenResult(streamCreateResponse); - return true; - } else { - logger.info("invalid stream channel state:{}", state.get()); - return false; - } - } - - - - - private boolean notifyOpenResult(StreamCreateResponse failResult) { - DefaultFuture openLatch = this.openLatch; - if (openLatch != null) { - return openLatch.setResult(failResult); - } - return false; - } - - - - public boolean close() { - return close0(true); - } - - - - boolean closeInternal() { - return close0(false); - } - - private boolean close0(boolean safeClose) { - if (!state.compareAndSet(RUN, CLOSED)) { - return false; - } - - if (safeClose) { - StreamClosePacket closePacket = new StreamClosePacket(this.channelId); - this.channel.write(closePacket); - - StreamChannelManager streamChannelManager = this.streamChannelManager; - if (streamChannelManager != null) { - streamChannelManager.closeChannel(channelId); - this.streamChannelManager = null; - } - } - return true; - } - - public void setStreamChannelManager(StreamChannelManager streamChannelManager) { - this.streamChannelManager = streamChannelManager; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - StreamChannel that = (StreamChannel) o; - - if (channelId != that.channelId) return false; - if (channel != null ? !channel.equals(that.channel) : that.channel != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = channelId; - result = 31 * result + (channel != null ? channel.hashCode() : 0); - return result; - } - - public void setStreamChannelMessageListener(StreamChannelMessageListener streamChannelMessageListener) { - this.streamChannelMessageListener = streamChannelMessageListener; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("StreamChannel"); - sb.append("{channelId=").append(channelId); - sb.append(", channel=").append(channel); - sb.append('}'); - return sb.toString(); - } -} - +package com.nhn.pinpoint.rpc.client; + +import com.nhn.pinpoint.rpc.DefaultFuture; +import com.nhn.pinpoint.rpc.FailureEventHandler; +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.StreamCreateResponse; +import com.nhn.pinpoint.rpc.packet.*; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class StreamChannel { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final int NONE = 0; + // OPEN 호출 + private static final int OPEN = 1; + // OPEN 결과 대기 + private static final int OPEN_AWAIT = 2; + // 동작중 + private static final int RUN = 3; + // 닫힘 + private static final int CLOSED = 4; + + private final AtomicInteger state = new AtomicInteger(NONE); + + private final int channelId; + + private StreamChannelManager streamChannelManager; + + private StreamChannelMessageListener streamChannelMessageListener; + + private DefaultFuture openLatch; + private Channel channel; + + public StreamChannel(int channelId) { + this.channelId = channelId; + } + + public int getChannelId() { + return channelId; + } + + public void setChannel(Channel channel) { + this.channel = channel; + } + + public Future open(byte[] bytes) { + if (!state.compareAndSet(NONE, OPEN)) { + throw new IllegalStateException("invalid state:" + state.get()); + } + StreamCreatePacket streamCreatePacket = new StreamCreatePacket(channelId, bytes); + + this.openLatch = new DefaultFuture(); + openLatch.setFailureEventHandler(new FailureEventHandler() { + @Override + public boolean fireFailure() { + streamChannelManager.closeChannel(channelId); + return false; + } + }); + ChannelFuture channelFuture = this.channel.write(streamCreatePacket); + channelFuture.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + future.setFailure(future.getCause()); + } + } + }); + + + if (!state.compareAndSet(OPEN, OPEN_AWAIT)) { + throw new IllegalStateException("invalid state"); + } + return openLatch; + } + + + public boolean receiveStreamPacket(StreamPacket packet) { + final short packetType = packet.getPacketType(); + switch (packetType) { + case PacketType.APPLICATION_STREAM_CREATE_SUCCESS: + logger.debug("APPLICATION_STREAM_CREATE_SUCCESS {}", channel); + StreamCreateResponse success = new StreamCreateResponse(true); + success.setMessage(packet.getPayload()); + return openChannel(RUN, success); + + case PacketType.APPLICATION_STREAM_CREATE_FAIL: + logger.debug("APPLICATION_STREAM_CREATE_FAIL {}", channel); + StreamCreateResponse failResult = new StreamCreateResponse(false); + failResult.setMessage(packet.getPayload()); + return openChannel(CLOSED, failResult); + + case PacketType.APPLICATION_STREAM_RESPONSE: { + logger.debug("APPLICATION_STREAM_RESPONSE {}", channel); + + StreamResponsePacket streamResponsePacket = (StreamResponsePacket) packet; + StreamChannelMessageListener streamChannelMessageListener = this.streamChannelMessageListener; + if (streamChannelMessageListener != null) { + streamChannelMessageListener.handleStreamResponse(this, streamResponsePacket.getPayload()); + } + return true; + } + case PacketType.APPLICATION_STREAM_CLOSE: { + logger.debug("APPLICATION_STREAM_CLOSE {}", channel); + + this.closeInternal(); + + StreamClosePacket streamClosePacket = (StreamClosePacket) packet; + StreamChannelMessageListener streamChannelMessageListener = this.streamChannelMessageListener; + if (streamChannelMessageListener != null) { + streamChannelMessageListener.handleClose(this, streamClosePacket.getPayload()); + } + + return true; + } + } + return false; + } + + private boolean openChannel(int channelState, StreamCreateResponse streamCreateResponse) { + if (state.compareAndSet(OPEN_AWAIT, channelState)) { + notifyOpenResult(streamCreateResponse); + return true; + } else { + logger.info("invalid stream channel state:{}", state.get()); + return false; + } + } + + + + + private boolean notifyOpenResult(StreamCreateResponse failResult) { + DefaultFuture openLatch = this.openLatch; + if (openLatch != null) { + return openLatch.setResult(failResult); + } + return false; + } + + + + public boolean close() { + return close0(true); + } + + + + boolean closeInternal() { + return close0(false); + } + + private boolean close0(boolean safeClose) { + if (!state.compareAndSet(RUN, CLOSED)) { + return false; + } + + if (safeClose) { + StreamClosePacket closePacket = new StreamClosePacket(this.channelId); + this.channel.write(closePacket); + + StreamChannelManager streamChannelManager = this.streamChannelManager; + if (streamChannelManager != null) { + streamChannelManager.closeChannel(channelId); + this.streamChannelManager = null; + } + } + return true; + } + + public void setStreamChannelManager(StreamChannelManager streamChannelManager) { + this.streamChannelManager = streamChannelManager; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + StreamChannel that = (StreamChannel) o; + + if (channelId != that.channelId) return false; + if (channel != null ? !channel.equals(that.channel) : that.channel != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = channelId; + result = 31 * result + (channel != null ? channel.hashCode() : 0); + return result; + } + + public void setStreamChannelMessageListener(StreamChannelMessageListener streamChannelMessageListener) { + this.streamChannelMessageListener = streamChannelMessageListener; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("StreamChannel"); + sb.append("{channelId=").append(channelId); + sb.append(", channel=").append(channel); + sb.append('}'); + return sb.toString(); + } +} + diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelManager.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelManager.java index b1fd77fc1592..91a1bf86a202 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelManager.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelManager.java @@ -1,80 +1,80 @@ -package com.nhn.pinpoint.rpc.client; - -import com.nhn.pinpoint.rpc.PinpointSocketException; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import org.jboss.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class StreamChannelManager { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final AtomicInteger idAllocator = new AtomicInteger(0); - - private final ConcurrentMap channelMap = new ConcurrentHashMap(); - - public StreamChannel createStreamChannel(Channel channel) { - final int channelId = allocateChannelId(); - StreamChannel streamChannel = new StreamChannel(channelId); - streamChannel.setChannel(channel); - - StreamChannel old = channelMap.put(channelId, streamChannel); - if (old != null) { - throw new PinpointSocketException("already channelId exist:" + channelId + " streamChannel:" + old); - } - // handle을 붙여서 리턴. - streamChannel.setStreamChannelManager(this); - - return streamChannel; - } - - private int allocateChannelId() { - return idAllocator.get(); - } - - - public StreamChannel findStreamChannel(int channelId) { - return this.channelMap.get(channelId); - } - - public boolean closeChannel(int channelId) { - StreamChannel remove = this.channelMap.remove(channelId); - return remove != null; - } - - public void close() { - logger.debug("close()"); - final ConcurrentMap channelMap = this.channelMap; - - int forceCloseChannel = 0; - for (Map.Entry entry : channelMap.entrySet()) { - if(entry.getValue().closeInternal()) { - forceCloseChannel++; - } - } - channelMap.clear(); - if(forceCloseChannel > 0) { - logger.info("streamChannelManager forceCloseChannel {}", forceCloseChannel); - } - } - - - public boolean messageReceived(StreamPacket streamPacket, Channel channel) { - final int channelId = streamPacket.getChannelId(); - final StreamChannel streamChannel = findStreamChannel(channelId); - if (streamChannel == null) { - logger.warn("streamChannel not found. channelId:{} ", streamPacket.getChannelId(), channel); - return false; - } - return streamChannel.receiveStreamPacket(streamPacket); - } -} +package com.nhn.pinpoint.rpc.client; + +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import org.jboss.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class StreamChannelManager { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final AtomicInteger idAllocator = new AtomicInteger(0); + + private final ConcurrentMap channelMap = new ConcurrentHashMap(); + + public StreamChannel createStreamChannel(Channel channel) { + final int channelId = allocateChannelId(); + StreamChannel streamChannel = new StreamChannel(channelId); + streamChannel.setChannel(channel); + + StreamChannel old = channelMap.put(channelId, streamChannel); + if (old != null) { + throw new PinpointSocketException("already channelId exist:" + channelId + " streamChannel:" + old); + } + // handle을 붙여서 리턴. + streamChannel.setStreamChannelManager(this); + + return streamChannel; + } + + private int allocateChannelId() { + return idAllocator.get(); + } + + + public StreamChannel findStreamChannel(int channelId) { + return this.channelMap.get(channelId); + } + + public boolean closeChannel(int channelId) { + StreamChannel remove = this.channelMap.remove(channelId); + return remove != null; + } + + public void close() { + logger.debug("close()"); + final ConcurrentMap channelMap = this.channelMap; + + int forceCloseChannel = 0; + for (Map.Entry entry : channelMap.entrySet()) { + if(entry.getValue().closeInternal()) { + forceCloseChannel++; + } + } + channelMap.clear(); + if(forceCloseChannel > 0) { + logger.info("streamChannelManager forceCloseChannel {}", forceCloseChannel); + } + } + + + public boolean messageReceived(StreamPacket streamPacket, Channel channel) { + final int channelId = streamPacket.getChannelId(); + final StreamChannel streamChannel = findStreamChannel(channelId); + if (streamChannel == null) { + logger.warn("streamChannel not found. channelId:{} ", streamPacket.getChannelId(), channel); + return false; + } + return streamChannel.receiveStreamPacket(streamPacket); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelMessageListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelMessageListener.java index cc2d19a5e581..d1dbdf5fcb53 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelMessageListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/StreamChannelMessageListener.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.rpc.client; - -/** - * @author emeroad - */ -public interface StreamChannelMessageListener { - void handleStreamResponse(StreamChannel streamChannel, byte[] bytes); - - void handleClose(StreamChannel streamChannel, byte[] bytes); -} +package com.nhn.pinpoint.rpc.client; + +/** + * @author emeroad + */ +public interface StreamChannelMessageListener { + void handleStreamResponse(StreamChannel streamChannel, byte[] bytes); + + void handleClose(StreamChannel streamChannel, byte[] bytes); +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/WriteFailFutureListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/WriteFailFutureListener.java index 3260e41dfc33..c2e3684de2aa 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/WriteFailFutureListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/client/WriteFailFutureListener.java @@ -1,38 +1,38 @@ -package com.nhn.pinpoint.rpc.client; - -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; -import org.slf4j.Logger; - -/** - * @author emeroad - */ -public class WriteFailFutureListener implements ChannelFutureListener { - - private final Logger logger; - private final String failMessage; - private final String successMessage; - - public WriteFailFutureListener(Logger logger, String failMessage, String successMessage) { - if (logger == null) { - throw new NullPointerException("logger must not be null"); - } - this.logger = logger; - this.failMessage = failMessage; - this.successMessage = successMessage; - } - - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (!future.isSuccess()) { - if (logger.isWarnEnabled()) { - final Throwable cause = future.getCause(); - logger.warn("{} channel:{} Caused:{}", failMessage, future.getChannel(), cause.getMessage(), cause); - } - } else { - if (logger.isDebugEnabled()) { - logger.debug("{} channel:{}", successMessage, future.getChannel()); - } - } - } -} +package com.nhn.pinpoint.rpc.client; + +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.slf4j.Logger; + +/** + * @author emeroad + */ +public class WriteFailFutureListener implements ChannelFutureListener { + + private final Logger logger; + private final String failMessage; + private final String successMessage; + + public WriteFailFutureListener(Logger logger, String failMessage, String successMessage) { + if (logger == null) { + throw new NullPointerException("logger must not be null"); + } + this.logger = logger; + this.failMessage = failMessage; + this.successMessage = successMessage; + } + + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + if (logger.isWarnEnabled()) { + final Throwable cause = future.getCause(); + logger.warn("{} channel:{} Caused:{}", failMessage, future.getChannel(), cause.getMessage(), cause); + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("{} channel:{}", successMessage, future.getChannel()); + } + } + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketDecoder.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketDecoder.java index acba4fdd1348..713215740f1f 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketDecoder.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketDecoder.java @@ -1,140 +1,140 @@ -package com.nhn.pinpoint.rpc.codec; - -import com.nhn.pinpoint.rpc.client.WriteFailFutureListener; -import com.nhn.pinpoint.rpc.packet.*; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - * @author koo.taejin - */ -public class PacketDecoder extends FrameDecoder { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final WriteFailFutureListener pongWriteFutureListener = new WriteFailFutureListener(logger, "pong write fail.", "pong write success."); - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { - if (buffer.readableBytes() < 2) { - return null; - } - buffer.markReaderIndex(); - final short packetType = buffer.readShort(); - switch (packetType) { - case PacketType.APPLICATION_SEND: - return readSend(packetType, buffer); - case PacketType.APPLICATION_REQUEST: - return readRequest(packetType, buffer); - case PacketType.APPLICATION_RESPONSE: - return readResponse(packetType, buffer); - case PacketType.APPLICATION_STREAM_CREATE: - return readStreamCreate(packetType, buffer); - case PacketType.APPLICATION_STREAM_CLOSE: - return readStreamClose(packetType, buffer); - case PacketType.APPLICATION_STREAM_CREATE_SUCCESS: - return readStreamCreateSuccess(packetType, buffer); - case PacketType.APPLICATION_STREAM_CREATE_FAIL: - return readStreamCreateFail(packetType, buffer); - case PacketType.APPLICATION_STREAM_RESPONSE: - return readStreamResponse(packetType, buffer); - case PacketType.CONTROL_CLIENT_CLOSE: - return readControlClientClose(packetType, buffer); - case PacketType.CONTROL_SERVER_CLOSE: - return readControlServerClose(packetType, buffer); - case PacketType.CONTROL_PING: - readPing(packetType, buffer); - sendPong(channel); - // 그냥 ping은 버리자. - return null; - case PacketType.CONTROL_PONG: - logger.debug("receive pong. {}", channel); - readPong(packetType, buffer); - // pong 도 그냥 버리자. - return null; - case PacketType.CONTROL_ENABLE_WORKER: - return readEnableWorker(packetType, buffer); - case PacketType.CONTROL_ENABLE_WORKER_CONFIRM: - return readEnableWorkerConfirm(packetType, buffer); - } - logger.error("invalid packetType received. packetType:{}, channel:{}", packetType, channel); - channel.close(); - return null; - } - - private void sendPong(Channel channel) { - // ping에 대한 응답으로 pong은 자동으로 응답한다. - logger.debug("receive ping. send pong. {}", channel); - ChannelFuture write = channel.write(PongPacket.PONG_PACKET); - write.addListener(pongWriteFutureListener); - } - - - private Object readControlClientClose(short packetType, ChannelBuffer buffer) { - return ClientClosePacket.readBuffer(packetType, buffer); - } - - private Object readControlServerClose(short packetType, ChannelBuffer buffer) { - return ServerClosePacket.readBuffer(packetType, buffer); - } - - private Object readPong(short packetType, ChannelBuffer buffer) { - return PongPacket.readBuffer(packetType, buffer); - } - - private Object readPing(short packetType, ChannelBuffer buffer) { - return PingPacket.readBuffer(packetType, buffer); - } - - - private Object readSend(short packetType, ChannelBuffer buffer) { - return SendPacket.readBuffer(packetType, buffer); - } - - - private Object readRequest(short packetType, ChannelBuffer buffer) { - return RequestPacket.readBuffer(packetType, buffer); - } - - private Object readResponse(short packetType, ChannelBuffer buffer) { - return ResponsePacket.readBuffer(packetType, buffer); - } - - - - private Object readStreamCreate(short packetType, ChannelBuffer buffer) { - return StreamCreatePacket.readBuffer(packetType, buffer); - } - - - private Object readStreamCreateSuccess(short packetType, ChannelBuffer buffer) { - return StreamCreateSuccessPacket.readBuffer(packetType, buffer); - } - - private Object readStreamCreateFail(short packetType, ChannelBuffer buffer) { - return StreamCreateFailPacket.readBuffer(packetType, buffer); - } - - private Object readStreamResponse(short packetType, ChannelBuffer buffer) { - return StreamResponsePacket.readBuffer(packetType, buffer); - } - - private Object readStreamClose(short packetType, ChannelBuffer buffer) { - return StreamClosePacket.readBuffer(packetType, buffer); - } - - private Object readEnableWorker(short packetType, ChannelBuffer buffer) { - return ControlEnableWorkerPacket.readBuffer(packetType, buffer); - } - - private Object readEnableWorkerConfirm(short packetType, ChannelBuffer buffer) { - return ControlEnableWorkerConfirmPacket.readBuffer(packetType, buffer); - } - -} +package com.nhn.pinpoint.rpc.codec; + +import com.nhn.pinpoint.rpc.client.WriteFailFutureListener; +import com.nhn.pinpoint.rpc.packet.*; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + * @author koo.taejin + */ +public class PacketDecoder extends FrameDecoder { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final WriteFailFutureListener pongWriteFutureListener = new WriteFailFutureListener(logger, "pong write fail.", "pong write success."); + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { + if (buffer.readableBytes() < 2) { + return null; + } + buffer.markReaderIndex(); + final short packetType = buffer.readShort(); + switch (packetType) { + case PacketType.APPLICATION_SEND: + return readSend(packetType, buffer); + case PacketType.APPLICATION_REQUEST: + return readRequest(packetType, buffer); + case PacketType.APPLICATION_RESPONSE: + return readResponse(packetType, buffer); + case PacketType.APPLICATION_STREAM_CREATE: + return readStreamCreate(packetType, buffer); + case PacketType.APPLICATION_STREAM_CLOSE: + return readStreamClose(packetType, buffer); + case PacketType.APPLICATION_STREAM_CREATE_SUCCESS: + return readStreamCreateSuccess(packetType, buffer); + case PacketType.APPLICATION_STREAM_CREATE_FAIL: + return readStreamCreateFail(packetType, buffer); + case PacketType.APPLICATION_STREAM_RESPONSE: + return readStreamResponse(packetType, buffer); + case PacketType.CONTROL_CLIENT_CLOSE: + return readControlClientClose(packetType, buffer); + case PacketType.CONTROL_SERVER_CLOSE: + return readControlServerClose(packetType, buffer); + case PacketType.CONTROL_PING: + readPing(packetType, buffer); + sendPong(channel); + // 그냥 ping은 버리자. + return null; + case PacketType.CONTROL_PONG: + logger.debug("receive pong. {}", channel); + readPong(packetType, buffer); + // pong 도 그냥 버리자. + return null; + case PacketType.CONTROL_ENABLE_WORKER: + return readEnableWorker(packetType, buffer); + case PacketType.CONTROL_ENABLE_WORKER_CONFIRM: + return readEnableWorkerConfirm(packetType, buffer); + } + logger.error("invalid packetType received. packetType:{}, channel:{}", packetType, channel); + channel.close(); + return null; + } + + private void sendPong(Channel channel) { + // ping에 대한 응답으로 pong은 자동으로 응답한다. + logger.debug("receive ping. send pong. {}", channel); + ChannelFuture write = channel.write(PongPacket.PONG_PACKET); + write.addListener(pongWriteFutureListener); + } + + + private Object readControlClientClose(short packetType, ChannelBuffer buffer) { + return ClientClosePacket.readBuffer(packetType, buffer); + } + + private Object readControlServerClose(short packetType, ChannelBuffer buffer) { + return ServerClosePacket.readBuffer(packetType, buffer); + } + + private Object readPong(short packetType, ChannelBuffer buffer) { + return PongPacket.readBuffer(packetType, buffer); + } + + private Object readPing(short packetType, ChannelBuffer buffer) { + return PingPacket.readBuffer(packetType, buffer); + } + + + private Object readSend(short packetType, ChannelBuffer buffer) { + return SendPacket.readBuffer(packetType, buffer); + } + + + private Object readRequest(short packetType, ChannelBuffer buffer) { + return RequestPacket.readBuffer(packetType, buffer); + } + + private Object readResponse(short packetType, ChannelBuffer buffer) { + return ResponsePacket.readBuffer(packetType, buffer); + } + + + + private Object readStreamCreate(short packetType, ChannelBuffer buffer) { + return StreamCreatePacket.readBuffer(packetType, buffer); + } + + + private Object readStreamCreateSuccess(short packetType, ChannelBuffer buffer) { + return StreamCreateSuccessPacket.readBuffer(packetType, buffer); + } + + private Object readStreamCreateFail(short packetType, ChannelBuffer buffer) { + return StreamCreateFailPacket.readBuffer(packetType, buffer); + } + + private Object readStreamResponse(short packetType, ChannelBuffer buffer) { + return StreamResponsePacket.readBuffer(packetType, buffer); + } + + private Object readStreamClose(short packetType, ChannelBuffer buffer) { + return StreamClosePacket.readBuffer(packetType, buffer); + } + + private Object readEnableWorker(short packetType, ChannelBuffer buffer) { + return ControlEnableWorkerPacket.readBuffer(packetType, buffer); + } + + private Object readEnableWorkerConfirm(short packetType, ChannelBuffer buffer) { + return ControlEnableWorkerConfirmPacket.readBuffer(packetType, buffer); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketEncoder.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketEncoder.java index 33b4b8af2200..33c72064591f 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketEncoder.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/codec/PacketEncoder.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.rpc.codec; - -import com.nhn.pinpoint.rpc.packet.Packet; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class PacketEncoder extends OneToOneEncoder { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { - if (!(msg instanceof Packet)) { - logger.error("invalid packet:{} channel:{}", msg, channel); - return null; - } - Packet packet = (Packet) msg; - return packet.toBuffer(); - } -} +package com.nhn.pinpoint.rpc.codec; + +import com.nhn.pinpoint.rpc.packet.Packet; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class PacketEncoder extends OneToOneEncoder { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + if (!(msg instanceof Packet)) { + logger.error("invalid packet:{} channel:{}", msg, channel); + return null; + } + Packet packet = (Packet) msg; + return packet.toBuffer(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageDecoder.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageDecoder.java index 6f1a8fe2530e..67c925499664 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageDecoder.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageDecoder.java @@ -1,94 +1,94 @@ -package com.nhn.pinpoint.rpc.control; - -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * @author koo.taejin - */ -public class ControlMessageDecoder { - - private Charset charset; - - public ControlMessageDecoder() { - this.charset = Charset.forName("UTF-8"); - } - - public Object decode(byte[] in) throws ProtocolException { - return decode(ByteBuffer.wrap(in)); - } - - public Object decode(ByteBuffer in) throws ProtocolException { - byte type = in.get(); - switch (type) { - case ControlMessageProtocolConstant.TYPE_CHARACTER_NULL: - return null; - case ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_TRUE: - return Boolean.TRUE; - case ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_FALSE: - return Boolean.FALSE; - case ControlMessageProtocolConstant.TYPE_CHARACTER_INT: - return in.getInt(); - case ControlMessageProtocolConstant.TYPE_CHARACTER_LONG: - return in.getLong(); - case ControlMessageProtocolConstant.TYPE_CHARACTER_DOUBLE: - return Double.longBitsToDouble(in.getLong()); - case ControlMessageProtocolConstant.TYPE_CHARACTER_STRING: - return decodeString(in); - case ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_START: - List answerList = new ArrayList(); - while (!isListFinished(in)) { - answerList.add(decode(in)); - } - in.get(); // Skip the terminator - return answerList; - case ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_START: - Map answerMap = new LinkedHashMap(); - while (!isMapFinished(in)) { - Object key = decode(in); - Object value = decode(in); - answerMap.put(key, value); - } - in.get(); // Skip the terminator - return answerMap; - default: - throw new ProtocolException("invalid type character: " + (char) type + " (" + "0x" + Integer.toHexString(type) + ")"); - } - } - - private Object decodeString(ByteBuffer in) { - int length = readStringLength(in); - - byte[] bytesToEncode = new byte[length]; - in.get(bytesToEncode); - - return new String(bytesToEncode, charset); - } - - private boolean isMapFinished(ByteBuffer in) { - return in.get(in.position()) == ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_END; - } - - private boolean isListFinished(ByteBuffer in) { - return in.get(in.position()) == ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_END; - } - - private int readStringLength(ByteBuffer in) { - int result = 0; - int shift = 0; - - while (true) { - byte b = in.get(); - result |= (b & 0x7F) << shift; - if ((b & 0x80) != 128) - break; - shift += 7; - } - return result; - } - -} +package com.nhn.pinpoint.rpc.control; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * @author koo.taejin + */ +public class ControlMessageDecoder { + + private Charset charset; + + public ControlMessageDecoder() { + this.charset = Charset.forName("UTF-8"); + } + + public Object decode(byte[] in) throws ProtocolException { + return decode(ByteBuffer.wrap(in)); + } + + public Object decode(ByteBuffer in) throws ProtocolException { + byte type = in.get(); + switch (type) { + case ControlMessageProtocolConstant.TYPE_CHARACTER_NULL: + return null; + case ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_TRUE: + return Boolean.TRUE; + case ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_FALSE: + return Boolean.FALSE; + case ControlMessageProtocolConstant.TYPE_CHARACTER_INT: + return in.getInt(); + case ControlMessageProtocolConstant.TYPE_CHARACTER_LONG: + return in.getLong(); + case ControlMessageProtocolConstant.TYPE_CHARACTER_DOUBLE: + return Double.longBitsToDouble(in.getLong()); + case ControlMessageProtocolConstant.TYPE_CHARACTER_STRING: + return decodeString(in); + case ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_START: + List answerList = new ArrayList(); + while (!isListFinished(in)) { + answerList.add(decode(in)); + } + in.get(); // Skip the terminator + return answerList; + case ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_START: + Map answerMap = new LinkedHashMap(); + while (!isMapFinished(in)) { + Object key = decode(in); + Object value = decode(in); + answerMap.put(key, value); + } + in.get(); // Skip the terminator + return answerMap; + default: + throw new ProtocolException("invalid type character: " + (char) type + " (" + "0x" + Integer.toHexString(type) + ")"); + } + } + + private Object decodeString(ByteBuffer in) { + int length = readStringLength(in); + + byte[] bytesToEncode = new byte[length]; + in.get(bytesToEncode); + + return new String(bytesToEncode, charset); + } + + private boolean isMapFinished(ByteBuffer in) { + return in.get(in.position()) == ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_END; + } + + private boolean isListFinished(ByteBuffer in) { + return in.get(in.position()) == ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_END; + } + + private int readStringLength(ByteBuffer in) { + int result = 0; + int shift = 0; + + while (true) { + byte b = in.get(); + result |= (b & 0x7F) << shift; + if ((b & 0x80) != 128) + break; + shift += 7; + } + return result; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageEncoder.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageEncoder.java index 251b13191cbb..ae54f59a7519 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageEncoder.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageEncoder.java @@ -1,179 +1,179 @@ -package com.nhn.pinpoint.rpc.control; - -import java.lang.reflect.Array; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author koo.taejin - */ -public class ControlMessageEncoder { - - // 단순하게 가자 NPC랑 비슷 단) String에서 Chunk대신 bit 연산 사용하게 함 - // UTF-8만 사용하게 함 - private Charset charset; - - public ControlMessageEncoder() { - this.charset = Charset.forName("UTF-8"); - } - - public byte[] encode(Map value) throws ProtocolException { - ChannelBuffer cb = ChannelBuffers.dynamicBuffer(100); - encode(value, cb); - - int writeIndex = cb.writerIndex(); - byte[] result = new byte[writeIndex]; - - cb.readBytes(result); - - return result; - } - - private void encode(Map value, ChannelBuffer cb) throws ProtocolException { - encodeMap(value, cb); - } - - private void encode(Object value, ChannelBuffer cb) throws ProtocolException { - try { - if (value == null) { - encodeNull(cb); - } else if (value instanceof String) { - encodeString((String) value, cb); - } else if (value instanceof Boolean) { - encodeBoolean((Boolean) value, cb); - } else if (value instanceof Short) { - encodeInt((Short) value, cb); - } else if (value instanceof Integer) { - encodeInt((Integer) value, cb); - } else if (value instanceof Long) { - encodeLong((Long) value, cb); - } else if (value instanceof Float) { - encodeDouble(((Float) value).doubleValue(), cb); - } else if (value instanceof Double) { - encodeDouble((Double) value, cb); - } else if (value instanceof Number) { // Other numbers (i.e. - // BigInteger and BigDecimal) - encodeString(value.toString(), cb); - } else if (value instanceof Collection) { - encodeCollection((Collection) value, cb); - } else if (value instanceof Map) { - encodeMap((Map) value, cb); - } else if (value.getClass().isArray()) { - int arraySize = Array.getLength(value); - - List arrayToList = new ArrayList(arraySize); - for (int i = 0; i < arraySize; i++) { - arrayToList.add(Array.get(value, i)); - } - encodeCollection(arrayToList, cb); - } else { - throw new ProtocolException("Unsupported type : " + value.getClass().getName()); - } - } catch (Exception e) { - throw new ProtocolException(e); - } - } - - private void encodeNull(ChannelBuffer out) { - out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_NULL); - } - - private void encodeString(String value, ChannelBuffer out) { - out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_STRING); - putPrefixedBytes(value.getBytes(charset), out); - } - - private void encodeBoolean(boolean value, ChannelBuffer out) { - if (value) { - out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_TRUE); - } else { - out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_FALSE); - } - } - - private void encodeInt(int value, ChannelBuffer out) { - out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_INT); - - out.writeByte((byte) (value >> 24)); - out.writeByte((byte) (value >> 16)); - out.writeByte((byte) (value >> 8)); - out.writeByte((byte) (value)); - } - - private void encodeLong(long value, ChannelBuffer out) { - out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_LONG); - - out.writeByte((byte) (value >> 56)); - out.writeByte((byte) (value >> 48)); - out.writeByte((byte) (value >> 40)); - out.writeByte((byte) (value >> 32)); - out.writeByte((byte) (value >> 24)); - out.writeByte((byte) (value >> 16)); - out.writeByte((byte) (value >> 8)); - out.writeByte((byte) (value)); - } - - private void encodeDouble(double value, ChannelBuffer out) { - out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_DOUBLE); - - long longValue = Double.doubleToLongBits(value); - - out.writeByte((byte) (longValue >> 56)); - out.writeByte((byte) (longValue >> 48)); - out.writeByte((byte) (longValue >> 40)); - out.writeByte((byte) (longValue >> 32)); - out.writeByte((byte) (longValue >> 24)); - out.writeByte((byte) (longValue >> 16)); - out.writeByte((byte) (longValue >> 8)); - out.writeByte((byte) (longValue)); - } - - private void encodeCollection(Collection collection, ChannelBuffer out) throws ProtocolException { - out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_START); - for (Object element : collection) { - encode(element, out); - } - out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_END); - } - - private void encodeMap(Map map, ChannelBuffer out) throws ProtocolException { - out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_START); - for (Object element : map.entrySet()) { - Map.Entry entry = (Map.Entry) element; - encode(entry.getKey(), out); - encode(entry.getValue(), out); - } - out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_END); - } - - private void putPrefixedBytes(byte[] value, ChannelBuffer out) { - int length = value.length; - - byte[] lengthBuf = new byte[5]; - - int idx = 0; - while (true) { - if ((length & 0xFFFFFF80) == 0) { - lengthBuf[(idx++)] = (byte) length; - break; - } - - lengthBuf[(idx++)] = (byte) (length & 0x7F | 0x80); - - length >>>= 7; - } - - for (int i = 0; i < idx; i++) { - out.writeByte(lengthBuf[i]); - } - - out.writeBytes(value); - } - -} +package com.nhn.pinpoint.rpc.control; + +import java.lang.reflect.Array; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author koo.taejin + */ +public class ControlMessageEncoder { + + // 단순하게 가자 NPC랑 비슷 단) String에서 Chunk대신 bit 연산 사용하게 함 + // UTF-8만 사용하게 함 + private Charset charset; + + public ControlMessageEncoder() { + this.charset = Charset.forName("UTF-8"); + } + + public byte[] encode(Map value) throws ProtocolException { + ChannelBuffer cb = ChannelBuffers.dynamicBuffer(100); + encode(value, cb); + + int writeIndex = cb.writerIndex(); + byte[] result = new byte[writeIndex]; + + cb.readBytes(result); + + return result; + } + + private void encode(Map value, ChannelBuffer cb) throws ProtocolException { + encodeMap(value, cb); + } + + private void encode(Object value, ChannelBuffer cb) throws ProtocolException { + try { + if (value == null) { + encodeNull(cb); + } else if (value instanceof String) { + encodeString((String) value, cb); + } else if (value instanceof Boolean) { + encodeBoolean((Boolean) value, cb); + } else if (value instanceof Short) { + encodeInt((Short) value, cb); + } else if (value instanceof Integer) { + encodeInt((Integer) value, cb); + } else if (value instanceof Long) { + encodeLong((Long) value, cb); + } else if (value instanceof Float) { + encodeDouble(((Float) value).doubleValue(), cb); + } else if (value instanceof Double) { + encodeDouble((Double) value, cb); + } else if (value instanceof Number) { // Other numbers (i.e. + // BigInteger and BigDecimal) + encodeString(value.toString(), cb); + } else if (value instanceof Collection) { + encodeCollection((Collection) value, cb); + } else if (value instanceof Map) { + encodeMap((Map) value, cb); + } else if (value.getClass().isArray()) { + int arraySize = Array.getLength(value); + + List arrayToList = new ArrayList(arraySize); + for (int i = 0; i < arraySize; i++) { + arrayToList.add(Array.get(value, i)); + } + encodeCollection(arrayToList, cb); + } else { + throw new ProtocolException("Unsupported type : " + value.getClass().getName()); + } + } catch (Exception e) { + throw new ProtocolException(e); + } + } + + private void encodeNull(ChannelBuffer out) { + out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_NULL); + } + + private void encodeString(String value, ChannelBuffer out) { + out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_STRING); + putPrefixedBytes(value.getBytes(charset), out); + } + + private void encodeBoolean(boolean value, ChannelBuffer out) { + if (value) { + out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_TRUE); + } else { + out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_BOOL_FALSE); + } + } + + private void encodeInt(int value, ChannelBuffer out) { + out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_INT); + + out.writeByte((byte) (value >> 24)); + out.writeByte((byte) (value >> 16)); + out.writeByte((byte) (value >> 8)); + out.writeByte((byte) (value)); + } + + private void encodeLong(long value, ChannelBuffer out) { + out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_LONG); + + out.writeByte((byte) (value >> 56)); + out.writeByte((byte) (value >> 48)); + out.writeByte((byte) (value >> 40)); + out.writeByte((byte) (value >> 32)); + out.writeByte((byte) (value >> 24)); + out.writeByte((byte) (value >> 16)); + out.writeByte((byte) (value >> 8)); + out.writeByte((byte) (value)); + } + + private void encodeDouble(double value, ChannelBuffer out) { + out.writeByte((byte) ControlMessageProtocolConstant.TYPE_CHARACTER_DOUBLE); + + long longValue = Double.doubleToLongBits(value); + + out.writeByte((byte) (longValue >> 56)); + out.writeByte((byte) (longValue >> 48)); + out.writeByte((byte) (longValue >> 40)); + out.writeByte((byte) (longValue >> 32)); + out.writeByte((byte) (longValue >> 24)); + out.writeByte((byte) (longValue >> 16)); + out.writeByte((byte) (longValue >> 8)); + out.writeByte((byte) (longValue)); + } + + private void encodeCollection(Collection collection, ChannelBuffer out) throws ProtocolException { + out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_START); + for (Object element : collection) { + encode(element, out); + } + out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_LIST_END); + } + + private void encodeMap(Map map, ChannelBuffer out) throws ProtocolException { + out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_START); + for (Object element : map.entrySet()) { + Map.Entry entry = (Map.Entry) element; + encode(entry.getKey(), out); + encode(entry.getValue(), out); + } + out.writeByte((byte) ControlMessageProtocolConstant.CONTROL_CHARACTER_MAP_END); + } + + private void putPrefixedBytes(byte[] value, ChannelBuffer out) { + int length = value.length; + + byte[] lengthBuf = new byte[5]; + + int idx = 0; + while (true) { + if ((length & 0xFFFFFF80) == 0) { + lengthBuf[(idx++)] = (byte) length; + break; + } + + lengthBuf[(idx++)] = (byte) (length & 0x7F | 0x80); + + length >>>= 7; + } + + for (int i = 0; i < idx; i++) { + out.writeByte(lengthBuf[i]); + } + + out.writeBytes(value); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageProtocolConstant.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageProtocolConstant.java index 76f31b01fe8c..99a6a99d8f57 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageProtocolConstant.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ControlMessageProtocolConstant.java @@ -1,30 +1,30 @@ -package com.nhn.pinpoint.rpc.control; - -/** - * @author koo.taejin - */ -public class ControlMessageProtocolConstant { - - public static final int TYPE_CHARACTER_NULL = 'N'; - - public static final int TYPE_CHARACTER_BOOL_TRUE = 'T'; - - public static final int TYPE_CHARACTER_BOOL_FALSE = 'F'; - - public static final int TYPE_CHARACTER_INT = 'I'; - - public static final int TYPE_CHARACTER_LONG = 'L'; - - public static final int TYPE_CHARACTER_DOUBLE = 'D'; - - public static final int TYPE_CHARACTER_STRING = 'S'; - - public static final int CONTROL_CHARACTER_LIST_START = 'V'; - - public static final int CONTROL_CHARACTER_LIST_END = 'z'; - - public static final int CONTROL_CHARACTER_MAP_START = 'M'; - - public static final int CONTROL_CHARACTER_MAP_END = 'z'; - -} +package com.nhn.pinpoint.rpc.control; + +/** + * @author koo.taejin + */ +public class ControlMessageProtocolConstant { + + public static final int TYPE_CHARACTER_NULL = 'N'; + + public static final int TYPE_CHARACTER_BOOL_TRUE = 'T'; + + public static final int TYPE_CHARACTER_BOOL_FALSE = 'F'; + + public static final int TYPE_CHARACTER_INT = 'I'; + + public static final int TYPE_CHARACTER_LONG = 'L'; + + public static final int TYPE_CHARACTER_DOUBLE = 'D'; + + public static final int TYPE_CHARACTER_STRING = 'S'; + + public static final int CONTROL_CHARACTER_LIST_START = 'V'; + + public static final int CONTROL_CHARACTER_LIST_END = 'z'; + + public static final int CONTROL_CHARACTER_MAP_START = 'M'; + + public static final int CONTROL_CHARACTER_MAP_END = 'z'; + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ProtocolException.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ProtocolException.java index 2d7abe5148b5..0ae938c8933c 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ProtocolException.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/control/ProtocolException.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.rpc.control; - -/** - * @author koo.taejin - */ -public class ProtocolException extends Exception { - - public ProtocolException() { - } - - public ProtocolException(String message) { - super(message); - } - - public ProtocolException(Throwable cause) { - super(cause); - } - - public ProtocolException(String message, Throwable cause) { - super(message, cause); - } - -} +package com.nhn.pinpoint.rpc.control; + +/** + * @author koo.taejin + */ +public class ProtocolException extends Exception { + + public ProtocolException() { + } + + public ProtocolException(String message) { + super(message); + } + + public ProtocolException(Throwable cause) { + super(cause); + } + + public ProtocolException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicPacket.java index c554d6307208..ed38ae9f35cf 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicPacket.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.rpc.packet; - -/** - * @author emeroad - */ -public abstract class BasicPacket implements Packet { - - protected byte[] payload; - - protected BasicPacket() { - } - - public BasicPacket(byte[] payload) { - if (payload == null) { - throw new NullPointerException("payload"); - } - this.payload = payload; - } - - public byte[] getPayload() { - return payload; - } - - public void setPayload(byte[] payload) { - this.payload = payload; - } - -} +package com.nhn.pinpoint.rpc.packet; + +/** + * @author emeroad + */ +public abstract class BasicPacket implements Packet { + + protected byte[] payload; + + protected BasicPacket() { + } + + public BasicPacket(byte[] payload) { + if (payload == null) { + throw new NullPointerException("payload"); + } + this.payload = payload; + } + + public byte[] getPayload() { + return payload; + } + + public void setPayload(byte[] payload) { + this.payload = payload; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicStreamPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicStreamPacket.java index 2891cc2f355e..3747fca167e2 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicStreamPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/BasicStreamPacket.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.rpc.packet; - -/** - * @author emeroad - */ -public abstract class BasicStreamPacket implements StreamPacket { - - protected byte[] payload; - - protected int channelId; - - public BasicStreamPacket() { - } - - public BasicStreamPacket(byte[] payload) { - if (payload == null) { - throw new NullPointerException("payload"); - } - this.payload = payload; - } - - protected BasicStreamPacket(int channelId) { - this.channelId = channelId; - } - - protected BasicStreamPacket(int channelId, byte[] payload) { - this.payload = payload; - this.channelId = channelId; - } - - public byte[] getPayload() { - return payload; - } - - public void setPayload(byte[] payload) { - this.payload = payload; - } - - public int getChannelId() { - return channelId; - } - - public void setChannelId(int channelId) { - this.channelId = channelId; - } -} +package com.nhn.pinpoint.rpc.packet; + +/** + * @author emeroad + */ +public abstract class BasicStreamPacket implements StreamPacket { + + protected byte[] payload; + + protected int channelId; + + public BasicStreamPacket() { + } + + public BasicStreamPacket(byte[] payload) { + if (payload == null) { + throw new NullPointerException("payload"); + } + this.payload = payload; + } + + protected BasicStreamPacket(int channelId) { + this.channelId = channelId; + } + + protected BasicStreamPacket(int channelId, byte[] payload) { + this.payload = payload; + this.channelId = channelId; + } + + public byte[] getPayload() { + return payload; + } + + public void setPayload(byte[] payload) { + this.payload = payload; + } + + public int getChannelId() { + return channelId; + } + + public void setChannelId(int channelId) { + this.channelId = channelId; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ClientClosePacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ClientClosePacket.java index 02f30166673e..598f979c75c4 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ClientClosePacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ClientClosePacket.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class ClientClosePacket extends BasicPacket { - - @Override - public short getPacketType() { - return PacketType.CONTROL_CLIENT_CLOSE; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4); - header.writeShort(PacketType.CONTROL_CLIENT_CLOSE); - - return PayloadPacket.appendPayload(header, payload); - } - - public static ClientClosePacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.CONTROL_CLIENT_CLOSE; - - if (buffer.readableBytes() < 4) { - buffer.resetReaderIndex(); - return null; - } - - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final ClientClosePacket requestPacket = new ClientClosePacket(); - return requestPacket; - - } - - @Override - public String toString() { - return "ClientClosePacket"; - } -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class ClientClosePacket extends BasicPacket { + + @Override + public short getPacketType() { + return PacketType.CONTROL_CLIENT_CLOSE; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4); + header.writeShort(PacketType.CONTROL_CLIENT_CLOSE); + + return PayloadPacket.appendPayload(header, payload); + } + + public static ClientClosePacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.CONTROL_CLIENT_CLOSE; + + if (buffer.readableBytes() < 4) { + buffer.resetReaderIndex(); + return null; + } + + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final ClientClosePacket requestPacket = new ClientClosePacket(); + return requestPacket; + + } + + @Override + public String toString() { + return "ClientClosePacket"; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerConfirmPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerConfirmPacket.java index b4f059ee1b71..bbcc5c465e75 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerConfirmPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerConfirmPacket.java @@ -1,74 +1,74 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author koo.taejin - */ -public class ControlEnableWorkerConfirmPacket extends ControlPacket { - - public static final int SUCCESS = 0; - public static final int ALREADY_REGISTER = 1; - public static final int INVALID_PROPERTIES = 2; - public static final int ILLEGAL_PROTOCOL = 3; - public static final int UNKNOWN_ERROR = 4; - - public ControlEnableWorkerConfirmPacket(byte[] payload) { - super(payload); - } - - public ControlEnableWorkerConfirmPacket(int requestId, byte[] payload) { - super(payload); - setRequestId(requestId); - } - - @Override - public short getPacketType() { - return PacketType.CONTROL_ENABLE_WORKER_CONFIRM; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.CONTROL_ENABLE_WORKER_CONFIRM); - header.writeInt(getRequestId()); - - return PayloadPacket.appendPayload(header, payload); - } - - public static ControlEnableWorkerConfirmPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.CONTROL_ENABLE_WORKER_CONFIRM; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int messageId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final ControlEnableWorkerConfirmPacket helloPacket = new ControlEnableWorkerConfirmPacket(payload.array()); - helloPacket.setRequestId(messageId); - return helloPacket; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append(this.getClass().getSimpleName()); - sb.append("{requestId=").append(getRequestId()); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author koo.taejin + */ +public class ControlEnableWorkerConfirmPacket extends ControlPacket { + + public static final int SUCCESS = 0; + public static final int ALREADY_REGISTER = 1; + public static final int INVALID_PROPERTIES = 2; + public static final int ILLEGAL_PROTOCOL = 3; + public static final int UNKNOWN_ERROR = 4; + + public ControlEnableWorkerConfirmPacket(byte[] payload) { + super(payload); + } + + public ControlEnableWorkerConfirmPacket(int requestId, byte[] payload) { + super(payload); + setRequestId(requestId); + } + + @Override + public short getPacketType() { + return PacketType.CONTROL_ENABLE_WORKER_CONFIRM; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.CONTROL_ENABLE_WORKER_CONFIRM); + header.writeInt(getRequestId()); + + return PayloadPacket.appendPayload(header, payload); + } + + public static ControlEnableWorkerConfirmPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.CONTROL_ENABLE_WORKER_CONFIRM; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int messageId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final ControlEnableWorkerConfirmPacket helloPacket = new ControlEnableWorkerConfirmPacket(payload.array()); + helloPacket.setRequestId(messageId); + return helloPacket; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append(this.getClass().getSimpleName()); + sb.append("{requestId=").append(getRequestId()); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerPacket.java index a177fdfb11a7..e31c661f914f 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlEnableWorkerPacket.java @@ -1,68 +1,68 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author koo.taejin - */ -public class ControlEnableWorkerPacket extends ControlPacket { - - public ControlEnableWorkerPacket(byte[] payload) { - super(payload); - } - - public ControlEnableWorkerPacket(int requestId, byte[] payload) { - super(payload); - setRequestId(requestId); - } - - @Override - public short getPacketType() { - return PacketType.CONTROL_ENABLE_WORKER; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.CONTROL_ENABLE_WORKER); - header.writeInt(getRequestId()); - - return PayloadPacket.appendPayload(header, payload); - } - - public static ControlEnableWorkerPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.CONTROL_ENABLE_WORKER; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int messageId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final ControlEnableWorkerPacket helloPacket = new ControlEnableWorkerPacket(payload.array()); - helloPacket.setRequestId(messageId); - return helloPacket; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append(this.getClass().getSimpleName()); - sb.append("{requestId=").append(getRequestId()); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author koo.taejin + */ +public class ControlEnableWorkerPacket extends ControlPacket { + + public ControlEnableWorkerPacket(byte[] payload) { + super(payload); + } + + public ControlEnableWorkerPacket(int requestId, byte[] payload) { + super(payload); + setRequestId(requestId); + } + + @Override + public short getPacketType() { + return PacketType.CONTROL_ENABLE_WORKER; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.CONTROL_ENABLE_WORKER); + header.writeInt(getRequestId()); + + return PayloadPacket.appendPayload(header, payload); + } + + public static ControlEnableWorkerPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.CONTROL_ENABLE_WORKER; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int messageId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final ControlEnableWorkerPacket helloPacket = new ControlEnableWorkerPacket(payload.array()); + helloPacket.setRequestId(messageId); + return helloPacket; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append(this.getClass().getSimpleName()); + sb.append("{requestId=").append(getRequestId()); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlPacket.java index 9c389ba54fe0..67447e638d26 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ControlPacket.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.rpc.packet; - -/** - * @author koo.taejin - */ -public abstract class ControlPacket extends BasicPacket { - - private int requestId; - - public ControlPacket(byte[] payload) { - super(payload); - } - - public int getRequestId() { - return requestId; - } - - public void setRequestId(int requestId) { - this.requestId = requestId; - } - -} +package com.nhn.pinpoint.rpc.packet; + +/** + * @author koo.taejin + */ +public abstract class ControlPacket extends BasicPacket { + + private int requestId; + + public ControlPacket(byte[] payload) { + super(payload); + } + + public int getRequestId() { + return requestId; + } + + public void setRequestId(int requestId) { + this.requestId = requestId; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/Packet.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/Packet.java index 40c1ea36496c..b1cc63896627 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/Packet.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/Packet.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; - -/** - * @author emeroad - */ -public interface Packet { - - short getPacketType(); - - byte[] getPayload(); - - ChannelBuffer toBuffer(); -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; + +/** + * @author emeroad + */ +public interface Packet { + + short getPacketType(); + + byte[] getPayload(); + + ChannelBuffer toBuffer(); +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PacketType.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PacketType.java index 783c17fb5bbd..c712d0f4670b 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PacketType.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PacketType.java @@ -1,39 +1,39 @@ -package com.nhn.pinpoint.rpc.packet; - -/** - * @author emeroad - * @author koo.taejin - */ -public class PacketType { - public static final short APPLICATION_SEND = 1; - public static final short APPLICATION_TRACE_SEND = 2; - public static final short APPLICATION_TRACE_SEND_ACK = 3; - - public static final short APPLICATION_REQUEST = 5; - public static final short APPLICATION_RESPONSE = 6; - - - public static final short APPLICATION_STREAM_CREATE = 10; - public static final short APPLICATION_STREAM_CREATE_SUCCESS = 12; - public static final short APPLICATION_STREAM_CREATE_FAIL = 14; - - public static final short APPLICATION_STREAM_CLOSE = 15; - - public static final short APPLICATION_STREAM_RESPONSE = 20; - - - public static final short CONTROL_CLIENT_CLOSE = 100; - public static final short CONTROL_SERVER_CLOSE = 110; - - // 컨트롤 패킷 - public static final short CONTROL_ENABLE_WORKER = 150; - public static final short CONTROL_ENABLE_WORKER_CONFIRM = 151; - - // ping, pong의 경우 성능상 두고 다른 CONTROL은 이걸로 뺌 - public static final short CONTROL_PING = 200; - public static final short CONTROL_PONG = 201; - - public static final short UNKNOWN = 500; - - public static final int PACKET_TYPE_SIZE = 2; -} +package com.nhn.pinpoint.rpc.packet; + +/** + * @author emeroad + * @author koo.taejin + */ +public class PacketType { + public static final short APPLICATION_SEND = 1; + public static final short APPLICATION_TRACE_SEND = 2; + public static final short APPLICATION_TRACE_SEND_ACK = 3; + + public static final short APPLICATION_REQUEST = 5; + public static final short APPLICATION_RESPONSE = 6; + + + public static final short APPLICATION_STREAM_CREATE = 10; + public static final short APPLICATION_STREAM_CREATE_SUCCESS = 12; + public static final short APPLICATION_STREAM_CREATE_FAIL = 14; + + public static final short APPLICATION_STREAM_CLOSE = 15; + + public static final short APPLICATION_STREAM_RESPONSE = 20; + + + public static final short CONTROL_CLIENT_CLOSE = 100; + public static final short CONTROL_SERVER_CLOSE = 110; + + // 컨트롤 패킷 + public static final short CONTROL_ENABLE_WORKER = 150; + public static final short CONTROL_ENABLE_WORKER_CONFIRM = 151; + + // ping, pong의 경우 성능상 두고 다른 CONTROL은 이걸로 뺌 + public static final short CONTROL_PING = 200; + public static final short CONTROL_PONG = 201; + + public static final short UNKNOWN = 500; + + public static final int PACKET_TYPE_SIZE = 2; +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PayloadPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PayloadPacket.java index 82a8ca35a712..6fc751de2010 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PayloadPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PayloadPacket.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class PayloadPacket { - - private static final Logger logger = LoggerFactory.getLogger(PayloadPacket.class); - - private static final ChannelBuffer EMPTY_BUFFER = ChannelBuffers.buffer(0); - - - public static ChannelBuffer readPayload(ChannelBuffer buffer) { - if (buffer.readableBytes() < 4) { - buffer.resetReaderIndex(); - return null; - } - - final int payloadLength = buffer.readInt(); - if (payloadLength <= 0) { - return EMPTY_BUFFER; - } - - if (buffer.readableBytes() < payloadLength) { - buffer.resetReaderIndex(); - return null; - } - return buffer.readBytes(payloadLength); - } - - - public static ChannelBuffer appendPayload(final ChannelBuffer header, final byte[] payload) { - if (payload == null) { - // 이건 payload 헤더이긴하다. - header.writeInt(-1); - return header; - } else { - // 이건 payload 헤더이긴하다. - header.writeInt(payload.length); - ChannelBuffer payloadWrap = ChannelBuffers.wrappedBuffer(payload); - return ChannelBuffers.wrappedBuffer(true, header, payloadWrap); - } - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class PayloadPacket { + + private static final Logger logger = LoggerFactory.getLogger(PayloadPacket.class); + + private static final ChannelBuffer EMPTY_BUFFER = ChannelBuffers.buffer(0); + + + public static ChannelBuffer readPayload(ChannelBuffer buffer) { + if (buffer.readableBytes() < 4) { + buffer.resetReaderIndex(); + return null; + } + + final int payloadLength = buffer.readInt(); + if (payloadLength <= 0) { + return EMPTY_BUFFER; + } + + if (buffer.readableBytes() < payloadLength) { + buffer.resetReaderIndex(); + return null; + } + return buffer.readBytes(payloadLength); + } + + + public static ChannelBuffer appendPayload(final ChannelBuffer header, final byte[] payload) { + if (payload == null) { + // 이건 payload 헤더이긴하다. + header.writeInt(-1); + return header; + } else { + // 이건 payload 헤더이긴하다. + header.writeInt(payload.length); + ChannelBuffer payloadWrap = ChannelBuffers.wrappedBuffer(payload); + return ChannelBuffers.wrappedBuffer(true, header, payloadWrap); + } + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PingPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PingPacket.java index 0da3ba9212f4..6653212236c2 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PingPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PingPacket.java @@ -1,45 +1,45 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class PingPacket extends BasicPacket { - - public static final PingPacket PING_PACKET = new PingPacket(); - - static { - ChannelBuffer buffer = ChannelBuffers.buffer(2); - buffer.writeShort(PacketType.CONTROL_PING); - PING_BYTE = buffer.array(); - } - - private static final byte[] PING_BYTE; - - public PingPacket() { - } - - @Override - public short getPacketType() { - return PacketType.CONTROL_PING; - } - - @Override - public ChannelBuffer toBuffer() { - return ChannelBuffers.wrappedBuffer(PING_BYTE); - } - - public static PingPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.CONTROL_PING; - - return PING_PACKET; - } - - @Override - public String toString() { - return "PingPacket"; - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class PingPacket extends BasicPacket { + + public static final PingPacket PING_PACKET = new PingPacket(); + + static { + ChannelBuffer buffer = ChannelBuffers.buffer(2); + buffer.writeShort(PacketType.CONTROL_PING); + PING_BYTE = buffer.array(); + } + + private static final byte[] PING_BYTE; + + public PingPacket() { + } + + @Override + public short getPacketType() { + return PacketType.CONTROL_PING; + } + + @Override + public ChannelBuffer toBuffer() { + return ChannelBuffers.wrappedBuffer(PING_BYTE); + } + + public static PingPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.CONTROL_PING; + + return PING_PACKET; + } + + @Override + public String toString() { + return "PingPacket"; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PongPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PongPacket.java index 4938fd7a0f3f..9fa07acaf15c 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PongPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/PongPacket.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class PongPacket extends BasicPacket { - - public static final PongPacket PONG_PACKET = new PongPacket(); - - static { - ChannelBuffer buffer = ChannelBuffers.buffer(2); - buffer.writeShort(PacketType.CONTROL_PONG); - PONG_BYTE = buffer.array(); - } - - private static final byte[] PONG_BYTE; - - public PongPacket() { - } - - @Override - public short getPacketType() { - return PacketType.CONTROL_PONG; - } - - @Override - public ChannelBuffer toBuffer() { - return ChannelBuffers.wrappedBuffer(PONG_BYTE); - } - - public static PongPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.CONTROL_PONG; - - - return PONG_PACKET; - } - - @Override - public String toString() { - return "PongPacket"; - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class PongPacket extends BasicPacket { + + public static final PongPacket PONG_PACKET = new PongPacket(); + + static { + ChannelBuffer buffer = ChannelBuffers.buffer(2); + buffer.writeShort(PacketType.CONTROL_PONG); + PONG_BYTE = buffer.array(); + } + + private static final byte[] PONG_BYTE; + + public PongPacket() { + } + + @Override + public short getPacketType() { + return PacketType.CONTROL_PONG; + } + + @Override + public ChannelBuffer toBuffer() { + return ChannelBuffers.wrappedBuffer(PONG_BYTE); + } + + public static PongPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.CONTROL_PONG; + + + return PONG_PACKET; + } + + @Override + public String toString() { + return "PongPacket"; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/RequestPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/RequestPacket.java index ebc79a2086c6..88e2122eadbe 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/RequestPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/RequestPacket.java @@ -1,84 +1,84 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class RequestPacket extends BasicPacket { - - private int requestId; - - public RequestPacket() { - } - - public RequestPacket(byte[] payload) { - super(payload); - } - - public RequestPacket(int requestId, byte[] payload) { - super(payload); - this.requestId = requestId; - } - - public int getRequestId() { - return requestId; - } - - public void setRequestId(int requestId) { - this.requestId = requestId; - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_REQUEST; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.APPLICATION_REQUEST); - header.writeInt(requestId); - - - return PayloadPacket.appendPayload(header, payload); - - } - - - public static RequestPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_REQUEST; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int messageId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final RequestPacket requestPacket = new RequestPacket(payload.array()); - requestPacket.setRequestId(messageId); - return requestPacket; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("RequestPacket"); - sb.append("{requestId=").append(requestId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class RequestPacket extends BasicPacket { + + private int requestId; + + public RequestPacket() { + } + + public RequestPacket(byte[] payload) { + super(payload); + } + + public RequestPacket(int requestId, byte[] payload) { + super(payload); + this.requestId = requestId; + } + + public int getRequestId() { + return requestId; + } + + public void setRequestId(int requestId) { + this.requestId = requestId; + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_REQUEST; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.APPLICATION_REQUEST); + header.writeInt(requestId); + + + return PayloadPacket.appendPayload(header, payload); + + } + + + public static RequestPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_REQUEST; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int messageId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final RequestPacket requestPacket = new RequestPacket(payload.array()); + requestPacket.setRequestId(messageId); + return requestPacket; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("RequestPacket"); + sb.append("{requestId=").append(requestId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ResponsePacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ResponsePacket.java index a55c122824be..d32b623348d3 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ResponsePacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ResponsePacket.java @@ -1,82 +1,82 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class ResponsePacket extends BasicPacket { - private int requestId; - - public ResponsePacket() { - } - - public ResponsePacket(byte[] payload) { - super(payload); - } - - public ResponsePacket(int requestId, byte[] payload) { - super(payload); - this.requestId = requestId; - } - - public int getRequestId() { - return requestId; - } - - public void setRequestId(int requestId) { - this.requestId = requestId; - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_RESPONSE; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.APPLICATION_RESPONSE); - header.writeInt(requestId); - - return PayloadPacket.appendPayload(header, payload); - } - - - public static ResponsePacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_RESPONSE; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int messageId = buffer.readInt(); - ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - ResponsePacket responsePacket = new ResponsePacket(payload.array()); - responsePacket.setRequestId(messageId); - - return responsePacket; - - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("ResponsePacket"); - sb.append("{requestId=").append(requestId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class ResponsePacket extends BasicPacket { + private int requestId; + + public ResponsePacket() { + } + + public ResponsePacket(byte[] payload) { + super(payload); + } + + public ResponsePacket(int requestId, byte[] payload) { + super(payload); + this.requestId = requestId; + } + + public int getRequestId() { + return requestId; + } + + public void setRequestId(int requestId) { + this.requestId = requestId; + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_RESPONSE; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.APPLICATION_RESPONSE); + header.writeInt(requestId); + + return PayloadPacket.appendPayload(header, payload); + } + + + public static ResponsePacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_RESPONSE; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int messageId = buffer.readInt(); + ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + ResponsePacket responsePacket = new ResponsePacket(payload.array()); + responsePacket.setRequestId(messageId); + + return responsePacket; + + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("ResponsePacket"); + sb.append("{requestId=").append(requestId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/SendPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/SendPacket.java index 0f76ef94f56e..f837cea3bc1f 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/SendPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/SendPacket.java @@ -1,62 +1,62 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class SendPacket extends BasicPacket { - - - public SendPacket() { - } - - public SendPacket(byte[] payload) { - super(payload); - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_SEND; - } - - @Override - public ChannelBuffer toBuffer() { - ChannelBuffer header = ChannelBuffers.buffer(2 + 4); - header.writeShort(PacketType.APPLICATION_SEND); - - - return PayloadPacket.appendPayload(header, payload); - } - - public static Packet readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_SEND; - - if (buffer.readableBytes() < 4) { - buffer.resetReaderIndex(); - return null; - } - - ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - return new SendPacket(payload.array()); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(64); - sb.append("SendPacket"); - if (payload == null) { - sb.append("{payload=null}"); - } else { - sb.append("{payloadLength=").append(payload.length); - sb.append('}'); - } - - return sb.toString(); - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class SendPacket extends BasicPacket { + + + public SendPacket() { + } + + public SendPacket(byte[] payload) { + super(payload); + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_SEND; + } + + @Override + public ChannelBuffer toBuffer() { + ChannelBuffer header = ChannelBuffers.buffer(2 + 4); + header.writeShort(PacketType.APPLICATION_SEND); + + + return PayloadPacket.appendPayload(header, payload); + } + + public static Packet readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_SEND; + + if (buffer.readableBytes() < 4) { + buffer.resetReaderIndex(); + return null; + } + + ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + return new SendPacket(payload.array()); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(64); + sb.append("SendPacket"); + if (payload == null) { + sb.append("{payload=null}"); + } else { + sb.append("{payloadLength=").append(payload.length); + sb.append('}'); + } + + return sb.toString(); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ServerClosePacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ServerClosePacket.java index f5cc45258cfd..9e0d0cdedd0a 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ServerClosePacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/ServerClosePacket.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class ServerClosePacket extends BasicPacket { - - @Override - public short getPacketType() { - return PacketType.CONTROL_SERVER_CLOSE; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4); - header.writeShort(PacketType.CONTROL_SERVER_CLOSE); - - return PayloadPacket.appendPayload(header, payload); - } - - public static ServerClosePacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.CONTROL_SERVER_CLOSE; - - if (buffer.readableBytes() < 4) { - buffer.resetReaderIndex(); - return null; - } - - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final ServerClosePacket requestPacket = new ServerClosePacket(); - return requestPacket; - - } - - @Override - public String toString() { - return "ServerClosePacket"; - } -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class ServerClosePacket extends BasicPacket { + + @Override + public short getPacketType() { + return PacketType.CONTROL_SERVER_CLOSE; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4); + header.writeShort(PacketType.CONTROL_SERVER_CLOSE); + + return PayloadPacket.appendPayload(header, payload); + } + + public static ServerClosePacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.CONTROL_SERVER_CLOSE; + + if (buffer.readableBytes() < 4) { + buffer.resetReaderIndex(); + return null; + } + + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final ServerClosePacket requestPacket = new ServerClosePacket(); + return requestPacket; + + } + + @Override + public String toString() { + return "ServerClosePacket"; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamClosePacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamClosePacket.java index 40188e1e2b8a..46e78ea89f8a 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamClosePacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamClosePacket.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class StreamClosePacket extends BasicStreamPacket { - - public StreamClosePacket(int channelId) { - super(channelId); - } - - public StreamClosePacket(byte[] payload) { - super(payload); - } - - public StreamClosePacket(int channelId, byte[] payload) { - super(channelId, payload); - } - - - @Override - public short getPacketType() { - return PacketType.APPLICATION_STREAM_CLOSE; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.APPLICATION_STREAM_CLOSE); - header.writeInt(channelId); - - return PayloadPacket.appendPayload(header, payload); - } - - - public static StreamClosePacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_STREAM_CLOSE; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int streamId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final StreamClosePacket streamClosePacket = new StreamClosePacket(payload.array()); - streamClosePacket.setChannelId(streamId); - return streamClosePacket; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("StreamClosePacket"); - sb.append("{channelId=").append(channelId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class StreamClosePacket extends BasicStreamPacket { + + public StreamClosePacket(int channelId) { + super(channelId); + } + + public StreamClosePacket(byte[] payload) { + super(payload); + } + + public StreamClosePacket(int channelId, byte[] payload) { + super(channelId, payload); + } + + + @Override + public short getPacketType() { + return PacketType.APPLICATION_STREAM_CLOSE; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.APPLICATION_STREAM_CLOSE); + header.writeInt(channelId); + + return PayloadPacket.appendPayload(header, payload); + } + + + public static StreamClosePacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_STREAM_CLOSE; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int streamId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final StreamClosePacket streamClosePacket = new StreamClosePacket(payload.array()); + streamClosePacket.setChannelId(streamId); + return streamClosePacket; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("StreamClosePacket"); + sb.append("{channelId=").append(channelId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateFailPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateFailPacket.java index 8576f2284e5c..8bdadf226979 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateFailPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateFailPacket.java @@ -1,75 +1,75 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class StreamCreateFailPacket extends BasicStreamPacket { - - private int channelId; - - public StreamCreateFailPacket(int channelId) { - super(channelId); - } - - public StreamCreateFailPacket(byte[] payload) { - super(payload); - } - - public StreamCreateFailPacket(int channelId, byte[] payload) { - super(channelId, payload); - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_STREAM_CREATE_FAIL; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - - header.writeShort(PacketType.APPLICATION_STREAM_CREATE_FAIL); - header.writeInt(channelId); - - return PayloadPacket.appendPayload(header, payload); - } - - public static StreamCreateFailPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_STREAM_CREATE_FAIL; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int streamId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final StreamCreateFailPacket streamCreatePacket = new StreamCreateFailPacket(payload.array()); - streamCreatePacket.setChannelId(streamId); - return streamCreatePacket; - } - - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("StreamCreateFailPacket"); - sb.append("{channelId=").append(channelId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class StreamCreateFailPacket extends BasicStreamPacket { + + private int channelId; + + public StreamCreateFailPacket(int channelId) { + super(channelId); + } + + public StreamCreateFailPacket(byte[] payload) { + super(payload); + } + + public StreamCreateFailPacket(int channelId, byte[] payload) { + super(channelId, payload); + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_STREAM_CREATE_FAIL; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + + header.writeShort(PacketType.APPLICATION_STREAM_CREATE_FAIL); + header.writeInt(channelId); + + return PayloadPacket.appendPayload(header, payload); + } + + public static StreamCreateFailPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_STREAM_CREATE_FAIL; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int streamId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final StreamCreateFailPacket streamCreatePacket = new StreamCreateFailPacket(payload.array()); + streamCreatePacket.setChannelId(streamId); + return streamCreatePacket; + } + + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("StreamCreateFailPacket"); + sb.append("{channelId=").append(channelId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreatePacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreatePacket.java index c1dad324a7b1..275a51cd793f 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreatePacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreatePacket.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class StreamCreatePacket extends BasicStreamPacket { - - public StreamCreatePacket(int channelId) { - super(channelId); - } - - public StreamCreatePacket(byte[] payload) { - super(payload); - } - - public StreamCreatePacket(int channelId, byte[] payload) { - super(channelId, payload); - } - - - @Override - public short getPacketType() { - return PacketType.APPLICATION_STREAM_CREATE; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.APPLICATION_STREAM_CREATE); - header.writeInt(channelId); - - return PayloadPacket.appendPayload(header, payload); - } - - - public static StreamCreatePacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_STREAM_CREATE; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int channelId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final StreamCreatePacket streamCreatePacket = new StreamCreatePacket(payload.array()); - streamCreatePacket.setChannelId(channelId); - return streamCreatePacket; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("StreamCreatePacket"); - sb.append("{channelId=").append(channelId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class StreamCreatePacket extends BasicStreamPacket { + + public StreamCreatePacket(int channelId) { + super(channelId); + } + + public StreamCreatePacket(byte[] payload) { + super(payload); + } + + public StreamCreatePacket(int channelId, byte[] payload) { + super(channelId, payload); + } + + + @Override + public short getPacketType() { + return PacketType.APPLICATION_STREAM_CREATE; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.APPLICATION_STREAM_CREATE); + header.writeInt(channelId); + + return PayloadPacket.appendPayload(header, payload); + } + + + public static StreamCreatePacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_STREAM_CREATE; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int channelId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final StreamCreatePacket streamCreatePacket = new StreamCreatePacket(payload.array()); + streamCreatePacket.setChannelId(channelId); + return streamCreatePacket; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("StreamCreatePacket"); + sb.append("{channelId=").append(channelId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateSuccessPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateSuccessPacket.java index 6269a220d9b4..d8920c1f16c2 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateSuccessPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamCreateSuccessPacket.java @@ -1,72 +1,72 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class StreamCreateSuccessPacket extends BasicStreamPacket { - - public StreamCreateSuccessPacket(int channelId) { - super(channelId); - } - - public StreamCreateSuccessPacket(byte[] payload) { - super(payload); - } - - public StreamCreateSuccessPacket(int channelId, byte[] payload) { - super(channelId, payload); - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_STREAM_CREATE_SUCCESS; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - - header.writeShort(PacketType.APPLICATION_STREAM_CREATE_SUCCESS); - header.writeInt(channelId); - - return PayloadPacket.appendPayload(header, payload); - } - - public static StreamCreateSuccessPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_STREAM_CREATE_SUCCESS; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int streamId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final StreamCreateSuccessPacket streamCreatePacket = new StreamCreateSuccessPacket(payload.array()); - streamCreatePacket.setChannelId(streamId); - return streamCreatePacket; - } - - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("StreamCreateSuccessPacket"); - sb.append("{channelId=").append(channelId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class StreamCreateSuccessPacket extends BasicStreamPacket { + + public StreamCreateSuccessPacket(int channelId) { + super(channelId); + } + + public StreamCreateSuccessPacket(byte[] payload) { + super(payload); + } + + public StreamCreateSuccessPacket(int channelId, byte[] payload) { + super(channelId, payload); + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_STREAM_CREATE_SUCCESS; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + + header.writeShort(PacketType.APPLICATION_STREAM_CREATE_SUCCESS); + header.writeInt(channelId); + + return PayloadPacket.appendPayload(header, payload); + } + + public static StreamCreateSuccessPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_STREAM_CREATE_SUCCESS; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int streamId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final StreamCreateSuccessPacket streamCreatePacket = new StreamCreateSuccessPacket(payload.array()); + streamCreatePacket.setChannelId(streamId); + return streamCreatePacket; + } + + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("StreamCreateSuccessPacket"); + sb.append("{channelId=").append(channelId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamPacket.java index d4c4feabcf71..136e8a907020 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamPacket.java @@ -1,9 +1,9 @@ -package com.nhn.pinpoint.rpc.packet; - -/** - * type marker - */ -public interface StreamPacket extends Packet { - int getChannelId(); - -} +package com.nhn.pinpoint.rpc.packet; + +/** + * type marker + */ +public interface StreamPacket extends Packet { + int getChannelId(); + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamResponsePacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamResponsePacket.java index c1d0048e3375..abd14dc32aca 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamResponsePacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/StreamResponsePacket.java @@ -1,71 +1,71 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class StreamResponsePacket extends BasicStreamPacket { - - public StreamResponsePacket(int channelId) { - super(channelId); - } - - public StreamResponsePacket(byte[] payload) { - super(payload); - } - - public StreamResponsePacket(int channelId, byte[] payload) { - super(channelId, payload); - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_STREAM_RESPONSE; - } - - @Override - public ChannelBuffer toBuffer() { - - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.APPLICATION_STREAM_RESPONSE); - header.writeInt(channelId); - - return PayloadPacket.appendPayload(header, payload); - } - - - public static StreamResponsePacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_STREAM_RESPONSE; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int channelId = buffer.readInt(); - final ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - final StreamResponsePacket streamResponsePacket = new StreamResponsePacket(payload.array()); - streamResponsePacket.setChannelId(channelId); - return streamResponsePacket; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("StreamResponsePacket"); - sb.append("{channelId=").append(channelId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null"); - } else { - sb.append("payloadLength=").append(payload.length); - } - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class StreamResponsePacket extends BasicStreamPacket { + + public StreamResponsePacket(int channelId) { + super(channelId); + } + + public StreamResponsePacket(byte[] payload) { + super(payload); + } + + public StreamResponsePacket(int channelId, byte[] payload) { + super(channelId, payload); + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_STREAM_RESPONSE; + } + + @Override + public ChannelBuffer toBuffer() { + + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.APPLICATION_STREAM_RESPONSE); + header.writeInt(channelId); + + return PayloadPacket.appendPayload(header, payload); + } + + + public static StreamResponsePacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_STREAM_RESPONSE; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int channelId = buffer.readInt(); + final ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + final StreamResponsePacket streamResponsePacket = new StreamResponsePacket(payload.array()); + streamResponsePacket.setChannelId(channelId); + return streamResponsePacket; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("StreamResponsePacket"); + sb.append("{channelId=").append(channelId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null"); + } else { + sb.append("payloadLength=").append(payload.length); + } + sb.append('}'); + return sb.toString(); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendAckPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendAckPacket.java index c48e6db769e8..3ab9b5e2c085 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendAckPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendAckPacket.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ - -public class TraceSendAckPacket implements Packet { - private int traceId; - - public TraceSendAckPacket() { - } - - public TraceSendAckPacket(int traceId) { - this.traceId = traceId; - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_TRACE_SEND_ACK; - } - - @Override - public byte[] getPayload() { - return new byte[0]; - } - - @Override - public ChannelBuffer toBuffer() { - ChannelBuffer header = ChannelBuffers.buffer(2 + 4); - header.writeShort(PacketType.APPLICATION_TRACE_SEND_ACK); - header.writeInt(traceId); - - return header; - } - - public static TraceSendAckPacket readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_TRACE_SEND_ACK; - - if (buffer.readableBytes() < 4) { - buffer.resetReaderIndex(); - return null; - } - - final int traceId = buffer.readInt(); - return new TraceSendAckPacket(traceId); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(64); - sb.append("TraceSendAckPacket"); - sb.append("{traceId=").append(traceId); - sb.append('}'); - return sb.toString(); - } - +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ + +public class TraceSendAckPacket implements Packet { + private int traceId; + + public TraceSendAckPacket() { + } + + public TraceSendAckPacket(int traceId) { + this.traceId = traceId; + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_TRACE_SEND_ACK; + } + + @Override + public byte[] getPayload() { + return new byte[0]; + } + + @Override + public ChannelBuffer toBuffer() { + ChannelBuffer header = ChannelBuffers.buffer(2 + 4); + header.writeShort(PacketType.APPLICATION_TRACE_SEND_ACK); + header.writeInt(traceId); + + return header; + } + + public static TraceSendAckPacket readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_TRACE_SEND_ACK; + + if (buffer.readableBytes() < 4) { + buffer.resetReaderIndex(); + return null; + } + + final int traceId = buffer.readInt(); + return new TraceSendAckPacket(traceId); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(64); + sb.append("TraceSendAckPacket"); + sb.append("{traceId=").append(traceId); + sb.append('}'); + return sb.toString(); + } + } \ No newline at end of file diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendPacket.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendPacket.java index 22db0eccc767..da813682ceea 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendPacket.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/packet/TraceSendPacket.java @@ -1,77 +1,77 @@ -package com.nhn.pinpoint.rpc.packet; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; - -/** - * @author emeroad - */ -public class TraceSendPacket extends SendPacket { - private int traceId; - - public TraceSendPacket() { - } - - public TraceSendPacket(byte[] payload) { - super(payload); - } - public TraceSendPacket(int traceId, byte[] payload) { - super(payload); - this.traceId = traceId; - } - - public int getTraceId() { - return traceId; - } - - public void setTraceId(int traceId) { - this.traceId = traceId; - } - - @Override - public short getPacketType() { - return PacketType.APPLICATION_TRACE_SEND; - } - - @Override - public ChannelBuffer toBuffer() { - ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); - header.writeShort(PacketType.APPLICATION_TRACE_SEND); - header.writeInt(traceId); - - return PayloadPacket.appendPayload(header, payload); - } - - public static Packet readBuffer(short packetType, ChannelBuffer buffer) { - assert packetType == PacketType.APPLICATION_TRACE_SEND; - - if (buffer.readableBytes() < 8) { - buffer.resetReaderIndex(); - return null; - } - - final int traceId = buffer.readInt(); - ChannelBuffer payload = PayloadPacket.readPayload(buffer); - if (payload == null) { - return null; - } - return new TraceSendPacket(traceId, payload.array()); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(64); - sb.append("TraceSendPacket"); - sb.append("{traceId=").append(traceId); - sb.append(", "); - if (payload == null) { - sb.append("payload=null}"); - } else { - sb.append("payloadLength=").append(payload.length); - sb.append('}'); - } - - return sb.toString(); - } - -} +package com.nhn.pinpoint.rpc.packet; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; + +/** + * @author emeroad + */ +public class TraceSendPacket extends SendPacket { + private int traceId; + + public TraceSendPacket() { + } + + public TraceSendPacket(byte[] payload) { + super(payload); + } + public TraceSendPacket(int traceId, byte[] payload) { + super(payload); + this.traceId = traceId; + } + + public int getTraceId() { + return traceId; + } + + public void setTraceId(int traceId) { + this.traceId = traceId; + } + + @Override + public short getPacketType() { + return PacketType.APPLICATION_TRACE_SEND; + } + + @Override + public ChannelBuffer toBuffer() { + ChannelBuffer header = ChannelBuffers.buffer(2 + 4 + 4); + header.writeShort(PacketType.APPLICATION_TRACE_SEND); + header.writeInt(traceId); + + return PayloadPacket.appendPayload(header, payload); + } + + public static Packet readBuffer(short packetType, ChannelBuffer buffer) { + assert packetType == PacketType.APPLICATION_TRACE_SEND; + + if (buffer.readableBytes() < 8) { + buffer.resetReaderIndex(); + return null; + } + + final int traceId = buffer.readInt(); + ChannelBuffer payload = PayloadPacket.readPayload(buffer); + if (payload == null) { + return null; + } + return new TraceSendPacket(traceId, payload.array()); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(64); + sb.append("TraceSendPacket"); + sb.append("{traceId=").append(traceId); + sb.append(", "); + if (payload == null) { + sb.append("payload=null}"); + } else { + sb.append("payloadLength=").append(payload.length); + sb.append('}'); + } + + return sb.toString(); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateCode.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateCode.java index 4bbbd190e2f5..678fd88d7b60 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateCode.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateCode.java @@ -1,84 +1,84 @@ -package com.nhn.pinpoint.rpc.server; - -import java.util.HashSet; -import java.util.Set; - -/** - * @author koo.taejin - */ -public enum PinpointServerSocketStateCode { - - // 상태는 다음과 같다. - // NONE : 아무 이벤트가 없는 상태 - // RUN : 서버로 메시지를 보내는 것만 가능한 Socket 상태 - // RUN_DUPLEX_COMMUNICATION : 양방향 통신이 가능한 Socket 상태 (서버로 메시지를 보내는 것 서버가 보낸 메시지를 처리하는 것 ) - // BEING_SHUTDOWN : CLOSE 등의 명령을 받고 연결을 종료를 대기하는 상태 - // SHUTDOWN : 내가 끊거나 종료대기가 되어있는 상태일때 종료 - // UNEXPECTED_SHUTDOWN : CLOSE 등의 명령을 받지 못한 상태에서 상대방이 연결을 종료하였을떄 - - NONE(), - RUN(NONE), //Simplex Communication - RUN_DUPLEX_COMMUNICATION(NONE, RUN), - BEING_SHUTDOWN(RUN_DUPLEX_COMMUNICATION, RUN), - SHUTDOWN(RUN_DUPLEX_COMMUNICATION, RUN, BEING_SHUTDOWN), - UNEXPECTED_SHUTDOWN(RUN_DUPLEX_COMMUNICATION, RUN), - - // 서버쪽에서 먼저 연결을 끊자는 메시지도 필요하다. - // 예를 들어 HELLO 이후 다 확인했는데, 같은 Agent명이 있으면(?) 이걸 사용자에게 말해야 할까? 아닐까? 알림 등 - ERROR_UNKOWN(RUN_DUPLEX_COMMUNICATION, RUN), - ERROR_ILLEGAL_STATE_CHANGE(NONE, RUN_DUPLEX_COMMUNICATION, RUN, BEING_SHUTDOWN); - - private final Set validBeforeStateSet; - - private PinpointServerSocketStateCode(PinpointServerSocketStateCode... validBeforeStates) { - this.validBeforeStateSet = new HashSet(); - - if (validBeforeStates != null) { - for (PinpointServerSocketStateCode eachStateCode : validBeforeStates) { - getValidBeforeStateSet().add(eachStateCode); - } - } - } - - public boolean canChangeState(PinpointServerSocketStateCode nextState) { - Set validBeforeStateSet = nextState.getValidBeforeStateSet(); - - if (validBeforeStateSet.contains(this)) { - return true; - } - - return false; - } - - public Set getValidBeforeStateSet() { - return validBeforeStateSet; - } - - public static boolean isRun(PinpointServerSocketStateCode code) { - if (code == RUN_DUPLEX_COMMUNICATION || code == RUN) { - return true; - } - - return false; - } - - public static boolean isFinished(PinpointServerSocketStateCode code) { - if (code == SHUTDOWN || code == UNEXPECTED_SHUTDOWN || code == ERROR_UNKOWN || code == ERROR_ILLEGAL_STATE_CHANGE) { - return true; - } - return false; - } - - public static PinpointServerSocketStateCode getStateCode(String name) { - PinpointServerSocketStateCode[] allStateCodes = PinpointServerSocketStateCode.values(); - - for (PinpointServerSocketStateCode code : allStateCodes) { - if (code.name().equalsIgnoreCase(name)) { - return code; - } - } - - return null; - } - -} +package com.nhn.pinpoint.rpc.server; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author koo.taejin + */ +public enum PinpointServerSocketStateCode { + + // 상태는 다음과 같다. + // NONE : 아무 이벤트가 없는 상태 + // RUN : 서버로 메시지를 보내는 것만 가능한 Socket 상태 + // RUN_DUPLEX_COMMUNICATION : 양방향 통신이 가능한 Socket 상태 (서버로 메시지를 보내는 것 서버가 보낸 메시지를 처리하는 것 ) + // BEING_SHUTDOWN : CLOSE 등의 명령을 받고 연결을 종료를 대기하는 상태 + // SHUTDOWN : 내가 끊거나 종료대기가 되어있는 상태일때 종료 + // UNEXPECTED_SHUTDOWN : CLOSE 등의 명령을 받지 못한 상태에서 상대방이 연결을 종료하였을떄 + + NONE(), + RUN(NONE), //Simplex Communication + RUN_DUPLEX_COMMUNICATION(NONE, RUN), + BEING_SHUTDOWN(RUN_DUPLEX_COMMUNICATION, RUN), + SHUTDOWN(RUN_DUPLEX_COMMUNICATION, RUN, BEING_SHUTDOWN), + UNEXPECTED_SHUTDOWN(RUN_DUPLEX_COMMUNICATION, RUN), + + // 서버쪽에서 먼저 연결을 끊자는 메시지도 필요하다. + // 예를 들어 HELLO 이후 다 확인했는데, 같은 Agent명이 있으면(?) 이걸 사용자에게 말해야 할까? 아닐까? 알림 등 + ERROR_UNKOWN(RUN_DUPLEX_COMMUNICATION, RUN), + ERROR_ILLEGAL_STATE_CHANGE(NONE, RUN_DUPLEX_COMMUNICATION, RUN, BEING_SHUTDOWN); + + private final Set validBeforeStateSet; + + private PinpointServerSocketStateCode(PinpointServerSocketStateCode... validBeforeStates) { + this.validBeforeStateSet = new HashSet(); + + if (validBeforeStates != null) { + for (PinpointServerSocketStateCode eachStateCode : validBeforeStates) { + getValidBeforeStateSet().add(eachStateCode); + } + } + } + + public boolean canChangeState(PinpointServerSocketStateCode nextState) { + Set validBeforeStateSet = nextState.getValidBeforeStateSet(); + + if (validBeforeStateSet.contains(this)) { + return true; + } + + return false; + } + + public Set getValidBeforeStateSet() { + return validBeforeStateSet; + } + + public static boolean isRun(PinpointServerSocketStateCode code) { + if (code == RUN_DUPLEX_COMMUNICATION || code == RUN) { + return true; + } + + return false; + } + + public static boolean isFinished(PinpointServerSocketStateCode code) { + if (code == SHUTDOWN || code == UNEXPECTED_SHUTDOWN || code == ERROR_UNKOWN || code == ERROR_ILLEGAL_STATE_CHANGE) { + return true; + } + return false; + } + + public static PinpointServerSocketStateCode getStateCode(String name) { + PinpointServerSocketStateCode[] allStateCodes = PinpointServerSocketStateCode.values(); + + for (PinpointServerSocketStateCode code : allStateCodes) { + if (code.name().equalsIgnoreCase(name)) { + return code; + } + } + + return null; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerMessageListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerMessageListener.java index 82d693ca7b20..eb718fdaa1ae 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerMessageListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerMessageListener.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.rpc.server; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; - -/** - * @author emeroad - */ -public interface ServerMessageListener { - - void handleSend(SendPacket sendPacket, SocketChannel channel); - // 외부 노출 Channel은 별도의 Tcp Channel로 감싸는걸로 변경할 것. - void handleRequest(RequestPacket requestPacket, SocketChannel channel); - - void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel); - - int handleEnableWorker(Map properties); - -} +package com.nhn.pinpoint.rpc.server; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; + +/** + * @author emeroad + */ +public interface ServerMessageListener { + + void handleSend(SendPacket sendPacket, SocketChannel channel); + // 외부 노출 Channel은 별도의 Tcp Channel로 감싸는걸로 변경할 것. + void handleRequest(RequestPacket requestPacket, SocketChannel channel); + + void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel); + + int handleEnableWorker(Map properties); + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerPipelineFactory.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerPipelineFactory.java index 44aba6ee352a..bdc8dd0607e6 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerPipelineFactory.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerPipelineFactory.java @@ -1,33 +1,33 @@ -package com.nhn.pinpoint.rpc.server; - - -import com.nhn.pinpoint.rpc.codec.PacketDecoder; -import com.nhn.pinpoint.rpc.codec.PacketEncoder; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; - -/** - * @author emeroad - */ -public class ServerPipelineFactory implements ChannelPipelineFactory { - private PinpointServerSocket serverSocket; - - public ServerPipelineFactory(PinpointServerSocket pinpointServerSocket) { - if (pinpointServerSocket == null) { - throw new NullPointerException("pinpointServerSocket"); - } - this.serverSocket = pinpointServerSocket; - } - - @Override - public ChannelPipeline getPipeline() throws Exception { - ChannelPipeline pipeline = Channels.pipeline(); - - pipeline.addLast("decoder", new PacketDecoder()); - pipeline.addLast("encoder", new PacketEncoder()); - pipeline.addLast("handler", serverSocket); - - return pipeline; - } -} +package com.nhn.pinpoint.rpc.server; + + +import com.nhn.pinpoint.rpc.codec.PacketDecoder; +import com.nhn.pinpoint.rpc.codec.PacketEncoder; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; + +/** + * @author emeroad + */ +public class ServerPipelineFactory implements ChannelPipelineFactory { + private PinpointServerSocket serverSocket; + + public ServerPipelineFactory(PinpointServerSocket pinpointServerSocket) { + if (pinpointServerSocket == null) { + throw new NullPointerException("pinpointServerSocket"); + } + this.serverSocket = pinpointServerSocket; + } + + @Override + public ChannelPipeline getPipeline() throws Exception { + ChannelPipeline pipeline = Channels.pipeline(); + + pipeline.addLast("decoder", new PacketDecoder()); + pipeline.addLast("encoder", new PacketEncoder()); + pipeline.addLast("handler", serverSocket); + + return pipeline; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannel.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannel.java index 7363e70e1415..08d6886f6789 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannel.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannel.java @@ -1,154 +1,154 @@ -package com.nhn.pinpoint.rpc.server; - -import com.nhn.pinpoint.rpc.packet.*; -import org.jboss.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author emeroad - */ -public class ServerStreamChannel { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private static final int NONE = 0; - // OPEN이 도착함. - private static final int OPEN_ARRIVED = 1; - // create success 던짐. 동작중 - private static final int RUN = 2; - // 닫힘 - private static final int CLOSED = 2; - - private final AtomicInteger state = new AtomicInteger(NONE); - - private final int channelId; - - private ServerStreamChannelManager serverStreamChannelManager; - - private Channel channel; - - public ServerStreamChannel(int channelId) { - this.channelId = channelId; - } - - public int getChannelId() { - return channelId; - } - - public void setChannel(Channel channel) { - this.channel = channel; - } - - -// public boolean receiveStreamPacket(StreamPacket packet) { -// final short packetType = packet.getPacketType(); -// switch (packetType) { -// case PacketType.APPLICATION_STREAM_CREATE: -// logger.info("APPLICATION_STREAM_CREATE_SUCCESS"); -// return receiveChannelCreate((StreamCreatePacket) packet); -// } -// return false; -// } - - public boolean receiveChannelCreate(StreamCreatePacket streamCreateResponse) { - if (state.compareAndSet(NONE, OPEN_ARRIVED)) { - return true; - } else { - logger.info("invalid state:{}", state.get()); - return false; - } - } - - public boolean sendOpenResult(boolean success, byte[] bytes) { - if(success ) { - if(!state.compareAndSet(OPEN_ARRIVED, RUN)) { - return false; - } - StreamCreateSuccessPacket streamCreateSuccessPacket = new StreamCreateSuccessPacket(channelId, bytes); - this.channel.write(streamCreateSuccessPacket); - return true; - } else { - if(!state.compareAndSet(OPEN_ARRIVED, CLOSED)) { - return false; - } - StreamCreateFailPacket streamCreateFailPacket = new StreamCreateFailPacket(channelId, bytes); - this.channel.write(streamCreateFailPacket); - return true; - } - } - - public boolean sendStreamMessage(byte[] bytes) { - if (state.get() != RUN) { - return false; - } - StreamResponsePacket response = new StreamResponsePacket(bytes); - this.channel.write(response); - return true; - } - - - public boolean close() { - return close0(true); - } - - boolean closeInternal() { - return close0(false); - } - - private boolean close0(boolean safeClose) { - if (!state.compareAndSet(RUN, CLOSED)) { - return false; - } - - if (safeClose) { - StreamClosePacket streamClosePacket = new StreamClosePacket(channelId); - this.channel.write(streamClosePacket); - - ServerStreamChannelManager serverStreamChannelManager = this.serverStreamChannelManager; - if (serverStreamChannelManager != null) { - serverStreamChannelManager.closeChannel(channelId); - this.serverStreamChannelManager = null; - } - } - return true; - } - - public void setServerStreamChannelManager(ServerStreamChannelManager serverStreamChannelManager) { - this.serverStreamChannelManager = serverStreamChannelManager; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ServerStreamChannel that = (ServerStreamChannel) o; - - if (channelId != that.channelId) return false; - if (channel != null ? !channel.equals(that.channel) : that.channel != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = channelId; - result = 31 * result + (channel != null ? channel.hashCode() : 0); - return result; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("ServerStreamChannel"); - sb.append("{state=").append(state); - sb.append(", channelId=").append(channelId); - sb.append(", channel=").append(channel); - sb.append('}'); - return sb.toString(); - } -} - +package com.nhn.pinpoint.rpc.server; + +import com.nhn.pinpoint.rpc.packet.*; +import org.jboss.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author emeroad + */ +public class ServerStreamChannel { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final int NONE = 0; + // OPEN이 도착함. + private static final int OPEN_ARRIVED = 1; + // create success 던짐. 동작중 + private static final int RUN = 2; + // 닫힘 + private static final int CLOSED = 2; + + private final AtomicInteger state = new AtomicInteger(NONE); + + private final int channelId; + + private ServerStreamChannelManager serverStreamChannelManager; + + private Channel channel; + + public ServerStreamChannel(int channelId) { + this.channelId = channelId; + } + + public int getChannelId() { + return channelId; + } + + public void setChannel(Channel channel) { + this.channel = channel; + } + + +// public boolean receiveStreamPacket(StreamPacket packet) { +// final short packetType = packet.getPacketType(); +// switch (packetType) { +// case PacketType.APPLICATION_STREAM_CREATE: +// logger.info("APPLICATION_STREAM_CREATE_SUCCESS"); +// return receiveChannelCreate((StreamCreatePacket) packet); +// } +// return false; +// } + + public boolean receiveChannelCreate(StreamCreatePacket streamCreateResponse) { + if (state.compareAndSet(NONE, OPEN_ARRIVED)) { + return true; + } else { + logger.info("invalid state:{}", state.get()); + return false; + } + } + + public boolean sendOpenResult(boolean success, byte[] bytes) { + if(success ) { + if(!state.compareAndSet(OPEN_ARRIVED, RUN)) { + return false; + } + StreamCreateSuccessPacket streamCreateSuccessPacket = new StreamCreateSuccessPacket(channelId, bytes); + this.channel.write(streamCreateSuccessPacket); + return true; + } else { + if(!state.compareAndSet(OPEN_ARRIVED, CLOSED)) { + return false; + } + StreamCreateFailPacket streamCreateFailPacket = new StreamCreateFailPacket(channelId, bytes); + this.channel.write(streamCreateFailPacket); + return true; + } + } + + public boolean sendStreamMessage(byte[] bytes) { + if (state.get() != RUN) { + return false; + } + StreamResponsePacket response = new StreamResponsePacket(bytes); + this.channel.write(response); + return true; + } + + + public boolean close() { + return close0(true); + } + + boolean closeInternal() { + return close0(false); + } + + private boolean close0(boolean safeClose) { + if (!state.compareAndSet(RUN, CLOSED)) { + return false; + } + + if (safeClose) { + StreamClosePacket streamClosePacket = new StreamClosePacket(channelId); + this.channel.write(streamClosePacket); + + ServerStreamChannelManager serverStreamChannelManager = this.serverStreamChannelManager; + if (serverStreamChannelManager != null) { + serverStreamChannelManager.closeChannel(channelId); + this.serverStreamChannelManager = null; + } + } + return true; + } + + public void setServerStreamChannelManager(ServerStreamChannelManager serverStreamChannelManager) { + this.serverStreamChannelManager = serverStreamChannelManager; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ServerStreamChannel that = (ServerStreamChannel) o; + + if (channelId != that.channelId) return false; + if (channel != null ? !channel.equals(that.channel) : that.channel != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = channelId; + result = 31 * result + (channel != null ? channel.hashCode() : 0); + return result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("ServerStreamChannel"); + sb.append("{state=").append(state); + sb.append(", channelId=").append(channelId); + sb.append(", channel=").append(channel); + sb.append('}'); + return sb.toString(); + } +} + diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannelManager.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannelManager.java index 731412649bc8..cef0ef09fff8 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannelManager.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/ServerStreamChannelManager.java @@ -1,65 +1,65 @@ -package com.nhn.pinpoint.rpc.server; - -import com.nhn.pinpoint.rpc.PinpointSocketException; -import org.jboss.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author emeroad - */ -public class ServerStreamChannelManager { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Channel channel; - private final ConcurrentMap channelMap = new ConcurrentHashMap(); - - public ServerStreamChannelManager(Channel channel) { - if (channel == null) { - throw new NullPointerException("channel"); - } - this.channel = channel; - } - - public ServerStreamChannel createStreamChannel(int channelId) { - ServerStreamChannel streamChannel = new ServerStreamChannel(channelId); - streamChannel.setChannel(channel); - - ServerStreamChannel old = channelMap.put(channelId, streamChannel); - if (old != null) { - throw new PinpointSocketException("already channelId exist:" + channelId + " streamChannel:" + old); - } - // handle을 붙여서 리턴. - streamChannel.setServerStreamChannelManager(this); - - return streamChannel; - } - - - public ServerStreamChannel findStreamChannel(int channelId) { - return this.channelMap.get(channelId); - } - - public boolean closeChannel(int channelId) { - ServerStreamChannel remove = this.channelMap.remove(channelId); - return remove != null; - } - - - public void closeInternal() { - final boolean debugEnabled = logger.isDebugEnabled(); - for (Map.Entry streamChannel : this.channelMap.entrySet()) { - streamChannel.getValue().closeInternal(); - if (debugEnabled) { - logger.debug("ServerStreamChannel.closeInternal() id:{}, {}", streamChannel.getKey(), channel); - } - } - - - } -} +package com.nhn.pinpoint.rpc.server; + +import com.nhn.pinpoint.rpc.PinpointSocketException; +import org.jboss.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author emeroad + */ +public class ServerStreamChannelManager { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Channel channel; + private final ConcurrentMap channelMap = new ConcurrentHashMap(); + + public ServerStreamChannelManager(Channel channel) { + if (channel == null) { + throw new NullPointerException("channel"); + } + this.channel = channel; + } + + public ServerStreamChannel createStreamChannel(int channelId) { + ServerStreamChannel streamChannel = new ServerStreamChannel(channelId); + streamChannel.setChannel(channel); + + ServerStreamChannel old = channelMap.put(channelId, streamChannel); + if (old != null) { + throw new PinpointSocketException("already channelId exist:" + channelId + " streamChannel:" + old); + } + // handle을 붙여서 리턴. + streamChannel.setServerStreamChannelManager(this); + + return streamChannel; + } + + + public ServerStreamChannel findStreamChannel(int channelId) { + return this.channelMap.get(channelId); + } + + public boolean closeChannel(int channelId) { + ServerStreamChannel remove = this.channelMap.remove(channelId); + return remove != null; + } + + + public void closeInternal() { + final boolean debugEnabled = logger.isDebugEnabled(); + for (Map.Entry streamChannel : this.channelMap.entrySet()) { + streamChannel.getValue().closeInternal(); + if (debugEnabled) { + logger.debug("ServerStreamChannel.closeInternal() id:{}, {}", streamChannel.getKey(), channel); + } + } + + + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/SimpleLoggingServerMessageListener.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/SimpleLoggingServerMessageListener.java index 42d0b72c3cb9..71d236ddc30b 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/SimpleLoggingServerMessageListener.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/server/SimpleLoggingServerMessageListener.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.rpc.server; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class SimpleLoggingServerMessageListener implements ServerMessageListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final SimpleLoggingServerMessageListener LISTENER = new SimpleLoggingServerMessageListener(); - - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - logger.info("handlerSend {} {}", sendPacket, channel); - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - logger.info("handlerRequest {} {}", requestPacket, channel); - } - - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.info("handlerStream {} {}", streamChannel, streamChannel); - } - - @Override - public int handleEnableWorker(Map properties) { - logger.info("handleEnableWorker {}", properties); - return ControlEnableWorkerConfirmPacket.SUCCESS; - } - -} +package com.nhn.pinpoint.rpc.server; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class SimpleLoggingServerMessageListener implements ServerMessageListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final SimpleLoggingServerMessageListener LISTENER = new SimpleLoggingServerMessageListener(); + + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.info("handlerSend {} {}", sendPacket, channel); + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.info("handlerRequest {} {}", requestPacket, channel); + } + + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.info("handlerStream {} {}", streamChannel, streamChannel); + } + + @Override + public int handleEnableWorker(Map properties) { + logger.info("handleEnableWorker {}", properties); + return ControlEnableWorkerConfirmPacket.SUCCESS; + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/AssertUtils.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/AssertUtils.java index b02be0fd87ff..0fb5aefcb79f 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/AssertUtils.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/AssertUtils.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.rpc.util; - -/** - * @author koo.taejin - */ -public final class AssertUtils { - - private AssertUtils() { - } - - public static void assertNotNull(Object object) { - assertNotNull(object, "Object may not be null."); - } - - public static void assertNotNull(Object object, String message) { - if (object == null) { - throw new NullPointerException(message); - } - } - - public static void assertNotNull(Object object, T throwable) throws T { - if (object == null) { - throw throwable; - } - } - -} +package com.nhn.pinpoint.rpc.util; + +/** + * @author koo.taejin + */ +public final class AssertUtils { + + private AssertUtils() { + } + + public static void assertNotNull(Object object) { + assertNotNull(object, "Object may not be null."); + } + + public static void assertNotNull(Object object, String message) { + if (object == null) { + throw new NullPointerException(message); + } + } + + public static void assertNotNull(Object object, T throwable) throws T { + if (object == null) { + throw throwable; + } + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClassUtils.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClassUtils.java index a3c716bc4603..3577e49b398f 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClassUtils.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClassUtils.java @@ -1,112 +1,112 @@ -package com.nhn.pinpoint.rpc.util; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author koo.taejin - */ -public class ClassUtils { - - private static final Map, Class> primitiveWrapperMap = new HashMap, Class>(); - static { - primitiveWrapperMap.put(Boolean.TYPE, Boolean.class); - primitiveWrapperMap.put(Byte.TYPE, Byte.class); - primitiveWrapperMap.put(Character.TYPE, Character.class); - primitiveWrapperMap.put(Short.TYPE, Short.class); - primitiveWrapperMap.put(Integer.TYPE, Integer.class); - primitiveWrapperMap.put(Long.TYPE, Long.class); - primitiveWrapperMap.put(Double.TYPE, Double.class); - primitiveWrapperMap.put(Float.TYPE, Float.class); - primitiveWrapperMap.put(Void.TYPE, Void.TYPE); - } - - private static final Map wrapperPrimitiveMap = new HashMap(); - static { - for (Object o : primitiveWrapperMap.keySet()) { - Class primitiveClass = (Class) o; - Class wrapperClass = primitiveWrapperMap.get(primitiveClass); - if (!primitiveClass.equals(wrapperClass)) { - wrapperPrimitiveMap.put(wrapperClass, primitiveClass); - } - } - } - - public static boolean isAssignable(Class cls, Class toClass) { - return isAssignable(cls, toClass, true); - } - - public static boolean isAssignable(Class cls, Class toClass, boolean autoboxing) { - if (toClass == null) { - return false; - } - // have to check for null, as isAssignableFrom doesn't - if (cls == null) { - return !(toClass.isPrimitive()); - } - // autoboxing: - if (autoboxing) { - if (cls.isPrimitive() && !toClass.isPrimitive()) { - cls = primitiveToWrapper(cls); - if (cls == null) { - return false; - } - } - if (toClass.isPrimitive() && !cls.isPrimitive()) { - cls = wrapperToPrimitive(cls); - if (cls == null) { - return false; - } - } - } - if (cls.equals(toClass)) { - return true; - } - if (cls.isPrimitive()) { - if (toClass.isPrimitive() == false) { - return false; - } - if (Integer.TYPE.equals(cls)) { - return Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); - } - if (Long.TYPE.equals(cls)) { - return Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); - } - if (Boolean.TYPE.equals(cls)) { - return false; - } - if (Double.TYPE.equals(cls)) { - return false; - } - if (Float.TYPE.equals(cls)) { - return Double.TYPE.equals(toClass); - } - if (Character.TYPE.equals(cls)) { - return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); - } - if (Short.TYPE.equals(cls)) { - return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); - } - if (Byte.TYPE.equals(cls)) { - return Short.TYPE.equals(toClass) || Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) - || Double.TYPE.equals(toClass); - } - // should never get here - return false; - } - return toClass.isAssignableFrom(cls); - } - - public static Class primitiveToWrapper(Class cls) { - Class convertedClass = cls; - if (cls != null && cls.isPrimitive()) { - convertedClass = primitiveWrapperMap.get(cls); - } - return convertedClass; - } - - public static Class wrapperToPrimitive(Class cls) { - return wrapperPrimitiveMap.get(cls); - } - -} +package com.nhn.pinpoint.rpc.util; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author koo.taejin + */ +public class ClassUtils { + + private static final Map, Class> primitiveWrapperMap = new HashMap, Class>(); + static { + primitiveWrapperMap.put(Boolean.TYPE, Boolean.class); + primitiveWrapperMap.put(Byte.TYPE, Byte.class); + primitiveWrapperMap.put(Character.TYPE, Character.class); + primitiveWrapperMap.put(Short.TYPE, Short.class); + primitiveWrapperMap.put(Integer.TYPE, Integer.class); + primitiveWrapperMap.put(Long.TYPE, Long.class); + primitiveWrapperMap.put(Double.TYPE, Double.class); + primitiveWrapperMap.put(Float.TYPE, Float.class); + primitiveWrapperMap.put(Void.TYPE, Void.TYPE); + } + + private static final Map wrapperPrimitiveMap = new HashMap(); + static { + for (Object o : primitiveWrapperMap.keySet()) { + Class primitiveClass = (Class) o; + Class wrapperClass = primitiveWrapperMap.get(primitiveClass); + if (!primitiveClass.equals(wrapperClass)) { + wrapperPrimitiveMap.put(wrapperClass, primitiveClass); + } + } + } + + public static boolean isAssignable(Class cls, Class toClass) { + return isAssignable(cls, toClass, true); + } + + public static boolean isAssignable(Class cls, Class toClass, boolean autoboxing) { + if (toClass == null) { + return false; + } + // have to check for null, as isAssignableFrom doesn't + if (cls == null) { + return !(toClass.isPrimitive()); + } + // autoboxing: + if (autoboxing) { + if (cls.isPrimitive() && !toClass.isPrimitive()) { + cls = primitiveToWrapper(cls); + if (cls == null) { + return false; + } + } + if (toClass.isPrimitive() && !cls.isPrimitive()) { + cls = wrapperToPrimitive(cls); + if (cls == null) { + return false; + } + } + } + if (cls.equals(toClass)) { + return true; + } + if (cls.isPrimitive()) { + if (toClass.isPrimitive() == false) { + return false; + } + if (Integer.TYPE.equals(cls)) { + return Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); + } + if (Long.TYPE.equals(cls)) { + return Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); + } + if (Boolean.TYPE.equals(cls)) { + return false; + } + if (Double.TYPE.equals(cls)) { + return false; + } + if (Float.TYPE.equals(cls)) { + return Double.TYPE.equals(toClass); + } + if (Character.TYPE.equals(cls)) { + return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); + } + if (Short.TYPE.equals(cls)) { + return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); + } + if (Byte.TYPE.equals(cls)) { + return Short.TYPE.equals(toClass) || Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) + || Double.TYPE.equals(toClass); + } + // should never get here + return false; + } + return toClass.isAssignableFrom(cls); + } + + public static Class primitiveToWrapper(Class cls) { + Class convertedClass = cls; + if (cls != null && cls.isPrimitive()) { + convertedClass = primitiveWrapperMap.get(cls); + } + return convertedClass; + } + + public static Class wrapperToPrimitive(Class cls) { + return wrapperPrimitiveMap.get(cls); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ControlMessageEnDeconderUtils.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ControlMessageEnDeconderUtils.java index 3cdfd2df17c0..d7ef4104169e 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ControlMessageEnDeconderUtils.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ControlMessageEnDeconderUtils.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.rpc.util; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.control.ControlMessageDecoder; -import com.nhn.pinpoint.rpc.control.ControlMessageEncoder; -import com.nhn.pinpoint.rpc.control.ProtocolException; - -/** - * @author koo.taejin - */ -public class ControlMessageEnDeconderUtils { - - private static final ControlMessageEncoder encoder = new ControlMessageEncoder(); - private static final ControlMessageDecoder decoder = new ControlMessageDecoder(); - - private ControlMessageEnDeconderUtils() { - } - - public static byte[] encode(Map value) throws ProtocolException { - return encoder.encode(value); - } - - public static Object decode(byte[] in) throws ProtocolException { - return decoder.decode(in); - } - -} +package com.nhn.pinpoint.rpc.util; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.control.ControlMessageDecoder; +import com.nhn.pinpoint.rpc.control.ControlMessageEncoder; +import com.nhn.pinpoint.rpc.control.ProtocolException; + +/** + * @author koo.taejin + */ +public class ControlMessageEnDeconderUtils { + + private static final ControlMessageEncoder encoder = new ControlMessageEncoder(); + private static final ControlMessageDecoder decoder = new ControlMessageDecoder(); + + private ControlMessageEnDeconderUtils() { + } + + public static byte[] encode(Map value) throws ProtocolException { + return encoder.encode(value); + } + + public static Object decode(byte[] in) throws ProtocolException { + return decoder.decode(in); + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CopyUtils.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CopyUtils.java index c3f30fefd7bd..43e139fe0083 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CopyUtils.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CopyUtils.java @@ -1,52 +1,52 @@ -package com.nhn.pinpoint.rpc.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * @author koo.taejin - */ -public final class CopyUtils { - - private CopyUtils() { - } - - /** - * Map, List 등의 기본 타입들은 DeepCopy를 하고, Bean등은 ShallowCopy를 함 - * Pinpoint의 Map등을 안전하게 복사할때만 사용하려고 하기 떄문에 기능에 제약이 있음 - * 사용하려면 기능제약을 확실히 알고 사용하기를 권함 - */ - public static Map mediumCopyMap(Map original) { - Map result = new LinkedHashMap(); - - for (Map.Entry entry : original.entrySet()) { - Object key = entry.getKey(); - Object value = entry.getValue(); - - result.put(mediumCopy(key), mediumCopy(value)); - } - return result; - } - - /** - * Map, List 등의 기본 타입들은 DeepCopy를 하고, Bean등은 ShallowCopy를 함 - * Pinpoint의 Map등을 안전하게 복사할때만 사용하려고 하기 떄문에 기능에 제약이 있음 - * 사용하려면 기능제약을 확실히 알고 사용하기를 권함 - */ - public static Collection mediumCopyCollection(Collection original) { - return new ArrayList(original); - } - - private static Object mediumCopy(Object original) { - if (original instanceof Map) { - return mediumCopyMap((Map) original); - } else if (original instanceof Collection) { - return mediumCopyCollection((Collection) original); - } else { - return original; - } - } - -} +package com.nhn.pinpoint.rpc.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author koo.taejin + */ +public final class CopyUtils { + + private CopyUtils() { + } + + /** + * Map, List 등의 기본 타입들은 DeepCopy를 하고, Bean등은 ShallowCopy를 함 + * Pinpoint의 Map등을 안전하게 복사할때만 사용하려고 하기 떄문에 기능에 제약이 있음 + * 사용하려면 기능제약을 확실히 알고 사용하기를 권함 + */ + public static Map mediumCopyMap(Map original) { + Map result = new LinkedHashMap(); + + for (Map.Entry entry : original.entrySet()) { + Object key = entry.getKey(); + Object value = entry.getValue(); + + result.put(mediumCopy(key), mediumCopy(value)); + } + return result; + } + + /** + * Map, List 등의 기본 타입들은 DeepCopy를 하고, Bean등은 ShallowCopy를 함 + * Pinpoint의 Map등을 안전하게 복사할때만 사용하려고 하기 떄문에 기능에 제약이 있음 + * 사용하려면 기능제약을 확실히 알고 사용하기를 권함 + */ + public static Collection mediumCopyCollection(Collection original) { + return new ArrayList(original); + } + + private static Object mediumCopy(Object original) { + if (original instanceof Map) { + return mediumCopyMap((Map) original); + } else if (original instanceof Collection) { + return mediumCopyCollection((Collection) original); + } else { + return original; + } + } + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CpuUtils.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CpuUtils.java index 4a9995b7fb57..7b775a1bbd74 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CpuUtils.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/CpuUtils.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.rpc.util; - -/** - * @author emeroad - */ -public final class CpuUtils { - - private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); - private static final int WORKER_COUNT = CPU_COUNT * 2; - - private CpuUtils() { - } - - public static int cpuCount() { - return CPU_COUNT; - } - - public static int workerCount() { - return WORKER_COUNT; - } -} +package com.nhn.pinpoint.rpc.util; + +/** + * @author emeroad + */ +public final class CpuUtils { + + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); + private static final int WORKER_COUNT = CPU_COUNT * 2; + + private CpuUtils() { + } + + public static int cpuCount() { + return CPU_COUNT; + } + + public static int workerCount() { + return WORKER_COUNT; + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/LoggerFactorySetup.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/LoggerFactorySetup.java index eb7e2668b132..78518c193a06 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/LoggerFactorySetup.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/LoggerFactorySetup.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.rpc.util; - -import org.jboss.netty.logging.InternalLoggerFactory; -import org.jboss.netty.logging.Slf4JLoggerFactory; - -/** - * @author emeroad - */ -public class LoggerFactorySetup { - - public static final Slf4JLoggerFactory LOGGER_FACTORY = new Slf4JLoggerFactory(); - - public static void setupSlf4jLoggerFactory() { - InternalLoggerFactory.setDefaultFactory(LOGGER_FACTORY); - } -} +package com.nhn.pinpoint.rpc.util; + +import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.logging.Slf4JLoggerFactory; + +/** + * @author emeroad + */ +public class LoggerFactorySetup { + + public static final Slf4JLoggerFactory LOGGER_FACTORY = new Slf4JLoggerFactory(); + + public static void setupSlf4jLoggerFactory() { + InternalLoggerFactory.setDefaultFactory(LOGGER_FACTORY); + } +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/MapUtils.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/MapUtils.java index 483cd7282110..0825abb65d71 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/MapUtils.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/MapUtils.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.rpc.util; - -import java.util.Map; - - -/** - * @author koo.taejin - */ -public class MapUtils { - - private MapUtils() { - } - - public static String getString(Map map, String key) { - return getString(map, key, null); - } - - public static String getString(Map map, String key, String defaultValue) { - if (map == null) { - return defaultValue; - } - - final Object value = map.get(key); - if (value instanceof String) { - return (String) value; - } - - return null; - } - - - public static Integer getInteger(Map map, String key) { - return getInteger(map, key, null); - } - - public static Integer getInteger(Map map, String key, Integer defaultValue) { - if (map == null) { - return defaultValue; - } - - final Object value = map.get(key); - if (value instanceof Integer) { - return (Integer) value; - } - - return null; - } - - -} +package com.nhn.pinpoint.rpc.util; + +import java.util.Map; + + +/** + * @author koo.taejin + */ +public class MapUtils { + + private MapUtils() { + } + + public static String getString(Map map, String key) { + return getString(map, key, null); + } + + public static String getString(Map map, String key, String defaultValue) { + if (map == null) { + return defaultValue; + } + + final Object value = map.get(key); + if (value instanceof String) { + return (String) value; + } + + return null; + } + + + public static Integer getInteger(Map map, String key) { + return getInteger(map, key, null); + } + + public static Integer getInteger(Map map, String key, Integer defaultValue) { + if (map == null) { + return defaultValue; + } + + final Object value = map.get(key); + if (value instanceof Integer) { + return (Integer) value; + } + + return null; + } + + +} diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java index 02bb21569476..c38e182218b9 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.rpc.util; - -import com.nhn.pinpoint.common.util.PinpointThreadFactory; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.ThreadNameDeterminer; - -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - */ -public class TimerFactory { - - public static HashedWheelTimer createHashedWheelTimer(String threadName, long tickDuration, TimeUnit unit, int ticksPerWheel) { - final PinpointThreadFactory threadFactory = new PinpointThreadFactory(threadName, true); - return new HashedWheelTimer(threadFactory, ThreadNameDeterminer.CURRENT, tickDuration, unit, ticksPerWheel); - } -} +package com.nhn.pinpoint.rpc.util; + +import com.nhn.pinpoint.common.util.PinpointThreadFactory; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.ThreadNameDeterminer; + +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + */ +public class TimerFactory { + + public static HashedWheelTimer createHashedWheelTimer(String threadName, long tickDuration, TimeUnit unit, int ticksPerWheel) { + final PinpointThreadFactory threadFactory = new PinpointThreadFactory(threadName, true); + return new HashedWheelTimer(threadFactory, ThreadNameDeterminer.CURRENT, tickDuration, unit, ticksPerWheel); + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/ClassPreLoaderTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/ClassPreLoaderTest.java index 6b3fb82f461c..7ccf810dce8b 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/ClassPreLoaderTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/ClassPreLoaderTest.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.rpc; - -import org.junit.Test; - -/** - * @author emeroad - */ -public class ClassPreLoaderTest { - @Test - public void testPreload() throws Exception { - ClassPreLoader.preload(); - } -} +package com.nhn.pinpoint.rpc; + +import org.junit.Test; + +/** + * @author emeroad + */ +public class ClassPreLoaderTest { + @Test + public void testPreload() throws Exception { + ClassPreLoader.preload(); + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardPipelineFactory.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardPipelineFactory.java index a2d2cc5066e4..5bec2cfaf4de 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardPipelineFactory.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardPipelineFactory.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.rpc; - -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; - -/** - * @author emeroad - */ -public class DiscardPipelineFactory implements ChannelPipelineFactory { - @Override - public ChannelPipeline getPipeline() throws Exception { - return Channels.pipeline(new DiscardServerHandler()); - } -} +package com.nhn.pinpoint.rpc; + +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; + +/** + * @author emeroad + */ +public class DiscardPipelineFactory implements ChannelPipelineFactory { + @Override + public ChannelPipeline getPipeline() throws Exception { + return Channels.pipeline(new DiscardServerHandler()); + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardServerHandler.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardServerHandler.java index 228695959700..9adb6e29a7cc 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardServerHandler.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/DiscardServerHandler.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.rpc; - - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class DiscardServerHandler extends SimpleChannelUpstreamHandler { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private long transferredBytes; - - public long getTransferredBytes() { - return transferredBytes; - } - - @Override - public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { - if (e instanceof ChannelStateEvent) { - logger.info("event:{}", e); - } - - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { - - transferredBytes += ((ChannelBuffer) e.getMessage()).readableBytes(); - logger.info("messageReceived. meg:{} channel:{}", e.getMessage(), e.getChannel()); - logger.info("transferredBytes. transferredBytes:{}", transferredBytes); - - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { - logger.warn("Unexpected exception from downstream. Caused:{}", e, e.getCause()); - } -} +package com.nhn.pinpoint.rpc; + + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class DiscardServerHandler extends SimpleChannelUpstreamHandler { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private long transferredBytes; + + public long getTransferredBytes() { + return transferredBytes; + } + + @Override + public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { + if (e instanceof ChannelStateEvent) { + logger.info("event:{}", e); + } + + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { + + transferredBytes += ((ChannelBuffer) e.getMessage()).readableBytes(); + logger.info("messageReceived. meg:{} channel:{}", e.getMessage(), e.getChannel()); + logger.info("transferredBytes. transferredBytes:{}", transferredBytes); + + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { + logger.warn("Unexpected exception from downstream. Caused:{}", e, e.getCause()); + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/FutureTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/FutureTest.java index 956f23ca4c5f..57373cabec30 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/FutureTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/FutureTest.java @@ -1,59 +1,59 @@ -package com.nhn.pinpoint.rpc; - -import java.util.concurrent.atomic.AtomicBoolean; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author emeroad - * @author koo.taejin - */ -public class FutureTest { - - @Test - public void simpleTest1() { - DefaultFuture future = new DefaultFuture(); - - SimpleListener listener1 = new SimpleListener(); - - future.setListener(listener1); -// future.addListener(listener2); - - Assert.assertFalse(listener1.isFinished()); -// Assert.assertFalse(listener2.isFinished()); - - future.setResult("Hello"); - - Assert.assertTrue(listener1.isFinished()); -// Assert.assertTrue(listener2.isFinished()); - } - - @Test - public void simpleTest2() { - DefaultFuture future = new DefaultFuture(); - - SimpleListener listener = new SimpleListener(); - - future.setResult("Hello"); - - future.setListener(listener); - - Assert.assertTrue(listener.isFinished()); - } - - static class SimpleListener implements FutureListener { - - private final AtomicBoolean isFinished = new AtomicBoolean(false); - - @Override - public void onComplete(Future future) { - isFinished.compareAndSet(false, true); - } - - public boolean isFinished() { - return isFinished.get(); - } - } - -} +package com.nhn.pinpoint.rpc; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author emeroad + * @author koo.taejin + */ +public class FutureTest { + + @Test + public void simpleTest1() { + DefaultFuture future = new DefaultFuture(); + + SimpleListener listener1 = new SimpleListener(); + + future.setListener(listener1); +// future.addListener(listener2); + + Assert.assertFalse(listener1.isFinished()); +// Assert.assertFalse(listener2.isFinished()); + + future.setResult("Hello"); + + Assert.assertTrue(listener1.isFinished()); +// Assert.assertTrue(listener2.isFinished()); + } + + @Test + public void simpleTest2() { + DefaultFuture future = new DefaultFuture(); + + SimpleListener listener = new SimpleListener(); + + future.setResult("Hello"); + + future.setListener(listener); + + Assert.assertTrue(listener.isFinished()); + } + + static class SimpleListener implements FutureListener { + + private final AtomicBoolean isFinished = new AtomicBoolean(false); + + @Override + public void onComplete(Future future) { + isFinished.compareAndSet(false, true); + } + + public boolean isFinished() { + return isFinished.get(); + } + } + +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/RecordedStreamChannelMessageListener.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/RecordedStreamChannelMessageListener.java index 22c65b3916e9..aaa19d39fcd0 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/RecordedStreamChannelMessageListener.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/RecordedStreamChannelMessageListener.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.rpc; - -import com.nhn.pinpoint.rpc.client.StreamChannel; -import com.nhn.pinpoint.rpc.client.StreamChannelMessageListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CountDownLatch; - -/** - * @author emeroad - */ -public class RecordedStreamChannelMessageListener implements StreamChannelMessageListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final CountDownLatch latch; - - private final List receivedMessageList = Collections.synchronizedList(new ArrayList()); - - public RecordedStreamChannelMessageListener(int receiveMessageCount) { - this.latch = new CountDownLatch(receiveMessageCount); - } - - - @Override - public void handleStreamResponse(StreamChannel streamChannel, byte[] bytes) { - logger.info("handleStreamResponse {}, {}", streamChannel, bytes.length); - receivedMessageList.add(bytes); - latch.countDown(); - } - - @Override - public void handleClose(StreamChannel streamChannel, byte[] bytes) { - logger.info("handleClose {}, {}", streamChannel, bytes.length); - receivedMessageList.add(bytes); - latch.countDown(); - } - - public CountDownLatch getLatch() { - return latch; - } - - public List getReceivedMessage() { - return receivedMessageList; - } -} - +package com.nhn.pinpoint.rpc; + +import com.nhn.pinpoint.rpc.client.StreamChannel; +import com.nhn.pinpoint.rpc.client.StreamChannelMessageListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +/** + * @author emeroad + */ +public class RecordedStreamChannelMessageListener implements StreamChannelMessageListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final CountDownLatch latch; + + private final List receivedMessageList = Collections.synchronizedList(new ArrayList()); + + public RecordedStreamChannelMessageListener(int receiveMessageCount) { + this.latch = new CountDownLatch(receiveMessageCount); + } + + + @Override + public void handleStreamResponse(StreamChannel streamChannel, byte[] bytes) { + logger.info("handleStreamResponse {}, {}", streamChannel, bytes.length); + receivedMessageList.add(bytes); + latch.countDown(); + } + + @Override + public void handleClose(StreamChannel streamChannel, byte[] bytes) { + logger.info("handleClose {}, {}", streamChannel, bytes.length); + receivedMessageList.add(bytes); + latch.countDown(); + } + + public CountDownLatch getLatch() { + return latch; + } + + public List getReceivedMessage() { + return receivedMessageList; + } +} + diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/TestByteUtils.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/TestByteUtils.java index cc9ddb7600f5..c794b3fd8145 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/TestByteUtils.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/TestByteUtils.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.rpc; - -import java.util.Random; - -/** - * @author emeroad - */ -public class TestByteUtils { - - private static final Random RANDOM = new Random(); - - public static byte[] createRandomByte(int size) { - byte[] bytes = new byte[size]; - RANDOM.nextBytes(bytes); - return bytes; - } -} +package com.nhn.pinpoint.rpc; + +import java.util.Random; + +/** + * @author emeroad + */ +public class TestByteUtils { + + private static final Random RANDOM = new Random(); + + public static byte[] createRandomByte(int size) { + byte[] bytes = new byte[size]; + RANDOM.nextBytes(bytes); + return bytes; + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactoryTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactoryTest.java index 2e0b4aa299b9..58d0a4922a33 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactoryTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/PinpointSocketFactoryTest.java @@ -1,241 +1,241 @@ -package com.nhn.pinpoint.rpc.client; - -import com.nhn.pinpoint.rpc.*; -import com.nhn.pinpoint.rpc.server.PinpointServerSocket; -import com.nhn.pinpoint.rpc.server.TestSeverMessageListener; -import org.jboss.netty.channel.ChannelFuture; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.ConnectException; -import java.net.InetSocketAddress; -import java.util.List; - - -/** - * @author emeroad - */ -public class PinpointSocketFactoryTest { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void connectFail() { - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - try { - pinpointSocketFactory.connect("127.0.0.1", 10234); - Assert.fail(); - } catch (PinpointSocketException e) { - Assert.assertTrue(ConnectException.class.isInstance(e.getCause())); - } finally { - pinpointSocketFactory.release(); - } - } - - @Test - public void reconnectFail() throws InterruptedException { - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - try { - // api 호출시 error 메시지 간략화 확인용. - InetSocketAddress remoteAddress = new InetSocketAddress("127.0.0.1", 10234); - ChannelFuture reconnect = pinpointSocketFactory.reconnect(remoteAddress); - reconnect.await(); - Assert.assertFalse(reconnect.isSuccess()); - Assert.assertTrue(ConnectException.class.isInstance(reconnect.getCause())); - } finally { - pinpointSocketFactory.release(); - } - Thread.sleep(1000); - } - - - @Test - public void connect() throws IOException, InterruptedException { - PinpointServerSocket ss = new PinpointServerSocket(); -// ss.setPipelineFactory(new DiscardPipelineFactory()); - ss.bind("127.0.0.1", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - - socket.close(); - } finally { - pinpointSocketFactory.release(); - ss.close(); - } - - } - - @Test - public void pingInternal() throws IOException, InterruptedException { - PinpointServerSocket ss = new PinpointServerSocket(); - ss.bind("127.0.0.1", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setPingDelay(100); - - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - Thread.sleep(1000); - socket.close(); - } finally { - pinpointSocketFactory.release(); - ss.close(); - } - - } - - @Test - public void ping() throws IOException, InterruptedException { - PinpointServerSocket ss = new PinpointServerSocket(); - ss.bind("127.0.0.1", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setPingDelay(100); - - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - socket.sendPing(); - socket.close(); - } finally { - pinpointSocketFactory.release(); - ss.close(); - } - - } - - @Test - public void pingAndRequestResponse() throws IOException, InterruptedException { - PinpointServerSocket ss = new PinpointServerSocket(); - ss.setMessageListener(new RequestResponseServerMessageListener()); - ss.bind("127.0.0.1", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setPingDelay(100); - - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - byte[] randomByte = TestByteUtils.createRandomByte(10); - Future response = socket.request(randomByte); - Thread.sleep(1000); - response.await(); - ResponseMessage result = response.getResult(); - Assert.assertArrayEquals(randomByte, result.getMessage()); - socket.close(); - } finally { - pinpointSocketFactory.release(); - ss.close(); - } - } - - @Test - public void sendSync() throws IOException, InterruptedException { - PinpointServerSocket ss = new PinpointServerSocket(); -// ss.setPipelineFactory(new DiscardPipelineFactory()); - ss.setMessageListener(new TestSeverMessageListener()); - ss.bind("localhost", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - logger.info("send1"); - socket.send(new byte[20]); - logger.info("send2"); - socket.sendSync(new byte[20]); - - socket.close(); - } finally { - pinpointSocketFactory.release(); - ss.close(); - } - - } - - @Test - public void requestAndResponse() throws IOException, InterruptedException { - PinpointServerSocket ss = new PinpointServerSocket(); -// ss.setPipelineFactory(new DiscardPipelineFactory()); - ss.setMessageListener(new TestSeverMessageListener()); - ss.bind("localhost", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - - byte[] bytes = TestByteUtils.createRandomByte(20); - Future request = socket.request(bytes); - request.await(); - ResponseMessage message = request.getResult(); - Assert.assertArrayEquals(message.getMessage(), bytes); - - socket.close(); - } finally { - pinpointSocketFactory.release(); - ss.close(); - } - - } - - - - - @Test - public void stream() throws IOException, InterruptedException { - PinpointServerSocket ss = new PinpointServerSocket(); - - TestSeverMessageListener testSeverMessageListener = new TestSeverMessageListener(); - ss.setMessageListener(testSeverMessageListener); - ss.bind("localhost", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - - - StreamChannel streamChannel = socket.createStreamChannel(); - byte[] openBytes = TestByteUtils.createRandomByte(30); - - // 현재 서버에서 3번 보내게 되어 있음. - RecordedStreamChannelMessageListener clientListener = new RecordedStreamChannelMessageListener(4); - streamChannel.setStreamChannelMessageListener(clientListener); - - Future open = streamChannel.open(openBytes); - open.await(); - StreamCreateResponse response = open.getResult(); - Assert.assertTrue(response.isSuccess()); - Assert.assertArrayEquals(response.getMessage(), openBytes); - // stream 메시지를 대기함. - clientListener.getLatch().await(); - List receivedMessage = clientListener.getReceivedMessage(); - List sendMessage = testSeverMessageListener.getSendMessage(); - - // 한개는 close 패킷임. - Assert.assertEquals(receivedMessage.size(), sendMessage.size()); - for(int i =0; i response = socket.request(randomByte); + Thread.sleep(1000); + response.await(); + ResponseMessage result = response.getResult(); + Assert.assertArrayEquals(randomByte, result.getMessage()); + socket.close(); + } finally { + pinpointSocketFactory.release(); + ss.close(); + } + } + + @Test + public void sendSync() throws IOException, InterruptedException { + PinpointServerSocket ss = new PinpointServerSocket(); +// ss.setPipelineFactory(new DiscardPipelineFactory()); + ss.setMessageListener(new TestSeverMessageListener()); + ss.bind("localhost", 10234); + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + try { + PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); + logger.info("send1"); + socket.send(new byte[20]); + logger.info("send2"); + socket.sendSync(new byte[20]); + + socket.close(); + } finally { + pinpointSocketFactory.release(); + ss.close(); + } + + } + + @Test + public void requestAndResponse() throws IOException, InterruptedException { + PinpointServerSocket ss = new PinpointServerSocket(); +// ss.setPipelineFactory(new DiscardPipelineFactory()); + ss.setMessageListener(new TestSeverMessageListener()); + ss.bind("localhost", 10234); + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + try { + PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); + + byte[] bytes = TestByteUtils.createRandomByte(20); + Future request = socket.request(bytes); + request.await(); + ResponseMessage message = request.getResult(); + Assert.assertArrayEquals(message.getMessage(), bytes); + + socket.close(); + } finally { + pinpointSocketFactory.release(); + ss.close(); + } + + } + + + + + @Test + public void stream() throws IOException, InterruptedException { + PinpointServerSocket ss = new PinpointServerSocket(); + + TestSeverMessageListener testSeverMessageListener = new TestSeverMessageListener(); + ss.setMessageListener(testSeverMessageListener); + ss.bind("localhost", 10234); + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + try { + PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); + + + StreamChannel streamChannel = socket.createStreamChannel(); + byte[] openBytes = TestByteUtils.createRandomByte(30); + + // 현재 서버에서 3번 보내게 되어 있음. + RecordedStreamChannelMessageListener clientListener = new RecordedStreamChannelMessageListener(4); + streamChannel.setStreamChannelMessageListener(clientListener); + + Future open = streamChannel.open(openBytes); + open.await(); + StreamCreateResponse response = open.getResult(); + Assert.assertTrue(response.isSuccess()); + Assert.assertArrayEquals(response.getMessage(), openBytes); + // stream 메시지를 대기함. + clientListener.getLatch().await(); + List receivedMessage = clientListener.getReceivedMessage(); + List sendMessage = testSeverMessageListener.getSendMessage(); + + // 한개는 close 패킷임. + Assert.assertEquals(receivedMessage.size(), sendMessage.size()); + for(int i =0; i response = socket.request(new byte[10]); - response.await(); - ResponseMessage result = response.getResult(); - Assert.fail("expected:exception"); - } catch (Exception e) { - // 기대된 에러라 skip - } - - newServerSocket = new PinpointServerSocket(); - newServerSocket.setMessageListener(new TestSeverMessageListener()); - newServerSocket.bind("localhost", 10234); - logger.info("bind server---------------------------"); - - Thread.sleep(3000); - logger.info("request server---------------------------"); - byte[] randomByte = TestByteUtils.createRandomByte(10); - Future response = socket.request(randomByte); - response.await(); - ResponseMessage result = response.getResult(); - Assert.assertArrayEquals(result.getMessage(), randomByte); - socket.close(); - } finally { - if (newServerSocket != null) { - newServerSocket.close(); - } - pinpointSocketFactory.release(); - } - - Assert.assertTrue(reconnectPerformed.get()); - } - - @Test - public void scheduledConnect() throws IOException, InterruptedException { - final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setReconnectDelay(200); - PinpointSocket socket = null; - PinpointServerSocket serverSocket = null; - try { - socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); - - serverSocket = new PinpointServerSocket(); - serverSocket.setMessageListener(new TestSeverMessageListener()); - serverSocket.bind("localhost", 10234); - - Thread.sleep(2000); - logger.info("request server---------------------------"); - byte[] randomByte = TestByteUtils.createRandomByte(10); - Future response = socket.request(randomByte); - response.await(); - ResponseMessage result = response.getResult(); - Assert.assertArrayEquals(randomByte, result.getMessage()); - - } finally { - if (socket != null) { - socket.close(); - } - pinpointSocketFactory.release(); - if (serverSocket != null) { - serverSocket.close(); - } - } - } - - @Test - public void scheduledConnectAndClosed() throws IOException, InterruptedException { - final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setReconnectDelay(100); - PinpointSocket socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); - - logger.debug("close"); - socket.close(); - pinpointSocketFactory.release(); - } - - @Test - public void scheduledConnectDelayAndClosed() throws IOException, InterruptedException { - final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setReconnectDelay(200); - PinpointSocket socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); - - Thread.sleep(2000); - logger.debug("close pinpoint socket"); - socket.close(); - pinpointSocketFactory.release(); - } - - @Test - public void scheduledConnectStateTest() { - final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setReconnectDelay(200); - PinpointSocket socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); - - - socket.send(new byte[10]); - - - try { - Future future = socket.sendAsync(new byte[10]); - future.await(); - future.getResult(); - Assert.fail(); - } catch (PinpointSocketException e) { - } - - try { - socket.sendSync(new byte[10]); - Assert.fail(); - } catch (PinpointSocketException e) { - } - - try { - Future request = socket.request(new byte[10]); - request.await(); - request.getResult(); - Assert.fail(); - } catch (PinpointSocketException e) { - } - - socket.close(); - pinpointSocketFactory.release(); - } - - @Test - public void serverFirstClose() throws IOException, InterruptedException { - // 서버가 먼저 닫힌 상황에서 비정상적인 상황에서 client socket이 잘 닫히는지 테스트 - - PinpointServerSocket ss = new PinpointServerSocket(); - ss.bind("127.0.0.1", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setReconnectDelay(200); - pinpointSocketFactory.setTimeoutMillis(500); - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - - byte[] randomByte = TestByteUtils.createRandomByte(10); - Future response = socket.request(randomByte); - response.await(); - try { - response.getResult(); - } catch (Exception e) { - logger.debug("timeout.", e); - } - // 강제로 서버를 close함. - ss.close(); - Thread.sleep(1000*2); - - socket.close(); - } finally { - pinpointSocketFactory.release(); - } - - } - - @Test - public void serverCloseAndWrite() throws IOException, InterruptedException { - // 서버가 먼저 닫힌 상황에서 비정상적인 상황에서 client socket이 잘 닫히는지 테스트 - - PinpointServerSocket ss = new PinpointServerSocket(); - ss.bind("127.0.0.1", 10234); - PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); - pinpointSocketFactory.setReconnectDelay(200); - pinpointSocketFactory.setTimeoutMillis(500); - try { - PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); - - byte[] randomByte = TestByteUtils.createRandomByte(10); - // 서버를 그냥 닫고 request - ss.close(); - Future response = socket.request(randomByte); - response.await(); - try { - response.getResult(); - Assert.fail("expected exception"); - } catch (Exception e) { - } - - - Thread.sleep(1000*3); - - socket.close(); - } finally { - pinpointSocketFactory.release(); - } - - } - - -} +package com.nhn.pinpoint.rpc.client; + +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.PinpointSocketException; +import com.nhn.pinpoint.rpc.ResponseMessage; +import com.nhn.pinpoint.rpc.TestByteUtils; +import com.nhn.pinpoint.rpc.server.PinpointServerSocket; +import com.nhn.pinpoint.rpc.server.TestSeverMessageListener; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; + + +/** + * @author emeroad + */ +//@Ignore +public class ReconnectTest { + + public static final int PORT = 10234; + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void reconnect() throws IOException, InterruptedException { + PinpointServerSocket serverSocket = new PinpointServerSocket(); + serverSocket.setMessageListener(new TestSeverMessageListener()); + serverSocket.bind("localhost", PORT); + + final AtomicBoolean reconnectPerformed = new AtomicBoolean(false); + + final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setReconnectDelay(200); + + PinpointServerSocket newServerSocket = null; + try { + PinpointSocket socket = pinpointSocketFactory.connect("localhost", 10234); + socket.addPinpointSocketReconnectEventListener(new PinpointSocketReconnectEventListener() { + + @Override + public void reconnectPerformed(PinpointSocket socket) { + reconnectPerformed.set(true); + } + + }); + + serverSocket.close(); + logger.info("server.close()---------------------------"); + Thread.sleep(1000); + try { + Future response = socket.request(new byte[10]); + response.await(); + ResponseMessage result = response.getResult(); + Assert.fail("expected:exception"); + } catch (Exception e) { + // 기대된 에러라 skip + } + + newServerSocket = new PinpointServerSocket(); + newServerSocket.setMessageListener(new TestSeverMessageListener()); + newServerSocket.bind("localhost", 10234); + logger.info("bind server---------------------------"); + + Thread.sleep(3000); + logger.info("request server---------------------------"); + byte[] randomByte = TestByteUtils.createRandomByte(10); + Future response = socket.request(randomByte); + response.await(); + ResponseMessage result = response.getResult(); + Assert.assertArrayEquals(result.getMessage(), randomByte); + socket.close(); + } finally { + if (newServerSocket != null) { + newServerSocket.close(); + } + pinpointSocketFactory.release(); + } + + Assert.assertTrue(reconnectPerformed.get()); + } + + @Test + public void scheduledConnect() throws IOException, InterruptedException { + final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setReconnectDelay(200); + PinpointSocket socket = null; + PinpointServerSocket serverSocket = null; + try { + socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); + + serverSocket = new PinpointServerSocket(); + serverSocket.setMessageListener(new TestSeverMessageListener()); + serverSocket.bind("localhost", 10234); + + Thread.sleep(2000); + logger.info("request server---------------------------"); + byte[] randomByte = TestByteUtils.createRandomByte(10); + Future response = socket.request(randomByte); + response.await(); + ResponseMessage result = response.getResult(); + Assert.assertArrayEquals(randomByte, result.getMessage()); + + } finally { + if (socket != null) { + socket.close(); + } + pinpointSocketFactory.release(); + if (serverSocket != null) { + serverSocket.close(); + } + } + } + + @Test + public void scheduledConnectAndClosed() throws IOException, InterruptedException { + final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setReconnectDelay(100); + PinpointSocket socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); + + logger.debug("close"); + socket.close(); + pinpointSocketFactory.release(); + } + + @Test + public void scheduledConnectDelayAndClosed() throws IOException, InterruptedException { + final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setReconnectDelay(200); + PinpointSocket socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); + + Thread.sleep(2000); + logger.debug("close pinpoint socket"); + socket.close(); + pinpointSocketFactory.release(); + } + + @Test + public void scheduledConnectStateTest() { + final PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setReconnectDelay(200); + PinpointSocket socket = pinpointSocketFactory.scheduledConnect("localhost", 10234); + + + socket.send(new byte[10]); + + + try { + Future future = socket.sendAsync(new byte[10]); + future.await(); + future.getResult(); + Assert.fail(); + } catch (PinpointSocketException e) { + } + + try { + socket.sendSync(new byte[10]); + Assert.fail(); + } catch (PinpointSocketException e) { + } + + try { + Future request = socket.request(new byte[10]); + request.await(); + request.getResult(); + Assert.fail(); + } catch (PinpointSocketException e) { + } + + socket.close(); + pinpointSocketFactory.release(); + } + + @Test + public void serverFirstClose() throws IOException, InterruptedException { + // 서버가 먼저 닫힌 상황에서 비정상적인 상황에서 client socket이 잘 닫히는지 테스트 + + PinpointServerSocket ss = new PinpointServerSocket(); + ss.bind("127.0.0.1", 10234); + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setReconnectDelay(200); + pinpointSocketFactory.setTimeoutMillis(500); + try { + PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); + + byte[] randomByte = TestByteUtils.createRandomByte(10); + Future response = socket.request(randomByte); + response.await(); + try { + response.getResult(); + } catch (Exception e) { + logger.debug("timeout.", e); + } + // 강제로 서버를 close함. + ss.close(); + Thread.sleep(1000*2); + + socket.close(); + } finally { + pinpointSocketFactory.release(); + } + + } + + @Test + public void serverCloseAndWrite() throws IOException, InterruptedException { + // 서버가 먼저 닫힌 상황에서 비정상적인 상황에서 client socket이 잘 닫히는지 테스트 + + PinpointServerSocket ss = new PinpointServerSocket(); + ss.bind("127.0.0.1", 10234); + PinpointSocketFactory pinpointSocketFactory = new PinpointSocketFactory(); + pinpointSocketFactory.setReconnectDelay(200); + pinpointSocketFactory.setTimeoutMillis(500); + try { + PinpointSocket socket = pinpointSocketFactory.connect("127.0.0.1", 10234); + + byte[] randomByte = TestByteUtils.createRandomByte(10); + // 서버를 그냥 닫고 request + ss.close(); + Future response = socket.request(randomByte); + response.await(); + try { + response.getResult(); + Assert.fail("expected exception"); + } catch (Exception e) { + } + + + Thread.sleep(1000*3); + + socket.close(); + } finally { + pinpointSocketFactory.release(); + } + + } + + +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/RequestManagerTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/RequestManagerTest.java index 81776fd4f7d2..7799efdc6ff2 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/RequestManagerTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/client/RequestManagerTest.java @@ -1,78 +1,78 @@ -package com.nhn.pinpoint.rpc.client; - -import com.nhn.pinpoint.rpc.DefaultFuture; -import com.nhn.pinpoint.rpc.Future; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import org.jboss.netty.util.HashedWheelTimer; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - */ -public class RequestManagerTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - - @Test - public void testRegisterRequest() throws Exception { - HashedWheelTimer timer = getTimer(); - RequestManager requestManager = new RequestManager(timer); - try { - RequestPacket packet = new RequestPacket(new byte[0]); - Future future = requestManager.register(packet, 50); - Thread.sleep(200); - - Assert.assertTrue(future.isReady()); - Assert.assertFalse(future.isSuccess()); - Assert.assertTrue(future.getCause().getMessage().contains("timeout")); - logger.debug(future.getCause().getMessage()); - } finally { - requestManager.close(); - timer.stop(); - } - } - - @Test - public void testRemoveMessageFuture() throws Exception { - HashedWheelTimer timer = getTimer(); - RequestManager requestManager = new RequestManager(timer); - try { - RequestPacket packet = new RequestPacket(1, new byte[0]); - DefaultFuture future = requestManager.register(packet, 2000); - - future.setFailure(new RuntimeException()); - - Future nullFuture = requestManager.removeMessageFuture(packet.getRequestId()); - Assert.assertNull(nullFuture); - - - } finally { - requestManager.close(); - timer.stop(); - } - - } - - private HashedWheelTimer getTimer() { - return new HashedWheelTimer(10, TimeUnit.MICROSECONDS); - } - - // @Test - public void testTimerStartTiming() throws InterruptedException { - HashedWheelTimer timer = new HashedWheelTimer(1000, TimeUnit.MILLISECONDS); - timer.start(); - // start해야 타이머가 thread가 동작한다. - timer.stop(); - } - - @Test - public void testClose() throws Exception { - - } -} +package com.nhn.pinpoint.rpc.client; + +import com.nhn.pinpoint.rpc.DefaultFuture; +import com.nhn.pinpoint.rpc.Future; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import org.jboss.netty.util.HashedWheelTimer; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + */ +public class RequestManagerTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @Test + public void testRegisterRequest() throws Exception { + HashedWheelTimer timer = getTimer(); + RequestManager requestManager = new RequestManager(timer); + try { + RequestPacket packet = new RequestPacket(new byte[0]); + Future future = requestManager.register(packet, 50); + Thread.sleep(200); + + Assert.assertTrue(future.isReady()); + Assert.assertFalse(future.isSuccess()); + Assert.assertTrue(future.getCause().getMessage().contains("timeout")); + logger.debug(future.getCause().getMessage()); + } finally { + requestManager.close(); + timer.stop(); + } + } + + @Test + public void testRemoveMessageFuture() throws Exception { + HashedWheelTimer timer = getTimer(); + RequestManager requestManager = new RequestManager(timer); + try { + RequestPacket packet = new RequestPacket(1, new byte[0]); + DefaultFuture future = requestManager.register(packet, 2000); + + future.setFailure(new RuntimeException()); + + Future nullFuture = requestManager.removeMessageFuture(packet.getRequestId()); + Assert.assertNull(nullFuture); + + + } finally { + requestManager.close(); + timer.stop(); + } + + } + + private HashedWheelTimer getTimer() { + return new HashedWheelTimer(10, TimeUnit.MICROSECONDS); + } + + // @Test + public void testTimerStartTiming() throws InterruptedException { + HashedWheelTimer timer = new HashedWheelTimer(1000, TimeUnit.MILLISECONDS); + timer.start(); + // start해야 타이머가 thread가 동작한다. + timer.stop(); + } + + @Test + public void testClose() throws Exception { + + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/message/SendPacketTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/message/SendPacketTest.java index 50e1a96018e3..160dffde55d9 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/message/SendPacketTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/message/SendPacketTest.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.rpc.message; - -import com.nhn.pinpoint.rpc.packet.SendPacket; -import org.jboss.netty.buffer.ChannelBuffer; -import org.junit.Assert; -import org.junit.Test; - -/** - * @author emeroad - */ -public class SendPacketTest { - @Test - public void testToBuffer() throws Exception { - byte[] bytes = new byte[10]; - SendPacket packetSend = new SendPacket(bytes); - - ChannelBuffer channelBuffer = packetSend.toBuffer(); - - short packetType = channelBuffer.readShort(); - SendPacket packet = (SendPacket) SendPacket.readBuffer(packetType, channelBuffer); - Assert.assertArrayEquals(bytes, packet.getPayload()); - - - } -} +package com.nhn.pinpoint.rpc.message; + +import com.nhn.pinpoint.rpc.packet.SendPacket; +import org.jboss.netty.buffer.ChannelBuffer; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class SendPacketTest { + @Test + public void testToBuffer() throws Exception { + byte[] bytes = new byte[10]; + SendPacket packetSend = new SendPacket(bytes); + + ChannelBuffer channelBuffer = packetSend.toBuffer(); + + short packetType = channelBuffer.readShort(); + SendPacket packet = (SendPacket) SendPacket.readBuffer(packetType, channelBuffer); + Assert.assertArrayEquals(bytes, packet.getPayload()); + + + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/packet/PongPacketTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/packet/PongPacketTest.java index 176019a1749a..ac16dd7e5439 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/packet/PongPacketTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/packet/PongPacketTest.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.rpc.packet; - -import junit.framework.Assert; -import org.jboss.netty.buffer.ChannelBuffer; -import org.junit.Test; - -/** - * @author emeroad - */ -public class PongPacketTest { - @Test - public void testToBuffer() throws Exception { - PongPacket pongPacket = new PongPacket(); - ChannelBuffer channelBuffer = pongPacket.toBuffer(); - - short pongCode = channelBuffer.readShort(); - Assert.assertEquals(PacketType.CONTROL_PONG, pongCode); - - - } -} +package com.nhn.pinpoint.rpc.packet; + +import junit.framework.Assert; +import org.jboss.netty.buffer.ChannelBuffer; +import org.junit.Test; + +/** + * @author emeroad + */ +public class PongPacketTest { + @Test + public void testToBuffer() throws Exception { + PongPacket pongPacket = new PongPacket(); + ChannelBuffer channelBuffer = pongPacket.toBuffer(); + + short pongCode = channelBuffer.readShort(); + Assert.assertEquals(PacketType.CONTROL_PONG, pongCode); + + + } +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentProperties.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentProperties.java index fbda1080147e..846654c75672 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentProperties.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentProperties.java @@ -1,38 +1,38 @@ -package com.nhn.pinpoint.rpc.server; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.util.ClassUtils; - -public class AgentProperties { - - public static final String KEY_HOSTNAME = "hostName"; - public static final String KEY_IP = "ip"; - public static final String KEY_AGENTID = "agentId"; - public static final String KEY_APPLICATION_NAME = "applicationName"; - public static final String KEY_SERVICE_TYPE = "serviceType"; - public static final String KEY_PID = "pid"; - public static final String KEY_VERSION = "version"; - public static final String KEY_START_TIME_MILLIS = "startTimestamp"; - - private final Map properties; - - public AgentProperties(Map properties) { - this.properties = properties; - } - - public T getProperties(String key, Class returnClazz) { - Object value = properties.get(key); - - if (value == null) { - return null; - } - - if (ClassUtils.isAssignable(value.getClass(), returnClazz)) { - return (T) value; - } - - return null; - } - -} +package com.nhn.pinpoint.rpc.server; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.util.ClassUtils; + +public class AgentProperties { + + public static final String KEY_HOSTNAME = "hostName"; + public static final String KEY_IP = "ip"; + public static final String KEY_AGENTID = "agentId"; + public static final String KEY_APPLICATION_NAME = "applicationName"; + public static final String KEY_SERVICE_TYPE = "serviceType"; + public static final String KEY_PID = "pid"; + public static final String KEY_VERSION = "version"; + public static final String KEY_START_TIME_MILLIS = "startTimestamp"; + + private final Map properties; + + public AgentProperties(Map properties) { + this.properties = properties; + } + + public T getProperties(String key, Class returnClazz) { + Object value = properties.get(key); + + if (value == null) { + return null; + } + + if (ClassUtils.isAssignable(value.getClass(), returnClazz)) { + return (T) value; + } + + return null; + } + +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentPropertiesType.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentPropertiesType.java index 2e38fcc36d87..8dd70f795302 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentPropertiesType.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/AgentPropertiesType.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.rpc.server; - -import java.util.Map; - -import com.nhn.pinpoint.rpc.util.ClassUtils; - -public enum AgentPropertiesType { - - HOSTNAME("hostName", String.class), - IP("ip", String.class), - AGENT_ID("agentId", String.class), - APPLICATION_NAME("applicationName", String.class), - SERVICE_TYPE("serviceType", Integer.class), - PID("pid", Integer.class), - VERSION("version", String.class), - START_TIMESTAMP("startTimestamp", Long.class); - - - private final String name; - private final Class clazzType; - - private AgentPropertiesType(String name, Class clazzType) { - this.name = name; - this.clazzType = clazzType; - } - - public String getName() { - return name; - } - - public Class getClazzType() { - return clazzType; - } - - public static boolean hasAllType(Map properties) { - for (AgentPropertiesType type : AgentPropertiesType.values()) { - Object value = properties.get(type.getName()); - - if (value == null) { - return false; - } - - if (!ClassUtils.isAssignable(value.getClass(), type.getClazzType())) { - return false; - } - } - - return true; - } - -} +package com.nhn.pinpoint.rpc.server; + +import java.util.Map; + +import com.nhn.pinpoint.rpc.util.ClassUtils; + +public enum AgentPropertiesType { + + HOSTNAME("hostName", String.class), + IP("ip", String.class), + AGENT_ID("agentId", String.class), + APPLICATION_NAME("applicationName", String.class), + SERVICE_TYPE("serviceType", Integer.class), + PID("pid", Integer.class), + VERSION("version", String.class), + START_TIMESTAMP("startTimestamp", Long.class); + + + private final String name; + private final Class clazzType; + + private AgentPropertiesType(String name, Class clazzType) { + this.name = name; + this.clazzType = clazzType; + } + + public String getName() { + return name; + } + + public Class getClazzType() { + return clazzType; + } + + public static boolean hasAllType(Map properties) { + for (AgentPropertiesType type : AgentPropertiesType.values()) { + Object value = properties.get(type.getName()); + + if (value == null) { + return false; + } + + if (!ClassUtils.isAssignable(value.getClass(), type.getClazzType())) { + return false; + } + } + + return true; + } + +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/ControlPacketServerTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/ControlPacketServerTest.java index cdf0a52d59e8..66a6794def8b 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/ControlPacketServerTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/ControlPacketServerTest.java @@ -1,286 +1,286 @@ -package com.nhn.pinpoint.rpc.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.rpc.control.ProtocolException; -import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; -import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerPacket; -import com.nhn.pinpoint.rpc.packet.RequestPacket; -import com.nhn.pinpoint.rpc.packet.ResponsePacket; -import com.nhn.pinpoint.rpc.packet.SendPacket; -import com.nhn.pinpoint.rpc.packet.StreamPacket; -import com.nhn.pinpoint.rpc.util.ControlMessageEnDeconderUtils; -import com.nhn.pinpoint.rpc.util.MapUtils; - -/** - * @author koo.taejin - */ -public class ControlPacketServerTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - // RegisterPacket 등록 실패한 경우에도 메시지 전달 가능 확인 (return code : 2 파라미터 부족) - @Test - public void registerAgentTest1() throws Exception { - PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); - pinpointServerSocket.setMessageListener(new SimpleListener()); - pinpointServerSocket.bind("127.0.0.1", 22234); - - Socket socket = null; - try { - socket = new Socket("127.0.0.1", 22234); - - sendAndReceiveSimplePacket(socket); - - int code= sendAndReceiveRegisterPacket(socket); - Assert.assertEquals(2, code); - - sendAndReceiveSimplePacket(socket); - } finally { - if (socket != null) { - socket.close(); - } - - if (pinpointServerSocket != null) { - pinpointServerSocket.close(); - } - } - } - - // RegisterPacket 등록 성공시 메시지 전달 가능 확인 (return code : 0) - @Test - public void registerAgentTest2() throws Exception { - PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); - pinpointServerSocket.setMessageListener(new SimpleListener()); - pinpointServerSocket.bind("127.0.0.1", 22234); - - Socket socket = null; - try { - socket = new Socket("127.0.0.1", 22234); - - sendAndReceiveSimplePacket(socket); - - int code= sendAndReceiveRegisterPacket(socket, getParams()); - Assert.assertEquals(0, code); - - sendAndReceiveSimplePacket(socket); - } finally { - if (socket != null) { - socket.close(); - } - - if (pinpointServerSocket != null) { - pinpointServerSocket.close(); - } - } - } - - // RegisterPacket 등록 실패한 경우 다시 Register Packet을 보낼 경우 동일한 메시지 던지는지 확인 (return code : 2 파라미터 부족) - @Test - public void registerAgentTest3() throws Exception { - PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); - pinpointServerSocket.setMessageListener(new SimpleListener()); - pinpointServerSocket.bind("127.0.0.1", 22234); - - Socket socket = null; - try { - socket = new Socket("127.0.0.1", 22234); - int code = sendAndReceiveRegisterPacket(socket); - Assert.assertEquals(2, code); - - code = sendAndReceiveRegisterPacket(socket); - Assert.assertEquals(2, code); - - sendAndReceiveSimplePacket(socket); - } finally { - if (socket != null) { - socket.close(); - } - - if (pinpointServerSocket != null) { - pinpointServerSocket.close(); - } - } - } - - // RegisterPacket 등록 성공 메시지를 여러번 보낼 경우 최초는 성공, 두번쨰는 이미 성공 code를 받는지 확인 - // 이후 메시지 전달 가능 확인 - @Test - public void registerAgentTest4() throws Exception { - PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); - pinpointServerSocket.setMessageListener(new SimpleListener()); - pinpointServerSocket.bind("127.0.0.1", 22234); - - Socket socket = null; - try { - socket = new Socket("127.0.0.1", 22234); - sendAndReceiveSimplePacket(socket); - - int code = sendAndReceiveRegisterPacket(socket, getParams()); - Assert.assertEquals(0, code); - - sendAndReceiveSimplePacket(socket); - - code = sendAndReceiveRegisterPacket(socket, getParams()); - Assert.assertEquals(1, code); - - sendAndReceiveSimplePacket(socket); - } finally { - if (socket != null) { - socket.close(); - } - - if (pinpointServerSocket != null) { - pinpointServerSocket.close(); - } - } - } - - - private int sendAndReceiveRegisterPacket(Socket socket) throws ProtocolException, IOException { - return sendAndReceiveRegisterPacket(socket, Collections.EMPTY_MAP); - } - - private int sendAndReceiveRegisterPacket(Socket socket, Map properties) throws ProtocolException, IOException { - sendRegisterPacket(socket.getOutputStream(), properties); - ControlEnableWorkerConfirmPacket packet = receiveRegisterConfirmPacket(socket.getInputStream()); - Map result = (Map) ControlMessageEnDeconderUtils.decode(packet.getPayload()); - - return MapUtils.getInteger(result, "code", -1); - } - - private void sendAndReceiveSimplePacket(Socket socket) throws ProtocolException, IOException { - sendSimpleRequestPacket(socket.getOutputStream()); - ResponsePacket responsePacket = readSimpleResponsePacket(socket.getInputStream()); - Assert.assertNotNull(responsePacket); - } - - private void sendRegisterPacket(OutputStream outputStream, Map properties) throws ProtocolException, IOException { - byte[] payload = ControlMessageEnDeconderUtils.encode(properties); - ControlEnableWorkerPacket packet = new ControlEnableWorkerPacket(1, payload); - - ByteBuffer bb = packet.toBuffer().toByteBuffer(0, packet.toBuffer().writerIndex()); - sendData(outputStream, bb.array()); - } - - private void sendSimpleRequestPacket(OutputStream outputStream) throws ProtocolException, IOException { - RequestPacket packet = new RequestPacket(new byte[0]); - packet.setRequestId(10); - - ByteBuffer bb = packet.toBuffer().toByteBuffer(0, packet.toBuffer().writerIndex()); - sendData(outputStream, bb.array()); - } - - private void sendData(OutputStream outputStream, byte[] payload) throws IOException { - outputStream.write(payload); - outputStream.flush(); - } - - private ControlEnableWorkerConfirmPacket receiveRegisterConfirmPacket(InputStream inputStream) throws ProtocolException, IOException { - - byte[] payload = readData(inputStream); - ChannelBuffer cb = ChannelBuffers.wrappedBuffer(payload); - - short packetType = cb.readShort(); - - ControlEnableWorkerConfirmPacket packet = ControlEnableWorkerConfirmPacket.readBuffer(packetType, cb); - return packet; - } - - private ResponsePacket readSimpleResponsePacket(InputStream inputStream) throws ProtocolException, IOException { - byte[] payload = readData(inputStream); - ChannelBuffer cb = ChannelBuffers.wrappedBuffer(payload); - - short packetType = cb.readShort(); - - ResponsePacket packet = ResponsePacket.readBuffer(packetType, cb); - return packet; - } - - private byte[] readData(InputStream inputStream) throws IOException { - int availableSize = 0; - - for (int i = 0; i < 3; i++) { - availableSize = inputStream.available(); - - if (availableSize > 0) { - break; - } - - try { - Thread.sleep(50); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - byte[] payload = new byte[availableSize]; - inputStream.read(payload); - - return payload; - } - - class SimpleListener implements ServerMessageListener { - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - logger.info("handlerRequest {} {}", requestPacket, channel); - channel.sendResponseMessage(requestPacket, requestPacket.getPayload()); - } - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.info("handleStream {} {}", streamPacket, streamChannel); - - } - - @Override - public int handleEnableWorker(Map properties) { - if (properties == null) { - return ControlEnableWorkerConfirmPacket.ILLEGAL_PROTOCOL; - } - - boolean hasAllType = AgentPropertiesType.hasAllType(properties); - if (!hasAllType) { - return ControlEnableWorkerConfirmPacket.INVALID_PROPERTIES; - } - - return ControlEnableWorkerConfirmPacket.SUCCESS; - } - } - - private Map getParams() { - Map properties = new HashMap(); - - properties.put(AgentProperties.KEY_AGENTID, "agent"); - properties.put(AgentProperties.KEY_APPLICATION_NAME, "application"); - properties.put(AgentProperties.KEY_HOSTNAME, "hostname"); - properties.put(AgentProperties.KEY_IP, "ip"); - properties.put(AgentProperties.KEY_PID, 1111); - properties.put(AgentProperties.KEY_SERVICE_TYPE, 10); - properties.put(AgentProperties.KEY_START_TIME_MILLIS, System.currentTimeMillis()); - properties.put(AgentProperties.KEY_VERSION, "1.0"); - - return properties; - } - -} +package com.nhn.pinpoint.rpc.server; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.rpc.control.ProtocolException; +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerConfirmPacket; +import com.nhn.pinpoint.rpc.packet.ControlEnableWorkerPacket; +import com.nhn.pinpoint.rpc.packet.RequestPacket; +import com.nhn.pinpoint.rpc.packet.ResponsePacket; +import com.nhn.pinpoint.rpc.packet.SendPacket; +import com.nhn.pinpoint.rpc.packet.StreamPacket; +import com.nhn.pinpoint.rpc.util.ControlMessageEnDeconderUtils; +import com.nhn.pinpoint.rpc.util.MapUtils; + +/** + * @author koo.taejin + */ +public class ControlPacketServerTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + // RegisterPacket 등록 실패한 경우에도 메시지 전달 가능 확인 (return code : 2 파라미터 부족) + @Test + public void registerAgentTest1() throws Exception { + PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); + pinpointServerSocket.setMessageListener(new SimpleListener()); + pinpointServerSocket.bind("127.0.0.1", 22234); + + Socket socket = null; + try { + socket = new Socket("127.0.0.1", 22234); + + sendAndReceiveSimplePacket(socket); + + int code= sendAndReceiveRegisterPacket(socket); + Assert.assertEquals(2, code); + + sendAndReceiveSimplePacket(socket); + } finally { + if (socket != null) { + socket.close(); + } + + if (pinpointServerSocket != null) { + pinpointServerSocket.close(); + } + } + } + + // RegisterPacket 등록 성공시 메시지 전달 가능 확인 (return code : 0) + @Test + public void registerAgentTest2() throws Exception { + PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); + pinpointServerSocket.setMessageListener(new SimpleListener()); + pinpointServerSocket.bind("127.0.0.1", 22234); + + Socket socket = null; + try { + socket = new Socket("127.0.0.1", 22234); + + sendAndReceiveSimplePacket(socket); + + int code= sendAndReceiveRegisterPacket(socket, getParams()); + Assert.assertEquals(0, code); + + sendAndReceiveSimplePacket(socket); + } finally { + if (socket != null) { + socket.close(); + } + + if (pinpointServerSocket != null) { + pinpointServerSocket.close(); + } + } + } + + // RegisterPacket 등록 실패한 경우 다시 Register Packet을 보낼 경우 동일한 메시지 던지는지 확인 (return code : 2 파라미터 부족) + @Test + public void registerAgentTest3() throws Exception { + PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); + pinpointServerSocket.setMessageListener(new SimpleListener()); + pinpointServerSocket.bind("127.0.0.1", 22234); + + Socket socket = null; + try { + socket = new Socket("127.0.0.1", 22234); + int code = sendAndReceiveRegisterPacket(socket); + Assert.assertEquals(2, code); + + code = sendAndReceiveRegisterPacket(socket); + Assert.assertEquals(2, code); + + sendAndReceiveSimplePacket(socket); + } finally { + if (socket != null) { + socket.close(); + } + + if (pinpointServerSocket != null) { + pinpointServerSocket.close(); + } + } + } + + // RegisterPacket 등록 성공 메시지를 여러번 보낼 경우 최초는 성공, 두번쨰는 이미 성공 code를 받는지 확인 + // 이후 메시지 전달 가능 확인 + @Test + public void registerAgentTest4() throws Exception { + PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); + pinpointServerSocket.setMessageListener(new SimpleListener()); + pinpointServerSocket.bind("127.0.0.1", 22234); + + Socket socket = null; + try { + socket = new Socket("127.0.0.1", 22234); + sendAndReceiveSimplePacket(socket); + + int code = sendAndReceiveRegisterPacket(socket, getParams()); + Assert.assertEquals(0, code); + + sendAndReceiveSimplePacket(socket); + + code = sendAndReceiveRegisterPacket(socket, getParams()); + Assert.assertEquals(1, code); + + sendAndReceiveSimplePacket(socket); + } finally { + if (socket != null) { + socket.close(); + } + + if (pinpointServerSocket != null) { + pinpointServerSocket.close(); + } + } + } + + + private int sendAndReceiveRegisterPacket(Socket socket) throws ProtocolException, IOException { + return sendAndReceiveRegisterPacket(socket, Collections.EMPTY_MAP); + } + + private int sendAndReceiveRegisterPacket(Socket socket, Map properties) throws ProtocolException, IOException { + sendRegisterPacket(socket.getOutputStream(), properties); + ControlEnableWorkerConfirmPacket packet = receiveRegisterConfirmPacket(socket.getInputStream()); + Map result = (Map) ControlMessageEnDeconderUtils.decode(packet.getPayload()); + + return MapUtils.getInteger(result, "code", -1); + } + + private void sendAndReceiveSimplePacket(Socket socket) throws ProtocolException, IOException { + sendSimpleRequestPacket(socket.getOutputStream()); + ResponsePacket responsePacket = readSimpleResponsePacket(socket.getInputStream()); + Assert.assertNotNull(responsePacket); + } + + private void sendRegisterPacket(OutputStream outputStream, Map properties) throws ProtocolException, IOException { + byte[] payload = ControlMessageEnDeconderUtils.encode(properties); + ControlEnableWorkerPacket packet = new ControlEnableWorkerPacket(1, payload); + + ByteBuffer bb = packet.toBuffer().toByteBuffer(0, packet.toBuffer().writerIndex()); + sendData(outputStream, bb.array()); + } + + private void sendSimpleRequestPacket(OutputStream outputStream) throws ProtocolException, IOException { + RequestPacket packet = new RequestPacket(new byte[0]); + packet.setRequestId(10); + + ByteBuffer bb = packet.toBuffer().toByteBuffer(0, packet.toBuffer().writerIndex()); + sendData(outputStream, bb.array()); + } + + private void sendData(OutputStream outputStream, byte[] payload) throws IOException { + outputStream.write(payload); + outputStream.flush(); + } + + private ControlEnableWorkerConfirmPacket receiveRegisterConfirmPacket(InputStream inputStream) throws ProtocolException, IOException { + + byte[] payload = readData(inputStream); + ChannelBuffer cb = ChannelBuffers.wrappedBuffer(payload); + + short packetType = cb.readShort(); + + ControlEnableWorkerConfirmPacket packet = ControlEnableWorkerConfirmPacket.readBuffer(packetType, cb); + return packet; + } + + private ResponsePacket readSimpleResponsePacket(InputStream inputStream) throws ProtocolException, IOException { + byte[] payload = readData(inputStream); + ChannelBuffer cb = ChannelBuffers.wrappedBuffer(payload); + + short packetType = cb.readShort(); + + ResponsePacket packet = ResponsePacket.readBuffer(packetType, cb); + return packet; + } + + private byte[] readData(InputStream inputStream) throws IOException { + int availableSize = 0; + + for (int i = 0; i < 3; i++) { + availableSize = inputStream.available(); + + if (availableSize > 0) { + break; + } + + try { + Thread.sleep(50); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + byte[] payload = new byte[availableSize]; + inputStream.read(payload); + + return payload; + } + + class SimpleListener implements ServerMessageListener { + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.info("handlerRequest {} {}", requestPacket, channel); + channel.sendResponseMessage(requestPacket, requestPacket.getPayload()); + } + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.info("handleStream {} {}", streamPacket, streamChannel); + + } + + @Override + public int handleEnableWorker(Map properties) { + if (properties == null) { + return ControlEnableWorkerConfirmPacket.ILLEGAL_PROTOCOL; + } + + boolean hasAllType = AgentPropertiesType.hasAllType(properties); + if (!hasAllType) { + return ControlEnableWorkerConfirmPacket.INVALID_PROPERTIES; + } + + return ControlEnableWorkerConfirmPacket.SUCCESS; + } + } + + private Map getParams() { + Map properties = new HashMap(); + + properties.put(AgentProperties.KEY_AGENTID, "agent"); + properties.put(AgentProperties.KEY_APPLICATION_NAME, "application"); + properties.put(AgentProperties.KEY_HOSTNAME, "hostname"); + properties.put(AgentProperties.KEY_IP, "ip"); + properties.put(AgentProperties.KEY_PID, 1111); + properties.put(AgentProperties.KEY_SERVICE_TYPE, 10); + properties.put(AgentProperties.KEY_START_TIME_MILLIS, System.currentTimeMillis()); + properties.put(AgentProperties.KEY_VERSION, "1.0"); + + return properties; + } + +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/MessageListenerTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/MessageListenerTest.java index aeb9d843031d..ec1a75218a40 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/MessageListenerTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/MessageListenerTest.java @@ -259,7 +259,7 @@ public void handleSend(SendPacket sendPacket, Channel channel) { sendPacketRepository.add(sendPacket); byte[] payload = sendPacket.getPayload(); - System.out.println(new String(payload)); + logger.debug(new String(payload)); } @Override @@ -267,7 +267,7 @@ public void handleRequest(RequestPacket requestPacket, Channel channel) { requestPacketRepository.add(requestPacket); byte[] payload = requestPacket.getPayload(); - System.out.println(new String(payload)); + logger.debug(new String(payload)); channel.write(new ResponsePacket(requestPacket.getRequestId(), requestPacket.getPayload())); } diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateTest.java index 116fd10e18f0..5bb0e5bc52fb 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketStateTest.java @@ -1,105 +1,105 @@ -package com.nhn.pinpoint.rpc.server; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author koo.taejin - */ -public class PinpointServerSocketStateTest { - - // Agent버전이 최신일 경우 (2014-07 기준) - // 가장 기본적인 형태 RUN -> 이후 Agent 정보 획득 RUN_DUPLEX_COMMUNICATION -> 클라이언트 종료전 Agent 정보 제거 요청에 따른 BEING_SHUTDOWN -> 연결종료 - @Test - public void changeStateTest1() { - PinpointServerSocketState state = new PinpointServerSocketState(); - - state.changeStateRun(); - Assert.assertEquals(PinpointServerSocketStateCode.RUN, state.getCurrentState()); - - state.changeStateRunDuplexCommunication(); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); - - state.changeStateBeingShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.BEING_SHUTDOWN, state.getCurrentState()); - - state.changeStateShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); - } - - // Agent버전이 최신일 경우 (2014-07 기준) - // 가장 기본적인 형태 RUN_DUPLEX_COMMUNICATION -> 이후 Agent 정보 획득 RUN_DUPLEX_COMMUNICATION -> 클라이언트 종료전 Agent 정보 제거 요청에 따른 BEING_SHUTDOWN -> 연결종료 - @Test - public void changeStateTest2() { - PinpointServerSocketState state = new PinpointServerSocketState(); - - state.changeStateRunDuplexCommunication(); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); - - state.changeStateBeingShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.BEING_SHUTDOWN, state.getCurrentState()); - - state.changeStateShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); - } - - // Agent버전이 구버전일 경우 (2014-07 기준) - // 가장 기본적인 형태 RUN -> 연결종료 - @Test - public void changeStateTest3() { - PinpointServerSocketState state = new PinpointServerSocketState(); - - state.changeStateRun(); - Assert.assertEquals(PinpointServerSocketStateCode.RUN, state.getCurrentState()); - - state.changeStateUnexpectedShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.UNEXPECTED_SHUTDOWN, state.getCurrentState()); - } - - // Agent버전이 구버전일 경우 (2014-07 기준) - // 가장 기본적인 형태 RUN -> 연결종료 - @Test - public void changeStateTest4() { - PinpointServerSocketState state = new PinpointServerSocketState(); - - state.changeStateRun(); - Assert.assertEquals(PinpointServerSocketStateCode.RUN, state.getCurrentState()); - - state.changeStateShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); - } - - @Test - public void changeStateTest5() { - PinpointServerSocketState state = new PinpointServerSocketState(); - - state.changeStateRunDuplexCommunication(); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); - - state.changeStateShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); - } - - - - @Test(expected = IllegalStateException.class) - public void invalidChangeStateTest1() { - PinpointServerSocketState state = new PinpointServerSocketState(); - - state.changeStateBeingShutdown(); - } - - @Test(expected = IllegalStateException.class) - public void invalidChangeStateTest2() { - PinpointServerSocketState state = new PinpointServerSocketState(); - - state.changeStateRunDuplexCommunication(); - Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); - - state.changeStateBeingShutdown(); - Assert.assertEquals(PinpointServerSocketStateCode.BEING_SHUTDOWN, state.getCurrentState()); - - state.changeStateUnexpectedShutdown(); - } - -} +package com.nhn.pinpoint.rpc.server; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author koo.taejin + */ +public class PinpointServerSocketStateTest { + + // Agent버전이 최신일 경우 (2014-07 기준) + // 가장 기본적인 형태 RUN -> 이후 Agent 정보 획득 RUN_DUPLEX_COMMUNICATION -> 클라이언트 종료전 Agent 정보 제거 요청에 따른 BEING_SHUTDOWN -> 연결종료 + @Test + public void changeStateTest1() { + PinpointServerSocketState state = new PinpointServerSocketState(); + + state.changeStateRun(); + Assert.assertEquals(PinpointServerSocketStateCode.RUN, state.getCurrentState()); + + state.changeStateRunDuplexCommunication(); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); + + state.changeStateBeingShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.BEING_SHUTDOWN, state.getCurrentState()); + + state.changeStateShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); + } + + // Agent버전이 최신일 경우 (2014-07 기준) + // 가장 기본적인 형태 RUN_DUPLEX_COMMUNICATION -> 이후 Agent 정보 획득 RUN_DUPLEX_COMMUNICATION -> 클라이언트 종료전 Agent 정보 제거 요청에 따른 BEING_SHUTDOWN -> 연결종료 + @Test + public void changeStateTest2() { + PinpointServerSocketState state = new PinpointServerSocketState(); + + state.changeStateRunDuplexCommunication(); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); + + state.changeStateBeingShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.BEING_SHUTDOWN, state.getCurrentState()); + + state.changeStateShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); + } + + // Agent버전이 구버전일 경우 (2014-07 기준) + // 가장 기본적인 형태 RUN -> 연결종료 + @Test + public void changeStateTest3() { + PinpointServerSocketState state = new PinpointServerSocketState(); + + state.changeStateRun(); + Assert.assertEquals(PinpointServerSocketStateCode.RUN, state.getCurrentState()); + + state.changeStateUnexpectedShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.UNEXPECTED_SHUTDOWN, state.getCurrentState()); + } + + // Agent버전이 구버전일 경우 (2014-07 기준) + // 가장 기본적인 형태 RUN -> 연결종료 + @Test + public void changeStateTest4() { + PinpointServerSocketState state = new PinpointServerSocketState(); + + state.changeStateRun(); + Assert.assertEquals(PinpointServerSocketStateCode.RUN, state.getCurrentState()); + + state.changeStateShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); + } + + @Test + public void changeStateTest5() { + PinpointServerSocketState state = new PinpointServerSocketState(); + + state.changeStateRunDuplexCommunication(); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); + + state.changeStateShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.SHUTDOWN, state.getCurrentState()); + } + + + + @Test(expected = IllegalStateException.class) + public void invalidChangeStateTest1() { + PinpointServerSocketState state = new PinpointServerSocketState(); + + state.changeStateBeingShutdown(); + } + + @Test(expected = IllegalStateException.class) + public void invalidChangeStateTest2() { + PinpointServerSocketState state = new PinpointServerSocketState(); + + state.changeStateRunDuplexCommunication(); + Assert.assertEquals(PinpointServerSocketStateCode.RUN_DUPLEX_COMMUNICATION, state.getCurrentState()); + + state.changeStateBeingShutdown(); + Assert.assertEquals(PinpointServerSocketStateCode.BEING_SHUTDOWN, state.getCurrentState()); + + state.changeStateUnexpectedShutdown(); + } + +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketTest.java index 6f86f39d7ea1..df96e01e9dc0 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/PinpointServerSocketTest.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.rpc.server; - -import com.nhn.pinpoint.rpc.DiscardPipelineFactory; -import org.junit.Test; - -import java.net.Socket; - -/** - * @author emeroad - */ -public class PinpointServerSocketTest { - @Test - public void testBind() throws Exception { - PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); - pinpointServerSocket.setPipelineFactory(new DiscardPipelineFactory()); - - pinpointServerSocket.bind("127.0.0.1", 22234); - - Socket socket = new Socket("127.0.0.1", 22234); - socket.getOutputStream().write(new byte[10]); - socket.getOutputStream().flush(); - socket.close(); - - Thread.sleep(1000); - pinpointServerSocket.close(); - } - - -} +package com.nhn.pinpoint.rpc.server; + +import com.nhn.pinpoint.rpc.DiscardPipelineFactory; +import org.junit.Test; + +import java.net.Socket; + +/** + * @author emeroad + */ +public class PinpointServerSocketTest { + @Test + public void testBind() throws Exception { + PinpointServerSocket pinpointServerSocket = new PinpointServerSocket(); + pinpointServerSocket.setPipelineFactory(new DiscardPipelineFactory()); + + pinpointServerSocket.bind("127.0.0.1", 22234); + + Socket socket = new Socket("127.0.0.1", 22234); + socket.getOutputStream().write(new byte[10]); + socket.getOutputStream().flush(); + socket.close(); + + Thread.sleep(1000); + pinpointServerSocket.close(); + } + + +} diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/TestSeverMessageListener.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/TestSeverMessageListener.java index 8f3e17d8b8e2..a5538e5a70e7 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/TestSeverMessageListener.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/server/TestSeverMessageListener.java @@ -1,79 +1,79 @@ -package com.nhn.pinpoint.rpc.server; - -import com.nhn.pinpoint.rpc.TestByteUtils; -import com.nhn.pinpoint.rpc.packet.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * @author emeroad - */ -public class TestSeverMessageListener implements ServerMessageListener { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private byte[] open; - private List sendMessageList = new ArrayList(); - - @Override - public void handleSend(SendPacket sendPacket, SocketChannel channel) { - logger.debug("sendPacket:{} channel:{}", sendPacket, channel); - } - - @Override - public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { - logger.debug("requestPacket:{} channel:{}", requestPacket, channel); - - channel.sendResponseMessage(requestPacket, requestPacket.getPayload()); - } - - - @Override - public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { - logger.debug("streamPacket:{} channel:{}", streamPacket, streamChannel); - if (streamPacket instanceof StreamCreatePacket) { - byte[] payload = streamPacket.getPayload(); - this.open = payload; - streamChannel.sendOpenResult(true, payload); - sendStreamMessage(streamChannel); - sendStreamMessage(streamChannel); - sendStreamMessage(streamChannel); - - sendClose(streamChannel); - } else if(streamPacket instanceof StreamClosePacket) { - // 채널 종료해야 함. - } - - } - - @Override - public int handleEnableWorker(Map properties) { - logger.debug("handleEnableWorker properties:{} channel:{}", properties); - return ControlEnableWorkerConfirmPacket.SUCCESS; - } - - private void sendClose(ServerStreamChannel streamChannel) { - sendMessageList.add(new byte[0]); - streamChannel.close(); - } - - private void sendStreamMessage(ServerStreamChannel streamChannel) { - byte[] randomByte = TestByteUtils.createRandomByte(10); - streamChannel.sendStreamMessage(randomByte); - sendMessageList.add(randomByte); - } - - public byte[] getOpen() { - return open; - } - - public List getSendMessage() { - return sendMessageList; - } -} - +package com.nhn.pinpoint.rpc.server; + +import com.nhn.pinpoint.rpc.TestByteUtils; +import com.nhn.pinpoint.rpc.packet.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author emeroad + */ +public class TestSeverMessageListener implements ServerMessageListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private byte[] open; + private List sendMessageList = new ArrayList(); + + @Override + public void handleSend(SendPacket sendPacket, SocketChannel channel) { + logger.debug("sendPacket:{} channel:{}", sendPacket, channel); + } + + @Override + public void handleRequest(RequestPacket requestPacket, SocketChannel channel) { + logger.debug("requestPacket:{} channel:{}", requestPacket, channel); + + channel.sendResponseMessage(requestPacket, requestPacket.getPayload()); + } + + + @Override + public void handleStream(StreamPacket streamPacket, ServerStreamChannel streamChannel) { + logger.debug("streamPacket:{} channel:{}", streamPacket, streamChannel); + if (streamPacket instanceof StreamCreatePacket) { + byte[] payload = streamPacket.getPayload(); + this.open = payload; + streamChannel.sendOpenResult(true, payload); + sendStreamMessage(streamChannel); + sendStreamMessage(streamChannel); + sendStreamMessage(streamChannel); + + sendClose(streamChannel); + } else if(streamPacket instanceof StreamClosePacket) { + // 채널 종료해야 함. + } + + } + + @Override + public int handleEnableWorker(Map properties) { + logger.debug("handleEnableWorker properties:{} channel:{}", properties); + return ControlEnableWorkerConfirmPacket.SUCCESS; + } + + private void sendClose(ServerStreamChannel streamChannel) { + sendMessageList.add(new byte[0]); + streamChannel.close(); + } + + private void sendStreamMessage(ServerStreamChannel streamChannel) { + byte[] randomByte = TestByteUtils.createRandomByte(10); + streamChannel.sendStreamMessage(randomByte); + sendMessageList.add(randomByte); + } + + public byte[] getOpen() { + return open; + } + + public List getSendMessage() { + return sendMessageList; + } +} + diff --git a/rpc/src/test/java/com/navercorp/pinpoint/rpc/util/CopyUtilsTest.java b/rpc/src/test/java/com/navercorp/pinpoint/rpc/util/CopyUtilsTest.java index ad862c5870d3..3a6406394328 100644 --- a/rpc/src/test/java/com/navercorp/pinpoint/rpc/util/CopyUtilsTest.java +++ b/rpc/src/test/java/com/navercorp/pinpoint/rpc/util/CopyUtilsTest.java @@ -1,65 +1,65 @@ -package com.nhn.pinpoint.rpc.util; - -import java.util.HashMap; -import java.util.Map; - -import junit.framework.Assert; - -import org.junit.Test; - -public class CopyUtilsTest { - - @Test - public void copyUtilsTest() { - Map original = createSimpleMap("key", 2); - - Map copied = CopyUtils.mediumCopyMap(original); - Assert.assertEquals(2, copied.get("key")); - Assert.assertEquals(2, original.get("key")); - - original.put("key", 4); - copied.put("key", 3); - copied.put("new", "new"); - - Assert.assertEquals(3, copied.get("key")); - Assert.assertEquals("new", copied.get("new")); - Assert.assertEquals(4, original.get("key")); - } - - @Test - public void copyUtilsTest2() { - Map original = createSimpleMap("key", 2); - - Map innerMap = createSimpleMap("innerKey", "inner"); - original.put("map", innerMap); - - Map copied = CopyUtils.mediumCopyMap(original); - - Assert.assertEquals(2, copied.get("key")); - Assert.assertEquals("inner", ((Map) copied.get("map")).get("innerKey")); - Assert.assertEquals(2, original.get("key")); - Assert.assertEquals("inner", ((Map) original.get("map")).get("innerKey")); - - original.put("key", 3); - copied.put("key", 4); - - innerMap.put("innerKey", "key"); - Map copiedInnerMap = (Map) copied.get("map"); - copiedInnerMap.put("test", "test"); - - Assert.assertEquals(4, copied.get("key")); - Assert.assertEquals("inner", ((Map) copied.get("map")).get("innerKey")); - Assert.assertEquals("test", ((Map) copied.get("map")).get("test")); - Assert.assertEquals(3, original.get("key")); - Assert.assertEquals("key", ((Map) original.get("map")).get("innerKey")); - Assert.assertFalse(((Map) original.get("map")).containsKey("test")); - } - - private Map createSimpleMap(Object key, Object value) { - Map map = new HashMap(); - map.put(key, value); - - return map; - } - -} +package com.nhn.pinpoint.rpc.util; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.Assert; + +import org.junit.Test; + +public class CopyUtilsTest { + + @Test + public void copyUtilsTest() { + Map original = createSimpleMap("key", 2); + + Map copied = CopyUtils.mediumCopyMap(original); + Assert.assertEquals(2, copied.get("key")); + Assert.assertEquals(2, original.get("key")); + + original.put("key", 4); + copied.put("key", 3); + copied.put("new", "new"); + + Assert.assertEquals(3, copied.get("key")); + Assert.assertEquals("new", copied.get("new")); + Assert.assertEquals(4, original.get("key")); + } + + @Test + public void copyUtilsTest2() { + Map original = createSimpleMap("key", 2); + + Map innerMap = createSimpleMap("innerKey", "inner"); + original.put("map", innerMap); + + Map copied = CopyUtils.mediumCopyMap(original); + + Assert.assertEquals(2, copied.get("key")); + Assert.assertEquals("inner", ((Map) copied.get("map")).get("innerKey")); + Assert.assertEquals(2, original.get("key")); + Assert.assertEquals("inner", ((Map) original.get("map")).get("innerKey")); + + original.put("key", 3); + copied.put("key", 4); + + innerMap.put("innerKey", "key"); + Map copiedInnerMap = (Map) copied.get("map"); + copiedInnerMap.put("test", "test"); + + Assert.assertEquals(4, copied.get("key")); + Assert.assertEquals("inner", ((Map) copied.get("map")).get("innerKey")); + Assert.assertEquals("test", ((Map) copied.get("map")).get("test")); + Assert.assertEquals(3, original.get("key")); + Assert.assertEquals("key", ((Map) original.get("map")).get("innerKey")); + Assert.assertFalse(((Map) original.get("map")).containsKey("test")); + } + + private Map createSimpleMap(Object key, Object value) { + Map map = new HashMap(); + map.put(key, value); + + return map; + } + +} diff --git a/rpc/src/test/resources/log4j.xml b/rpc/src/test/resources/log4j.xml index 7067a1bb8a5f..e8645d9b610e 100644 --- a/rpc/src/test/resources/log4j.xml +++ b/rpc/src/test/resources/log4j.xml @@ -1,49 +1,49 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testweb/src/main/java/com/linecorp/games/common/baseFramework/handlers/HttpCustomServerHandler.java b/testweb/src/main/java/com/linecorp/games/common/baseFramework/handlers/HttpCustomServerHandler.java index aae9541c4d93..9d9900022fb6 100644 --- a/testweb/src/main/java/com/linecorp/games/common/baseFramework/handlers/HttpCustomServerHandler.java +++ b/testweb/src/main/java/com/linecorp/games/common/baseFramework/handlers/HttpCustomServerHandler.java @@ -1,269 +1,269 @@ -package com.linecorp.games.common.baseFramework.handlers; - -import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive; -import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; -import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH; -import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; -import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.COOKIE; -import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.SET_COOKIE; -import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK; -import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import net.spy.memcached.ArcusClient; -import net.spy.memcached.ConnectionFactoryBuilder; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.jboss.netty.handler.codec.http.Cookie; -import org.jboss.netty.handler.codec.http.CookieDecoder; -import org.jboss.netty.handler.codec.http.CookieEncoder; -import org.jboss.netty.handler.codec.http.DefaultHttpResponse; -import org.jboss.netty.handler.codec.http.HttpHeaders; -import org.jboss.netty.handler.codec.http.HttpMethod; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponse; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.HttpVersion; -import org.jboss.netty.handler.codec.http.QueryStringDecoder; -import org.jboss.netty.util.CharsetUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.convert.ConverterNotFoundException; - -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; -import com.nhn.pinpoint.testweb.connector.ningasync.NingAsyncHttpClient; -import com.ning.http.client.Response; - -public class HttpCustomServerHandler extends SimpleChannelUpstreamHandler { - private static final Logger logger = LoggerFactory.getLogger(HttpCustomServerHandler.class.getName()); - - private final ListeningExecutorService listeningExecutorService; - - private final ArcusClient arcus; - private final NingAsyncHttpClient asyncHttpInvoker = new NingAsyncHttpClient(); - - public HttpCustomServerHandler() { - this.listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); - this.arcus = ArcusClient.createArcusClient("dev.arcuscloud.nhncorp.com:17288", "dev", new ConnectionFactoryBuilder()); - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - System.out.println("HttpCustomServerHandler.messageReceived (" + Thread.currentThread().getName() + ")"); - this.listeningExecutorService.submit(new InvokeTask(ctx, e)); - } - - private void accessArcus() { - Future future = null; - try { - future = arcus.set("pinpoint:test", 10, "Hello, Arcus"); - future.get(100L, TimeUnit.MILLISECONDS); - } catch (Exception e) { - if (future != null) { - future.cancel(true); - } - } - } - - private void accessNaver() { - asyncHttpInvoker.requestGet("http://blog.naver.com", NingAsyncHttpClient.getDummyParams(), NingAsyncHttpClient.getDummyHeaders(), NingAsyncHttpClient.getDummyCookies()); - } - - private void accessPinPointDev() { - asyncHttpInvoker.requestGet("http://10.101.55.177:9080/threetier.pinpoint", null, null, null); - } - - private class InvokeTask implements Runnable { - private final ChannelHandlerContext ctx; - private final MessageEvent e; - - public InvokeTask(ChannelHandlerContext ctx, MessageEvent e) { - this.ctx = ctx; - this.e = e; - } - - public void run() { - System.out.println("InvokeTask.run (" + Thread.currentThread().getName() + ")"); - - if (!(e.getMessage() instanceof HttpRequest)) { - logger.debug("[n/a] received message is illegal."); - DefaultHttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST); - ctx.getChannel().write(res).addListener(ChannelFutureListener.CLOSE); - return; - } - - HttpRequest request = (HttpRequest) e.getMessage(); - - // intercept - - try { - StringBuilder buf = new StringBuilder(); - - // this.request = (HttpRequest) e.getMessage(); - Object[] requestBody = null; - Object functionsResult = null; - - HttpResponseStatus status = OK; - String uri = request.getUri().substring(1); - - // List> headers = request.getHeaders(); - List> reponseHeader = new ArrayList>(); - - buf.setLength(0); - - HttpMethod reqMethod = request.getMethod(); - if (reqMethod.equals(HttpMethod.POST) || reqMethod.equals(HttpMethod.PUT) || reqMethod.equals(HttpMethod.DELETE)) { - ChannelBuffer content = request.getContent(); - - // invoke bo (async ??) - - buf.append("HelloNetty"); - - if (content.readable()) { - try { - - } catch (ConverterNotFoundException e1) { - status = HttpResponseStatus.BAD_REQUEST; - logger.error("convert fail : exception={}", e1.getMessage()); - buf.append(getResultString(status.getCode(), "Invalid parameter")); - } - } else { - status = HttpResponseStatus.BAD_REQUEST; - buf.append(getResultString(status.getCode(), "No content on request.")); - } - } else if (reqMethod.equals(HttpMethod.GET)) { - QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri); - Map> queries = queryStringDecoder.getParameters(); - - buf.append("HelloNetty"); - - } else { - status = HttpResponseStatus.METHOD_NOT_ALLOWED; - buf.append(getResultString(status.getCode(), "method not supports")); - } - - // for demo - accessArcus(); - accessNaver(); - accessPinPointDev(); - - writeResponse(request, e, status, reponseHeader, buf); - } catch (Exception ex) { - handleException(request, this.ctx, ex); - } - } - } - - protected void writeResponse(HttpRequest request, MessageEvent e, HttpResponseStatus status, List> reponseHeader, StringBuilder resultContents) { - // Decide whether to close the connection or not. - boolean keepAlive = isKeepAlive(request); - - // Build the response object. - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status); - - response.setContent(ChannelBuffers.copiedBuffer(resultContents.toString(), CharsetUtil.UTF_8)); - - // response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); - response.setHeader(CONTENT_TYPE, "application/json"); - - response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes()); - if (keepAlive) { - response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); - } - - for (Entry header : reponseHeader) { - response.setHeader(header.getKey(), header.getValue()); - } - - // Encode the cookie. - String cookieString = request.getHeader(COOKIE); - if (cookieString != null) { - CookieDecoder cookieDecoder = new CookieDecoder(); - Set cookies = cookieDecoder.decode(cookieString); - if (!cookies.isEmpty()) { - CookieEncoder cookieEncoder = new CookieEncoder(true); - for (Cookie cookie : cookies) { - cookieEncoder.addCookie(cookie); - response.addHeader(SET_COOKIE, cookieEncoder.encode()); - } - } - } - - ChannelFuture future = e.getChannel().write(response); - - if (!keepAlive) { - future.addListener(ChannelFutureListener.CLOSE); - } else - future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE); - } - - private String stackTraceToStr(Throwable e) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - return sw.toString(); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { - - Channel channel = ctx.getChannel(); - if (channel.isOpen()) { - - logger.error("channel error : exception={}", e); - channel.close(); - } - } - - public void handleException(HttpRequest request, ChannelHandlerContext ctx, Exception e) { - Channel channel = ctx.getChannel(); - if (channel.isOpen()) { - String body = request.getContent().readable() ? new String(request.getContent().array()) : ""; - String cause = stackTraceToStr(e.getCause()); - - logger.error("exceptionCaught : method={} \r\nURI={}, \r\nheaders={}, \r\nbody={}, \r\ncauseBy={}", request.getMethod().getName(), request.getUri(), request.getHeaders(), body, cause); - - if (channel.isWritable() && !(e.getCause() instanceof java.io.IOException)) { - - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); - - response.setHeader(CONTENT_TYPE, "application/json; charset=UTF-8"); - response.setContent(ChannelBuffers.copiedBuffer(this.getResultString(500, "Internal Server Error", e.getCause().toString()), CharsetUtil.UTF_8)); - - channel.write(response); - - String uri = request.getUri().substring(1); - HttpMethod reqMethod = request.getMethod(); - - } - channel.close(); - } - } - - private String getResultString(int statusCode, String message) { - return String.format("{\"statusCode\":%s,\"statusMessage\":\"%s\"}", statusCode, message); - } - - private String getResultString(int statusCode, String message, String cause) { - return String.format("{\"statusCode\":%s,\"statusMessage\":\"%s\",\"causeBy\":\"%s\"}", statusCode, message, cause); - } -} +package com.linecorp.games.common.baseFramework.handlers; + +import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.COOKIE; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.SET_COOKIE; +import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK; +import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import net.spy.memcached.ArcusClient; +import net.spy.memcached.ConnectionFactoryBuilder; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.handler.codec.http.Cookie; +import org.jboss.netty.handler.codec.http.CookieDecoder; +import org.jboss.netty.handler.codec.http.CookieEncoder; +import org.jboss.netty.handler.codec.http.DefaultHttpResponse; +import org.jboss.netty.handler.codec.http.HttpHeaders; +import org.jboss.netty.handler.codec.http.HttpMethod; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.HttpResponse; +import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import org.jboss.netty.handler.codec.http.HttpVersion; +import org.jboss.netty.handler.codec.http.QueryStringDecoder; +import org.jboss.netty.util.CharsetUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.ConverterNotFoundException; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.nhn.pinpoint.testweb.connector.ningasync.NingAsyncHttpClient; +import com.ning.http.client.Response; + +public class HttpCustomServerHandler extends SimpleChannelUpstreamHandler { + private static final Logger logger = LoggerFactory.getLogger(HttpCustomServerHandler.class.getName()); + + private final ListeningExecutorService listeningExecutorService; + + private final ArcusClient arcus; + private final NingAsyncHttpClient asyncHttpInvoker = new NingAsyncHttpClient(); + + public HttpCustomServerHandler() { + this.listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); + this.arcus = ArcusClient.createArcusClient("dev.arcuscloud.nhncorp.com:17288", "dev", new ConnectionFactoryBuilder()); + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + logger.debug("HttpCustomServerHandler.messageReceived ({})", Thread.currentThread().getName()); + this.listeningExecutorService.submit(new InvokeTask(ctx, e)); + } + + private void accessArcus() { + Future future = null; + try { + future = arcus.set("pinpoint:test", 10, "Hello, Arcus"); + future.get(100L, TimeUnit.MILLISECONDS); + } catch (Exception e) { + if (future != null) { + future.cancel(true); + } + } + } + + private void accessNaver() { + asyncHttpInvoker.requestGet("http://blog.naver.com", NingAsyncHttpClient.getDummyParams(), NingAsyncHttpClient.getDummyHeaders(), NingAsyncHttpClient.getDummyCookies()); + } + + private void accessPinPointDev() { + asyncHttpInvoker.requestGet("http://10.101.55.177:9080/threetier.pinpoint", null, null, null); + } + + private class InvokeTask implements Runnable { + private final ChannelHandlerContext ctx; + private final MessageEvent e; + + public InvokeTask(ChannelHandlerContext ctx, MessageEvent e) { + this.ctx = ctx; + this.e = e; + } + + public void run() { + logger.debug("InvokeTask.run ({}}", Thread.currentThread().getName()); + + if (!(e.getMessage() instanceof HttpRequest)) { + logger.debug("[n/a] received message is illegal."); + DefaultHttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST); + ctx.getChannel().write(res).addListener(ChannelFutureListener.CLOSE); + return; + } + + HttpRequest request = (HttpRequest) e.getMessage(); + + // intercept + + try { + StringBuilder buf = new StringBuilder(); + + // this.request = (HttpRequest) e.getMessage(); + Object[] requestBody = null; + Object functionsResult = null; + + HttpResponseStatus status = OK; + String uri = request.getUri().substring(1); + + // List> headers = request.getHeaders(); + List> reponseHeader = new ArrayList>(); + + buf.setLength(0); + + HttpMethod reqMethod = request.getMethod(); + if (reqMethod.equals(HttpMethod.POST) || reqMethod.equals(HttpMethod.PUT) || reqMethod.equals(HttpMethod.DELETE)) { + ChannelBuffer content = request.getContent(); + + // invoke bo (async ??) + + buf.append("HelloNetty"); + + if (content.readable()) { + try { + + } catch (ConverterNotFoundException e1) { + status = HttpResponseStatus.BAD_REQUEST; + logger.error("convert fail : exception={}", e1.getMessage()); + buf.append(getResultString(status.getCode(), "Invalid parameter")); + } + } else { + status = HttpResponseStatus.BAD_REQUEST; + buf.append(getResultString(status.getCode(), "No content on request.")); + } + } else if (reqMethod.equals(HttpMethod.GET)) { + QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri); + Map> queries = queryStringDecoder.getParameters(); + + buf.append("HelloNetty"); + + } else { + status = HttpResponseStatus.METHOD_NOT_ALLOWED; + buf.append(getResultString(status.getCode(), "method not supports")); + } + + // for demo + accessArcus(); + accessNaver(); + accessPinPointDev(); + + writeResponse(request, e, status, reponseHeader, buf); + } catch (Exception ex) { + handleException(request, this.ctx, ex); + } + } + } + + protected void writeResponse(HttpRequest request, MessageEvent e, HttpResponseStatus status, List> reponseHeader, StringBuilder resultContents) { + // Decide whether to close the connection or not. + boolean keepAlive = isKeepAlive(request); + + // Build the response object. + HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status); + + response.setContent(ChannelBuffers.copiedBuffer(resultContents.toString(), CharsetUtil.UTF_8)); + + // response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); + response.setHeader(CONTENT_TYPE, "application/json"); + + response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes()); + if (keepAlive) { + response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + } + + for (Entry header : reponseHeader) { + response.setHeader(header.getKey(), header.getValue()); + } + + // Encode the cookie. + String cookieString = request.getHeader(COOKIE); + if (cookieString != null) { + CookieDecoder cookieDecoder = new CookieDecoder(); + Set cookies = cookieDecoder.decode(cookieString); + if (!cookies.isEmpty()) { + CookieEncoder cookieEncoder = new CookieEncoder(true); + for (Cookie cookie : cookies) { + cookieEncoder.addCookie(cookie); + response.addHeader(SET_COOKIE, cookieEncoder.encode()); + } + } + } + + ChannelFuture future = e.getChannel().write(response); + + if (!keepAlive) { + future.addListener(ChannelFutureListener.CLOSE); + } else + future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE); + } + + private String stackTraceToStr(Throwable e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + return sw.toString(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + + Channel channel = ctx.getChannel(); + if (channel.isOpen()) { + + logger.error("channel error : exception={}", e); + channel.close(); + } + } + + public void handleException(HttpRequest request, ChannelHandlerContext ctx, Exception e) { + Channel channel = ctx.getChannel(); + if (channel.isOpen()) { + String body = request.getContent().readable() ? new String(request.getContent().array()) : ""; + String cause = stackTraceToStr(e.getCause()); + + logger.error("exceptionCaught : method={} \r\nURI={}, \r\nheaders={}, \r\nbody={}, \r\ncauseBy={}", request.getMethod().getName(), request.getUri(), request.getHeaders(), body, cause); + + if (channel.isWritable() && !(e.getCause() instanceof java.io.IOException)) { + + HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); + + response.setHeader(CONTENT_TYPE, "application/json; charset=UTF-8"); + response.setContent(ChannelBuffers.copiedBuffer(this.getResultString(500, "Internal Server Error", e.getCause().toString()), CharsetUtil.UTF_8)); + + channel.write(response); + + String uri = request.getUri().substring(1); + HttpMethod reqMethod = request.getMethod(); + + } + channel.close(); + } + } + + private String getResultString(int statusCode, String message) { + return String.format("{\"statusCode\":%s,\"statusMessage\":\"%s\"}", statusCode, message); + } + + private String getResultString(int statusCode, String message, String cause) { + return String.format("{\"statusCode\":%s,\"statusMessage\":\"%s\",\"causeBy\":\"%s\"}", statusCode, message, cause); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheClosableAsyncHttpClient.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheClosableAsyncHttpClient.java index 9ce5fdd10422..e0e1281e6c53 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheClosableAsyncHttpClient.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheClosableAsyncHttpClient.java @@ -67,8 +67,7 @@ public String post() { return result; } catch (Exception e) { - e.printStackTrace(); - return null; + throw new RuntimeException(e); } } } \ No newline at end of file diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheHttpClient4.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheHttpClient4.java index b9984ed4f3ed..3c4e4a30af10 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheHttpClient4.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/ApacheHttpClient4.java @@ -1,142 +1,142 @@ -package com.nhn.pinpoint.testweb.connector.apachehttp4; - -import java.io.UnsupportedEncodingException; -import java.util.Map; - -import org.apache.http.HttpEntity; -import org.apache.http.client.HttpClient; -import org.apache.http.client.ResponseHandler; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.conn.scheme.PlainSocketFactory; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicResponseHandler; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.SingleClientConnManager; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.CoreProtocolPNames; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * - * @author netspider - * - */ -@Component -public class ApacheHttpClient4 { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public final static int SLOW_REQUEST_TIME = 1000; - - private HttpConnectorOptions connectorOptions; - - public ApacheHttpClient4() { - this(new HttpConnectorOptions()); - } - - public ApacheHttpClient4(HttpConnectorOptions connectorOptions) { - this.connectorOptions = connectorOptions; - } - - private HttpClient getHttpClient(HttpParams params) { - SchemeRegistry schemeRegistry = new SchemeRegistry(); - schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); - if (connectorOptions != null && connectorOptions.getPort() > 0) { - schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), connectorOptions.getPort())); - } - schemeRegistry.register(new Scheme("https", PlainSocketFactory.getSocketFactory(), 443)); - - SingleClientConnManager cm = new SingleClientConnManager(getHttpParams(), schemeRegistry); - DefaultHttpClient httpClient = new DefaultHttpClient(cm, getHttpParams()); - httpClient.setParams(params); - return httpClient; - } - - public String execute(String uri, Map paramMap, String cookie) { - if (null == uri) { - return null; - } - - HttpClient httpClient = null; - try { - HttpPost post = new HttpPost(uri); - if (cookie != null) { - post.setHeader("Cookie", cookie); - } - post.setEntity(getEntity(paramMap)); - post.setParams(getHttpParams()); - post.addHeader("Content-Type", "application/json;charset=UTF-8"); - - ResponseHandler responseHandler = new BasicResponseHandler(); - - httpClient = getHttpClient(getHttpParams()); - - return httpClient.execute(post, responseHandler); - } catch (Exception e) { - logger.warn("HttpClient.execute() error. Caused:{}", e.getMessage(), e); - return e.getMessage(); - } finally { - if (null != httpClient && null != httpClient.getConnectionManager()) { - httpClient.getConnectionManager().shutdown(); - } - } - } - - public String execute(String uri, Map paramMap) { - return execute(uri, paramMap, null); - } - - public int executeToBlocWithReturnInt(String uri, Map paramMap) { - if (null == uri) { - return 0; - } - - String responseBody = null; - HttpClient httpClient = null; - try { - HttpPost post = new HttpPost(uri); - post.setEntity(getEntity(paramMap)); - post.setParams(getHttpParams()); - post.addHeader("Content-Type", "application/json;charset=UTF-8"); - - ResponseHandler responseHandler = new BasicResponseHandler(); - - httpClient = getHttpClient(getHttpParams()); - - responseBody = httpClient.execute(post, responseHandler); - - return Integer.parseInt(responseBody); - } catch (Exception e) { - e.printStackTrace(); - return 0; - } finally { - if (null != httpClient && null != httpClient.getConnectionManager()) { - httpClient.getConnectionManager().shutdown(); - } - } - } - - private HttpEntity getEntity(Map paramMap) throws UnsupportedEncodingException { - if (paramMap.size() != 0) { - // size가 0일때 호출하면 entity에 {}가 들어감. - return new StringEntity(paramMap.toString(), "UTF-8"); - } else { - return new StringEntity("", "UTF-8"); - } - } - - private HttpParams getHttpParams() { - HttpParams params = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(params, (int) connectorOptions.getConnectionTimeout()); - HttpConnectionParams.setSoTimeout(params, connectorOptions.getSoTimeout()); - params.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8"); - params.setParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET, "UTF-8"); - return params; - } -} +package com.nhn.pinpoint.testweb.connector.apachehttp4; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import org.apache.http.HttpEntity; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.SingleClientConnManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * + * @author netspider + * + */ +@Component +public class ApacheHttpClient4 { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public final static int SLOW_REQUEST_TIME = 1000; + + private HttpConnectorOptions connectorOptions; + + public ApacheHttpClient4() { + this(new HttpConnectorOptions()); + } + + public ApacheHttpClient4(HttpConnectorOptions connectorOptions) { + this.connectorOptions = connectorOptions; + } + + private HttpClient getHttpClient(HttpParams params) { + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + if (connectorOptions != null && connectorOptions.getPort() > 0) { + schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), connectorOptions.getPort())); + } + schemeRegistry.register(new Scheme("https", PlainSocketFactory.getSocketFactory(), 443)); + + SingleClientConnManager cm = new SingleClientConnManager(getHttpParams(), schemeRegistry); + DefaultHttpClient httpClient = new DefaultHttpClient(cm, getHttpParams()); + httpClient.setParams(params); + return httpClient; + } + + public String execute(String uri, Map paramMap, String cookie) { + if (null == uri) { + return null; + } + + HttpClient httpClient = null; + try { + HttpPost post = new HttpPost(uri); + if (cookie != null) { + post.setHeader("Cookie", cookie); + } + post.setEntity(getEntity(paramMap)); + post.setParams(getHttpParams()); + post.addHeader("Content-Type", "application/json;charset=UTF-8"); + + ResponseHandler responseHandler = new BasicResponseHandler(); + + httpClient = getHttpClient(getHttpParams()); + + return httpClient.execute(post, responseHandler); + } catch (Exception e) { + logger.warn("HttpClient.execute() error. Caused:{}", e.getMessage(), e); + return e.getMessage(); + } finally { + if (null != httpClient && null != httpClient.getConnectionManager()) { + httpClient.getConnectionManager().shutdown(); + } + } + } + + public String execute(String uri, Map paramMap) { + return execute(uri, paramMap, null); + } + + public int executeToBlocWithReturnInt(String uri, Map paramMap) { + if (null == uri) { + return 0; + } + + String responseBody = null; + HttpClient httpClient = null; + try { + HttpPost post = new HttpPost(uri); + post.setEntity(getEntity(paramMap)); + post.setParams(getHttpParams()); + post.addHeader("Content-Type", "application/json;charset=UTF-8"); + + ResponseHandler responseHandler = new BasicResponseHandler(); + + httpClient = getHttpClient(getHttpParams()); + + responseBody = httpClient.execute(post, responseHandler); + + return Integer.parseInt(responseBody); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } finally { + if (null != httpClient && null != httpClient.getConnectionManager()) { + httpClient.getConnectionManager().shutdown(); + } + } + } + + private HttpEntity getEntity(Map paramMap) throws UnsupportedEncodingException { + if (paramMap.size() != 0) { + // size가 0일때 호출하면 entity에 {}가 들어감. + return new StringEntity(paramMap.toString(), "UTF-8"); + } else { + return new StringEntity("", "UTF-8"); + } + } + + private HttpParams getHttpParams() { + HttpParams params = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(params, (int) connectorOptions.getConnectionTimeout()); + HttpConnectionParams.setSoTimeout(params, connectorOptions.getSoTimeout()); + params.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8"); + params.setParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET, "UTF-8"); + return params; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/HttpConnectorOptions.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/HttpConnectorOptions.java index ff7bbd233fab..c7076c037c39 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/HttpConnectorOptions.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/HttpConnectorOptions.java @@ -1,74 +1,74 @@ -package com.nhn.pinpoint.testweb.connector.apachehttp4; - -import java.nio.charset.Charset; - -/** - * - * @author netspider - * - */ -public class HttpConnectorOptions { - private String host; - private int port; - private int callTimeout; - private int connectionTimeout; - private int soTimeout; - private Charset charset; - private String modulePath; - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public int getCallTimeout() { - return callTimeout; - } - - public void setCallTimeout(int callTimeout) { - this.callTimeout = callTimeout; - } - - public int getConnectionTimeout() { - return connectionTimeout; - } - - public void setConnectionTimeout(int connectionTimeout) { - this.connectionTimeout = connectionTimeout; - } - - public int getSoTimeout() { - return soTimeout; - } - - public void setSoTimeout(int soTimeout) { - this.soTimeout = soTimeout; - } - - public Charset getCharset() { - return charset; - } - - public void setCharset(Charset charset) { - this.charset = charset; - } - - public String getModulePath() { - return modulePath; - } - - public void setModulePath(String modulePath) { - this.modulePath = modulePath; - } -} +package com.nhn.pinpoint.testweb.connector.apachehttp4; + +import java.nio.charset.Charset; + +/** + * + * @author netspider + * + */ +public class HttpConnectorOptions { + private String host; + private int port; + private int callTimeout; + private int connectionTimeout; + private int soTimeout; + private Charset charset; + private String modulePath; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public int getCallTimeout() { + return callTimeout; + } + + public void setCallTimeout(int callTimeout) { + this.callTimeout = callTimeout; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public int getSoTimeout() { + return soTimeout; + } + + public void setSoTimeout(int soTimeout) { + this.soTimeout = soTimeout; + } + + public Charset getCharset() { + return charset; + } + + public void setCharset(Charset charset) { + this.charset = charset; + } + + public String getModulePath() { + return modulePath; + } + + public void setModulePath(String modulePath) { + this.modulePath = modulePath; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtil.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtil.java index fb17c4cf3e1f..b25172f4f4a9 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtil.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtil.java @@ -1,317 +1,317 @@ -/* - * @(#)HttpUtil.java $version 2011. 12. 14. - * - * Copyright 2007 NHN Corp. All rights Reserved. - * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -package com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.apache.commons.lang3.StringUtils; -import org.apache.http.Header; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.SingleClientConnManager; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -/** - * 간편하게 http데이터를 가져올 수 있는 클래스
- *
- * 사용법은,
- * HttpUtil.url(String url).call();
- * 이 기본이다.
- * 이렇게 호출을 하면, GET방식으로 해당 url을 호출하게 되며, 다른 옵션들은 url()과 call()사이에 넣어주면 된다
- * .
- * 최대 사용할 수 있는 파라메터는 다음과 같으며
- * HttpUtil.url(String - * url).method(Method.POST).charset("EUC-KR").passSSLError(true - * ).connectionTimeout(1000).readTimeout(1000).call();
- * 이중에서 자신이 원하는 파라메터들만 선택해서 사용할 수 있다.
- * 반드시 url()이 맨 먼저 와야 하고, call()이 맨 뒤에 와야 하며, 그외 다른 옵션들은 순서에 관계 없다.
- *
- * 각 옵션들의 디폴트 값은 다음과 같다.
- * method : Method.GET
- * charset : 페이지 기본값
- * passSSLError : false
- * connectionTimeout : 0 (JRE기본값)
- * readTimeout : 0 (무제한)
- * - * @author Xenos - */ -public class HttpUtil { - private static Charset defaultCharset = Charset.forName("UTF-8"); - private static X509TrustManager IgnoreSLLErrorTrustManager = new X509TrustManager() { - - @Override - public void checkClientTrusted(X509Certificate[] ax509certificate, String s) throws CertificateException { - } - - @Override - public void checkServerTrusted(X509Certificate[] ax509certificate, String s) throws CertificateException { - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - }; - - /** - * HttpUtil이 지원하는 Method - * - * @author Xenos - */ - public enum Method { - GET, POST - }; - - /** - * Static Util 클래스이므로, 생성자 막음 - */ - private HttpUtil() { - } - - /** - * HttpUtil을 사용하기 위해서 최초로 호출해야 하는 함수 이 함수는 Parameters를 반환한다. - * - * @param theURL - * 호출하고자 하는 URL - * @return HttpUtil을 이용할 수 있는 파라메터들을 담고 있는 Parameters 클래스 - * @throws WrongParameterException - * theURL에 null이 들어왔을 경우 발생하는 Exception - */ - public static Parameters url(String theURL) throws HttpUtilException { - return new Parameters(theURL); - } - - /** - * theURL로 http(s)연결을 하여 응답값의 내용을 반환한다. JSON 형태의 파라미터로 요청하기 위한 method - * - * @param theURL - * 연결할 http(s) 주소 - * @param method - * GET/POST - * @param charset - * 응답값의 charset(null이면 페이지 기본값) - * @param passSSLError - * SSL오류를 무시할지 여부 - * @param connectionTimeout - * 접속 제한시간 (0이면 JRE 기본값) - * @param readTimeout - * 데이터를 받아오는데 제한시간 (0이면 무제한) - * @param jsonEntity - * 넘겨주고자 하는 String 요소값 - * @return 결과값의 InputStreamReader형태 - * @throws HttpUtilException - */ - static InputStreamReader callUrl(String theURL, Method method, Charset charset, boolean passSSLError, int connectionTimeout, int readTimeout, String jsonEntity, Map header) throws HttpUtilException { - - // 타임아웃을 설정 - HttpParams params = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(params, connectionTimeout); - HttpConnectionParams.setSoTimeout(params, readTimeout); - - HttpClient httpClient; - - // SSL 오류 우회하는 설정 - if (passSSLError) { - // 포트 번호를 추출 - int sslPort = getPortFromURL(theURL); - - try { - SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(null, new TrustManager[] { IgnoreSLLErrorTrustManager }, new SecureRandom()); - SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - Scheme httpsScheme = new Scheme("https", sslPort, sf); - SchemeRegistry schemeRegistry = new SchemeRegistry(); - schemeRegistry.register(httpsScheme); - - ClientConnectionManager conman = new SingleClientConnManager(schemeRegistry); - - httpClient = new DefaultHttpClient(conman, params); - } catch (NoSuchAlgorithmException en) { - throw new HttpUtilException(en.toString(), en); - } catch (KeyManagementException ek) { - throw new HttpUtilException(ek.toString(), ek); - } - } else { - httpClient = new DefaultHttpClient(params); - } - - HttpRequestBase request = null; - - try { - // Method를 결정 - switch (method) { - case GET: - request = new HttpGet(theURL); - break; - case POST: - String[] splitURL = StringUtils.split(theURL, "?", 2); - - HttpPost requestPost = new HttpPost(splitURL[0]); - - if (jsonEntity == null) { - requestPost.setEntity(makeFormEntity(splitURL.length < 2 ? null : splitURL[1], charset)); - } else { - requestPost.setEntity(new StringEntity(jsonEntity, "application/json", "UTF-8")); - requestPost.addHeader("Content-Type", "application/json"); - requestPost.addHeader("accept", "text/plain, application/json"); - } - - request = requestPost; - break; - } - - // 헤더를 추가 - if (header != null && header.size() > 0) { - Set> entrySet = header.entrySet(); - for (Entry entry : entrySet) { - request.addHeader(entry.getKey(), entry.getValue()); - } - } - - HttpResponse response = httpClient.execute(request); - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode < 200 || statusCode >= 300) { - throw new HttpUtilException(response.getStatusLine().getStatusCode() + ":" + response.getStatusLine().getReasonPhrase()); - } - - // HTML문서의 charset을 가져온다. 만약에 사용자가 charset을 지정 하였다면, 해당 charset으로 변경 - Charset encodingCharset = null; - try { - Header contentEncoding = response.getEntity().getContentEncoding(); - if (contentEncoding != null) { - encodingCharset = Charset.forName(contentEncoding.getValue()); - } - } catch (Exception e) { - // 오류따윈 무시함 - } - - // 지정된 캐릭터셋이 있으면 설정 - if (charset != null) { - encodingCharset = charset; - } - - // 케리터셋이 결정되지 않았다면, 디폴트 - if (encodingCharset == null) { - encodingCharset = defaultCharset; - } - - return new InputStreamReader(response.getEntity().getContent(), encodingCharset); - } catch (IOException e) { - throw new HttpUtilException(e.toString(), e); - } - } - - /** - * 포트 번호 검색을 위한 urlPattern - 미리 컴파일 해둔다. - */ - private static Pattern urlPattern = Pattern.compile("^(https?):\\/\\/([^:\\/\\s]+)((:([^\\/]*))?(((\\/[^\\s/\\/]+)*)?\\/([^#\\s\\?]*)(\\?([^#\\s]*))?(#(\\w*))?)?)?$"); - - /** - * url로부터 포트번호를 찾아서 반환한다. - * - * @param url - * 포트번호를 찾을 url - * @return 포트번호 - */ - private static int getPortFromURL(String url) { - int returnPort = 80; - - try { - // url처음이 http로 시작하지 않으면 http를 붙여준다. - if (!url.toLowerCase().startsWith("http")) { - url = "http://" + url; - } - - // 포트번호를 검색한다. - Matcher match = urlPattern.matcher(url); - - if (match.matches() && match.group(5) != null) { - // 지정된 포트 번호가 있는 경우 - returnPort = Integer.parseInt(match.group(5)); - } else if (url.toLowerCase().startsWith("https://")) { - // 지정된 포트는 없지만, https인 경우 - returnPort = 443; - } - } catch (Exception e) { - /* 오류시엔 기본포트(80)으로 반환한다. */ - } - - return returnPort; - } - - /** - * url의 queryString을 잘라서, UrlEncodedFormEntity 형태로 반환한다. - * - * @param url - * 데이터를 잘라낼 url - * @return UrlEncodedFormEntity 형태로 변환된 데이터 - */ - private static UrlEncodedFormEntity makeFormEntity(String queryString, Charset charset) { - List postParams = new ArrayList(); - - if (StringUtils.isNotEmpty(queryString)) { - String[] data = queryString.split("&"); - - for (String aData : data) { - String[] splitData = StringUtils.split(aData, "=", 2); - - if (splitData.length < 2) { - continue; - } - - postParams.add(new BasicNameValuePair(splitData[0].trim(), splitData[1].trim())); - } - - } - - try { - if (charset != null) { - return new UrlEncodedFormEntity(postParams, charset.toString()); - } else { - return new UrlEncodedFormEntity(postParams); - } - } catch (UnsupportedEncodingException e) { - return null; - } - } -} +/* + * @(#)HttpUtil.java $version 2011. 12. 14. + * + * Copyright 2007 NHN Corp. All rights Reserved. + * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.SingleClientConnManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * 간편하게 http데이터를 가져올 수 있는 클래스
+ *
+ * 사용법은,
+ * HttpUtil.url(String url).call();
+ * 이 기본이다.
+ * 이렇게 호출을 하면, GET방식으로 해당 url을 호출하게 되며, 다른 옵션들은 url()과 call()사이에 넣어주면 된다
+ * .
+ * 최대 사용할 수 있는 파라메터는 다음과 같으며
+ * HttpUtil.url(String + * url).method(Method.POST).charset("EUC-KR").passSSLError(true + * ).connectionTimeout(1000).readTimeout(1000).call();
+ * 이중에서 자신이 원하는 파라메터들만 선택해서 사용할 수 있다.
+ * 반드시 url()이 맨 먼저 와야 하고, call()이 맨 뒤에 와야 하며, 그외 다른 옵션들은 순서에 관계 없다.
+ *
+ * 각 옵션들의 디폴트 값은 다음과 같다.
+ * method : Method.GET
+ * charset : 페이지 기본값
+ * passSSLError : false
+ * connectionTimeout : 0 (JRE기본값)
+ * readTimeout : 0 (무제한)
+ * + * @author Xenos + */ +public class HttpUtil { + private static Charset defaultCharset = Charset.forName("UTF-8"); + private static X509TrustManager IgnoreSLLErrorTrustManager = new X509TrustManager() { + + @Override + public void checkClientTrusted(X509Certificate[] ax509certificate, String s) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] ax509certificate, String s) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + }; + + /** + * HttpUtil이 지원하는 Method + * + * @author Xenos + */ + public enum Method { + GET, POST + }; + + /** + * Static Util 클래스이므로, 생성자 막음 + */ + private HttpUtil() { + } + + /** + * HttpUtil을 사용하기 위해서 최초로 호출해야 하는 함수 이 함수는 Parameters를 반환한다. + * + * @param theURL + * 호출하고자 하는 URL + * @return HttpUtil을 이용할 수 있는 파라메터들을 담고 있는 Parameters 클래스 + * @throws WrongParameterException + * theURL에 null이 들어왔을 경우 발생하는 Exception + */ + public static Parameters url(String theURL) throws HttpUtilException { + return new Parameters(theURL); + } + + /** + * theURL로 http(s)연결을 하여 응답값의 내용을 반환한다. JSON 형태의 파라미터로 요청하기 위한 method + * + * @param theURL + * 연결할 http(s) 주소 + * @param method + * GET/POST + * @param charset + * 응답값의 charset(null이면 페이지 기본값) + * @param passSSLError + * SSL오류를 무시할지 여부 + * @param connectionTimeout + * 접속 제한시간 (0이면 JRE 기본값) + * @param readTimeout + * 데이터를 받아오는데 제한시간 (0이면 무제한) + * @param jsonEntity + * 넘겨주고자 하는 String 요소값 + * @return 결과값의 InputStreamReader형태 + * @throws HttpUtilException + */ + static InputStreamReader callUrl(String theURL, Method method, Charset charset, boolean passSSLError, int connectionTimeout, int readTimeout, String jsonEntity, Map header) throws HttpUtilException { + + // 타임아웃을 설정 + HttpParams params = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(params, connectionTimeout); + HttpConnectionParams.setSoTimeout(params, readTimeout); + + HttpClient httpClient; + + // SSL 오류 우회하는 설정 + if (passSSLError) { + // 포트 번호를 추출 + int sslPort = getPortFromURL(theURL); + + try { + SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, new TrustManager[] { IgnoreSLLErrorTrustManager }, new SecureRandom()); + SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + Scheme httpsScheme = new Scheme("https", sslPort, sf); + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(httpsScheme); + + ClientConnectionManager conman = new SingleClientConnManager(schemeRegistry); + + httpClient = new DefaultHttpClient(conman, params); + } catch (NoSuchAlgorithmException en) { + throw new HttpUtilException(en.toString(), en); + } catch (KeyManagementException ek) { + throw new HttpUtilException(ek.toString(), ek); + } + } else { + httpClient = new DefaultHttpClient(params); + } + + HttpRequestBase request = null; + + try { + // Method를 결정 + switch (method) { + case GET: + request = new HttpGet(theURL); + break; + case POST: + String[] splitURL = StringUtils.split(theURL, "?", 2); + + HttpPost requestPost = new HttpPost(splitURL[0]); + + if (jsonEntity == null) { + requestPost.setEntity(makeFormEntity(splitURL.length < 2 ? null : splitURL[1], charset)); + } else { + requestPost.setEntity(new StringEntity(jsonEntity, "application/json", "UTF-8")); + requestPost.addHeader("Content-Type", "application/json"); + requestPost.addHeader("accept", "text/plain, application/json"); + } + + request = requestPost; + break; + } + + // 헤더를 추가 + if (header != null && header.size() > 0) { + Set> entrySet = header.entrySet(); + for (Entry entry : entrySet) { + request.addHeader(entry.getKey(), entry.getValue()); + } + } + + HttpResponse response = httpClient.execute(request); + int statusCode = response.getStatusLine().getStatusCode(); + + if (statusCode < 200 || statusCode >= 300) { + throw new HttpUtilException(response.getStatusLine().getStatusCode() + ":" + response.getStatusLine().getReasonPhrase()); + } + + // HTML문서의 charset을 가져온다. 만약에 사용자가 charset을 지정 하였다면, 해당 charset으로 변경 + Charset encodingCharset = null; + try { + Header contentEncoding = response.getEntity().getContentEncoding(); + if (contentEncoding != null) { + encodingCharset = Charset.forName(contentEncoding.getValue()); + } + } catch (Exception e) { + // 오류따윈 무시함 + } + + // 지정된 캐릭터셋이 있으면 설정 + if (charset != null) { + encodingCharset = charset; + } + + // 케리터셋이 결정되지 않았다면, 디폴트 + if (encodingCharset == null) { + encodingCharset = defaultCharset; + } + + return new InputStreamReader(response.getEntity().getContent(), encodingCharset); + } catch (IOException e) { + throw new HttpUtilException(e.toString(), e); + } + } + + /** + * 포트 번호 검색을 위한 urlPattern - 미리 컴파일 해둔다. + */ + private static Pattern urlPattern = Pattern.compile("^(https?):\\/\\/([^:\\/\\s]+)((:([^\\/]*))?(((\\/[^\\s/\\/]+)*)?\\/([^#\\s\\?]*)(\\?([^#\\s]*))?(#(\\w*))?)?)?$"); + + /** + * url로부터 포트번호를 찾아서 반환한다. + * + * @param url + * 포트번호를 찾을 url + * @return 포트번호 + */ + private static int getPortFromURL(String url) { + int returnPort = 80; + + try { + // url처음이 http로 시작하지 않으면 http를 붙여준다. + if (!url.toLowerCase().startsWith("http")) { + url = "http://" + url; + } + + // 포트번호를 검색한다. + Matcher match = urlPattern.matcher(url); + + if (match.matches() && match.group(5) != null) { + // 지정된 포트 번호가 있는 경우 + returnPort = Integer.parseInt(match.group(5)); + } else if (url.toLowerCase().startsWith("https://")) { + // 지정된 포트는 없지만, https인 경우 + returnPort = 443; + } + } catch (Exception e) { + /* 오류시엔 기본포트(80)으로 반환한다. */ + } + + return returnPort; + } + + /** + * url의 queryString을 잘라서, UrlEncodedFormEntity 형태로 반환한다. + * + * @param url + * 데이터를 잘라낼 url + * @return UrlEncodedFormEntity 형태로 변환된 데이터 + */ + private static UrlEncodedFormEntity makeFormEntity(String queryString, Charset charset) { + List postParams = new ArrayList(); + + if (StringUtils.isNotEmpty(queryString)) { + String[] data = queryString.split("&"); + + for (String aData : data) { + String[] splitData = StringUtils.split(aData, "=", 2); + + if (splitData.length < 2) { + continue; + } + + postParams.add(new BasicNameValuePair(splitData[0].trim(), splitData[1].trim())); + } + + } + + try { + if (charset != null) { + return new UrlEncodedFormEntity(postParams, charset.toString()); + } else { + return new UrlEncodedFormEntity(postParams); + } + } catch (UnsupportedEncodingException e) { + return null; + } + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/Parameters.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/Parameters.java index 511e6915aac8..b3c1b3e54495 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/Parameters.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/Parameters.java @@ -1,214 +1,214 @@ -/* - * @(#)Parameters.java $version 2012. 2. 3. - * - * Copyright 2007 NHN Corp. All rights Reserved. - * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ - -package com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpException; - -import com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent.HttpUtil.Method; - -/** - * HttpUtil에 들어가는 파라메터 클래스 HttpUtil을 보다 쉽게 사용하기 위해서 제공되는 클래스 외부에서 생성할 수 있는 방법은 - * 없고, HttpUtil.url()을 통해서만 생성할 수 있다. - * - * @author Xenos - */ -public class Parameters { - private static final int READ_BUFFER_SIZE = 4096; - - private String urlValue; - private Method methodValue = Method.GET; /* default = GET */ - private Charset charsetValue = null; /* default = 페이지 기본값 */ - private boolean passSSLErrorValue = false; /* default = false */ - private int connectionTimeoutValue = 0; /* default = JRE기본값 */ - private int readTimeoutValue = 0; /* default = 무제한 */ - private String jsonEntityValue = null; /* jsonEntity */ - private Map header = new HashMap(); /* - * 헤더내용 - * 추가 - */ - - Parameters(String theURL) throws HttpUtilException { - if (theURL == null) { - throw new HttpUtilException("url have to be not null"); - } - this.urlValue = theURL; - } - - /** - * 호출할 Method를 선택
- * HttpUtil.Method의 값을 전달해야 한다.
- *
- * default : HttpUtil.Method.GET
- * - * @param value - * HttpUtil.Method 값 - * @return Parameters 클래스 - */ - public Parameters method(Method value) { - this.methodValue = value; - return this; - } - - /** - * 호출할 페이지의 인코딩 방식을 결정한다.
- * default : null(페이지 기본값) - * - * @param value - * 캐릭터셋 - * @return Parameters 클래스 - */ - public Parameters charset(Charset value) { - this.charsetValue = value; - return this; - } - - /** - * 호출할때에, SSL오류를 무시할지 여부를 결정한다.
- * default : false
- *
- * 참고사항 : 이 값을 true로 설정하고, readTimeout을 함께 설정할 경우, timeout시에도 - * java.net.SocketTimeoutException: Read timed out 이 발생하지 않고, - * javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 가 발생하는 - * 문제가 있음
- * - * @param value - * true/false 값 - * @return Parameters 클래스 - */ - public Parameters passSSLError(boolean value) { - this.passSSLErrorValue = value; - return this; - } - - /** - * 접속시 timeout을 설정한다.
- * default : 무제한
- * - * @param value - * 0 이상의 정수 - * @return Parameters 클래스 - * @throws HttpUtilException - * 설정값이 0 이하인 경우 - */ - public Parameters connectionTimeout(int value) throws HttpUtilException { - if (value < 0) { - throw new HttpUtilException("connectionTimeout"); - } - this.connectionTimeoutValue = value; - return this; - } - - /** - * 접속이 이루어진 후, 응답값을 기다리는 최대 시간을 설정한다.
- * default : 무제한
- * - * @param value - * 0 이상의 정수 - * @return Parameters 클래스 - * @throws HttpUtilException - * 설정값이 0 이하인 경우 - */ - public Parameters readTimeout(int value) throws HttpUtilException { - if (value < 0) { - throw new HttpUtilException("readTimeout"); - } - this.readTimeoutValue = value; - return this; - } - - /** - * request에 추가할 헤더 기본적으로 헤더는 없음 - * - * @param name - * 헤더 이름 - * @param value - * 헤더 값 - * @return Parameters 클래스 - * @throws HttpUtilException - * name에 값이 없을 경우 - */ - public Parameters addHeader(String name, String value) throws HttpUtilException { - if (StringUtils.isEmpty(name)) { - throw new HttpUtilException("header"); - } - this.header.put(name, value); - return this; - } - - public Parameters jsonEntity(String value) { - this.jsonEntityValue = value; - return this; - } - - /** - * 설정된 Parameters로 url을 호출한다.
- * - * @return 해당 url의 응답값의 String 형태 - * @throws HttpException - * http통신중 오류 발생시 - */ - public String getContents() throws HttpUtilException { - Writer writer = new StringWriter(); - char[] buffer = new char[READ_BUFFER_SIZE]; - Reader reader = new BufferedReader(getInputStreamReader()); - int readSize; - try { - while ((readSize = reader.read(buffer)) != -1) { - writer.write(buffer, 0, readSize); - } - - reader.close(); - } catch (IOException e) { - throw new HttpUtilException("Http read error! " + this.toString(), e); - } - - return writer.toString(); - } - - /** - * 설정된 Parameters로 url을 호출한다.
- * inputStreamReader를 모두 읽고 난 뒤에, close해주어야 한다.
- * - * @return 해당 url의 응답값의 inputStreamReader - * @throws HttpException - * http통신준 오류 발생시 - */ - public InputStreamReader getInputStreamReader() throws HttpUtilException { - return HttpUtil.callUrl(urlValue, methodValue, charsetValue, passSSLErrorValue, connectionTimeoutValue, readTimeoutValue, jsonEntityValue, header); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Parameters["); - sb.append("url=").append(urlValue); - sb.append(", method=").append(methodValue.toString()); - if (charsetValue != null) { - sb.append(", charset=").append(charsetValue.toString()); - } else { - sb.append(", charset=null"); - } - sb.append(", passSSLError=").append(passSSLErrorValue); - sb.append(", connectionTimeout=").append(connectionTimeoutValue); - sb.append(", readTimeout=").append(readTimeoutValue); - sb.append(", jsonEntityValue=").append(jsonEntityValue); - - return sb.toString(); - } +/* + * @(#)Parameters.java $version 2012. 2. 3. + * + * Copyright 2007 NHN Corp. All rights Reserved. + * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +package com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpException; + +import com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent.HttpUtil.Method; + +/** + * HttpUtil에 들어가는 파라메터 클래스 HttpUtil을 보다 쉽게 사용하기 위해서 제공되는 클래스 외부에서 생성할 수 있는 방법은 + * 없고, HttpUtil.url()을 통해서만 생성할 수 있다. + * + * @author Xenos + */ +public class Parameters { + private static final int READ_BUFFER_SIZE = 4096; + + private String urlValue; + private Method methodValue = Method.GET; /* default = GET */ + private Charset charsetValue = null; /* default = 페이지 기본값 */ + private boolean passSSLErrorValue = false; /* default = false */ + private int connectionTimeoutValue = 0; /* default = JRE기본값 */ + private int readTimeoutValue = 0; /* default = 무제한 */ + private String jsonEntityValue = null; /* jsonEntity */ + private Map header = new HashMap(); /* + * 헤더내용 + * 추가 + */ + + Parameters(String theURL) throws HttpUtilException { + if (theURL == null) { + throw new HttpUtilException("url have to be not null"); + } + this.urlValue = theURL; + } + + /** + * 호출할 Method를 선택
+ * HttpUtil.Method의 값을 전달해야 한다.
+ *
+ * default : HttpUtil.Method.GET
+ * + * @param value + * HttpUtil.Method 값 + * @return Parameters 클래스 + */ + public Parameters method(Method value) { + this.methodValue = value; + return this; + } + + /** + * 호출할 페이지의 인코딩 방식을 결정한다.
+ * default : null(페이지 기본값) + * + * @param value + * 캐릭터셋 + * @return Parameters 클래스 + */ + public Parameters charset(Charset value) { + this.charsetValue = value; + return this; + } + + /** + * 호출할때에, SSL오류를 무시할지 여부를 결정한다.
+ * default : false
+ *
+ * 참고사항 : 이 값을 true로 설정하고, readTimeout을 함께 설정할 경우, timeout시에도 + * java.net.SocketTimeoutException: Read timed out 이 발생하지 않고, + * javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 가 발생하는 + * 문제가 있음
+ * + * @param value + * true/false 값 + * @return Parameters 클래스 + */ + public Parameters passSSLError(boolean value) { + this.passSSLErrorValue = value; + return this; + } + + /** + * 접속시 timeout을 설정한다.
+ * default : 무제한
+ * + * @param value + * 0 이상의 정수 + * @return Parameters 클래스 + * @throws HttpUtilException + * 설정값이 0 이하인 경우 + */ + public Parameters connectionTimeout(int value) throws HttpUtilException { + if (value < 0) { + throw new HttpUtilException("connectionTimeout"); + } + this.connectionTimeoutValue = value; + return this; + } + + /** + * 접속이 이루어진 후, 응답값을 기다리는 최대 시간을 설정한다.
+ * default : 무제한
+ * + * @param value + * 0 이상의 정수 + * @return Parameters 클래스 + * @throws HttpUtilException + * 설정값이 0 이하인 경우 + */ + public Parameters readTimeout(int value) throws HttpUtilException { + if (value < 0) { + throw new HttpUtilException("readTimeout"); + } + this.readTimeoutValue = value; + return this; + } + + /** + * request에 추가할 헤더 기본적으로 헤더는 없음 + * + * @param name + * 헤더 이름 + * @param value + * 헤더 값 + * @return Parameters 클래스 + * @throws HttpUtilException + * name에 값이 없을 경우 + */ + public Parameters addHeader(String name, String value) throws HttpUtilException { + if (StringUtils.isEmpty(name)) { + throw new HttpUtilException("header"); + } + this.header.put(name, value); + return this; + } + + public Parameters jsonEntity(String value) { + this.jsonEntityValue = value; + return this; + } + + /** + * 설정된 Parameters로 url을 호출한다.
+ * + * @return 해당 url의 응답값의 String 형태 + * @throws HttpException + * http통신중 오류 발생시 + */ + public String getContents() throws HttpUtilException { + Writer writer = new StringWriter(); + char[] buffer = new char[READ_BUFFER_SIZE]; + Reader reader = new BufferedReader(getInputStreamReader()); + int readSize; + try { + while ((readSize = reader.read(buffer)) != -1) { + writer.write(buffer, 0, readSize); + } + + reader.close(); + } catch (IOException e) { + throw new HttpUtilException("Http read error! " + this.toString(), e); + } + + return writer.toString(); + } + + /** + * 설정된 Parameters로 url을 호출한다.
+ * inputStreamReader를 모두 읽고 난 뒤에, close해주어야 한다.
+ * + * @return 해당 url의 응답값의 inputStreamReader + * @throws HttpException + * http통신준 오류 발생시 + */ + public InputStreamReader getInputStreamReader() throws HttpUtilException { + return HttpUtil.callUrl(urlValue, methodValue, charsetValue, passSSLErrorValue, connectionTimeoutValue, readTimeoutValue, jsonEntityValue, header); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Parameters["); + sb.append("url=").append(urlValue); + sb.append(", method=").append(methodValue.toString()); + if (charsetValue != null) { + sb.append(", charset=").append(charsetValue.toString()); + } else { + sb.append(", charset=null"); + } + sb.append(", passSSLError=").append(passSSLErrorValue); + sb.append(", connectionTimeout=").append(connectionTimeoutValue); + sb.append(", readTimeout=").append(readTimeoutValue); + sb.append(", jsonEntityValue=").append(jsonEntityValue); + + return sb.toString(); + } } \ No newline at end of file diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ApacheClosableAsyncHttpClientController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ApacheClosableAsyncHttpClientController.java index e3a34588f37f..8d6975cebd78 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ApacheClosableAsyncHttpClientController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ApacheClosableAsyncHttpClientController.java @@ -1,52 +1,49 @@ package com.nhn.pinpoint.testweb.controller; +import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheClosableAsyncHttpClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; -import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheClosableAsyncHttpClient; - /** - * * @author netspider - * */ @Controller public class ApacheClosableAsyncHttpClientController { - @Autowired - private ApacheClosableAsyncHttpClient client; - - @RequestMapping(value = "/apacheClosableAsyncHttp/get") - public @ResponseBody - String requestGet(Model model) { - return "NOT_IMPLEMENTED"; - } - - @RequestMapping(value = "/apacheClosableAsyncHttp/getWithParam") - public @ResponseBody - String requestGetWithParam(Model model) { - return "NOT_IMPLEMENTED"; - } - - @RequestMapping(value = "/apacheClosableAsyncHttp/post") - public @ResponseBody - String requestPost(Model model) { - client.post(); - return "OK"; - } - - @RequestMapping(value = "/apacheClosableAsyncHttp/postWithBody") - public @ResponseBody - String requestPostWithBody(Model model) { - return "NOT_IMPLEMENTED"; - } - - @RequestMapping(value = "/apacheClosableAsyncHttp/postWithMultipart") - public @ResponseBody - String requestPostWithMultipart(Model model) { - return "NOT_IMPLEMENTED"; - } + @Autowired + private ApacheClosableAsyncHttpClient client; + + @RequestMapping(value = "/apacheClosableAsyncHttp/get") + @ResponseBody + public String requestGet() { + return "NOT_IMPLEMENTED"; + } + + @RequestMapping(value = "/apacheClosableAsyncHttp/getWithParam") + @ResponseBody + public String requestGetWithParam() { + return "NOT_IMPLEMENTED"; + } + + @RequestMapping(value = "/apacheClosableAsyncHttp/post") + @ResponseBody + public String requestPost() { + client.post(); + return "OK"; + } + + @RequestMapping(value = "/apacheClosableAsyncHttp/postWithBody") + @ResponseBody + public String requestPostWithBody() { + return "NOT_IMPLEMENTED"; + } + + @RequestMapping(value = "/apacheClosableAsyncHttp/postWithMultipart") + @ResponseBody + public String requestPostWithMultipart() { + return "NOT_IMPLEMENTED"; + } } \ No newline at end of file diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/BLOC4Controller.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/BLOC4Controller.java index 480719d3563b..ec460adf36a2 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/BLOC4Controller.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/BLOC4Controller.java @@ -1,28 +1,24 @@ package com.nhn.pinpoint.testweb.controller; +import com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent.HttpUtil; import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent.HttpUtil; - /** - * * @author netspider - * */ @Controller public class BLOC4Controller { - private final String LOCAL_BLOC4_FORMAT = "http://%s:%s/welcome/test/hello?name=netspider"; + private final String LOCAL_BLOC4_FORMAT = "http://%s:%s/welcome/test/hello?name=netspider"; - @RequestMapping(value = "/bloc4/callLocal") - public @ResponseBody - String requestGet(Model model, - @RequestParam(required = false, defaultValue = "localhost") String host, - @RequestParam(required = false, defaultValue = "5001") String port) { - return HttpUtil.url(String.format(LOCAL_BLOC4_FORMAT, host, port)).method(HttpUtil.Method.GET).connectionTimeout(10000).readTimeout(10000).getContents(); - } + @RequestMapping(value = "/bloc4/callLocal") + @ResponseBody + public String requestGet( + @RequestParam(required = false, defaultValue = "localhost") String host, + @RequestParam(required = false, defaultValue = "5001") String port) { + return HttpUtil.url(String.format(LOCAL_BLOC4_FORMAT, host, port)).method(HttpUtil.Method.GET).connectionTimeout(10000).readTimeout(10000).getContents(); + } } diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/CubridController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/CubridController.java index 4c2ee4e7c7ed..ab907e79fd65 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/CubridController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/CubridController.java @@ -1,55 +1,43 @@ -package com.nhn.pinpoint.testweb.controller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.testweb.service.CubridService; - -/** - * - */ -@Controller -public class CubridController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private CubridService cubridService; - - @RequestMapping(value = "/cubrid/selectOne") - public @ResponseBody - String selectOne(Model model) { - try { - logger.info("selectOne start"); - - int i = cubridService.selectOne(); - - logger.info("selectOne end:{}", i); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } - - @RequestMapping(value = "/cubrid/createStatement") - public @ResponseBody - String oracleStatement(Model model) { - try { - logger.info("createStatement start"); - - cubridService.createStatement(); - - logger.info("createStatement end:{}"); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.service.CubridService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * + */ +@Controller +public class CubridController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private CubridService cubridService; + + @RequestMapping(value = "/cubrid/selectOne") + @ResponseBody + public String selectOne() { + logger.info("selectOne start"); + + int i = cubridService.selectOne(); + + logger.info("selectOne end:{}", i); + return "OK"; + } + + @RequestMapping(value = "/cubrid/createStatement") + @ResponseBody + public String createStatement() { + logger.info("createStatement start"); + + cubridService.createStatement(); + + logger.info("createStatement end:{}"); + return "OK"; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DemoController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DemoController.java index 7329ecbd5e7f..e10f1f2ea696 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DemoController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DemoController.java @@ -1,181 +1,178 @@ -package com.nhn.pinpoint.testweb.controller; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.testweb.configuration.DemoURLHolder; -import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; -import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; -import com.nhn.pinpoint.testweb.connector.ningasync.NingAsyncHttpClient; -import com.nhn.pinpoint.testweb.service.CacheService; -import com.nhn.pinpoint.testweb.service.CubridService; -import com.nhn.pinpoint.testweb.service.MemberService; -import com.ning.http.client.cookie.Cookie; - -/** - * - * @author netspider - * - */ -@Controller -public class DemoController { - - private final DemoURLHolder urls; - - private final Random random = new Random(); - - @Autowired - private CacheService cacheService; - - @Autowired - @Qualifier("memberService") - private MemberService mysqlService; - - @Autowired - private CubridService cubridService; - - @Autowired - private NingAsyncHttpClient ningAsyncHttpClient; - - @Autowired - private ApacheHttpClient4 apacheHttpClient; - - public DemoController() { - urls = DemoURLHolder.getHolder(); - } - - @RequestMapping(value = "/netspider") - public @ResponseBody - String demo1() { - accessNaverBlog(); - accessNaverCafe(); - randomSlowMethod(); - callRemote(urls.getBackendApiURL()); - return "OK"; - } - - @RequestMapping(value = "/emeroad") - public @ResponseBody - String demo2() { - randomSlowMethod(); - callRemote(urls.getBackendWebURL()); - return "OK"; - } - - @RequestMapping(value = "/harebox") - public @ResponseBody - String demo3() { - cacheService.memcached(); - accessNaver(); - return "OK"; - } - - @RequestMapping(value = "/denny") - public @ResponseBody - String demo4() { - mysqlService.list(); - randomSlowMethod(); - return "OK"; - } - - @RequestMapping(value = "/backendweb") - public @ResponseBody - String backendweb() { - cacheService.arcus(); - mysqlService.list(); - if (random.nextBoolean()) { - callRemote(urls.getBackendApiURL()); - } - return "OK"; - } - - @RequestMapping(value = "/backendapi") - public @ResponseBody - String backendapi() { - mysqlService.list(); - cubrid(); - return "OK"; - } - - private void callRemote(String url) { - apacheHttpClient.execute(url, new HashMap()); - } - - private void cubrid() { - switch (new Random().nextInt(3)) { - case 1: - cubridService.createErrorStatement(); - case 2: - cubridService.createStatement(); - case 3: - cubridService.selectOne(); - } - } - - private void accessNaver() { - Map params = new HashMap(); - params.put("query", "naver"); - params.put("ie", "utf8"); - - Map headers = new HashMap(); - headers.put("header1", "header1"); - headers.put("header2", "header2"); - - List cookies = new ArrayList(); - cookies.add(new Cookie("cookieName1", "cookieValue1", "cookieRawValue1", "", "/", 10, 10, false, false)); - cookies.add(new Cookie("cookieName2", "cookieValue2", "cookieRawValue2", "", "/", 10, 10, false, false)); - - ningAsyncHttpClient.requestGet("http://search.naver.com/search.naver?where=nexearch", params, headers, cookies); - } - - private void accessNaverBlog() { - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://section.blog.naver.com/", new HashMap()); - } - - private void accessNaverCafe() { - HttpURLConnection connection = null; - BufferedReader reader = null; - try { - connection = (HttpURLConnection) new URL("http://section.cafe.naver.com/").openConnection(); - connection.connect(); - - reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - try { - if (reader != null) { - reader.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - if (connection != null) { - connection.disconnect(); - } - } - } - - private void randomSlowMethod() { - try { - Thread.sleep(((new Random().nextInt(90)) + 10) * 10L); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.configuration.DemoURLHolder; +import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; +import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; +import com.nhn.pinpoint.testweb.connector.ningasync.NingAsyncHttpClient; +import com.nhn.pinpoint.testweb.service.CacheService; +import com.nhn.pinpoint.testweb.service.CubridService; +import com.nhn.pinpoint.testweb.service.MemberService; +import com.ning.http.client.cookie.Cookie; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.*; + +/** + * @author netspider + */ +@Controller +public class DemoController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final DemoURLHolder urls; + + private final Random random = new Random(); + + @Autowired + private CacheService cacheService; + + @Autowired + @Qualifier("memberService") + private MemberService mysqlService; + + @Autowired + private CubridService cubridService; + + @Autowired + private NingAsyncHttpClient ningAsyncHttpClient; + + @Autowired + private ApacheHttpClient4 apacheHttpClient; + + public DemoController() { + urls = DemoURLHolder.getHolder(); + } + + @RequestMapping(value = "/netspider") + @ResponseBody + public String demo1() { + accessNaverBlog(); + accessNaverCafe(); + randomSlowMethod(); + callRemote(urls.getBackendApiURL()); + return "OK"; + } + + @RequestMapping(value = "/emeroad") + @ResponseBody + public String demo2() { + randomSlowMethod(); + callRemote(urls.getBackendWebURL()); + return "OK"; + } + + @RequestMapping(value = "/harebox") + @ResponseBody + public String demo3() { + cacheService.memcached(); + accessNaver(); + return "OK"; + } + + @RequestMapping(value = "/denny") + @ResponseBody + public String demo4() { + mysqlService.list(); + randomSlowMethod(); + return "OK"; + } + + @RequestMapping(value = "/backendweb") + @ResponseBody + public String backendweb() { + cacheService.arcus(); + mysqlService.list(); + if (random.nextBoolean()) { + callRemote(urls.getBackendApiURL()); + } + return "OK"; + } + + @RequestMapping(value = "/backendapi") + @ResponseBody + public String backendapi() { + mysqlService.list(); + cubrid(); + return "OK"; + } + + private void callRemote(String url) { + apacheHttpClient.execute(url, new HashMap()); + } + + private void cubrid() { + switch (new Random().nextInt(3)) { + case 1: + cubridService.createErrorStatement(); + case 2: + cubridService.createStatement(); + case 3: + cubridService.selectOne(); + } + } + + private void accessNaver() { + Map params = new HashMap(); + params.put("query", "naver"); + params.put("ie", "utf8"); + + Map headers = new HashMap(); + headers.put("header1", "header1"); + headers.put("header2", "header2"); + + List cookies = new ArrayList(); + cookies.add(new Cookie("cookieName1", "cookieValue1", "cookieRawValue1", "", "/", 10, 10, false, false)); + cookies.add(new Cookie("cookieName2", "cookieValue2", "cookieRawValue2", "", "/", 10, 10, false, false)); + + ningAsyncHttpClient.requestGet("http://search.naver.com/search.naver?where=nexearch", params, headers, cookies); + } + + private void accessNaverBlog() { + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://section.blog.naver.com/", new HashMap()); + } + + private void accessNaverCafe() { + HttpURLConnection connection = null; + BufferedReader reader = null; + try { + connection = (HttpURLConnection) new URL("http://section.cafe.naver.com/").openConnection(); + connection.connect(); + + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + logger.warn("reader.close() error {}", e.getMessage(), e); + } + if (connection != null) { + connection.disconnect(); + } + } + } + + private void randomSlowMethod() { + try { + Thread.sleep(((new Random().nextInt(90)) + 10) * 10L); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DoNothingController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DoNothingController.java index 290b9216db85..60688e98b001 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DoNothingController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/DoNothingController.java @@ -1,23 +1,19 @@ -package com.nhn.pinpoint.testweb.controller; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.testweb.util.Description; - -/** - * - * @author netspider - * - */ -@Controller -public class DoNothingController { - @Description("아무일도 하지 않음.") - @RequestMapping(value = "/donothing") - public @ResponseBody - String donothing(Model model) { - return "OK"; - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.util.Description; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author netspider + */ +@Controller +public class DoNothingController { + @Description("아무일도 하지 않음.") + @RequestMapping(value = "/donothing") + @ResponseBody + public String donothing() { + return "OK"; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ExceptionalCaseController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ExceptionalCaseController.java index 2141bd6484a9..f71047da35b8 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ExceptionalCaseController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/ExceptionalCaseController.java @@ -1,36 +1,35 @@ -package com.nhn.pinpoint.testweb.controller; - -import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; -import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; -import com.nhn.pinpoint.testweb.util.Description; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -import java.util.HashMap; - -@Controller -public class ExceptionalCaseController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - /** - * 루트의 완성이 지연될 경우 먼저 끝난 rpc콜을 정상적으로 읽을수 있는지 테스트 - */ - @Description("root의 완료가 지연될경우 parent가 완료된 데이터를 정상적으로 확인가능지.") - @RequestMapping(value = "/exceptionalcase/rootslow") - public void rootSlow() { - ApacheHttpClient4 client2 = new ApacheHttpClient4(new HttpConnectorOptions()); - client2.execute("http://localhost:8080/donothing.pinpoint", new HashMap()); - - try { - final int sleep = 1000 * 30; - logger.info("sleep:{}", sleep); - Thread.sleep(sleep); - } catch (InterruptedException e) { - - } - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; +import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; +import com.nhn.pinpoint.testweb.util.Description; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.HashMap; + +@Controller +public class ExceptionalCaseController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 루트의 완성이 지연될 경우 먼저 끝난 rpc콜을 정상적으로 읽을수 있는지 테스트 + */ + @Description("root의 완료가 지연될경우 parent가 완료된 데이터를 정상적으로 확인가능지.") + @RequestMapping(value = "/exceptionalcase/rootslow") + public void rootSlow() { + ApacheHttpClient4 client2 = new ApacheHttpClient4(new HttpConnectorOptions()); + client2.execute("http://localhost:8080/donothing.pinpoint", new HashMap()); + + try { + final int sleep = 1000 * 30; + logger.info("sleep:{}", sleep); + Thread.sleep(sleep); + } catch (InterruptedException e) { + + } + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HelloWorldController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HelloWorldController.java index d8d5c5e65810..f87875507fed 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HelloWorldController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HelloWorldController.java @@ -1,352 +1,334 @@ -package com.nhn.pinpoint.testweb.controller; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import net.spy.memcached.AddrUtil; -import net.spy.memcached.ArcusClient; -import net.spy.memcached.ConnectionFactoryBuilder; -import net.spy.memcached.MemcachedClient; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import perftest.LevelManager; - -import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; -import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.service.CacheService; -import com.nhn.pinpoint.testweb.service.DummyService; -import com.nhn.pinpoint.testweb.service.MemberService; -import com.nhn.pinpoint.testweb.util.Description; -import com.nhncorp.lucy.net.invoker.InvocationFuture; -import com.nhncorp.lucy.npc.connector.NpcHessianConnector; - -@Controller -@Deprecated -public class HelloWorldController implements DisposableBean { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final ArcusClient arcus; - private final MemcachedClient memcached; - private final LevelManager levelManager; - - public HelloWorldController() throws IOException { - arcus = ArcusClient.createArcusClient("dev.arcuscloud.nhncorp.com:17288", "dev", new ConnectionFactoryBuilder()); - memcached = new MemcachedClient(AddrUtil.getAddresses("10.25.149.80:11244,10.25.149.80:11211,10.25.149.79:11211")); - levelManager = new LevelManager(); - } - - @Autowired - @Qualifier("memberService") - private MemberService service; - - @Autowired - private DummyService dummyService; - - @Autowired - private CacheService cacheService; - - private void randomSlowMethod() { - try { - Thread.sleep((new Random().nextInt(3)) * 1000L); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - @RequestMapping(value = "/dummy") - public @ResponseBody - String dummy(Model model) { - dummyService.doSomething(); - return "OK"; - } - - @RequestMapping(value = "/encoding") - public @ResponseBody - String encoding(Model model, @RequestParam("name") String name) { - logger.debug("name=" + name); - return "OK"; - } - - @RequestMapping(value = "/arcus") - public @ResponseBody - String arcus(Model model) { - cacheService.arcus(); - return "OK"; - } - - @RequestMapping(value = "/memcached") - public @ResponseBody - String memcached(Model model) { - cacheService.memcached(); - return "OK"; - } - - @RequestMapping(value = "/mysql") - public @ResponseBody - String mysql(Model model) { - int id = (new Random()).nextInt(); - - Member member = new Member(); - member.setId(id); - member.setName("chisu"); - member.setJoined(new Date()); - - // add - service.add(member); - - // list - service.list(); - - // del - service.delete(id); - - return "OK"; - } - - @Description("바인드 변수 + 상수값 파싱 로직테스트") - @RequestMapping(value = "/mysqlStatement") - public @ResponseBody - String mysqlStatement(Model model) { - int id = (new Random()).nextInt(); - - Member member = new Member(); - member.setId(id); - member.setName("chisu"); - member.setJoined(new Date()); - - // add - service.addStatement(member); - - // list - service.list(); - - // del - service.delete(id); - - return "OK"; - } - - @RequestMapping(value = "/nested") - public @ResponseBody - String nested(Model model) { - ApacheHttpClient4 client2 = new ApacheHttpClient4(new HttpConnectorOptions()); - client2.execute("http://localhost:8080/donothing.pinpoint", new HashMap()); - - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://www.naver.com/", new HashMap()); - mysql(model); - return "OK"; - } - - @RequestMapping(value = "/remotecombination") - public @ResponseBody - String remotecombination(Model model) { - String[] ports = new String[] { "9080", "10080", "11080" }; - Random random = new Random(); - String port = ports[random.nextInt(3)]; - - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://localhost:" + port + "/combination.pinpoint", new HashMap()); - - ApacheHttpClient4 client2 = new ApacheHttpClient4(new HttpConnectorOptions()); - client2.execute("http://localhost:8080/arcus.pinpoint", new HashMap()); - - client.execute("http://www.naver.com/", new HashMap()); - client.execute("http://www.naver.com/", new HashMap()); - try { - client.execute("http://very.very.very.long.long.url/", new HashMap()); - client.execute("http://url1/", new HashMap()); - client.execute("http://url2/", new HashMap()); - client.execute("http://url2/", new HashMap()); - client.execute("http://url3/", new HashMap()); - client.execute("http://url3/", new HashMap()); - client.execute("http://url3/", new HashMap()); - } catch (Exception e) { - } - return "OK"; - } - - @RequestMapping(value = "/remotearcus") - public @ResponseBody - String remotearcus(Model model) { - arcus(model); - - String[] ports = new String[] { "9080", "10080", "11080" }; - Random random = new Random(); - String port = ports[random.nextInt(3)]; - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://localhost:" + port + "/arcus.pinpoint", new HashMap()); - return "OK"; - } - - @RequestMapping(value = "/combination") - public @ResponseBody - String combination(Model model) { - try { - mysql(model); - } catch (Exception e) { - e.printStackTrace(); - } - - try { - arcus(model); - } catch (Exception e) { - e.printStackTrace(); - } - - try { - memcached(model); - } catch (Exception e) { - e.printStackTrace(); - } - - randomSlowMethod(); - - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://www.naver.com/", new HashMap()); - client.execute("http://www.naver.com/", new HashMap()); - - client.execute("http://section.cafe.naver.com/", new HashMap()); - client.execute("http://section.cafe.naver.com/", new HashMap()); - - npc(model); - - return "OK"; - } - - @RequestMapping(value = "/httperror") - public @ResponseBody - String httperror(Model model) { - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://127.0.0.1/", new HashMap()); - return "OK"; - } - - @RequestMapping(value = "/error500") - public @ResponseBody - String error500(Model model) { - try { - int i = 1 / 0; - return "OK"; - } catch (Exception e) { - return e.getMessage(); - } - } - - @RequestMapping(value = "/slow") - public @ResponseBody - String slow(Model model) { - try { - Thread.sleep(new Random().nextInt(10) * 100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return "OK"; - } - - @RequestMapping(value = "/throwexception") - public @ResponseBody - String exception(Model model) { - throw new RuntimeException("Exception test"); - } - - @RequestMapping(value = "/arcustimeout") - public @ResponseBody - String arcustimeout(Model model) { - Future future = null; - try { - future = arcus.set("pinpoint:expect-timeout", 10, "Hello, Timeout."); - future.get(10L, TimeUnit.MICROSECONDS); - } catch (Exception e) { - if (future != null) - future.cancel(true); - e.printStackTrace(); - return e.getMessage(); - } - return "OK"; - } - - @RequestMapping(value = "/remotesimple") - public @ResponseBody - String remotesimple(Model model) { - String[] ports = new String[] { "9080", "10080", "11080" }; - Random random = new Random(); - String port = ports[random.nextInt(3)]; - - arcus(model); - - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://localhost:" + port + "/arcus.pinpoint", new HashMap()); - return "OK"; - } - - @RequestMapping(value = "/remoteerror") - public @ResponseBody - String remoteError(Model model) { - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://localhost:10080/rpcerror.pinpoint", new HashMap()); - return "OK"; - } - - @RequestMapping(value = "/rpcerror") - public @ResponseBody - String rpcError(Model model) { - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("UNKNOWN_URL", new HashMap()); - return "OK"; - } - - @RequestMapping(value = "/npc") - public @ResponseBody - String npc(Model model) { - try { - InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); - NpcHessianConnector connector = new NpcHessianConnector(serverAddress, true); - - Map params = new HashMap(); - params.put("message", "hello pinpoint"); - - InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); - - future.await(); - - // Object result = future.get(); - Object result = future.getReturnValue(); - System.out.println("npc result=" + result); - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - return "OK"; - } - - @RequestMapping(value = "/perftest") - public @ResponseBody - String perfTest(Model model) { - levelManager.traverse(); - return "OK"; - } - - @Override - public void destroy() throws Exception { - arcus.shutdown(); - memcached.shutdown(); - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; +import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.service.CacheService; +import com.nhn.pinpoint.testweb.service.DummyService; +import com.nhn.pinpoint.testweb.service.MemberService; +import com.nhn.pinpoint.testweb.util.Description; +import com.nhncorp.lucy.net.invoker.InvocationFuture; +import com.nhncorp.lucy.npc.connector.NpcHessianConnector; +import net.spy.memcached.AddrUtil; +import net.spy.memcached.ArcusClient; +import net.spy.memcached.ConnectionFactoryBuilder; +import net.spy.memcached.MemcachedClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import perftest.LevelManager; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +@Controller +@Deprecated +public class HelloWorldController implements DisposableBean { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ArcusClient arcus; + private final MemcachedClient memcached; + private final LevelManager levelManager; + + public HelloWorldController() throws IOException { + arcus = ArcusClient.createArcusClient("dev.arcuscloud.nhncorp.com:17288", "dev", new ConnectionFactoryBuilder()); + memcached = new MemcachedClient(AddrUtil.getAddresses("10.25.149.80:11244,10.25.149.80:11211,10.25.149.79:11211")); + levelManager = new LevelManager(); + } + + @Autowired + @Qualifier("memberService") + private MemberService service; + + @Autowired + private DummyService dummyService; + + @Autowired + private CacheService cacheService; + + private void randomSlowMethod() { + try { + Thread.sleep((new Random().nextInt(3)) * 1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @RequestMapping(value = "/dummy") + @ResponseBody + public String dummy() { + dummyService.doSomething(); + return "OK"; + } + + @RequestMapping(value = "/encoding") + @ResponseBody + public String encoding(Model model, @RequestParam("name") String name) { + logger.debug("name=" + name); + return "OK"; + } + + @RequestMapping(value = "/arcus") + @ResponseBody + public String arcus() { + cacheService.arcus(); + return "OK"; + } + + @RequestMapping(value = "/memcached") + @ResponseBody + public String memcached() { + cacheService.memcached(); + return "OK"; + } + + @RequestMapping(value = "/mysql") + @ResponseBody + public String mysql() { + int id = (new Random()).nextInt(); + + Member member = new Member(); + member.setId(id); + member.setName("pinpoint_user"); + member.setJoined(new Date()); + + // add + service.add(member); + + // list + service.list(); + + // del + service.delete(id); + + return "OK"; + } + + @Description("바인드 변수 + 상수값 파싱 로직테스트") + @RequestMapping(value = "/mysqlStatement") + @ResponseBody + public String mysqlStatement() { + int id = (new Random()).nextInt(); + + Member member = new Member(); + member.setId(id); + member.setName("pinpoint_user"); + member.setJoined(new Date()); + + // add + service.addStatement(member); + + // list + service.list(); + + // del + service.delete(id); + + return "OK"; + } + + @RequestMapping(value = "/nested") + @ResponseBody + public String nested() { + ApacheHttpClient4 client2 = new ApacheHttpClient4(new HttpConnectorOptions()); + client2.execute("http://localhost:8080/donothing.pinpoint", new HashMap()); + + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://www.naver.com/", new HashMap()); + mysql(); + return "OK"; + } + + @RequestMapping(value = "/remotecombination") + @ResponseBody + public String remotecombination() { + String[] ports = new String[]{"9080", "10080", "11080"}; + Random random = new Random(); + String port = ports[random.nextInt(3)]; + + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://localhost:" + port + "/combination.pinpoint", new HashMap()); + + ApacheHttpClient4 client2 = new ApacheHttpClient4(new HttpConnectorOptions()); + client2.execute("http://localhost:8080/arcus.pinpoint", new HashMap()); + + client.execute("http://www.naver.com/", new HashMap()); + client.execute("http://www.naver.com/", new HashMap()); + try { + client.execute("http://very.very.very.long.long.url/", new HashMap()); + client.execute("http://url1/", new HashMap()); + client.execute("http://url2/", new HashMap()); + client.execute("http://url2/", new HashMap()); + client.execute("http://url3/", new HashMap()); + client.execute("http://url3/", new HashMap()); + client.execute("http://url3/", new HashMap()); + } catch (Exception e) { + } + return "OK"; + } + + @RequestMapping(value = "/remotearcus") + @ResponseBody + public String remotearcus() { + arcus(); + + String[] ports = new String[]{"9080", "10080", "11080"}; + Random random = new Random(); + String port = ports[random.nextInt(3)]; + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://localhost:" + port + "/arcus.pinpoint", new HashMap()); + return "OK"; + } + + @RequestMapping(value = "/combination") + @ResponseBody + public String combination() { + + mysql(); + + arcus(); + + memcached(); + + + randomSlowMethod(); + + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://www.naver.com/", new HashMap()); + client.execute("http://www.naver.com/", new HashMap()); + + client.execute("http://section.cafe.naver.com/", new HashMap()); + client.execute("http://section.cafe.naver.com/", new HashMap()); + + npc(); + + return "OK"; + } + + @RequestMapping(value = "/httperror") + @ResponseBody + public String httperror() { + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://127.0.0.1/", new HashMap()); + return "OK"; + } + + @RequestMapping(value = "/error500") + @ResponseBody + public String error500() { + int i = 1 / 0; + return "OK"; + + } + + @RequestMapping(value = "/slow") + @ResponseBody + public String slow() { + try { + Thread.sleep(new Random().nextInt(10) * 100); + } catch (InterruptedException e) { + } + return "OK"; + } + + @RequestMapping(value = "/throwexception") + @ResponseBody + public String exception() { + throw new RuntimeException("Exception test"); + } + + @RequestMapping(value = "/arcustimeout") + @ResponseBody + public String arcustimeout() { + Future future = null; + try { + future = arcus.set("pinpoint:expect-timeout", 10, "Hello, Timeout."); + future.get(10L, TimeUnit.MICROSECONDS); + } catch (Exception e) { + if (future != null) { + future.cancel(true); + } + throw new RuntimeException(e); + } + return "OK"; + } + + @RequestMapping(value = "/remotesimple") + @ResponseBody + public String remotesimple() { + String[] ports = new String[]{"9080", "10080", "11080"}; + Random random = new Random(); + String port = ports[random.nextInt(3)]; + + arcus(); + + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://localhost:" + port + "/arcus.pinpoint", new HashMap()); + return "OK"; + } + + @RequestMapping(value = "/remoteerror") + @ResponseBody + public String remoteError() { + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://localhost:10080/rpcerror.pinpoint", new HashMap()); + return "OK"; + } + + @RequestMapping(value = "/rpcerror") + @ResponseBody + public String rpcError() { + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("UNKNOWN_URL", new HashMap()); + return "OK"; + } + + @RequestMapping(value = "/npc") + @ResponseBody + public String npc() { + try { + InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); + NpcHessianConnector connector = new NpcHessianConnector(serverAddress, true); + + Map params = new HashMap(); + params.put("message", "hello pinpoint"); + + InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); + + future.await(); + + // Object result = future.get(); + Object result = future.getReturnValue(); + logger.debug("npc result={}", result); + } catch (Exception e) { + throw new RuntimeException(e); + } + return "OK"; + } + + @RequestMapping(value = "/perftest") + @ResponseBody + public String perfTest() { + levelManager.traverse(); + return "OK"; + } + + @Override + public void destroy() throws Exception { + arcus.shutdown(); + memcached.shutdown(); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HttpClient4Controller.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HttpClient4Controller.java index 85f4a75ac65a..8f380f0b73aa 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HttpClient4Controller.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/HttpClient4Controller.java @@ -1,54 +1,51 @@ -package com.nhn.pinpoint.testweb.controller; - -import java.util.HashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; -import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; -import com.nhn.pinpoint.testweb.util.Description; - -/** - * - * @author netspider - * - */ -@Controller -public class HttpClient4Controller { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Description("에러시 cookie덤프") - @RequestMapping(value = "/httpclient4/cookie") - public @ResponseBody - String cookie(@RequestHeader(value = "Cookie", required = false) String cookie) { - logger.info("Cookie:{}", cookie); - - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - client.execute("http://localhost:" + 9999 + "/combination.pinpoint", new HashMap(), cookie); - - return "OK"; - } - - @Description("에러시 post덤프") - @RequestMapping(value = "/httpclient4/post") - public @ResponseBody - String post() { - logger.info("Post"); - // String[] ports = new String[] { "9080", "10080", "11080" }; - // Random random = new Random(); - // String port = ports[random.nextInt(3)]; - // - ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); - HashMap post = new HashMap(); - post.put("test", "1"); - post.put("test2", "2"); - client.execute("http://localhost:" + 9999 + "/combination.pinpoint", post); - - return "OK"; - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; +import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; +import com.nhn.pinpoint.testweb.util.Description; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.HashMap; + +/** + * @author netspider + */ +@Controller +public class HttpClient4Controller { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Description("에러시 cookie덤프") + @RequestMapping(value = "/httpclient4/cookie") + @ResponseBody + public String cookie(@RequestHeader(value = "Cookie", required = false) String cookie) { + logger.info("Cookie:{}", cookie); + + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + client.execute("http://localhost:" + 9999 + "/combination.pinpoint", new HashMap(), cookie); + + return "OK"; + } + + @Description("에러시 post덤프") + @RequestMapping(value = "/httpclient4/post") + @ResponseBody + public String post() { + logger.info("Post"); + // String[] ports = new String[] { "9080", "10080", "11080" }; + // Random random = new Random(); + // String port = ports[random.nextInt(3)]; + // + ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); + HashMap post = new HashMap(); + post.put("test", "1"); + post.put("test2", "2"); + client.execute("http://localhost:" + 9999 + "/combination.pinpoint", post); + + return "OK"; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MainController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MainController.java index 8221a5bfcb63..00ed9765ae99 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MainController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MainController.java @@ -1,128 +1,102 @@ package com.nhn.pinpoint.testweb.controller; -import java.io.File; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - +import com.nhn.pinpoint.testweb.domain.ControllerMappingInfo; +import com.nhn.pinpoint.testweb.util.Description; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import com.nhn.pinpoint.testweb.vo.RequestMappingInfo; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.*; /** - * * @author netspider - * */ @Controller public class MainController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final RequestMappingHandlerMapping handlerMapping; + + @Autowired + public MainController(RequestMappingHandlerMapping handlerMapping) { + this.handlerMapping = handlerMapping; + } + + + @RequestMapping(value = "/docs", method = RequestMethod.GET) + public String getEndPointsInView(Model model) { + model.addAttribute("mapping", getMappingInfo()); + return "docs"; + } + + + public Map> getMappingInfo() { + Map> info = new TreeMap>(); + + Map handlerMethods = handlerMapping.getHandlerMethods(); + for (Map.Entry requestMappingInfoHandlerMethodEntry : handlerMethods.entrySet()) { + RequestMappingInfo requestMappingInfoKey = requestMappingInfoHandlerMethodEntry.getKey(); + HandlerMethod handlerMethod = requestMappingInfoHandlerMethodEntry.getValue(); + Method method = handlerMethod.getMethod(); + Class declaringClass = method.getDeclaringClass(); + + List controllerMappingInfoList = info.get(declaringClass.getSimpleName()); + if (controllerMappingInfoList == null) { + controllerMappingInfoList = new ArrayList(); + info.put(declaringClass.getSimpleName(), controllerMappingInfoList); + } + + List requestInfo = createRequestMappingInfo(requestMappingInfoKey, handlerMethod); + controllerMappingInfoList.addAll(requestInfo); + } + sort(info); + + logger.debug("{}", info); + return info; + } + + private void sort(Map> info) { + for (List controllerMappingInfos : info.values()) { + Collections.sort(controllerMappingInfos, new Comparator() { + @Override + public int compare(ControllerMappingInfo o1, ControllerMappingInfo o2) { + return o1.getUrl().compareTo(o2.getUrl()); + } + }); + } + } + + private List createRequestMappingInfo(RequestMappingInfo requestMappingInfo, HandlerMethod handlerMethod) { + List requestInfo = new ArrayList(); + + Set patterns = requestMappingInfo.getPatternsCondition().getPatterns(); + for (String pattern : patterns) { + Description description = getDescription(handlerMethod); + ControllerMappingInfo info = new ControllerMappingInfo(pattern, (description == null) ? "" : description.value()); + requestInfo.add(info); + } + + return requestInfo; + } + + private Description getDescription(HandlerMethod handlerMethod) { + Annotation[] annotations = handlerMethod.getMethod().getAnnotations(); + for (Annotation annotation : annotations) { + if (annotation instanceof com.nhn.pinpoint.testweb.util.Description) { + return (Description) annotation; + } + } + + return null; + } - @RequestMapping(value = "/docs", method = RequestMethod.GET) - public String getEndPointsInView(Model model) { - model.addAttribute("mapping", getMappingInfo()); - return "docs"; - } - - public Map> getMappingInfo() { - Map> info = new HashMap>(); - try { - String packaze = "com.nhn.pinpoint.testweb.controller"; - ArrayList classNamesFromPackage = MainController.getClassNamesFromPackage(packaze); - - for (String className : classNamesFromPackage) { - Class clazz = Class.forName(packaze + "." + className); - - List requestInfo = new ArrayList(); - - Method[] methods = clazz.getDeclaredMethods(); - - for (Method m : methods) { - Annotation[] annotations = m.getDeclaredAnnotations(); - - org.springframework.web.bind.annotation.RequestMapping mappingInfo = null; - com.nhn.pinpoint.testweb.util.Description description = null; - - for (Annotation a : annotations) { - if (a instanceof org.springframework.web.bind.annotation.RequestMapping) { - mappingInfo = (org.springframework.web.bind.annotation.RequestMapping) a; - } - if (a instanceof com.nhn.pinpoint.testweb.util.Description) { - description = (com.nhn.pinpoint.testweb.util.Description) a; - } - } - - if (mappingInfo != null) { - requestInfo.add(new RequestMappingInfo(mappingInfo.value()[0], (description == null) ? "" : description.value())); - } - } - - if (requestInfo.size() > 0) { - info.put(clazz.getSimpleName(), requestInfo); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return info; - } - - // spring에서 제공하는 기능이 있는것 같긴 하지만 그냥 구식으로. - public static ArrayList getClassNamesFromPackage(String packageName) throws IOException, URISyntaxException { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - URL packageURL; - ArrayList names = new ArrayList(); - - packageName = packageName.replace(".", "/"); - packageURL = classLoader.getResource(packageName); - - if (packageURL.getProtocol().equals("jar")) { - String jarFileName; - JarFile jf; - Enumeration jarEntries; - String entryName; - - // build jar file name, then loop through zipped entries - jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8"); - jarFileName = jarFileName.substring(5, jarFileName.indexOf("!")); - System.out.println(">" + jarFileName); - jf = new JarFile(jarFileName); - jarEntries = jf.entries(); - while (jarEntries.hasMoreElements()) { - entryName = jarEntries.nextElement().getName(); - if (entryName.startsWith(packageName) && entryName.length() > packageName.length() + 5) { - entryName = entryName.substring(packageName.length(), entryName.lastIndexOf('.')); - names.add(entryName); - } - } - - // loop through files in classpath - } else { - URI uri = new URI(packageURL.toString()); - File folder = new File(uri.getPath()); - // won't work with path which contains blank (%20) - // File folder = new File(packageURL.getFile()); - File[] contenuti = folder.listFiles(); - String entryName; - for (File actual : contenuti) { - entryName = actual.getName(); - entryName = entryName.substring(0, entryName.lastIndexOf('.')); - names.add(entryName); - } - } - return names; - } } diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MsSqlServerController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MsSqlServerController.java new file mode 100644 index 000000000000..07794ff7d7e8 --- /dev/null +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MsSqlServerController.java @@ -0,0 +1,47 @@ +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.service.MsSqlServerService; +import com.nhn.pinpoint.testweb.util.Description; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * + */ +@Controller +public class MsSqlServerController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private MsSqlServerService msSqlServerService; + + + @Description("preparedStatement 테스트. resultset은 가지고 오지 않음.") + @RequestMapping(value = "/mssqlserver/selectOne") + @ResponseBody + public String selectOne() { + logger.info("selectOne start"); + + int i = msSqlServerService.selectOne(); + + logger.info("selectOne end:{}", i); + return "OK"; + } + + @Description("statement 테스트. resultset은 가지고 오지 않음.") + @RequestMapping(value = "/mssqlserver/createStatement") + @ResponseBody + public String createStatement() { + logger.info("createStatement start"); + + msSqlServerService.createStatement(); + + logger.info("createStatement end:{}"); + + return "OK"; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MySqlController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MySqlController.java index 71377f1cfc5e..64c5ba8dc5b9 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MySqlController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/MySqlController.java @@ -1,111 +1,92 @@ -package com.nhn.pinpoint.testweb.controller; - -import java.util.Date; -import java.util.Random; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.service.MemberService; -import com.nhn.pinpoint.testweb.service.MySqlService; -import com.nhn.pinpoint.testweb.util.Description; - -/** - * - */ -@Controller -public class MySqlController { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private MySqlService mySqlService; - - @Autowired - @Qualifier("memberService") - private MemberService service; - - @RequestMapping(value = "/mysql/crud") - public @ResponseBody - String crud(Model model) { - try { - int id = (new Random()).nextInt(); - - Member member = new Member(); - member.setId(id); - member.setName("chisu"); - member.setJoined(new Date()); - - service.add(member); - service.list(); - service.delete(id); - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - - return "OK"; - } - - @RequestMapping(value = "/mysql/crudWithStatement") - public @ResponseBody - String crudWithStatement(Model model) { - try { - int id = (new Random()).nextInt(); - - Member member = new Member(); - member.setId(id); - member.setName("chisu"); - member.setJoined(new Date()); - - service.addStatement(member); - service.list(); - service.delete(id); - - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } - - @Description("preparedStatement 테스트. resultset은 가지고 오지 않음.") - @RequestMapping(value = "/mysql/selectOne") - public @ResponseBody - String selectOne(Model model) { - try { - logger.info("selectOne start"); - - int i = mySqlService.selectOne(); - - logger.info("selectOne end:{}", i); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } - - @Description("statement 테스트. resultset은 가지고 오지 않음.") - @RequestMapping(value = "/mysql/createStatement") - public @ResponseBody - String oracleStatement(Model model) { - try { - logger.info("createStatement start"); - - mySqlService.createStatement(); - - logger.info("createStatement end:{}"); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.service.MemberService; +import com.nhn.pinpoint.testweb.service.MySqlService; +import com.nhn.pinpoint.testweb.util.Description; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.Date; +import java.util.Random; + +/** + * + */ +@Controller +public class MySqlController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private MySqlService mySqlService; + + @Autowired + @Qualifier("memberService") + private MemberService service; + + @RequestMapping(value = "/mysql/crud") + @ResponseBody + public String crud() { + int id = (new Random()).nextInt(); + + Member member = new Member(); + member.setId(id); + member.setName("pinpoint_user"); + member.setJoined(new Date()); + + service.add(member); + service.list(); + service.delete(id); + + return "OK"; + } + + @RequestMapping(value = "/mysql/crudWithStatement") + @ResponseBody + public String crudWithStatement() { + + int id = (new Random()).nextInt(); + + Member member = new Member(); + member.setId(id); + member.setName("pinpoint_user"); + member.setJoined(new Date()); + + service.addStatement(member); + service.list(); + service.delete(id); + + return "OK"; + } + + @Description("preparedStatement 테스트. resultset은 가지고 오지 않음.") + @RequestMapping(value = "/mysql/selectOne") + @ResponseBody + public String selectOne() { + logger.info("selectOne start"); + + int i = mySqlService.selectOne(); + + logger.info("selectOne end:{}", i); + return "OK"; + + } + + @Description("statement 테스트. resultset은 가지고 오지 않음.") + @RequestMapping(value = "/mysql/createStatement") + @ResponseBody + public String createStatement() { + logger.info("createStatement start"); + + mySqlService.createStatement(); + + logger.info("createStatement end:{}"); + return "OK"; + + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NHNEntHttpClientController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NHNEntHttpClientController.java index 4f38754e6a90..6b870a4ac178 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NHNEntHttpClientController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NHNEntHttpClientController.java @@ -1,48 +1,44 @@ package com.nhn.pinpoint.testweb.controller; +import com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent.HttpUtil; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent.HttpUtil; - /** - * * @author netspider - * */ @Controller public class NHNEntHttpClientController { - @RequestMapping(value = "/nhnent/get") - public @ResponseBody - String requestGet(Model model, @RequestParam(required = false, defaultValue = "http") String protocol) { - return HttpUtil.url(protocol + "://www.naver.com").method(HttpUtil.Method.GET).connectionTimeout(10000).readTimeout(10000).getContents(); - } - - @RequestMapping(value = "/nhnent/getWithParam") - public @ResponseBody - String requestGetWithParam(Model model) { - return "NOT_IMPLEMENTED"; - } - - @RequestMapping(value = "/nhnent/post") - public @ResponseBody - String requestPost(Model model, @RequestParam(required = false, defaultValue = "http") String protocol) { - return HttpUtil.url(protocol + "://www.naver.com").method(HttpUtil.Method.POST).connectionTimeout(10000).readTimeout(10000).getContents(); - } - - @RequestMapping(value = "/nhnent/postWithBody") - public @ResponseBody - String requestPostWithBody(Model model) { - return "NOT_IMPLEMENTED"; - } - - @RequestMapping(value = "/nhnent/postWithMultipart") - public @ResponseBody - String requestPostWithMultipart(Model model) { - return "NOT_IMPLEMENTED"; - } + @RequestMapping(value = "/nhnent/get") + @ResponseBody + public String requestGet(Model model, @RequestParam(required = false, defaultValue = "http") String protocol) { + return HttpUtil.url(protocol + "://www.naver.com").method(HttpUtil.Method.GET).connectionTimeout(10000).readTimeout(10000).getContents(); + } + + @RequestMapping(value = "/nhnent/getWithParam") + @ResponseBody + public String requestGetWithParam() { + return "NOT_IMPLEMENTED"; + } + + @RequestMapping(value = "/nhnent/post") + @ResponseBody + public String requestPost(Model model, @RequestParam(required = false, defaultValue = "http") String protocol) { + return HttpUtil.url(protocol + "://www.naver.com").method(HttpUtil.Method.POST).connectionTimeout(10000).readTimeout(10000).getContents(); + } + + @RequestMapping(value = "/nhnent/postWithBody") + @ResponseBody + public String requestPostWithBody() { + return "NOT_IMPLEMENTED"; + } + + @RequestMapping(value = "/nhnent/postWithMultipart") + public String requestPostWithMultipart() { + return "NOT_IMPLEMENTED"; + } } \ No newline at end of file diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NIMMController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NIMMController.java index fb05d2982048..d3948671a388 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NIMMController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NIMMController.java @@ -1,48 +1,43 @@ -package com.nhn.pinpoint.testweb.controller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.testweb.nimm.mockupserver.NimmInvokerTest; - -/** - * - * @author netspider - * - */ -@Controller -public class NIMMController implements DisposableBean { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private NimmInvokerTest nimm; - - @RequestMapping(value = "/nimm/1") - public @ResponseBody - String npc(Model model) { - try { - nimm.testInvoke(); - } catch (Exception e) { - e.printStackTrace(); - return e.getMessage(); - } - return "OK"; - } - - @Override - public void destroy() throws Exception { - try { - nimm.tearDown(); - } catch (Exception e) { - logger.warn("tearDown() error Caused:" + e.getMessage(), e); - } - nimm.dispose(); - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.nimm.mockupserver.NimmInvokerTest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author netspider + */ +@Controller +public class NIMMController implements DisposableBean { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private NimmInvokerTest nimm; + + @RequestMapping(value = "/nimm/1") + @ResponseBody + public String npc() { + try { + nimm.testInvoke(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return "OK"; + } + + @Override + public void destroy() throws Exception { + try { + nimm.tearDown(); + } catch (Exception e) { + logger.warn("tearDown() error Caused:" + e.getMessage(), e); + } + nimm.dispose(); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NPCController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NPCController.java index 23b185dedc55..6305b4d96ed1 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NPCController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NPCController.java @@ -1,230 +1,207 @@ -package com.nhn.pinpoint.testweb.controller; - -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhncorp.lucy.net.invoker.InvocationFuture; -import com.nhncorp.lucy.net.invoker.InvocationFutureListener; -import com.nhncorp.lucy.npc.connector.ConnectionFactory; -import com.nhncorp.lucy.npc.connector.KeepAliveNpcHessianConnector; -import com.nhncorp.lucy.npc.connector.NpcConnectionFactory; -import com.nhncorp.lucy.npc.connector.NpcHessianConnector; - -/** - * - * @author netspider - * - */ -@Controller -public class NPCController { - - /** - * using basic connector - * - * @param model - * @return - */ - @RequestMapping(value = "/npc/1") - public @ResponseBody - String npc(Model model) { - NpcHessianConnector connector = null; - try { - InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); - connector = new NpcHessianConnector(serverAddress, true); - - Map params = new HashMap(); - params.put("message", "hello pinpoint"); - - InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); - - future.await(); - - // Object result = future.get(); - Object result = future.getReturnValue(); - System.out.println("npc result=" + result); - } catch (Exception e) { - e.printStackTrace(); - return e.getMessage(); - } finally { - if (connector != null) { - connector.dispose(); - } - } - return "OK"; - } - - /** - * using keepalive connector - * - * @param model - * @return - */ - @RequestMapping(value = "/npc/2") - public @ResponseBody - String npc2(Model model) { - KeepAliveNpcHessianConnector connector = null; - try { - InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); - - connector = new KeepAliveNpcHessianConnector(serverAddress); - - Map params = new HashMap(); - params.put("message", "hello pinpoint"); - - InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); - - future.await(); - - // Object result = future.get(); - Object result = future.getReturnValue(); - System.out.println("npc result=" + result); - } catch (Exception e) { - e.printStackTrace(); - return e.getMessage(); - } finally { - if (connector != null) { - connector.dispose(); - } - } - return "OK"; - } - - /** - * using connection factory - * - * @param model - * @return - */ - @RequestMapping(value = "/npc/3") - public @ResponseBody - String npc3(Model model) { - NpcHessianConnector connector = null; - try { - InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); - - ConnectionFactory npcConnectionFactory = new NpcConnectionFactory(); - - npcConnectionFactory.setTimeout(1000L); - npcConnectionFactory.setAddress(serverAddress); - - connector = npcConnectionFactory.create(); - - Map params = new HashMap(); - params.put("message", "hello pinpoint"); - - InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); - - future.await(); - - // Object result = future.get(); - Object result = future.getReturnValue(); - System.out.println("npc result=" + result); - } catch (Exception e) { - e.printStackTrace(); - return e.getMessage(); - } finally { - if (connector != null) { - connector.dispose(); - } - } - return "OK"; - } - - /** - * using lightweight connector - * - * @param model - * @return - */ - @RequestMapping(value = "/npc/4") - public @ResponseBody - String npc4(Model model) { - NpcHessianConnector connector = null; - try { - InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); - - ConnectionFactory npcConnectionFactory = new NpcConnectionFactory(); - - npcConnectionFactory.setTimeout(1000L); - npcConnectionFactory.setAddress(serverAddress); - npcConnectionFactory.setLightWeight(true); - - connector = npcConnectionFactory.create(); - - Map params = new HashMap(); - params.put("message", "hello pinpoint"); - - InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); - - future.await(); - - // Object result = future.get(); - Object result = future.getReturnValue(); - System.out.println("npc result=" + result); - } catch (Exception e) { - e.printStackTrace(); - return e.getMessage(); - } finally { - if (connector != null) { - connector.dispose(); - } - } - return "OK"; - } - - /** - * using lightweight connector and listener - * - * @param model - * @return - */ - @RequestMapping(value = "/npc/5") - public @ResponseBody - String npc5(Model model) { - NpcHessianConnector connector = null; - try { - InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); - - ConnectionFactory npcConnectionFactory = new NpcConnectionFactory(); - - npcConnectionFactory.setTimeout(1000L); - npcConnectionFactory.setAddress(serverAddress); - npcConnectionFactory.setLightWeight(true); - - connector = npcConnectionFactory.create(); - - Map params = new HashMap(); - params.put("message", "hello pinpoint"); - - InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); - - future.addListener(new InvocationFutureListener() { - @Override - public void invocationComplete(InvocationFuture future) throws Exception { - Object result = future.getReturnValue(); - System.out.println("npc result=" + result); - } - }); - } catch (Exception e) { - e.printStackTrace(); - return e.getMessage(); - } finally { - if (connector != null) { - connector.dispose(); - } - } - return "OK"; - } - - @RequestMapping(value = "/npc/6") - public @ResponseBody - String npcStream(Model model) { - return "NOT_IMPLEMENTED"; - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhncorp.lucy.net.invoker.InvocationFuture; +import com.nhncorp.lucy.net.invoker.InvocationFutureListener; +import com.nhncorp.lucy.npc.connector.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; + +/** + * @author netspider + */ +@Controller +public class NPCController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * using basic connector + * + * @return + */ + @RequestMapping(value = "/npc/1") + @ResponseBody + public String npc() throws Exception { + NpcHessianConnector connector = null; + try { + InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); + connector = new NpcHessianConnector(serverAddress, true); + + Map params = new HashMap(); + params.put("message", "hello pinpoint"); + + InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); + + future.await(); + + // Object result = future.get(); + Object result = future.getReturnValue(); + logger.debug("npc result={}", result); + } finally { + if (connector != null) { + connector.dispose(); + } + } + return "OK"; + } + + /** + * using keepalive connector + * + * @return + */ + @RequestMapping(value = "/npc/2") + @ResponseBody + public String npc2() throws Exception { + KeepAliveNpcHessianConnector connector = null; + try { + InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); + + connector = new KeepAliveNpcHessianConnector(serverAddress); + + Map params = new HashMap(); + params.put("message", "hello pinpoint"); + + InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); + + future.await(); + + // Object result = future.get(); + Object result = future.getReturnValue(); + logger.debug("npc result={}", result); + } finally { + if (connector != null) { + connector.dispose(); + } + } + return "OK"; + } + + /** + * using connection factory + * + * @return + */ + @RequestMapping(value = "/npc/3") + @ResponseBody + public String npc3() throws Exception { + NpcHessianConnector connector = null; + try { + InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); + + ConnectionFactory npcConnectionFactory = new NpcConnectionFactory(); + + npcConnectionFactory.setTimeout(1000L); + npcConnectionFactory.setAddress(serverAddress); + + connector = npcConnectionFactory.create(); + + Map params = new HashMap(); + params.put("message", "hello pinpoint"); + + InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); + + future.await(); + + // Object result = future.get(); + Object result = future.getReturnValue(); + logger.debug("npc result={}", result); + } finally { + if (connector != null) { + connector.dispose(); + } + } + return "OK"; + } + + /** + * using lightweight connector + * + * @return + */ + @RequestMapping(value = "/npc/4") + @ResponseBody + public String npc4() throws Exception { + NpcHessianConnector connector = null; + try { + InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); + + ConnectionFactory npcConnectionFactory = new NpcConnectionFactory(); + + npcConnectionFactory.setTimeout(1000L); + npcConnectionFactory.setAddress(serverAddress); + npcConnectionFactory.setLightWeight(true); + + connector = npcConnectionFactory.create(); + + Map params = new HashMap(); + params.put("message", "hello pinpoint"); + + InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); + + future.await(); + + // Object result = future.get(); + Object result = future.getReturnValue(); + logger.debug("npc result={}", result); + } finally { + if (connector != null) { + connector.dispose(); + } + } + return "OK"; + } + + /** + * using lightweight connector and listener + * + * @return + */ + @RequestMapping(value = "/npc/5") + @ResponseBody + public String npc5() throws NpcCallException { + NpcHessianConnector connector = null; + try { + InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 5000); + + ConnectionFactory npcConnectionFactory = new NpcConnectionFactory(); + + npcConnectionFactory.setTimeout(1000L); + npcConnectionFactory.setAddress(serverAddress); + npcConnectionFactory.setLightWeight(true); + + connector = npcConnectionFactory.create(); + + Map params = new HashMap(); + params.put("message", "hello pinpoint"); + + InvocationFuture future = connector.invoke("welcome/com.nhncorp.lucy.bloc.welcome.EchoBO", "execute", params); + + future.addListener(new InvocationFutureListener() { + @Override + public void invocationComplete(InvocationFuture future) throws Exception { + Object result = future.getReturnValue(); + logger.debug("npc result={}", result); + } + }); + } finally { + if (connector != null) { + connector.dispose(); + } + } + return "OK"; + } + + @RequestMapping(value = "/npc/6") + @ResponseBody + public String npcStream() { + return "NOT_IMPLEMENTED"; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NingAsyncHTTPClientController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NingAsyncHTTPClientController.java index dc8dd00ccdeb..9c867c7ec034 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NingAsyncHTTPClientController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/NingAsyncHTTPClientController.java @@ -1,130 +1,105 @@ -package com.nhn.pinpoint.testweb.controller; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.testweb.connector.ningasync.NingAsyncHttpClient; -import com.ning.http.client.Part; -import com.ning.http.client.Response; -import com.ning.http.client.cookie.Cookie; -import com.ning.http.multipart.StringPart; - -/** - * - * @author netspider - * - */ -@Controller -public class NingAsyncHTTPClientController { - - private static final Logger logger = LoggerFactory.getLogger(NingAsyncHTTPClientController.class); - - @Autowired - private NingAsyncHttpClient ningAsyncHttpClient; - - @Autowired - private NingAsyncHttpClient httpInvoker; - - @RequestMapping(value = "/ningAsyncHttp/get") - public @ResponseBody - String requestGet(Model model) { - try { - Response r = httpInvoker.requestGet("http://www.naver.com", null, null, null); - logger.debug("r={}" + r.toString()); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } - - @RequestMapping(value = "/ningAsyncHttp/getWithParam") - public @ResponseBody - String requestGetWithParam(Model model) { - try { - Map params = new HashMap(); - params.put("query", "naver"); - params.put("ie", "utf8"); - - Map headers = new HashMap(); - headers.put("header1", "header1"); - headers.put("header2", "header2"); - - List cookies = new ArrayList(); - cookies.add(new Cookie("cookieName1", "cookieValue1", "cookieRawValue1", "", "/", 10, 10, false, false)); - cookies.add(new Cookie("cookieName2", "cookieValue2", "cookieRawValue2", "", "/", 10, 10, false, false)); - - Response r = httpInvoker.requestGet("http://search.naver.com/search.naver?where=nexearch", params, headers, cookies); - logger.debug("r={}" + r.toString()); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } - - @RequestMapping(value = "/ningAsyncHttp/post") - public @ResponseBody - String requestPost(Model model) { - try { - Response r = httpInvoker.requestPost("http://www.naver.com", null, null); - logger.debug("r={}" + r.toString()); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } - - @RequestMapping(value = "/ningAsyncHttp/postWithBody") - public @ResponseBody - String requestPostWithBody(Model model) { - try { - Map headers = new HashMap(); - headers.put("header1", "header1"); - headers.put("header2", "header2"); - - Response r = httpInvoker.requestPost("http://www.naver.com", headers, "postbody"); - logger.debug("r={}" + r.toString()); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } - - @RequestMapping(value = "/ningAsyncHttp/postWithMultipart") - public @ResponseBody - String requestPostWithMultipart(Model model) { - try { - Map headers = new HashMap(); - headers.put("header1", "header1"); - headers.put("header2", "header2"); - - List parts = new ArrayList(); - parts.add(new com.ning.http.client.ByteArrayPart("name1", "filename1", "data".getBytes(), "plain/text", "utf-8")); - parts.add(new com.ning.http.client.FilePart("name2", new File("./test"), "mimeType", "utf-8")); - parts.add(new com.ning.http.client.StringPart("name3", "value3")); - parts.add(new com.ning.http.multipart.FilePart("name4", new File("./test"))); - parts.add(new StringPart("name5", "value5")); - - Response r = httpInvoker.requestMultipart("http://www.naver.com", headers, parts); - logger.debug("r={}" + r.toString()); - return "OK"; - } catch (Exception e) { - logger.error(e.getMessage(), e); - return e.getMessage(); - } - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.connector.ningasync.NingAsyncHttpClient; +import com.ning.http.client.Part; +import com.ning.http.client.Response; +import com.ning.http.client.cookie.Cookie; +import com.ning.http.multipart.StringPart; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author netspider + */ +@Controller +public class NingAsyncHTTPClientController { + + private static final Logger logger = LoggerFactory.getLogger(NingAsyncHTTPClientController.class); + + @Autowired + private NingAsyncHttpClient ningAsyncHttpClient; + + @Autowired + private NingAsyncHttpClient httpInvoker; + + @RequestMapping(value = "/ningAsyncHttp/get") + @ResponseBody + public String requestGet() { + Response r = httpInvoker.requestGet("http://www.naver.com", null, null, null); + logger.debug("r={}" + r.toString()); + return "OK"; + } + + @RequestMapping(value = "/ningAsyncHttp/getWithParam") + @ResponseBody + public String requestGetWithParam() { + Map params = new HashMap(); + params.put("query", "naver"); + params.put("ie", "utf8"); + + Map headers = new HashMap(); + headers.put("header1", "header1"); + headers.put("header2", "header2"); + + List cookies = new ArrayList(); + cookies.add(new Cookie("cookieName1", "cookieValue1", "cookieRawValue1", "", "/", 10, 10, false, false)); + cookies.add(new Cookie("cookieName2", "cookieValue2", "cookieRawValue2", "", "/", 10, 10, false, false)); + + Response r = httpInvoker.requestGet("http://search.naver.com/search.naver?where=nexearch", params, headers, cookies); + logger.debug("r={}" + r.toString()); + return "OK"; + + } + + @RequestMapping(value = "/ningAsyncHttp/post") + @ResponseBody + public String requestPost() { + Response r = httpInvoker.requestPost("http://www.naver.com", null, null); + logger.debug("r={}" + r.toString()); + return "OK"; + + } + + @RequestMapping(value = "/ningAsyncHttp/postWithBody") + public String requestPostWithBody() { + Map headers = new HashMap(); + headers.put("header1", "header1"); + headers.put("header2", "header2"); + + Response r = httpInvoker.requestPost("http://www.naver.com", headers, "postbody"); + logger.debug("r={}" + r.toString()); + return "OK"; + + } + + @RequestMapping(value = "/ningAsyncHttp/postWithMultipart") + @ResponseBody + public String requestPostWithMultipart() throws FileNotFoundException { + Map headers = new HashMap(); + headers.put("header1", "header1"); + headers.put("header2", "header2"); + + List parts = new ArrayList(); + parts.add(new com.ning.http.client.ByteArrayPart("name1", "filename1", "data".getBytes(), "plain/text", "utf-8")); + parts.add(new com.ning.http.client.FilePart("name2", new File("./test"), "mimeType", "utf-8")); + parts.add(new com.ning.http.client.StringPart("name3", "value3")); + parts.add(new com.ning.http.multipart.FilePart("name4", new File("./test"))); + parts.add(new StringPart("name5", "value5")); + + Response r = httpInvoker.requestMultipart("http://www.naver.com", headers, parts); + logger.debug("r={}" + r.toString()); + return "OK"; + + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OracleController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OracleController.java index 77da745b741a..6be05b805350 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OracleController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OracleController.java @@ -1,48 +1,46 @@ -package com.nhn.pinpoint.testweb.controller; - -import com.nhn.pinpoint.testweb.service.OracleService; -import com.nhn.pinpoint.testweb.util.Description; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * - */ -@Controller -public class OracleController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private OracleService oracleService; - - @Description("preparedStatement 테스트. resultset은 가지고 오지 않음.") - @RequestMapping(value = "/oracle/selectOne") - public @ResponseBody - String selectOne(Model model) { - logger.info("selectOne start"); - - int i = oracleService.selectOne(); - - logger.info("selectOne end:{}", i); - return "OK"; - } - - @Description("statement 테스트. resultset은 가지고 오지 않음") - @RequestMapping(value = "/oracle/createStatement") - public @ResponseBody - String oracleStatement(Model model) { - logger.info("createStatement start"); - - oracleService.createStatement(); - - logger.info("createStatement end:{}"); - return "OK"; - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.service.OracleService; +import com.nhn.pinpoint.testweb.util.Description; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * + */ +@Controller +public class OracleController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private OracleService oracleService; + + @Description("preparedStatement 테스트. resultset은 가지고 오지 않음.") + @RequestMapping(value = "/oracle/selectOne") + @ResponseBody + public String selectOne() { + logger.info("selectOne start"); + + int i = oracleService.selectOne(); + + logger.info("selectOne end:{}", i); + return "OK"; + } + + @Description("statement 테스트. resultset은 가지고 오지 않음") + @RequestMapping(value = "/oracle/createStatement") + @ResponseBody + public String createStatement() { + logger.info("createStatement start"); + + oracleService.createStatement(); + + logger.info("createStatement end:{}"); + return "OK"; + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OrmController.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OrmController.java index 86d97ec42427..64c0611e2d91 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OrmController.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/controller/OrmController.java @@ -1,120 +1,118 @@ -package com.nhn.pinpoint.testweb.controller; - -import java.util.Date; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.service.MemberService; - -/** - * @author Hyun Jeong - */ -@Controller -public class OrmController { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public static final String IBATIS_VIEW = "orm/ibatis"; - public static final String MYBATIS_VIEW = "orm/mybatis"; - - @Autowired - @Qualifier("sqlMapClientMemberService") - private MemberService sqlMapClientMemberService; - - @Autowired - @Qualifier("sqlMapSessionMemberService") - private MemberService sqlMapSessionMemberService; - - @Autowired - @Qualifier("myBatisMemberService") - private MemberService myBatisMemberService; - - @RequestMapping(value = "/orm/ibatis/sqlMapClient/query") - public String iBatisSqlMapClientQuery(Model model) { - logger.info("/orm/ibatis/sqlMapClient/query"); - - this.sqlMapClientMemberService.get(0); - - return IBATIS_VIEW; - } - - @RequestMapping(value = "/orm/ibatis/sqlMapClient/transaction") - public String iBatisSqlMapClientTranscation(Model model) { - logger.info("/orm/ibatis/sqlMapClient/transaction - add, update, get, delete"); - - runTransaction(this.sqlMapClientMemberService); - - return IBATIS_VIEW; - } - - @RequestMapping(value = "/orm/ibatis/sqlMapSession/query") - public String iBatisSqlMapSessionQuery(Model model) { - logger.info("/orm/ibatis/sqlMapSession/query"); - - this.sqlMapSessionMemberService.get(0); - - return IBATIS_VIEW; - } - - @RequestMapping(value = "/orm/ibatis/sqlMapSession/transaction") - public String iBatisSqlMapSessionTransaction(Model model) { - logger.info("/orm/ibatis/sqlMapSession/transaction - add, update, get, delete"); - - runTransaction(this.sqlMapSessionMemberService); - - return IBATIS_VIEW; - } - - @RequestMapping(value = "/orm/mybatis/sqlSessionTemplate/query") - public String myBatisSqlSessionTemplateQuery(Model model) { - logger.info("/orm/mybatis/sqlSessionTemplate/query"); - - this.myBatisMemberService.get(0); - - return MYBATIS_VIEW; - } - - @RequestMapping(value = "/orm/mybatis/sqlSessionTemplate/transaction") - public String myBatisSqlSessionTemplateTransaction(Model model) { - logger.info("/orm/mybatis/sqlSessionTemplate/transaction"); - - runTransaction(this.myBatisMemberService); - - return MYBATIS_VIEW; - } - - @RequestMapping(value = "/orm/mybatis/sqlSessionTemplate/invalid") - public String myBatisSqlSessionTemplateInvalid(Model model) { - logger.info("/orm/mybatis/sqlSessionTemplate/invalid"); - - this.myBatisMemberService.list(); - - return MYBATIS_VIEW; - } - - private void runTransaction(MemberService memberService) { - - final int memberId = 1574; - - Member member = new Member(); - member.setId(memberId); - member.setName("test User"); - member.setJoined(new Date(System.currentTimeMillis())); - - memberService.add(member); - - member.setName("updated test User"); - memberService.update(member); - - memberService.get(memberId); - logger.info("\tId:[" + member.getId() + "], name:[" + member.getName() + "]"); - - memberService.delete(memberId); - } -} +package com.nhn.pinpoint.testweb.controller; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.service.MemberService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.Date; + +/** + * @author Hyun Jeong + */ +@Controller +public class OrmController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final String IBATIS_VIEW = "orm/ibatis"; + public static final String MYBATIS_VIEW = "orm/mybatis"; + + @Autowired + @Qualifier("sqlMapClientMemberService") + private MemberService sqlMapClientMemberService; + + @Autowired + @Qualifier("sqlMapSessionMemberService") + private MemberService sqlMapSessionMemberService; + + @Autowired + @Qualifier("myBatisMemberService") + private MemberService myBatisMemberService; + + @RequestMapping(value = "/orm/ibatis/sqlMapClient/query") + public String iBatisSqlMapClientQuery() { + logger.info("/orm/ibatis/sqlMapClient/query"); + + this.sqlMapClientMemberService.get(0); + + return IBATIS_VIEW; + } + + @RequestMapping(value = "/orm/ibatis/sqlMapClient/transaction") + public String iBatisSqlMapClientTranscation() { + logger.info("/orm/ibatis/sqlMapClient/transaction - add, update, get, delete"); + + runTransaction(this.sqlMapClientMemberService); + + return IBATIS_VIEW; + } + + @RequestMapping(value = "/orm/ibatis/sqlMapSession/query") + public String iBatisSqlMapSessionQuery() { + logger.info("/orm/ibatis/sqlMapSession/query"); + + this.sqlMapSessionMemberService.get(0); + + return IBATIS_VIEW; + } + + @RequestMapping(value = "/orm/ibatis/sqlMapSession/transaction") + public String iBatisSqlMapSessionTransaction() { + logger.info("/orm/ibatis/sqlMapSession/transaction - add, update, get, delete"); + + runTransaction(this.sqlMapSessionMemberService); + + return IBATIS_VIEW; + } + + @RequestMapping(value = "/orm/mybatis/sqlSessionTemplate/query") + public String myBatisSqlSessionTemplateQuery() { + logger.info("/orm/mybatis/sqlSessionTemplate/query"); + + this.myBatisMemberService.get(0); + + return MYBATIS_VIEW; + } + + @RequestMapping(value = "/orm/mybatis/sqlSessionTemplate/transaction") + public String myBatisSqlSessionTemplateTransaction() { + logger.info("/orm/mybatis/sqlSessionTemplate/transaction"); + + runTransaction(this.myBatisMemberService); + + return MYBATIS_VIEW; + } + + @RequestMapping(value = "/orm/mybatis/sqlSessionTemplate/invalid") + public String myBatisSqlSessionTemplateInvalid() { + logger.info("/orm/mybatis/sqlSessionTemplate/invalid"); + + this.myBatisMemberService.list(); + + return MYBATIS_VIEW; + } + + private void runTransaction(MemberService memberService) { + + final int memberId = 1574; + + Member member = new Member(); + member.setId(memberId); + member.setName("test User"); + member.setJoined(new Date(System.currentTimeMillis())); + + memberService.add(member); + + member.setName("updated test User"); + memberService.update(member); + + memberService.get(memberId); + logger.info("\tId:[" + member.getId() + "], name:[" + member.getName() + "]"); + + memberService.delete(memberId); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/vo/RequestMappingInfo.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/domain/ControllerMappingInfo.java similarity index 77% rename from testweb/src/main/java/com/nhn/pinpoint/testweb/vo/RequestMappingInfo.java rename to testweb/src/main/java/com/nhn/pinpoint/testweb/domain/ControllerMappingInfo.java index 960b1d91789b..215f5c42b4a0 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/vo/RequestMappingInfo.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/domain/ControllerMappingInfo.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.testweb.vo; +package com.nhn.pinpoint.testweb.domain; -public class RequestMappingInfo { +public class ControllerMappingInfo { private String url; private String description; - public RequestMappingInfo(String url, String description) { + public ControllerMappingInfo(String url, String description) { this.url = url; this.description = description; } diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/domain/Member.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/domain/Member.java index 0bcbf0d36eb5..a33d976d5f66 100755 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/domain/Member.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/domain/Member.java @@ -1,58 +1,58 @@ -package com.nhn.pinpoint.testweb.domain; - -import java.util.Date; - -public class Member { - - int id; - - String name; - - Date joined; - - /** - * @return the id - */ - public int getId() { - return id; - } - - /** - * @param id - * the id to set - */ - public void setId(int id) { - this.id = id; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name - * the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the joined - */ - public Date getJoined() { - return joined; - } - - /** - * @param joined - * the joined to set - */ - public void setJoined(Date joined) { - this.joined = joined; - } - -} +package com.nhn.pinpoint.testweb.domain; + +import java.util.Date; + +public class Member { + + int id; + + String name; + + Date joined; + + /** + * @return the id + */ + public int getId() { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the joined + */ + public Date getJoined() { + return joined; + } + + /** + * @param joined + * the joined to set + */ + public void setJoined(Date joined) { + this.joined = joined; + } + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/nimm/mockupserver/NimmInvokerTest.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/nimm/mockupserver/NimmInvokerTest.java index 037fdcad5d6c..5c26d571f2eb 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/nimm/mockupserver/NimmInvokerTest.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/nimm/mockupserver/NimmInvokerTest.java @@ -1,277 +1,277 @@ -package com.nhn.pinpoint.testweb.nimm.mockupserver; - -import java.nio.ByteBuffer; - -import java.util.logging.Logger; - -//import org.junit.Assert; -import org.springframework.stereotype.Component; - -import com.nhncorp.lucy.net.call.Call; -import com.nhncorp.lucy.net.call.DefaultReturnValue; -import com.nhncorp.lucy.net.call.Reply; -import com.nhncorp.lucy.net.call.ReturnValue; -import com.nhncorp.lucy.net.invoker.InvocationFuture; -import com.nhncorp.lucy.net.invoker.Invoker; -import com.nhncorp.lucy.nimm.connector.NimmConnector; -import com.nhncorp.lucy.nimm.connector.NimmSocket; -import com.nhncorp.lucy.nimm.connector.bloc.NimmInvoker; -import com.nhncorp.lucy.nimm.connector.message.NimmMessage; -import com.nhncorp.lucy.nimm.connector.worker.NimmAbstractWorkerMock; -import com.nhncorp.lucy.npc.DefaultNpcMessage; -import com.nhncorp.lucy.npc.NpcMessage; -import com.nhncorp.lucy.npc.decoder.NpcHessianDecoder; -import com.nhncorp.lucy.npc.encoder.NpcHessianEncoder; - -import external.org.apache.mina.filter.codec.ProtocolEncoderException; - -/** - *
- * original source : com.nhncorp.lucy.nimm.connector.bloc.NimmInvokerTest
- * 
- * - * @author netspider - * - */ -@Component -public class NimmInvokerTest extends AbstractNimmTest { - - private Logger log = Logger.getLogger(getClass().getName()); - - private Invoker invoker; - - private NimmSocket sendSocket; - private NimmSocket receiveSocket; - - private static int SEND_SOCKET_DOMAIN_ID = 101; - private static int SEND_SOCKET_SOCKET_ID = 13; - - private static int RECEIVE_SOCKET_DOMAIN_ID = 103; - private static int RECEIVE_SOCKET_SOCKET_ID = 15; - - public NimmInvokerTest() { - try { - initialize("/NimmMockupServer.xml"); - - sendSocket = NimmConnector.createNimmSocket(SEND_SOCKET_DOMAIN_ID, SEND_SOCKET_SOCKET_ID); - receiveSocket = NimmConnector.createNimmSocket(RECEIVE_SOCKET_DOMAIN_ID, RECEIVE_SOCKET_SOCKET_ID); - invoker = new NimmInvoker(receiveSocket.getAddress(), sendSocket); - - NimmInvoker nimmInvoker = (NimmInvoker) invoker; - long currentTimeout = nimmInvoker.getTimeout(); - nimmInvoker.setTimeout(currentTimeout + 1000L); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void tearDown() { - if (sendSocket != null) { - sendSocket.dispose(); - } - if (receiveSocket != null) { - receiveSocket.dispose(); - } - if (invoker != null) { - invoker.dispose(); - // Assert.assertFalse(invoker.isValid()); - if (!invoker.isValid()) { - throw new RuntimeException("invokoer is not valid."); - } - } - } - - public void testInvoke() throws Exception { - log.info("setWorker"); - - receiveSocket.setWorker(new NimmAbstractWorkerMock() { - @Override - protected ByteBuffer responseMessage(NimmMessage request) throws Exception { - log.info("message response"); - - ByteBuffer npcHessianByteBuffer = request.getMessage(); - NpcMessage decodeCall = NpcHessianDecoder.decodeCall(npcHessianByteBuffer); - Call call = (Call) decodeCall.getPayload(); - log.info("Call:" + call); - - DefaultReturnValue result = null; - if (decodeCall.getNamespace() == null) { - result = new DefaultReturnValue("response without namespace"); - } else { - result = new DefaultReturnValue("response"); - } - - DefaultNpcMessage reply = new DefaultNpcMessage(); - reply.setNamespace(decodeCall.getNamespace()); - reply.setTransactionId(decodeCall.getTransactionId()); - reply.setPayloadCharset(decodeCall.getPayloadCharset()); - reply.setPayload(result); - return NpcHessianEncoder.encodeReply(reply); - } - }); - - InvocationFuture future = invoker.invoke("objectName", "methodName", "params"); - log.info("await"); - future.await(); - Reply reply = (Reply) future.getReturnValue(); - if (reply instanceof ReturnValue) { - ReturnValue value = (ReturnValue) reply; - String message = (String) value.get(); - - if (!"response".equals(message)) { - throw new RuntimeException("invalid response, " + message); - } - // Assert.assertEquals("response", message); - } else { - throw new RuntimeException("reply retrun type=" + reply); - // Assert.fail("reply retrun type=" + reply); - } - - // Without object name - future = invoker.invoke(null, "methodName", "params"); - log.info("await"); - future.await(); - reply = (Reply) future.getReturnValue(); - if (reply instanceof ReturnValue) { - ReturnValue value = (ReturnValue) reply; - String message = (String) value.get(); - - if (!"response without namespace".equals(message)) { - throw new RuntimeException("invalid response, " + message); - } - // Assert.assertEquals("response without namespace", message); - } else { - throw new RuntimeException("reply retrun type=" + reply); - // Assert.fail("reply retrun type=" + reply); - } - - // Assert.assertTrue(invoker.isValid()); - if (!invoker.isValid()) { - throw new RuntimeException("invokoer is not valid."); - } - - invoker.dispose(); - } - - public void testConstructorWithInvalidParams() throws Exception { - Invoker invalidInvoker = null; - - // First parameters - try { - invalidInvoker = new NimmInvoker(null, sendSocket); - } catch (NullPointerException ex) { - // TODO make the tested code have a better exception like - // NimmRuntimeException - String msg = ex.getMessage(); - - if (msg.indexOf("nimmBlocAddress") == -1) { - throw new RuntimeException("Invalid NullPointerException for nimmBlocAddress"); - // Assert.fail("Invalid NullPointerException for nimmBlocAddress"); - } - } catch (Exception ex) { - throw new RuntimeException("Invaid Exception for nimmBlocAddress", ex); - // Assert.fail("Invaid Exception for nimmBlocAddress - " + - // ex.getMessage()); - } - - // Second parameters - try { - invalidInvoker = new NimmInvoker(receiveSocket.getAddress(), null); - } catch (NullPointerException ex) { - // TODO make the tested code have a better exception like - // NimmRuntimeException - String msg = ex.getMessage(); - if (msg.indexOf("nimmLocalSocket") == -1) { - throw new RuntimeException("Invalid NullPointerException for nimmLocalSocket"); - // Assert.fail("Invalid NullPointerException for nimmLocalSocket"); - } - } catch (Exception ex) { - throw new RuntimeException("Invaid Exception for nimmLocalSocket", ex); - // Assert.fail("Invaid Exception for nimmLocalSocket - " + - // ex.getMessage()); - } - - // Third parameters - try { - invalidInvoker = new NimmInvoker(receiveSocket.getAddress(), sendSocket, -1000L); - } catch (IllegalArgumentException ex) { - String msg = ex.getMessage(); - if (msg.indexOf("timeoutMillis") == -1) { - throw new RuntimeException("Invalid IllegalArgumentException for timeoutMillis"); - // Assert.fail("Invalid IllegalArgumentException for timeoutMillis"); - } - } catch (Exception ex) { - throw new RuntimeException("Invaid Exception for timeoutMillis - " + ex.getMessage()); - // Assert.fail("Invaid Exception for timeoutMillis - " + - // ex.getMessage()); - } - - if (invalidInvoker != null) { - invalidInvoker.dispose(); - } - } - - public void testInvokeWithInvalidParams() throws Exception { - // methodName - try { - invoker.invoke("objectName", null, "params"); - } catch (NullPointerException ex) { - // TODO make the tested code have a better exception like - // NimmRuntimeException - String msg = ex.getMessage(); - if (msg.indexOf("methodName") == -1) { - throw new RuntimeException("Invalid NullPointerException for methodName"); - // Assert.fail("Invalid NullPointerException for methodName"); - } - } catch (Exception ex) { - throw new RuntimeException("Invaid Exception for methodName - " + ex.getMessage()); - // Assert.fail("Invaid Exception for methodName - " + - // ex.getMessage()); - } - - // timeoutMillis - try { - NimmInvoker nimmInvoker = (NimmInvoker) invoker; - nimmInvoker.invoke(-1000L, "objectName", "methodName", "params"); - } catch (IllegalArgumentException ex) { - String msg = ex.getMessage(); - if (msg.indexOf("timeoutMillis") == -1) { - throw new RuntimeException("Invalid IllegalArgumentException for timeoutMillis"); - // Assert.fail("Invalid IllegalArgumentException for timeoutMillis"); - } - } catch (Exception ex) { - throw new RuntimeException("Invaid Exception for timeoutMillis - " + ex.getMessage()); - // Assert.fail("Invaid Exception for timeoutMillis - " + - // ex.getMessage()); - } - - // setTimeoutMillis - try { - NimmInvoker nimmInvoker = (NimmInvoker) invoker; - nimmInvoker.setTimeout(-1000L); - } catch (IllegalArgumentException ex) { - String msg = ex.getMessage(); - if (msg.indexOf("timeoutMillis") == -1) { - throw new RuntimeException("Invalid IllegalArgumentException for timeoutMillis"); - // Assert.fail("Invalid IllegalArgumentException for timeoutMillis"); - } - } catch (Exception ex) { - throw new RuntimeException("Invaid Exception for timeoutMillis - " + ex.getMessage()); - // Assert.fail("Invaid Exception for timeoutMillis - " + - // ex.getMessage()); - } - - // params : java.lang.Class cannot be encoded. - InvocationFuture future = invoker.invoke("objectName", "methodName", Integer.class); - log.info("await"); - future.await(); - Exception ex = (Exception) future.getException(); - - if (!(ex instanceof ProtocolEncoderException)) { - throw new RuntimeException("!(ex instanceof ProtocolEncoderException)"); - } - // Assert.assertTrue(ex instanceof ProtocolEncoderException); - - invoker.dispose(); - } -} +package com.nhn.pinpoint.testweb.nimm.mockupserver; + +import java.nio.ByteBuffer; + +import java.util.logging.Logger; + +//import org.junit.Assert; +import org.springframework.stereotype.Component; + +import com.nhncorp.lucy.net.call.Call; +import com.nhncorp.lucy.net.call.DefaultReturnValue; +import com.nhncorp.lucy.net.call.Reply; +import com.nhncorp.lucy.net.call.ReturnValue; +import com.nhncorp.lucy.net.invoker.InvocationFuture; +import com.nhncorp.lucy.net.invoker.Invoker; +import com.nhncorp.lucy.nimm.connector.NimmConnector; +import com.nhncorp.lucy.nimm.connector.NimmSocket; +import com.nhncorp.lucy.nimm.connector.bloc.NimmInvoker; +import com.nhncorp.lucy.nimm.connector.message.NimmMessage; +import com.nhncorp.lucy.nimm.connector.worker.NimmAbstractWorkerMock; +import com.nhncorp.lucy.npc.DefaultNpcMessage; +import com.nhncorp.lucy.npc.NpcMessage; +import com.nhncorp.lucy.npc.decoder.NpcHessianDecoder; +import com.nhncorp.lucy.npc.encoder.NpcHessianEncoder; + +import external.org.apache.mina.filter.codec.ProtocolEncoderException; + +/** + *
+ * original source : com.nhncorp.lucy.nimm.connector.bloc.NimmInvokerTest
+ * 
+ * + * @author netspider + * + */ +@Component +public class NimmInvokerTest extends AbstractNimmTest { + + private Logger log = Logger.getLogger(getClass().getName()); + + private Invoker invoker; + + private NimmSocket sendSocket; + private NimmSocket receiveSocket; + + private static int SEND_SOCKET_DOMAIN_ID = 101; + private static int SEND_SOCKET_SOCKET_ID = 13; + + private static int RECEIVE_SOCKET_DOMAIN_ID = 103; + private static int RECEIVE_SOCKET_SOCKET_ID = 15; + + public NimmInvokerTest() { + try { + initialize("/NimmMockupServer.xml"); + + sendSocket = NimmConnector.createNimmSocket(SEND_SOCKET_DOMAIN_ID, SEND_SOCKET_SOCKET_ID); + receiveSocket = NimmConnector.createNimmSocket(RECEIVE_SOCKET_DOMAIN_ID, RECEIVE_SOCKET_SOCKET_ID); + invoker = new NimmInvoker(receiveSocket.getAddress(), sendSocket); + + NimmInvoker nimmInvoker = (NimmInvoker) invoker; + long currentTimeout = nimmInvoker.getTimeout(); + nimmInvoker.setTimeout(currentTimeout + 1000L); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void tearDown() { + if (sendSocket != null) { + sendSocket.dispose(); + } + if (receiveSocket != null) { + receiveSocket.dispose(); + } + if (invoker != null) { + invoker.dispose(); + // Assert.assertFalse(invoker.isValid()); + if (!invoker.isValid()) { + throw new RuntimeException("invokoer is not valid."); + } + } + } + + public void testInvoke() throws Exception { + log.info("setWorker"); + + receiveSocket.setWorker(new NimmAbstractWorkerMock() { + @Override + protected ByteBuffer responseMessage(NimmMessage request) throws Exception { + log.info("message response"); + + ByteBuffer npcHessianByteBuffer = request.getMessage(); + NpcMessage decodeCall = NpcHessianDecoder.decodeCall(npcHessianByteBuffer); + Call call = (Call) decodeCall.getPayload(); + log.info("Call:" + call); + + DefaultReturnValue result = null; + if (decodeCall.getNamespace() == null) { + result = new DefaultReturnValue("response without namespace"); + } else { + result = new DefaultReturnValue("response"); + } + + DefaultNpcMessage reply = new DefaultNpcMessage(); + reply.setNamespace(decodeCall.getNamespace()); + reply.setTransactionId(decodeCall.getTransactionId()); + reply.setPayloadCharset(decodeCall.getPayloadCharset()); + reply.setPayload(result); + return NpcHessianEncoder.encodeReply(reply); + } + }); + + InvocationFuture future = invoker.invoke("objectName", "methodName", "params"); + log.info("await"); + future.await(); + Reply reply = (Reply) future.getReturnValue(); + if (reply instanceof ReturnValue) { + ReturnValue value = (ReturnValue) reply; + String message = (String) value.get(); + + if (!"response".equals(message)) { + throw new RuntimeException("invalid response, " + message); + } + // Assert.assertEquals("response", message); + } else { + throw new RuntimeException("reply retrun type=" + reply); + // Assert.fail("reply retrun type=" + reply); + } + + // Without object name + future = invoker.invoke(null, "methodName", "params"); + log.info("await"); + future.await(); + reply = (Reply) future.getReturnValue(); + if (reply instanceof ReturnValue) { + ReturnValue value = (ReturnValue) reply; + String message = (String) value.get(); + + if (!"response without namespace".equals(message)) { + throw new RuntimeException("invalid response, " + message); + } + // Assert.assertEquals("response without namespace", message); + } else { + throw new RuntimeException("reply retrun type=" + reply); + // Assert.fail("reply retrun type=" + reply); + } + + // Assert.assertTrue(invoker.isValid()); + if (!invoker.isValid()) { + throw new RuntimeException("invokoer is not valid."); + } + + invoker.dispose(); + } + + public void testConstructorWithInvalidParams() throws Exception { + Invoker invalidInvoker = null; + + // First parameters + try { + invalidInvoker = new NimmInvoker(null, sendSocket); + } catch (NullPointerException ex) { + // TODO make the tested code have a better exception like + // NimmRuntimeException + String msg = ex.getMessage(); + + if (msg.indexOf("nimmBlocAddress") == -1) { + throw new RuntimeException("Invalid NullPointerException for nimmBlocAddress"); + // Assert.fail("Invalid NullPointerException for nimmBlocAddress"); + } + } catch (Exception ex) { + throw new RuntimeException("Invaid Exception for nimmBlocAddress", ex); + // Assert.fail("Invaid Exception for nimmBlocAddress - " + + // ex.getMessage()); + } + + // Second parameters + try { + invalidInvoker = new NimmInvoker(receiveSocket.getAddress(), null); + } catch (NullPointerException ex) { + // TODO make the tested code have a better exception like + // NimmRuntimeException + String msg = ex.getMessage(); + if (msg.indexOf("nimmLocalSocket") == -1) { + throw new RuntimeException("Invalid NullPointerException for nimmLocalSocket"); + // Assert.fail("Invalid NullPointerException for nimmLocalSocket"); + } + } catch (Exception ex) { + throw new RuntimeException("Invaid Exception for nimmLocalSocket", ex); + // Assert.fail("Invaid Exception for nimmLocalSocket - " + + // ex.getMessage()); + } + + // Third parameters + try { + invalidInvoker = new NimmInvoker(receiveSocket.getAddress(), sendSocket, -1000L); + } catch (IllegalArgumentException ex) { + String msg = ex.getMessage(); + if (msg.indexOf("timeoutMillis") == -1) { + throw new RuntimeException("Invalid IllegalArgumentException for timeoutMillis"); + // Assert.fail("Invalid IllegalArgumentException for timeoutMillis"); + } + } catch (Exception ex) { + throw new RuntimeException("Invaid Exception for timeoutMillis - " + ex.getMessage()); + // Assert.fail("Invaid Exception for timeoutMillis - " + + // ex.getMessage()); + } + + if (invalidInvoker != null) { + invalidInvoker.dispose(); + } + } + + public void testInvokeWithInvalidParams() throws Exception { + // methodName + try { + invoker.invoke("objectName", null, "params"); + } catch (NullPointerException ex) { + // TODO make the tested code have a better exception like + // NimmRuntimeException + String msg = ex.getMessage(); + if (msg.indexOf("methodName") == -1) { + throw new RuntimeException("Invalid NullPointerException for methodName"); + // Assert.fail("Invalid NullPointerException for methodName"); + } + } catch (Exception ex) { + throw new RuntimeException("Invaid Exception for methodName - " + ex.getMessage()); + // Assert.fail("Invaid Exception for methodName - " + + // ex.getMessage()); + } + + // timeoutMillis + try { + NimmInvoker nimmInvoker = (NimmInvoker) invoker; + nimmInvoker.invoke(-1000L, "objectName", "methodName", "params"); + } catch (IllegalArgumentException ex) { + String msg = ex.getMessage(); + if (msg.indexOf("timeoutMillis") == -1) { + throw new RuntimeException("Invalid IllegalArgumentException for timeoutMillis"); + // Assert.fail("Invalid IllegalArgumentException for timeoutMillis"); + } + } catch (Exception ex) { + throw new RuntimeException("Invaid Exception for timeoutMillis - " + ex.getMessage()); + // Assert.fail("Invaid Exception for timeoutMillis - " + + // ex.getMessage()); + } + + // setTimeoutMillis + try { + NimmInvoker nimmInvoker = (NimmInvoker) invoker; + nimmInvoker.setTimeout(-1000L); + } catch (IllegalArgumentException ex) { + String msg = ex.getMessage(); + if (msg.indexOf("timeoutMillis") == -1) { + throw new RuntimeException("Invalid IllegalArgumentException for timeoutMillis"); + // Assert.fail("Invalid IllegalArgumentException for timeoutMillis"); + } + } catch (Exception ex) { + throw new RuntimeException("Invaid Exception for timeoutMillis - " + ex.getMessage()); + // Assert.fail("Invaid Exception for timeoutMillis - " + + // ex.getMessage()); + } + + // params : java.lang.Class cannot be encoded. + InvocationFuture future = invoker.invoke("objectName", "methodName", Integer.class); + log.info("await"); + future.await(); + Exception ex = (Exception) future.getException(); + + if (!(ex instanceof ProtocolEncoderException)) { + throw new RuntimeException("!(ex instanceof ProtocolEncoderException)"); + } + // Assert.assertTrue(ex instanceof ProtocolEncoderException); + + invoker.dispose(); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDao.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDao.java index c940d3deb49d..73ff11743eb2 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDao.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDao.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.testweb.repository; - -/** - * - */ -public interface CubridDao { - int selectOne(); - - void createStatement(); - - void createErrorStatement(); -} +package com.nhn.pinpoint.testweb.repository; + +/** + * + */ +public interface CubridDao { + int selectOne(); + + boolean createStatement(); + + boolean createErrorStatement(); +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDaoIbatis.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDaoIbatis.java index 4b0a25e280cd..d4377dbf1425 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDaoIbatis.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/CubridDaoIbatis.java @@ -1,87 +1,85 @@ -package com.nhn.pinpoint.testweb.repository; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.orm.ibatis.SqlMapClientTemplate; -import org.springframework.stereotype.Repository; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * - */ -@Repository -public class CubridDaoIbatis implements CubridDao { - - @Autowired - @Qualifier("cubridSqlMapClientTemplate") - private SqlMapClientTemplate sqlMapClientTemplate; - - @Autowired - @Qualifier("cubridDatasource") - private DataSource datasource; - - @Override - public int selectOne() { - return (Integer) sqlMapClientTemplate.queryForObject("selectOne"); - } - - @Override - public void createStatement() { - Connection connection = null; - Statement statement = null; - try { - connection = datasource.getConnection(); - statement = connection.createStatement(); - statement.execute("select 1"); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (statement != null) { - try { - statement.close(); - } catch (SQLException e) { - } - } - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - } - } - - } - //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public void createErrorStatement() { - Connection connection = null; - Statement statement = null; - try { - connection = datasource.getConnection(); - statement = connection.createStatement(); - statement.execute("SELECT * FROM NOT_EXISTS_TABLE"); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (statement != null) { - try { - statement.close(); - } catch (SQLException e) { - } - } - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - } - } - - } - //To change body of implemented methods use File | Settings | File Templates. - } -} +package com.nhn.pinpoint.testweb.repository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * + */ +@Repository +public class CubridDaoIbatis implements CubridDao { + + @Autowired + @Qualifier("cubridSqlMapClientTemplate") + private SqlMapClientTemplate sqlMapClientTemplate; + + @Autowired + @Qualifier("cubridDataSource") + private DataSource datasource; + + @Override + public int selectOne() { + return (Integer) sqlMapClientTemplate.queryForObject("selectOne"); + } + + @Override + public boolean createStatement() { + Connection connection = null; + Statement statement = null; + try { + connection = datasource.getConnection(); + statement = connection.createStatement(); + return statement.execute("select 1"); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + if (statement != null) { + try { + statement.close(); + } catch (SQLException e) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + } + } + + } + } + + @Override + public boolean createErrorStatement() { + Connection connection = null; + Statement statement = null; + try { + connection = datasource.getConnection(); + statement = connection.createStatement(); + return statement.execute("SELECT * FROM NOT_EXISTS_TABLE"); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + if (statement != null) { + try { + statement.close(); + } catch (SQLException e) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + } + } + + } + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDao.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDao.java index fdfdace6c1dd..bb3acdabbfda 100755 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDao.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDao.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.testweb.repository; - -import java.util.List; - -import com.nhn.pinpoint.testweb.domain.Member; - -public interface MemberDao { - - void add(Member member); - - void addStatement(Member member); - - void update(Member member); - - Member get(int id); - - List list(); - - void delete(int id); - -} +package com.nhn.pinpoint.testweb.repository; + +import java.util.List; + +import com.nhn.pinpoint.testweb.domain.Member; + +public interface MemberDao { + + void add(Member member); + + void addStatement(Member member); + + void update(Member member); + + Member get(int id); + + List list(); + + void delete(int id); + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatis.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatis.java index 9f9ffbf70130..5eaaaa28bb22 100755 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatis.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatis.java @@ -1,45 +1,45 @@ -package com.nhn.pinpoint.testweb.repository; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.orm.ibatis.SqlMapClientTemplate; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.testweb.domain.Member; - -@Repository -public class MemberDaoIbatis implements MemberDao { - - @Autowired - @Qualifier("mysqlSqlMapClientTemplate") - private SqlMapClientTemplate sqlMapClientTemplate; - - public void add(Member member) { - sqlMapClientTemplate.insert("add", member); - } - - @Override - public void addStatement(Member member) { - sqlMapClientTemplate.insert("addStatement", member); - } - - public void delete(int id) { - sqlMapClientTemplate.delete("delete", id); - } - - public Member get(int id) { - return (Member) sqlMapClientTemplate.queryForObject("get", id); - } - - @SuppressWarnings("unchecked") - public List list() { - return sqlMapClientTemplate.queryForList("list"); - } - - public void update(Member member) { - sqlMapClientTemplate.update("update", member); - } - -} +package com.nhn.pinpoint.testweb.repository; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.testweb.domain.Member; + +@Repository +public class MemberDaoIbatis implements MemberDao { + + @Autowired + @Qualifier("mysqlSqlMapClientTemplate") + private SqlMapClientTemplate sqlMapClientTemplate; + + public void add(Member member) { + sqlMapClientTemplate.insert("add", member); + } + + @Override + public void addStatement(Member member) { + sqlMapClientTemplate.insert("addStatement", member); + } + + public void delete(int id) { + sqlMapClientTemplate.delete("delete", id); + } + + public Member get(int id) { + return (Member) sqlMapClientTemplate.queryForObject("get", id); + } + + @SuppressWarnings("unchecked") + public List list() { + return sqlMapClientTemplate.queryForList("list"); + } + + public void update(Member member) { + sqlMapClientTemplate.update("update", member); + } + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbc.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbc.java index c8ae7d8f8588..6575f1352b98 100755 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbc.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbc.java @@ -1,59 +1,59 @@ -package com.nhn.pinpoint.testweb.repository; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.testweb.domain.Member; - -@Repository -public class MemberDaoJdbc implements MemberDao { - - @Autowired - SimpleJdbcTemplate jdbcTemplateMysql; - - public void setMemberMapper(RowMapper memberMapper) { - this.memberMapper = memberMapper; - } - - RowMapper memberMapper = new RowMapper() { - public Member mapRow(ResultSet rs, int rowNum) throws SQLException { - Member member = new Member(); - member.setId(rs.getInt("id")); - member.setName(rs.getString("name")); - member.setJoined(rs.getDate("joined")); - return member; - } - }; - - public void add(Member member) { - jdbcTemplateMysql.update("/* testquery */ insert into member(id, name, joined) values (?, ?, ?)", member.getId(), member.getName(), member.getJoined()); - } - - @Override - public void addStatement(Member member) { - jdbcTemplateMysql.update("/* testquery */ insert into member(id, name, joined) values ('" + member.getId() + "', '" + member.getName() + "', ?)", member.getJoined()); - } - - public void delete(int id) { - jdbcTemplateMysql.update("/* testquery */ delete from member where id = ?", id); - } - - public Member get(int id) { - return jdbcTemplateMysql.queryForObject("/* testquery */ select * from member where id = ?", memberMapper, id); - } - - public List list() { - return jdbcTemplateMysql.query("/* testquery */ select * from member", memberMapper); - } - - public void update(Member member) { - jdbcTemplateMysql.update("/* testquery */ update member set name = :name, joined = :joined where id = :id", new BeanPropertySqlParameterSource(member)); - } -} +package com.nhn.pinpoint.testweb.repository; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.testweb.domain.Member; + +@Repository +public class MemberDaoJdbc implements MemberDao { + + @Autowired + SimpleJdbcTemplate jdbcTemplateMysql; + + public void setMemberMapper(RowMapper memberMapper) { + this.memberMapper = memberMapper; + } + + RowMapper memberMapper = new RowMapper() { + public Member mapRow(ResultSet rs, int rowNum) throws SQLException { + Member member = new Member(); + member.setId(rs.getInt("id")); + member.setName(rs.getString("name")); + member.setJoined(rs.getDate("joined")); + return member; + } + }; + + public void add(Member member) { + jdbcTemplateMysql.update("/* testquery */ insert into member(id, name, joined) values (?, ?, ?)", member.getId(), member.getName(), member.getJoined()); + } + + @Override + public void addStatement(Member member) { + jdbcTemplateMysql.update("/* testquery */ insert into member(id, name, joined) values ('" + member.getId() + "', '" + member.getName() + "', ?)", member.getJoined()); + } + + public void delete(int id) { + jdbcTemplateMysql.update("/* testquery */ delete from member where id = ?", id); + } + + public Member get(int id) { + return jdbcTemplateMysql.queryForObject("/* testquery */ select * from member where id = ?", memberMapper, id); + } + + public List list() { + return jdbcTemplateMysql.query("/* testquery */ select * from member", memberMapper); + } + + public void update(Member member) { + jdbcTemplateMysql.update("/* testquery */ update member set name = :name, joined = :joined where id = :id", new BeanPropertySqlParameterSource(member)); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MsSqlServerDao.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MsSqlServerDao.java new file mode 100644 index 000000000000..816f09a7d924 --- /dev/null +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MsSqlServerDao.java @@ -0,0 +1,11 @@ +package com.nhn.pinpoint.testweb.repository; + +/** + * @author emeroad + */ +public interface MsSqlServerDao { + int selectOne(); + + boolean createStatement(); + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MsSqlServerDaoIbatis.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MsSqlServerDaoIbatis.java new file mode 100644 index 000000000000..6a22fc4a543a --- /dev/null +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MsSqlServerDaoIbatis.java @@ -0,0 +1,58 @@ +package com.nhn.pinpoint.testweb.repository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * + */ +@Repository +public class MsSqlServerDaoIbatis implements MsSqlServerDao { + + @Autowired + @Qualifier("msSqlServerSqlMapClientTemplate") + private SqlMapClientTemplate sqlMapClientTemplate; + + @Autowired + @Qualifier("jtdsDataSource") + private DataSource datasource; + + @Override + public int selectOne() { + return (Integer) sqlMapClientTemplate.queryForObject("selectOne"); + } + + @Override + public boolean createStatement() { + Connection connection = null; + Statement statement = null; + try { + connection = datasource.getConnection(); + statement = connection.createStatement(); + return statement.execute("select 1"); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + if (statement != null) { + try { + statement.close(); + } catch (SQLException e) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + } + } + + } + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDao.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDao.java index 475317d413bc..6a22902fbf75 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDao.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDao.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.testweb.repository; - -/** - * - */ -public interface MySqlDao { - - int selectOne(); - - void createStatement(); -} +package com.nhn.pinpoint.testweb.repository; + +/** + * + */ +public interface MySqlDao { + + int selectOne(); + + boolean createStatement(); +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDaoIbatis.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDaoIbatis.java index d607e158c692..42a19d553670 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDaoIbatis.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/MySqlDaoIbatis.java @@ -1,59 +1,58 @@ -package com.nhn.pinpoint.testweb.repository; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.orm.ibatis.SqlMapClientTemplate; -import org.springframework.stereotype.Repository; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * - */ -@Repository -public class MySqlDaoIbatis implements MySqlDao { - - @Autowired - @Qualifier("mysqlSqlMapClientTemplate") - private SqlMapClientTemplate sqlMapClientTemplate; - - @Autowired - @Qualifier("mysqlDatasource") - private DataSource datasource; - - @Override - public int selectOne() { - return (Integer) sqlMapClientTemplate.queryForObject("selectOne"); - } - - @Override - public void createStatement() { - Connection connection = null; - Statement statement = null; - try { - connection = datasource.getConnection(); - statement = connection.createStatement(); - statement.execute("select 1"); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (statement != null) { - try { - statement.close(); - } catch (SQLException e) { - } - } - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - } - } - - } - //To change body of implemented methods use File | Settings | File Templates. - } -} +package com.nhn.pinpoint.testweb.repository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * + */ +@Repository +public class MySqlDaoIbatis implements MySqlDao { + + @Autowired + @Qualifier("mysqlSqlMapClientTemplate") + private SqlMapClientTemplate sqlMapClientTemplate; + + @Autowired + @Qualifier("mysqlDataSource") + private DataSource datasource; + + @Override + public int selectOne() { + return (Integer) sqlMapClientTemplate.queryForObject("selectOne"); + } + + @Override + public boolean createStatement() { + Connection connection = null; + Statement statement = null; + try { + connection = datasource.getConnection(); + statement = connection.createStatement(); + return statement.execute("select 1"); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + if (statement != null) { + try { + statement.close(); + } catch (SQLException e) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + } + } + + } + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDao.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDao.java index d18df9b05275..62edfdcab2f5 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDao.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDao.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.testweb.repository; - -/** - * - */ -public interface OracleDao { - int selectOne(); - - void createStatement(); -} +package com.nhn.pinpoint.testweb.repository; + +/** + * + */ +public interface OracleDao { + int selectOne(); + + boolean createStatement(); +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDaoIbatis.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDaoIbatis.java index 66b1b71982ab..385c1b4c7698 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDaoIbatis.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/OracleDaoIbatis.java @@ -1,59 +1,58 @@ -package com.nhn.pinpoint.testweb.repository; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.orm.ibatis.SqlMapClientTemplate; -import org.springframework.stereotype.Repository; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * - */ -@Repository -public class OracleDaoIbatis implements OracleDao { - - @Autowired - @Qualifier("oracleSqlMapClientTemplate") - private SqlMapClientTemplate sqlMapClientTemplate; - - @Autowired - @Qualifier("oracleDatasource") - private DataSource datasource; - - @Override - public int selectOne() { - return (Integer) sqlMapClientTemplate.queryForObject("selectOne"); - } - - @Override - public void createStatement() { - Connection connection = null; - Statement statement = null; - try { - connection = datasource.getConnection(); - statement = connection.createStatement(); - statement.execute("select 1 from dual"); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (statement != null) { - try { - statement.close(); - } catch (SQLException e) { - } - } - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - } - } - - } - //To change body of implemented methods use File | Settings | File Templates. - } -} +package com.nhn.pinpoint.testweb.repository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * + */ +@Repository +public class OracleDaoIbatis implements OracleDao { + + @Autowired + @Qualifier("oracleSqlMapClientTemplate") + private SqlMapClientTemplate sqlMapClientTemplate; + + @Autowired + @Qualifier("oracleDataSource") + private DataSource datasource; + + @Override + public int selectOne() { + return (Integer) sqlMapClientTemplate.queryForObject("selectOne"); + } + + @Override + public boolean createStatement() { + Connection connection = null; + Statement statement = null; + try { + connection = datasource.getConnection(); + statement = connection.createStatement(); + return statement.execute("select 1 from dual"); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + if (statement != null) { + try { + statement.close(); + } catch (SQLException e) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + } + } + + } + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapClientMemberDao.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapClientMemberDao.java index 5726f2e6038b..3ac7100808ec 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapClientMemberDao.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapClientMemberDao.java @@ -1,84 +1,84 @@ -package com.nhn.pinpoint.testweb.repository.ibatis; - -import java.sql.SQLException; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.dao.DataAccessException; -import org.springframework.orm.ibatis.SqlMapClientTemplate; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.repository.MemberDao; - -/** - * @author Hyun Jeong - */ -@Repository("sqlMapClientMemberDao") -public class SqlMapClientMemberDao implements MemberDao { - - @Autowired - @Qualifier("mysqlSqlMapClientTemplate") - protected SqlMapClientTemplate sqlMapClientTemplate; - - @Override - public void add(Member member) { - try { - this.sqlMapClientTemplate.getSqlMapClient().insert("add", member); - } catch (SQLException e) { - throw translateSqlException("SqlMapClient add", e); - } - } - - @Override - public void addStatement(Member member) { - try { - this.sqlMapClientTemplate.getSqlMapClient().insert("addStatement", member); - } catch (SQLException e) { - throw translateSqlException("SqlMapClient addStatement", e); - } - } - - @Override - public void update(Member member) { - try { - this.sqlMapClientTemplate.getSqlMapClient().update("update", member); - } catch (SQLException e) { - throw translateSqlException("SqlMapClient addStatement", e); - } - } - - @Override - public Member get(int id) { - try { - return (Member)this.sqlMapClientTemplate.getSqlMapClient().queryForObject("get", id); - } catch (SQLException e) { - throw translateSqlException("SqlMapClient get", e); - } - } - - @Override - @SuppressWarnings("unchecked") - public List list() { - try { - return this.sqlMapClientTemplate.getSqlMapClient().queryForList("list"); - } catch (SQLException e) { - throw translateSqlException("SqlMapClient list", e); - } - } - - @Override - public void delete(int id) { - try { - this.sqlMapClientTemplate.getSqlMapClient().delete("delete", id); - } catch (SQLException e) { - throw translateSqlException("SqlMapClient delete", e); - } - } - - private DataAccessException translateSqlException(String task, SQLException e) { - return this.sqlMapClientTemplate.getExceptionTranslator().translate(task, null, e); - } - -} +package com.nhn.pinpoint.testweb.repository.ibatis; + +import java.sql.SQLException; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.DataAccessException; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.repository.MemberDao; + +/** + * @author Hyun Jeong + */ +@Repository("sqlMapClientMemberDao") +public class SqlMapClientMemberDao implements MemberDao { + + @Autowired + @Qualifier("mysqlSqlMapClientTemplate") + protected SqlMapClientTemplate sqlMapClientTemplate; + + @Override + public void add(Member member) { + try { + this.sqlMapClientTemplate.getSqlMapClient().insert("add", member); + } catch (SQLException e) { + throw translateSqlException("SqlMapClient add", e); + } + } + + @Override + public void addStatement(Member member) { + try { + this.sqlMapClientTemplate.getSqlMapClient().insert("addStatement", member); + } catch (SQLException e) { + throw translateSqlException("SqlMapClient addStatement", e); + } + } + + @Override + public void update(Member member) { + try { + this.sqlMapClientTemplate.getSqlMapClient().update("update", member); + } catch (SQLException e) { + throw translateSqlException("SqlMapClient addStatement", e); + } + } + + @Override + public Member get(int id) { + try { + return (Member)this.sqlMapClientTemplate.getSqlMapClient().queryForObject("get", id); + } catch (SQLException e) { + throw translateSqlException("SqlMapClient get", e); + } + } + + @Override + @SuppressWarnings("unchecked") + public List list() { + try { + return this.sqlMapClientTemplate.getSqlMapClient().queryForList("list"); + } catch (SQLException e) { + throw translateSqlException("SqlMapClient list", e); + } + } + + @Override + public void delete(int id) { + try { + this.sqlMapClientTemplate.getSqlMapClient().delete("delete", id); + } catch (SQLException e) { + throw translateSqlException("SqlMapClient delete", e); + } + } + + private DataAccessException translateSqlException(String task, SQLException e) { + return this.sqlMapClientTemplate.getExceptionTranslator().translate(task, null, e); + } + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapSessionMemberDao.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapSessionMemberDao.java index 4eb6b516582f..866591e8791c 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapSessionMemberDao.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/ibatis/SqlMapSessionMemberDao.java @@ -1,54 +1,54 @@ -package com.nhn.pinpoint.testweb.repository.ibatis; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.orm.ibatis.SqlMapClientTemplate; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.repository.MemberDao; - -/** - * @author Hyun Jeong - */ -@Repository("sqlMapSessionMemberDao") -public class SqlMapSessionMemberDao implements MemberDao { - - @Autowired - @Qualifier("mysqlSqlMapClientTemplate") - private SqlMapClientTemplate sqlMapClientTemplate; - - @Override - public void add(Member member) { - this.sqlMapClientTemplate.insert("add", member); - } - - @Override - public void addStatement(Member member) { - this.sqlMapClientTemplate.insert("addStatement", member); - } - - @Override - public void update(Member member) { - this.sqlMapClientTemplate.update("update", member); - } - - @Override - public Member get(int id) { - return (Member)this.sqlMapClientTemplate.queryForObject("get", id); - } - - @Override - @SuppressWarnings("unchecked") - public List list() { - return this.sqlMapClientTemplate.queryForList("list"); - } - - @Override - public void delete(int id) { - this.sqlMapClientTemplate.delete("delete", id); - } - -} +package com.nhn.pinpoint.testweb.repository.ibatis; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.repository.MemberDao; + +/** + * @author Hyun Jeong + */ +@Repository("sqlMapSessionMemberDao") +public class SqlMapSessionMemberDao implements MemberDao { + + @Autowired + @Qualifier("mysqlSqlMapClientTemplate") + private SqlMapClientTemplate sqlMapClientTemplate; + + @Override + public void add(Member member) { + this.sqlMapClientTemplate.insert("add", member); + } + + @Override + public void addStatement(Member member) { + this.sqlMapClientTemplate.insert("addStatement", member); + } + + @Override + public void update(Member member) { + this.sqlMapClientTemplate.update("update", member); + } + + @Override + public Member get(int id) { + return (Member)this.sqlMapClientTemplate.queryForObject("get", id); + } + + @Override + @SuppressWarnings("unchecked") + public List list() { + return this.sqlMapClientTemplate.queryForList("list"); + } + + @Override + public void delete(int id) { + this.sqlMapClientTemplate.delete("delete", id); + } + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/mybatis/MemberMapper.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/mybatis/MemberMapper.java index 42cd8c4697c5..aa32bffd04c4 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/mybatis/MemberMapper.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/repository/mybatis/MemberMapper.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.testweb.repository.mybatis; - -import java.util.List; - -import org.apache.ibatis.annotations.Param; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.testweb.domain.Member; - -/** - * @author Hyun Jeong - */ -@Repository("memberMapper") -public interface MemberMapper { - - public Member selectUser(@Param("id") int id); - - public List selectAllUsersInvalid(); - - public int insertUser(Member member); - - public int updateUser(Member member); - - public int deleteUser(@Param("id") int id); -} +package com.nhn.pinpoint.testweb.repository.mybatis; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.testweb.domain.Member; + +/** + * @author Hyun Jeong + */ +@Repository("memberMapper") +public interface MemberMapper { + + public Member selectUser(@Param("id") int id); + + public List selectAllUsersInvalid(); + + public int insertUser(Member member); + + public int updateUser(Member member); + + public int deleteUser(@Param("id") int id); +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridService.java index ddbf00a8a786..d28508e9ca1c 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridService.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridService.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.testweb.service; - -/** - * - */ -public interface CubridService { - - int selectOne(); - - void createStatement(); - - void createErrorStatement(); -} +package com.nhn.pinpoint.testweb.service; + +/** + * + */ +public interface CubridService { + + int selectOne(); + + void createStatement(); + + void createErrorStatement(); +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridServiceImpl.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridServiceImpl.java index e0690eafe32d..13bf0e4d1223 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridServiceImpl.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/CubridServiceImpl.java @@ -1,32 +1,32 @@ -package com.nhn.pinpoint.testweb.service; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.nhn.pinpoint.testweb.repository.CubridDao; - -/** - * - */ -@Service -@Transactional("cubridTransactionManager") -public class CubridServiceImpl implements CubridService { - @Autowired - private CubridDao cubridDao; - - @Override - public int selectOne() { - return cubridDao.selectOne(); - } - - @Override - public void createStatement() { - cubridDao.createStatement(); - } - - @Override - public void createErrorStatement() { - cubridDao.createErrorStatement(); - } -} +package com.nhn.pinpoint.testweb.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.nhn.pinpoint.testweb.repository.CubridDao; + +/** + * + */ +@Service +@Transactional("cubridTransactionManager") +public class CubridServiceImpl implements CubridService { + @Autowired + private CubridDao cubridDao; + + @Override + public int selectOne() { + return cubridDao.selectOne(); + } + + @Override + public void createStatement() { + cubridDao.createStatement(); + } + + @Override + public void createErrorStatement() { + cubridDao.createErrorStatement(); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberService.java index 583875955c40..b739cb8dcaf1 100755 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberService.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberService.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.testweb.service; - -import java.util.List; - -import com.nhn.pinpoint.testweb.domain.Member; - -public interface MemberService { - - void add(Member member); - - void addStatement(Member member); - - void update(Member member); - - Member get(int id); - - List list(); - - void delete(int id); - - -} +package com.nhn.pinpoint.testweb.service; + +import java.util.List; + +import com.nhn.pinpoint.testweb.domain.Member; + +public interface MemberService { + + void add(Member member); + + void addStatement(Member member); + + void update(Member member); + + Member get(int id); + + List list(); + + void delete(int id); + + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberServiceImpl.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberServiceImpl.java index 3bbd40a066b5..c39f8c218277 100755 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberServiceImpl.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MemberServiceImpl.java @@ -1,54 +1,54 @@ -package com.nhn.pinpoint.testweb.service; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.repository.MemberDao; - -@Service("memberService") -@Transactional("mysqlTransactionManager") -public class MemberServiceImpl implements MemberService { - - @Autowired - @Qualifier("memberDaoJdbc") - private MemberDao dao; - - public MemberDao getDao() { - return dao; - } - - public void setDao(MemberDao dao) { - this.dao = dao; - } - - public void add(Member member) { - dao.add(member); - } - - @Override - public void addStatement(Member member) { - dao.addStatement(member); - } - - public void delete(int id) { - dao.delete(id); - } - - public Member get(int id) { - return dao.get(id); - } - - public List list() { - return dao.list(); - } - - public void update(Member member) { - dao.update(member); - } - -} +package com.nhn.pinpoint.testweb.service; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.repository.MemberDao; + +@Service("memberService") +@Transactional("mysqlTransactionManager") +public class MemberServiceImpl implements MemberService { + + @Autowired + @Qualifier("memberDaoJdbc") + private MemberDao dao; + + public MemberDao getDao() { + return dao; + } + + public void setDao(MemberDao dao) { + this.dao = dao; + } + + public void add(Member member) { + dao.add(member); + } + + @Override + public void addStatement(Member member) { + dao.addStatement(member); + } + + public void delete(int id) { + dao.delete(id); + } + + public Member get(int id) { + return dao.get(id); + } + + public List list() { + return dao.list(); + } + + public void update(Member member) { + dao.update(member); + } + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MsSqlServerService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MsSqlServerService.java new file mode 100644 index 000000000000..fdb560a0844d --- /dev/null +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MsSqlServerService.java @@ -0,0 +1,12 @@ +package com.nhn.pinpoint.testweb.service; + +/** + * + */ +public interface MsSqlServerService { + + int selectOne(); + + void createStatement(); + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MsSqlServerServiceImpl.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MsSqlServerServiceImpl.java new file mode 100644 index 000000000000..836c86935819 --- /dev/null +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MsSqlServerServiceImpl.java @@ -0,0 +1,27 @@ +package com.nhn.pinpoint.testweb.service; + +import com.nhn.pinpoint.testweb.repository.MsSqlServerDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * + */ +@Service +@Transactional("msSqlServerTransactionManager") +public class MsSqlServerServiceImpl implements MsSqlServerService { + + @Autowired + private MsSqlServerDao msSqlServerDao; + + @Override + public int selectOne() { + return msSqlServerDao.selectOne(); + } + + @Override + public void createStatement() { + msSqlServerDao.createStatement(); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlService.java index db1a09093f2f..942121a8b382 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlService.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlService.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.testweb.service; - -/** - * - */ -public interface MySqlService { - - int selectOne(); - - void createStatement(); - -} +package com.nhn.pinpoint.testweb.service; + +/** + * + */ +public interface MySqlService { + + int selectOne(); + + void createStatement(); + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlServiceImpl.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlServiceImpl.java index 20231651564a..472cf365c200 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlServiceImpl.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/MySqlServiceImpl.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.testweb.service; - -import com.nhn.pinpoint.testweb.repository.MySqlDao; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * - */ -@Service -@Transactional("mysqlTransactionManager") -public class MySqlServiceImpl implements MySqlService { - - @Autowired - private MySqlDao mysqlDao; - - @Override - public int selectOne() { - return mysqlDao.selectOne(); - } - - @Override - public void createStatement() { - mysqlDao.createStatement(); - } -} +package com.nhn.pinpoint.testweb.service; + +import com.nhn.pinpoint.testweb.repository.MySqlDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * + */ +@Service +@Transactional("mysqlTransactionManager") +public class MySqlServiceImpl implements MySqlService { + + @Autowired + private MySqlDao mysqlDao; + + @Override + public int selectOne() { + return mysqlDao.selectOne(); + } + + @Override + public void createStatement() { + mysqlDao.createStatement(); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleService.java index 4104bcb67dbe..15b7ba877429 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleService.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleService.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.testweb.service; - -/** - * - */ -public interface OracleService { - - int selectOne(); - - void createStatement(); - -} +package com.nhn.pinpoint.testweb.service; + +/** + * + */ +public interface OracleService { + + int selectOne(); + + void createStatement(); + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleServiceImpl.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleServiceImpl.java index b114f696481f..9d2bc0f302f3 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleServiceImpl.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/OracleServiceImpl.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.testweb.service; - -import com.nhn.pinpoint.testweb.repository.OracleDao; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * - */ -@Service -@Transactional("oracleTransactionManager") -public class OracleServiceImpl implements OracleService { - @Autowired - private OracleDao oracleDao; - - @Override - public int selectOne() { - return oracleDao.selectOne(); - } - - @Override - public void createStatement() { - oracleDao.createStatement(); - } -} +package com.nhn.pinpoint.testweb.service; + +import com.nhn.pinpoint.testweb.repository.OracleDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * + */ +@Service +@Transactional("oracleTransactionManager") +public class OracleServiceImpl implements OracleService { + @Autowired + private OracleDao oracleDao; + + @Override + public int selectOne() { + return oracleDao.selectOne(); + } + + @Override + public void createStatement() { + oracleDao.createStatement(); + } +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapClientMemberService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapClientMemberService.java index 67e8a8ff4495..8108ba94c41b 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapClientMemberService.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapClientMemberService.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.testweb.service.orm.ibatis; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.repository.MemberDao; -import com.nhn.pinpoint.testweb.service.MemberService; - -/** - * @author Hyun Jeong - */ -@Service("sqlMapClientMemberService") -@Transactional("mysqlTransactionManager") -public class SqlMapClientMemberService implements MemberService { - - @Autowired - @Qualifier("sqlMapClientMemberDao") - private MemberDao sqlMapClientMemberDao; - - @Override - public void add(Member member) { - this.sqlMapClientMemberDao.add(member); - } - - @Override - public void addStatement(Member member) { - this.sqlMapClientMemberDao.addStatement(member); - } - - @Override - public void update(Member member) { - this.sqlMapClientMemberDao.update(member); - } - - @Override - public Member get(int id) { - return this.sqlMapClientMemberDao.get(id); - } - - @Override - public List list() { - return this.sqlMapClientMemberDao.list(); - } - - @Override - public void delete(int id) { - this.sqlMapClientMemberDao.delete(id); - } - -} +package com.nhn.pinpoint.testweb.service.orm.ibatis; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.repository.MemberDao; +import com.nhn.pinpoint.testweb.service.MemberService; + +/** + * @author Hyun Jeong + */ +@Service("sqlMapClientMemberService") +@Transactional("mysqlTransactionManager") +public class SqlMapClientMemberService implements MemberService { + + @Autowired + @Qualifier("sqlMapClientMemberDao") + private MemberDao sqlMapClientMemberDao; + + @Override + public void add(Member member) { + this.sqlMapClientMemberDao.add(member); + } + + @Override + public void addStatement(Member member) { + this.sqlMapClientMemberDao.addStatement(member); + } + + @Override + public void update(Member member) { + this.sqlMapClientMemberDao.update(member); + } + + @Override + public Member get(int id) { + return this.sqlMapClientMemberDao.get(id); + } + + @Override + public List list() { + return this.sqlMapClientMemberDao.list(); + } + + @Override + public void delete(int id) { + this.sqlMapClientMemberDao.delete(id); + } + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapSessionMemberService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapSessionMemberService.java index f92ba62a4f82..04585501b0fa 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapSessionMemberService.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/ibatis/SqlMapSessionMemberService.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.testweb.service.orm.ibatis; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.repository.MemberDao; -import com.nhn.pinpoint.testweb.service.MemberService; - -/** - * @author Hyun Jeong - */ -@Service("sqlMapSessionMemberService") -@Transactional("mysqlTransactionManager") -public class SqlMapSessionMemberService implements MemberService { - - @Autowired - @Qualifier("sqlMapSessionMemberDao") - private MemberDao sqlMapSessionMemberDao; - - @Override - public void add(Member member) { - this.sqlMapSessionMemberDao.add(member); - } - - @Override - public void addStatement(Member member) { - this.sqlMapSessionMemberDao.addStatement(member); - } - - @Override - public void update(Member member) { - this.sqlMapSessionMemberDao.update(member); - } - - @Override - public Member get(int id) { - return this.sqlMapSessionMemberDao.get(id); - } - - @Override - public List list() { - return this.sqlMapSessionMemberDao.list(); - } - - @Override - public void delete(int id) { - this.sqlMapSessionMemberDao.delete(id); - } - -} +package com.nhn.pinpoint.testweb.service.orm.ibatis; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.repository.MemberDao; +import com.nhn.pinpoint.testweb.service.MemberService; + +/** + * @author Hyun Jeong + */ +@Service("sqlMapSessionMemberService") +@Transactional("mysqlTransactionManager") +public class SqlMapSessionMemberService implements MemberService { + + @Autowired + @Qualifier("sqlMapSessionMemberDao") + private MemberDao sqlMapSessionMemberDao; + + @Override + public void add(Member member) { + this.sqlMapSessionMemberDao.add(member); + } + + @Override + public void addStatement(Member member) { + this.sqlMapSessionMemberDao.addStatement(member); + } + + @Override + public void update(Member member) { + this.sqlMapSessionMemberDao.update(member); + } + + @Override + public Member get(int id) { + return this.sqlMapSessionMemberDao.get(id); + } + + @Override + public List list() { + return this.sqlMapSessionMemberDao.list(); + } + + @Override + public void delete(int id) { + this.sqlMapSessionMemberDao.delete(id); + } + +} diff --git a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/mybatis/MyBatisMemberService.java b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/mybatis/MyBatisMemberService.java index 29016e3be9e8..bad499fb14a2 100644 --- a/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/mybatis/MyBatisMemberService.java +++ b/testweb/src/main/java/com/nhn/pinpoint/testweb/service/orm/mybatis/MyBatisMemberService.java @@ -1,53 +1,53 @@ -package com.nhn.pinpoint.testweb.service.orm.mybatis; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.repository.mybatis.MemberMapper; -import com.nhn.pinpoint.testweb.service.MemberService; - -/** - * @author Hyun Jeong - */ -@Service("myBatisMemberService") -@Transactional("mysqlTransactionManager") -public class MyBatisMemberService implements MemberService { - - @Autowired - private MemberMapper memberMapper; - - @Override - public void add(Member member) { - this.memberMapper.insertUser(member); - } - - @Override - public void addStatement(Member member) { - this.memberMapper.insertUser(member); - } - - @Override - public void update(Member member) { - this.memberMapper.updateUser(member); - } - - @Override - public Member get(int id) { - return this.memberMapper.selectUser(id); - } - - @Override - public List list() { - return this.memberMapper.selectAllUsersInvalid(); - } - - @Override - public void delete(int id) { - this.memberMapper.deleteUser(id); - } - -} +package com.nhn.pinpoint.testweb.service.orm.mybatis; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.repository.mybatis.MemberMapper; +import com.nhn.pinpoint.testweb.service.MemberService; + +/** + * @author Hyun Jeong + */ +@Service("myBatisMemberService") +@Transactional("mysqlTransactionManager") +public class MyBatisMemberService implements MemberService { + + @Autowired + private MemberMapper memberMapper; + + @Override + public void add(Member member) { + this.memberMapper.insertUser(member); + } + + @Override + public void addStatement(Member member) { + this.memberMapper.insertUser(member); + } + + @Override + public void update(Member member) { + this.memberMapper.updateUser(member); + } + + @Override + public Member get(int id) { + return this.memberMapper.selectUser(id); + } + + @Override + public List list() { + return this.memberMapper.selectAllUsersInvalid(); + } + + @Override + public void delete(int id) { + this.memberMapper.deleteUser(id); + } + +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/agent/AnnotatedMgmtAgent.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/agent/AnnotatedMgmtAgent.java index 8bd4e3b99900..d63c59531d26 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/agent/AnnotatedMgmtAgent.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/agent/AnnotatedMgmtAgent.java @@ -1,83 +1,83 @@ -package com.nhncorp.lucy.nimm.connector.agent; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.logging.Logger; - -import com.nhncorp.lucy.nimm.connector.MessageFuture; -import com.nhncorp.lucy.nimm.connector.NimmSocket; -import com.nhncorp.lucy.nimm.connector.agent.provider.AgentInfo; -import com.nhncorp.lucy.nimm.connector.agent.provider.NimmAgentArchetype; -import com.nhncorp.lucy.nimm.connector.message.NimmMessage; -import com.nhncorp.lucy.nimm.connector.worker.NimmAbstractWorker; -import com.nhncorp.lucy.nimm.connector.worker.NimmWorker; - -@AgentInfo( domainId = 7, socketId = 1) -public class AnnotatedMgmtAgent extends NimmAgentArchetype implements ManagementAgentAPI { - - private static final Logger LOGGER = Logger.getLogger(AnnotatedMgmtAgent.class.getName()); - - private final NimmWorker worker; - - public AnnotatedMgmtAgent() { - this.worker = new AnnotatedMgmtWorker(); - } - @Override - public void destroy() { - LOGGER.info("AnnotatedMgmtAgent.destroy()"); - } - - @Override - public NimmWorker getNimmWorker() { - return worker; - } - - @Override - public void init() { - LOGGER.info("AnnotatedMgmtAgent.init()"); - } - - public String getName() { - return "AnnotatedMgmtAgent"; - } - - public String getVersion() { - return "1.0.0"; - } - - private class AnnotatedMgmtWorker extends NimmAbstractWorker { - - @Override - public void destroy() { - LOGGER.info("AnnotatedMgmtWorker.destroy()"); - } - - @Override - public void init() { - LOGGER.info("AnnotatedMgmtWorker.init()"); - } - - @Override - protected void processMessage(NimmMessage message) throws Exception { - getMySocket().send(message.getSourceAddress(), message.getMessage()); - } - - @Override - protected ByteBuffer responseMessage(NimmMessage request) - throws Exception { - return request.getMessage(); - } - - } - - public boolean loopMessage() throws Exception { - NimmSocket localSocket = createSocket(); - - byte[] msg = "UlaUlaWowWow".getBytes(); - MessageFuture future = localSocket.request(getMySocket(), msg); - - future.await(); - - return Arrays.equals(future.getResponse().getMessageAsArray(),msg); - } -} +package com.nhncorp.lucy.nimm.connector.agent; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.logging.Logger; + +import com.nhncorp.lucy.nimm.connector.MessageFuture; +import com.nhncorp.lucy.nimm.connector.NimmSocket; +import com.nhncorp.lucy.nimm.connector.agent.provider.AgentInfo; +import com.nhncorp.lucy.nimm.connector.agent.provider.NimmAgentArchetype; +import com.nhncorp.lucy.nimm.connector.message.NimmMessage; +import com.nhncorp.lucy.nimm.connector.worker.NimmAbstractWorker; +import com.nhncorp.lucy.nimm.connector.worker.NimmWorker; + +@AgentInfo( domainId = 7, socketId = 1) +public class AnnotatedMgmtAgent extends NimmAgentArchetype implements ManagementAgentAPI { + + private static final Logger LOGGER = Logger.getLogger(AnnotatedMgmtAgent.class.getName()); + + private final NimmWorker worker; + + public AnnotatedMgmtAgent() { + this.worker = new AnnotatedMgmtWorker(); + } + @Override + public void destroy() { + LOGGER.info("AnnotatedMgmtAgent.destroy()"); + } + + @Override + public NimmWorker getNimmWorker() { + return worker; + } + + @Override + public void init() { + LOGGER.info("AnnotatedMgmtAgent.init()"); + } + + public String getName() { + return "AnnotatedMgmtAgent"; + } + + public String getVersion() { + return "1.0.0"; + } + + private class AnnotatedMgmtWorker extends NimmAbstractWorker { + + @Override + public void destroy() { + LOGGER.info("AnnotatedMgmtWorker.destroy()"); + } + + @Override + public void init() { + LOGGER.info("AnnotatedMgmtWorker.init()"); + } + + @Override + protected void processMessage(NimmMessage message) throws Exception { + getMySocket().send(message.getSourceAddress(), message.getMessage()); + } + + @Override + protected ByteBuffer responseMessage(NimmMessage request) + throws Exception { + return request.getMessage(); + } + + } + + public boolean loopMessage() throws Exception { + NimmSocket localSocket = createSocket(); + + byte[] msg = "UlaUlaWowWow".getBytes(); + MessageFuture future = localSocket.request(getMySocket(), msg); + + future.await(); + + return Arrays.equals(future.getResponse().getMessageAsArray(),msg); + } +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmControlRecordFactory.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmControlRecordFactory.java index 1afba69c2419..0942bc4d2533 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmControlRecordFactory.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmControlRecordFactory.java @@ -1,34 +1,34 @@ -package com.nhncorp.lucy.nimm.connector.record; - -import com.nhncorp.lucy.nimm.connector.record.NimmControlRecord; -import com.nhncorp.lucy.nimm.connector.record.NimmRecordHeader; - -import external.org.apache.mina.common.IoBuffer; - - -/** - * NimmMockupServer에서 사용하는 NimmControlRecordFactory를 생성 - * - * @author nhn - * - */ -public final class NimmControlRecordFactory { - - /** - * Blank private constructor - */ - private NimmControlRecordFactory() { - // Blank private constructor - } - - /** - * create NimmControlRecord by given header and payload - * - * @param header header of NIMM control message - * @param payload payload of NIMM control message - * @return NIMM control message - */ - public static NimmControlRecord create(NimmRecordHeader header, byte[] payload) { - return NimmControlRecord.recordCreationFactory(header, IoBuffer.wrap(payload)); - } -} +package com.nhncorp.lucy.nimm.connector.record; + +import com.nhncorp.lucy.nimm.connector.record.NimmControlRecord; +import com.nhncorp.lucy.nimm.connector.record.NimmRecordHeader; + +import external.org.apache.mina.common.IoBuffer; + + +/** + * NimmMockupServer에서 사용하는 NimmControlRecordFactory를 생성 + * + * @author nhn + * + */ +public final class NimmControlRecordFactory { + + /** + * Blank private constructor + */ + private NimmControlRecordFactory() { + // Blank private constructor + } + + /** + * create NimmControlRecord by given header and payload + * + * @param header header of NIMM control message + * @param payload payload of NIMM control message + * @return NIMM control message + */ + public static NimmControlRecord create(NimmRecordHeader header, byte[] payload) { + return NimmControlRecord.recordCreationFactory(header, IoBuffer.wrap(payload)); + } +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmRecordHeaderFactory.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmRecordHeaderFactory.java index 23e6d7eb4c6c..09a6c49105c5 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmRecordHeaderFactory.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/record/NimmRecordHeaderFactory.java @@ -1,42 +1,42 @@ -package com.nhncorp.lucy.nimm.connector.record; - -import com.nhncorp.lucy.nimm.connector.address.NimmAddress; -import com.nhncorp.lucy.nimm.connector.address.NimmIndividual; -import com.nhncorp.lucy.nimm.connector.record.NimmControlRecord.ControlCode; - -/** - * NimmMockupServer에서 사용하는 NimmRecordHeader를 생성 - * - * @author nhn - * - */ -public final class NimmRecordHeaderFactory { - - /** - * Blank private constructor - */ - private NimmRecordHeaderFactory() { - // Blank private constructor - } - - /** - * create NimmRecordHeader - * (NIMM Control Message, BYE, Duplicated Address) - * - * @param remoteAddress remote NIMM address - * @param localAddress local NIMM address - * @return BYE control message header with duplicated address - */ - public static NimmRecordHeader createBYEwithDuplicatedAddr(NimmAddress remoteAddress, NimmAddress localAddress) { - NimmIndividual[] blankPathThrogh = new NimmIndividual[0]; - int messageId = NimmRecordUtilities.getNextId(); - - NimmRecordHeader header = new NimmRecordHeader.Normal(Constants.HEADER.VERSION, - ControlCode.BYE.getCodeNumber(), 12, - Constants.HEADER.OPTION.FLAG_NONE, - Constants.HEADER.CONTROLPARAMETER.NACK_DUPLICATED_ADDRESS_LIST, 0, 0, messageId, 0, - remoteAddress, localAddress, blankPathThrogh); - - return header; - } -} +package com.nhncorp.lucy.nimm.connector.record; + +import com.nhncorp.lucy.nimm.connector.address.NimmAddress; +import com.nhncorp.lucy.nimm.connector.address.NimmIndividual; +import com.nhncorp.lucy.nimm.connector.record.NimmControlRecord.ControlCode; + +/** + * NimmMockupServer에서 사용하는 NimmRecordHeader를 생성 + * + * @author nhn + * + */ +public final class NimmRecordHeaderFactory { + + /** + * Blank private constructor + */ + private NimmRecordHeaderFactory() { + // Blank private constructor + } + + /** + * create NimmRecordHeader + * (NIMM Control Message, BYE, Duplicated Address) + * + * @param remoteAddress remote NIMM address + * @param localAddress local NIMM address + * @return BYE control message header with duplicated address + */ + public static NimmRecordHeader createBYEwithDuplicatedAddr(NimmAddress remoteAddress, NimmAddress localAddress) { + NimmIndividual[] blankPathThrogh = new NimmIndividual[0]; + int messageId = NimmRecordUtilities.getNextId(); + + NimmRecordHeader header = new NimmRecordHeader.Normal(Constants.HEADER.VERSION, + ControlCode.BYE.getCodeNumber(), 12, + Constants.HEADER.OPTION.FLAG_NONE, + Constants.HEADER.CONTROLPARAMETER.NACK_DUPLICATED_ADDRESS_LIST, 0, 0, messageId, 0, + remoteAddress, localAddress, blankPathThrogh); + + return header; + } +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/worker/NimmAbstractWorkerMock.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/worker/NimmAbstractWorkerMock.java index dad0d00aa910..d1241f075a45 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/worker/NimmAbstractWorkerMock.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/connector/worker/NimmAbstractWorkerMock.java @@ -1,38 +1,38 @@ -package com.nhncorp.lucy.nimm.connector.worker; - -import java.nio.ByteBuffer; - -import com.nhncorp.lucy.nimm.connector.message.NimmMessage; - -/** - * User: emeroad Date: 2009. 2. 27 Time: 오후 10:34:23 - */ -public class NimmAbstractWorkerMock extends NimmAbstractWorker { - private Exception ex; - - public void init() { - } - - public void destroy() { - } - - protected void processMessage(NimmMessage message) throws Exception { - ex = new UnsupportedOperationException("processMessage"); - } - - protected ByteBuffer responseMessage(NimmMessage request) throws Exception { - ex = new UnsupportedOperationException("responseMessage"); - return ByteBuffer.allocate(0); - } - - public void checkException() { - if (ex == null) { - return; - } - // Assert.fail(ex.getMessage()); - } - - protected void setException(Exception ex) { - this.ex = ex; - } -} +package com.nhncorp.lucy.nimm.connector.worker; + +import java.nio.ByteBuffer; + +import com.nhncorp.lucy.nimm.connector.message.NimmMessage; + +/** + * User: emeroad Date: 2009. 2. 27 Time: 오후 10:34:23 + */ +public class NimmAbstractWorkerMock extends NimmAbstractWorker { + private Exception ex; + + public void init() { + } + + public void destroy() { + } + + protected void processMessage(NimmMessage message) throws Exception { + ex = new UnsupportedOperationException("processMessage"); + } + + protected ByteBuffer responseMessage(NimmMessage request) throws Exception { + ex = new UnsupportedOperationException("responseMessage"); + return ByteBuffer.allocate(0); + } + + public void checkException() { + if (ex == null) { + return; + } + // Assert.fail(ex.getMessage()); + } + + protected void setException(Exception ex) { + this.ex = ex; + } +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastKey.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastKey.java index eeb3d2b10fad..cd2e14051055 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastKey.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastKey.java @@ -1,42 +1,42 @@ -package com.nhncorp.lucy.nimm.mockupserver; - -public class AnycastKey { - - private final int domainId; - private final int idcId; - - AnycastKey(int domainId, int idcId) { - this.domainId = domainId; - this.idcId = idcId; - } - - int getDomainId() { - return domainId; - } - - int getIdcId() { - return idcId; - } - - - @Override - public boolean equals(Object o) { - if (null == o) return true; - if (!(o instanceof AnycastKey)) return false; - - AnycastKey that = (AnycastKey) o; - - if (domainId != that.domainId) return false; - if (idcId != that.idcId) return false; - - return true; - } - - @Override - public int hashCode() { - int result = domainId; - result = 31 * result + idcId; - return result; - } - +package com.nhncorp.lucy.nimm.mockupserver; + +public class AnycastKey { + + private final int domainId; + private final int idcId; + + AnycastKey(int domainId, int idcId) { + this.domainId = domainId; + this.idcId = idcId; + } + + int getDomainId() { + return domainId; + } + + int getIdcId() { + return idcId; + } + + + @Override + public boolean equals(Object o) { + if (null == o) return true; + if (!(o instanceof AnycastKey)) return false; + + AnycastKey that = (AnycastKey) o; + + if (domainId != that.domainId) return false; + if (idcId != that.idcId) return false; + + return true; + } + + @Override + public int hashCode() { + int result = domainId; + result = 31 * result + idcId; + return result; + } + } \ No newline at end of file diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastRoutingTable.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastRoutingTable.java index 82bb7a48a2cc..7cf6af5e66f4 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastRoutingTable.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/AnycastRoutingTable.java @@ -1,68 +1,68 @@ -package com.nhncorp.lucy.nimm.mockupserver; - -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * User: emeroad - * Date: 2010. 3. 24 - * Time: 오전 11:52:07 - * - * @author Middleware Platform Dev. Team - */ -public class AnycastRoutingTable { - private Logger logger = Logger.getLogger(getClass().getName()); - - private final ConcurrentMap> routingTable = new ConcurrentHashMap>(); - private final AtomicInteger rrKey = new AtomicInteger(0); - - public List register(AnycastKey anycastKey, IoSessionPair pair) { - List list = this.routingTable.get(anycastKey); - if (list == null) { - // 약간의 동시성 문제가 있나? 생각좀 해봐야 할듯. - list = new CopyOnWriteArrayList(); - } - list.add(pair); - return this.routingTable.put(anycastKey, list); - } - - public List select(AnycastKey key) { - return this.routingTable.get(key); - } - - public IoSessionPair roundRobinSelect(AnycastKey key, boolean routingCheck) { - List ioSessionPairList = select(key); - if(ioSessionPairList == null) { - return null; - } - int size = ioSessionPairList.size(); - if (size == 0) { - // anycast로 roundRobin할 키가 없음. - return null; - } - for (int i = 0; i < size; i++) { - try { - IoSessionPair sessionPair = ioSessionPairList.get(rrKey.incrementAndGet() % size); - if(routingCheck) { - RoutingState routingState = RoutingState.getRoutingState(sessionPair.getIoSession()); - if(routingState.isAnycastRouting(key.getDomainId())) { - return sessionPair; - } else { - continue; - } - } else { - return sessionPair; - } - } catch (IndexOutOfBoundsException e) { - logger.log(Level.WARNING, "index select error", e); - } - } - return null; - } - -} +package com.nhncorp.lucy.nimm.mockupserver; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * User: emeroad + * Date: 2010. 3. 24 + * Time: 오전 11:52:07 + * + * @author Middleware Platform Dev. Team + */ +public class AnycastRoutingTable { + private Logger logger = Logger.getLogger(getClass().getName()); + + private final ConcurrentMap> routingTable = new ConcurrentHashMap>(); + private final AtomicInteger rrKey = new AtomicInteger(0); + + public List register(AnycastKey anycastKey, IoSessionPair pair) { + List list = this.routingTable.get(anycastKey); + if (list == null) { + // 약간의 동시성 문제가 있나? 생각좀 해봐야 할듯. + list = new CopyOnWriteArrayList(); + } + list.add(pair); + return this.routingTable.put(anycastKey, list); + } + + public List select(AnycastKey key) { + return this.routingTable.get(key); + } + + public IoSessionPair roundRobinSelect(AnycastKey key, boolean routingCheck) { + List ioSessionPairList = select(key); + if(ioSessionPairList == null) { + return null; + } + int size = ioSessionPairList.size(); + if (size == 0) { + // anycast로 roundRobin할 키가 없음. + return null; + } + for (int i = 0; i < size; i++) { + try { + IoSessionPair sessionPair = ioSessionPairList.get(rrKey.incrementAndGet() % size); + if(routingCheck) { + RoutingState routingState = RoutingState.getRoutingState(sessionPair.getIoSession()); + if(routingState.isAnycastRouting(key.getDomainId())) { + return sessionPair; + } else { + continue; + } + } else { + return sessionPair; + } + } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "index select error", e); + } + } + return null; + } + +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/ClientKey.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/ClientKey.java index d9e65d3bbb4f..5c556810e124 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/ClientKey.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/ClientKey.java @@ -1,70 +1,70 @@ -package com.nhncorp.lucy.nimm.mockupserver; - -/** - * User: emeroad - * Date: 2010. 3. 24 - * Time: 오전 11:56:13 - * - * @author Middleware Platform Dev. Team - */ -public class ClientKey { - private final int domainId; - private final int idcId; - private final int serverId; - - ClientKey(int domainId, int idcId, int serverId) { - this.domainId = domainId; - this.idcId = idcId; - this.serverId = serverId; - } - - int getDomainId() { - return domainId; - } - - int getIdcId() { - return idcId; - } - - int getServerId() { - return serverId; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + domainId; - result = prime * result + idcId; - result = prime * result + serverId; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final ClientKey other = (ClientKey) obj; - if (domainId != other.domainId) - return false; - if (idcId != other.idcId) - return false; - if (serverId != other.serverId) - return false; - return true; - } - - - @Override - public String toString() { - return "ClientKey{" + - "domainId=" + domainId + - ", idcId=" + idcId + - ", serverId=" + serverId + - '}'; - } -} +package com.nhncorp.lucy.nimm.mockupserver; + +/** + * User: emeroad + * Date: 2010. 3. 24 + * Time: 오전 11:56:13 + * + * @author Middleware Platform Dev. Team + */ +public class ClientKey { + private final int domainId; + private final int idcId; + private final int serverId; + + ClientKey(int domainId, int idcId, int serverId) { + this.domainId = domainId; + this.idcId = idcId; + this.serverId = serverId; + } + + int getDomainId() { + return domainId; + } + + int getIdcId() { + return idcId; + } + + int getServerId() { + return serverId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + domainId; + result = prime * result + idcId; + result = prime * result + serverId; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final ClientKey other = (ClientKey) obj; + if (domainId != other.domainId) + return false; + if (idcId != other.idcId) + return false; + if (serverId != other.serverId) + return false; + return true; + } + + + @Override + public String toString() { + return "ClientKey{" + + "domainId=" + domainId + + ", idcId=" + idcId + + ", serverId=" + serverId + + '}'; + } +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/IoSessionPair.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/IoSessionPair.java index 96cdbda93e1a..791fcfa8acb0 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/IoSessionPair.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/IoSessionPair.java @@ -1,31 +1,31 @@ -package com.nhncorp.lucy.nimm.mockupserver; - -import com.nhncorp.lucy.nimm.connector.address.NimmAddress; -import external.org.apache.mina.common.IoSession; - -/** - * User: emeroad - * Date: 2010. 3. 24 - * Time: 오전 11:57:46 - * - * @author Middleware Platform Dev. Team - */ -public class IoSessionPair { - private IoSession ioSession; - private NimmAddress address; - - - public IoSessionPair(IoSession session, NimmAddress address){ - this.ioSession = session; - this.address = address; - } - - public IoSession getIoSession() { - return ioSession; - } - - public NimmAddress getAddress() { - return address; - } - -} +package com.nhncorp.lucy.nimm.mockupserver; + +import com.nhncorp.lucy.nimm.connector.address.NimmAddress; +import external.org.apache.mina.common.IoSession; + +/** + * User: emeroad + * Date: 2010. 3. 24 + * Time: 오전 11:57:46 + * + * @author Middleware Platform Dev. Team + */ +public class IoSessionPair { + private IoSession ioSession; + private NimmAddress address; + + + public IoSessionPair(IoSession session, NimmAddress address){ + this.ioSession = session; + this.address = address; + } + + public IoSession getIoSession() { + return ioSession; + } + + public NimmAddress getAddress() { + return address; + } + +} diff --git a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/RoutingState.java b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/RoutingState.java index 9cc5535483da..5874938d2ce9 100644 --- a/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/RoutingState.java +++ b/testweb/src/main/java/com/nhncorp/lucy/nimm/mockupserver/RoutingState.java @@ -1,56 +1,56 @@ -package com.nhncorp.lucy.nimm.mockupserver; - -import external.org.apache.mina.common.IoSession; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * User: emeroad - * Date: 2010. 3. 25 - * Time: 오후 4:08:32 - * - * @author Middleware Platform Dev. Team - */ -public class RoutingState { - - private ConcurrentMap routingState; - private static final String ROUTING_STATE = "_ROUTING_STATE"; - - public static RoutingState getRoutingState(IoSession ioSession) { - return (RoutingState) ioSession.getAttribute(ROUTING_STATE); - } - - public static void createRoutingState(IoSession ioSession) { - ioSession.setAttribute(ROUTING_STATE, new RoutingState()); - } - - private RoutingState() { - this.routingState = new ConcurrentHashMap(); - } - - public boolean register(int domainId) { - AtomicBoolean before = this.routingState.putIfAbsent(domainId, new AtomicBoolean()); - return before == null; - } - - public void routingEnable(int domainId, boolean enable) { - AtomicBoolean routing = this.routingState.get(domainId); - if(routing == null) { - throw new RuntimeException("domainId not found:" + domainId); - } - boolean success = routing.compareAndSet(!enable, enable); - if(!success) { - throw new RuntimeException("Invalid RoutingState:" + domainId + " enable:" + enable); - } - } - - public boolean isAnycastRouting(int domainId) { - AtomicBoolean routing = this.routingState.get(domainId); - if(routing == null) { - throw new RuntimeException("domainId not found:" + domainId); - } - return routing.get(); - } -} +package com.nhncorp.lucy.nimm.mockupserver; + +import external.org.apache.mina.common.IoSession; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * User: emeroad + * Date: 2010. 3. 25 + * Time: 오후 4:08:32 + * + * @author Middleware Platform Dev. Team + */ +public class RoutingState { + + private ConcurrentMap routingState; + private static final String ROUTING_STATE = "_ROUTING_STATE"; + + public static RoutingState getRoutingState(IoSession ioSession) { + return (RoutingState) ioSession.getAttribute(ROUTING_STATE); + } + + public static void createRoutingState(IoSession ioSession) { + ioSession.setAttribute(ROUTING_STATE, new RoutingState()); + } + + private RoutingState() { + this.routingState = new ConcurrentHashMap(); + } + + public boolean register(int domainId) { + AtomicBoolean before = this.routingState.putIfAbsent(domainId, new AtomicBoolean()); + return before == null; + } + + public void routingEnable(int domainId, boolean enable) { + AtomicBoolean routing = this.routingState.get(domainId); + if(routing == null) { + throw new RuntimeException("domainId not found:" + domainId); + } + boolean success = routing.compareAndSet(!enable, enable); + if(!success) { + throw new RuntimeException("Invalid RoutingState:" + domainId + " enable:" + enable); + } + } + + public boolean isAnycastRouting(int domainId) { + AtomicBoolean routing = this.routingState.get(domainId); + if(routing == null) { + throw new RuntimeException("domainId not found:" + domainId); + } + return routing.get(); + } +} diff --git a/testweb/src/main/resources/applicationContext-datasource.xml b/testweb/src/main/resources/applicationContext-datasource.xml index 56fa6db1f68b..cbe853970f69 100644 --- a/testweb/src/main/resources/applicationContext-datasource.xml +++ b/testweb/src/main/resources/applicationContext-datasource.xml @@ -1,97 +1,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testweb/src/main/resources/root-context.xml b/testweb/src/main/resources/applicationContext-testweb.xml similarity index 64% rename from testweb/src/main/resources/root-context.xml rename to testweb/src/main/resources/applicationContext-testweb.xml index fd4fed067b30..26ea5d329a52 100644 --- a/testweb/src/main/resources/root-context.xml +++ b/testweb/src/main/resources/applicationContext-testweb.xml @@ -4,35 +4,42 @@ xmlns:context="http://www.springframework.org/schema/context" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:beans="http://www.springframework.org/schema/beans" + xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> + - + + - + - + - + - + - + - + @@ -41,12 +48,12 @@ - + - + @@ -55,12 +62,12 @@ - + - + - + @@ -69,7 +76,23 @@ - + + + + + + + + + + + + + + + + + diff --git a/testweb/src/main/resources/create_table.sql b/testweb/src/main/resources/create_table.sql index b58488eb6c16..05911bf9c551 100755 --- a/testweb/src/main/resources/create_table.sql +++ b/testweb/src/main/resources/create_table.sql @@ -1,5 +1,5 @@ -CREATE TABLE IF NOT EXISTS member ( - id varchar(11) primary key, - name varchar(20) not null, - joined date +CREATE TABLE IF NOT EXISTS member ( + id varchar(11) primary key, + name varchar(20) not null, + joined date ); \ No newline at end of file diff --git a/testweb/src/main/resources/cubrid/sql-member.xml b/testweb/src/main/resources/cubrid/sql-member.xml index 6be6e908c738..3ba4ad238c76 100755 --- a/testweb/src/main/resources/cubrid/sql-member.xml +++ b/testweb/src/main/resources/cubrid/sql-member.xml @@ -1,33 +1,33 @@ - - - - - - - - delete from member where id = #id# - - - - insert into member (id, name, joined) values(#id#, #name#, #joined#) - - - - insert into member (id, name, joined) values($id$, $name$, #joined#); - - - - - update member set name = #name#, joined = #joined# where id = #id# - - - - - - + + + + + + + + delete from member where id = #id# + + + + insert into member (id, name, joined) values(#id#, #name#, #joined#) + + + + insert into member (id, name, joined) values($id$, $name$, #joined#); + + + + + update member set name = #name#, joined = #joined# where id = #id# + + + + + + diff --git a/testweb/src/main/resources/cubrid/test-sql.xml b/testweb/src/main/resources/cubrid/test-sql.xml index ee2aebcaebb0..fc4ea7e9ef3a 100644 --- a/testweb/src/main/resources/cubrid/test-sql.xml +++ b/testweb/src/main/resources/cubrid/test-sql.xml @@ -1,13 +1,13 @@ - - - - - - - - - + + + + + + + + + diff --git a/testweb/src/main/resources/database.properties b/testweb/src/main/resources/database.properties index d3d651a89fb2..28e98a284bf0 100755 --- a/testweb/src/main/resources/database.properties +++ b/testweb/src/main/resources/database.properties @@ -1 +1,23 @@ -hibernate.dialect=org.hibernate.dialect.HSQLDialect +hibernate.dialect=org.hibernate.dialect.HSQLDialect + + +# oracle +oracle.url=jdbc:oracle:thin:@10.98.133.174:1725:INDEV +oracle.user=lucy +oracle.password=lucy + +# ms sqlserver +mssqlserver.url=jdbc:jtds:sqlserver://10.99.220.85:1433/pinpoint_test +mssqlserver.user=pinpoint_user +mssqlserver.password=pinpoint!234 + +# mysql +mysql.url=jdbc:mysql://10.98.133.22:3306/hippo +mysql.url.loadbalance=jdbc:mysql:loadbalance://10.98.133.23:3306,10.98.133.22:3306/hippo +mysql.user=lucytest +mysql.password=testlucy + +# cubrid +cubrid.url=jdbc:cubrid:10.101.57.233:30102:pinpoint::: +cubrid.user=dba +cubrid.password=nhn!@#123 \ No newline at end of file diff --git a/testweb/src/main/resources/log4j.xml b/testweb/src/main/resources/log4j.xml index 2593c35dd3d8..b4f556f93d85 100644 --- a/testweb/src/main/resources/log4j.xml +++ b/testweb/src/main/resources/log4j.xml @@ -18,7 +18,7 @@ - + diff --git a/testweb/src/main/resources/mssqlserver/SqlMapConfig.xml b/testweb/src/main/resources/mssqlserver/SqlMapConfig.xml new file mode 100644 index 000000000000..d0dd17437e2d --- /dev/null +++ b/testweb/src/main/resources/mssqlserver/SqlMapConfig.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/testweb/src/main/resources/mssqlserver/sql-member.xml b/testweb/src/main/resources/mssqlserver/sql-member.xml new file mode 100644 index 000000000000..3ba4ad238c76 --- /dev/null +++ b/testweb/src/main/resources/mssqlserver/sql-member.xml @@ -0,0 +1,33 @@ + + + + + + + + delete from member where id = #id# + + + + insert into member (id, name, joined) values(#id#, #name#, #joined#) + + + + insert into member (id, name, joined) values($id$, $name$, #joined#); + + + + + update member set name = #name#, joined = #joined# where id = #id# + + + + + + diff --git a/testweb/src/main/resources/mssqlserver/test-sql.xml b/testweb/src/main/resources/mssqlserver/test-sql.xml new file mode 100644 index 000000000000..031f2844cb35 --- /dev/null +++ b/testweb/src/main/resources/mssqlserver/test-sql.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/testweb/src/main/resources/mysql/sql-member.xml b/testweb/src/main/resources/mysql/sql-member.xml index 6be6e908c738..3ba4ad238c76 100755 --- a/testweb/src/main/resources/mysql/sql-member.xml +++ b/testweb/src/main/resources/mysql/sql-member.xml @@ -1,33 +1,33 @@ - - - - - - - - delete from member where id = #id# - - - - insert into member (id, name, joined) values(#id#, #name#, #joined#) - - - - insert into member (id, name, joined) values($id$, $name$, #joined#); - - - - - update member set name = #name#, joined = #joined# where id = #id# - - - - - - + + + + + + + + delete from member where id = #id# + + + + insert into member (id, name, joined) values(#id#, #name#, #joined#) + + + + insert into member (id, name, joined) values($id$, $name$, #joined#); + + + + + update member set name = #name#, joined = #joined# where id = #id# + + + + + + diff --git a/testweb/src/main/resources/mysql/test-sql.xml b/testweb/src/main/resources/mysql/test-sql.xml index bfb52dbaa8d9..3fa4180782ca 100644 --- a/testweb/src/main/resources/mysql/test-sql.xml +++ b/testweb/src/main/resources/mysql/test-sql.xml @@ -1,13 +1,13 @@ - - - - - - - - - + + + + + + + + + diff --git a/testweb/src/main/resources/oracle/test-sql.xml b/testweb/src/main/resources/oracle/test-sql.xml index 3c7aadc455a2..16636a0fd529 100755 --- a/testweb/src/main/resources/oracle/test-sql.xml +++ b/testweb/src/main/resources/oracle/test-sql.xml @@ -1,13 +1,13 @@ - - - - - - - - - + + + + + + + + + diff --git a/testweb/src/main/resources/orm/mybatis/mapper/memberMapper.xml b/testweb/src/main/resources/orm/mybatis/mapper/memberMapper.xml index 8bc4632c1f0a..87bd165aa92b 100644 --- a/testweb/src/main/resources/orm/mybatis/mapper/memberMapper.xml +++ b/testweb/src/main/resources/orm/mybatis/mapper/memberMapper.xml @@ -1,44 +1,44 @@ - - - - - - - - - - - INSERT INTO member ( - id, name, joined - ) VALUES ( - #{id}, #{name}, #{joined} - ) - - - - UPDATE member - SET name = #{name}, - joined = #{joined} - WHERE id = #{id} - - - - DELETE FROM member - WHERE id = #{id} - - - + + + + + + + + + + + INSERT INTO member ( + id, name, joined + ) VALUES ( + #{id}, #{name}, #{joined} + ) + + + + UPDATE member + SET name = #{name}, + joined = #{joined} + WHERE id = #{id} + + + + DELETE FROM member + WHERE id = #{id} + + + diff --git a/testweb/src/main/resources/orm/mybatis/mybatis-config.xml b/testweb/src/main/resources/orm/mybatis/mybatis-config.xml index 0ae5d7ca29ea..c8e1f7e775fb 100644 --- a/testweb/src/main/resources/orm/mybatis/mybatis-config.xml +++ b/testweb/src/main/resources/orm/mybatis/mybatis-config.xml @@ -1,28 +1,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testweb/src/main/resources/orm/mybatis/mybatis-dao-config.xml b/testweb/src/main/resources/orm/mybatis/mybatis-dao-config.xml index 91311b399369..2915e8636ec0 100644 --- a/testweb/src/main/resources/orm/mybatis/mybatis-dao-config.xml +++ b/testweb/src/main/resources/orm/mybatis/mybatis-dao-config.xml @@ -1,64 +1,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testweb/src/main/resources/servlet-context.xml b/testweb/src/main/resources/servlet-context.xml index 968ddb05626c..5431834479c8 100644 --- a/testweb/src/main/resources/servlet-context.xml +++ b/testweb/src/main/resources/servlet-context.xml @@ -1,29 +1,22 @@ - - + + - - - - - - + + + + + + + - - \ No newline at end of file diff --git a/testweb/src/main/webapp/META-INF/MANIFEST.MF b/testweb/src/main/webapp/META-INF/MANIFEST.MF index 5e9495128c03..254272e1c074 100644 --- a/testweb/src/main/webapp/META-INF/MANIFEST.MF +++ b/testweb/src/main/webapp/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ -Manifest-Version: 1.0 -Class-Path: - +Manifest-Version: 1.0 +Class-Path: + diff --git a/testweb/src/main/webapp/WEB-INF/views/orm/ibatis.jsp b/testweb/src/main/webapp/WEB-INF/views/orm/ibatis.jsp index aecc0b2235aa..04b361f66d42 100644 --- a/testweb/src/main/webapp/WEB-INF/views/orm/ibatis.jsp +++ b/testweb/src/main/webapp/WEB-INF/views/orm/ibatis.jsp @@ -1,3 +1,3 @@ -<%@ page language="java" contentType="text/html; charset=EUC-KR" - pageEncoding="EUC-KR" %> -IBATIS +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8" %> +IBATIS diff --git a/testweb/src/main/webapp/WEB-INF/views/orm/mybatis.jsp b/testweb/src/main/webapp/WEB-INF/views/orm/mybatis.jsp index 3458e66ab2f7..f63acdae1da5 100644 --- a/testweb/src/main/webapp/WEB-INF/views/orm/mybatis.jsp +++ b/testweb/src/main/webapp/WEB-INF/views/orm/mybatis.jsp @@ -1,3 +1,3 @@ -<%@ page language="java" contentType="text/html; charset=EUC-KR" - pageEncoding="EUC-KR" %> -MYBATIS +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8" %> +MYBATIS diff --git a/testweb/src/main/webapp/WEB-INF/web.xml b/testweb/src/main/webapp/WEB-INF/web.xml index 3cbf84a8782b..1649f30d4057 100644 --- a/testweb/src/main/webapp/WEB-INF/web.xml +++ b/testweb/src/main/webapp/WEB-INF/web.xml @@ -1,69 +1,73 @@ - - - - - log4jConfigLocation - classpath:log4j.xml - - - - - contextConfigLocation - classpath:root-context.xml - - - - - org.springframework.web.context.ContextLoaderListener - - - - - - pinpoint-testweb - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - classpath:servlet-context.xml - - 1 - - - - - pinpoint-testweb - *.pinpoint - - - - encodingFilter - org.springframework.web.filter.CharacterEncodingFilter - - encoding - UTF-8 - - - - - encodingFilter - /* - - - - default - *.css - *.js - *.gif - *.png - *.ico - *.swf - *.html - + + + + + log4jConfigLocation + classpath:log4j.xml + + + + + contextConfigLocation + classpath:applicationContext-testweb.xml + + + + + org.springframework.web.context.ContextLoaderListener + + + + + + pinpoint-testweb + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + classpath:servlet-context.xml + + 1 + + + + + pinpoint-testweb + *.pinpoint + + + + encodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + + + encodingFilter + /* + + + + index.html + + + + default + *.css + *.js + *.gif + *.png + *.ico + *.swf + *.html + \ No newline at end of file diff --git a/testweb/src/main/webapp/index.html b/testweb/src/main/webapp/index.html index 58caf2b0306d..8a9f55b2b7a8 100644 --- a/testweb/src/main/webapp/index.html +++ b/testweb/src/main/webapp/index.html @@ -11,57 +11,6 @@ pinpoint Test web -
-
-
-/combination.pinpoint
-/mysql.pinpoint
- -/mysqlStatement.pinpoint 바인드 변수 + 상수값 파싱 로직테스트.
-/donothing.pinpoint
-/remotecombination.pinpoint
- -/httperror.pinpoint
- - -/remotecombination2.pinpoint
-/combination2.pinpoint
-

-oracle -
-/selectOne.pinpoint preparedStatement 테스트. resultset은 가지고 오지 않음.
-/createStatement.pinpoint statement 테스트. resultset은 가지고 오지 않음.
- -mysql -
-/selectOne.pinpoint preparedStatement 테스트. resultset은 가지고 오지 않음.
-/createStatement.pinpoint statement 테스트. resultset은 가지고 오지 않음.
-

- -arcus -
-/arcus
-

- -nestedcall test -
-/nested.pinpoint
-

- -/httpclient4 -
-/httpclient4/cookie.pinpoint 에러시 cookie덤프
-
-/httpclient4/post.pinpoint 에러시 post덤프
-

- - -/exceptionalcase/rootslow - -
-/exceptionalcase/rootslow.pinpoint root의 완료가 지연될경우 parent가 완료된 데이터를 정상적으로 확인가능지.
-
-

diff --git a/testweb/src/main/webapp/jsp.jsp b/testweb/src/main/webapp/jsp.jsp deleted file mode 100644 index 2226753c8d1b..000000000000 --- a/testweb/src/main/webapp/jsp.jsp +++ /dev/null @@ -1 +0,0 @@ -This is JSP. \ No newline at end of file diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/OracleErrorStackTraceCapture.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/OracleErrorStackTraceCapture.java index d3fdbe00f649..43229621d324 100644 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/OracleErrorStackTraceCapture.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/OracleErrorStackTraceCapture.java @@ -1,33 +1,33 @@ -package com.nhn.pinpoint.testweb; - -import oracle.jdbc.driver.OracleDriver; -import org.junit.Test; - -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Properties; - -/** - * - */ -public class OracleErrorStackTraceCapture { - -// @Test - public void errorConnect() throws SQLException { - String url = "jdbc:oracle:thin:@10.98.133.173:1725:INDEV"; - Properties properties = new Properties(); - - properties.setProperty("user", "lucy1"); - properties.setProperty("password", "lucy"); - - OracleDriver oracleDriver = new OracleDriver(); - - oracleDriver.connect(url, properties); - - -// DriverManager.getConnection(url, "lucy", "lucy"); - - - - } -} +package com.nhn.pinpoint.testweb; + +import oracle.jdbc.driver.OracleDriver; +import org.junit.Test; + +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +/** + * + */ +public class OracleErrorStackTraceCapture { + +// @Test + public void errorConnect() throws SQLException { + String url = "jdbc:oracle:thin:@10.98.133.173:1725:INDEV"; + Properties properties = new Properties(); + + properties.setProperty("user", "lucy1"); + properties.setProperty("password", "lucy"); + + OracleDriver oracleDriver = new OracleDriver(); + + oracleDriver.connect(url, properties); + + +// DriverManager.getConnection(url, "lucy", "lucy"); + + + + } +} diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtilTest.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtilTest.java index 009a759fc235..e80a25e3f038 100644 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtilTest.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/connector/apachehttp4/nhnent/HttpUtilTest.java @@ -1,6 +1,8 @@ package com.nhn.pinpoint.testweb.connector.apachehttp4.nhnent; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -8,18 +10,17 @@ * */ public class HttpUtilTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final String URL = "http://www.naver.com/"; @Test public void callUrl() { - String response = null; try { - response = HttpUtil.url(URL).method(HttpUtil.Method.POST).connectionTimeout(10000).readTimeout(10000).getContents(); + String response = HttpUtil.url(URL).method(HttpUtil.Method.POST).connectionTimeout(10000).readTimeout(10000).getContents(); + logger.debug(response); } catch (HttpUtilException e) { } - - System.out.println(response); } } diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/npc/NPCTest.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/npc/NPCTest.java index 9b8a966a2ce5..17be2fe3ede9 100644 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/npc/NPCTest.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/npc/NPCTest.java @@ -10,8 +10,12 @@ import com.nhncorp.lucy.net.invoker.InvocationFuture; import com.nhncorp.lucy.npc.connector.NpcHessianConnector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NPCTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Test public void connect() { @@ -29,7 +33,7 @@ public void connect() { // Object result = future.get(); Object result = future.getReturnValue(); - System.out.println(result); + logger.debug("{}", result); Assert.assertNotNull(result); } catch (Exception e) { e.printStackTrace(); diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatisTest.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatisTest.java index 53e6e4debf00..a75350796825 100755 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatisTest.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoIbatisTest.java @@ -1,49 +1,49 @@ -package com.nhn.pinpoint.testweb.repository; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; - -import java.util.Date; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.transaction.annotation.Transactional; - -import com.nhn.pinpoint.testweb.DBUnitSupport; -import com.nhn.pinpoint.testweb.domain.Member; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration({ "/root-context.xml", "/servlet-context.xml" }) -@Transactional -public class MemberDaoIbatisTest extends DBUnitSupport { - - @Autowired - MemberDaoIbatis memberDao; - - @Test - public void di() { - assertThat(memberDao, is(notNullValue())); - } - - @Test - public void crud() { - Member member = new Member(); - member.setId(1); - member.setName("netspider"); - member.setJoined(new Date()); - memberDao.add(member); - assertThat(memberDao.list().size(), is(1)); - - member.setName("chisu"); - memberDao.update(member); - assertThat(memberDao.get(1).getName(), is("chisu")); - - memberDao.delete(1); - assertThat(memberDao.list().size(), is(0)); - } - -} +package com.nhn.pinpoint.testweb.repository; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.util.Date; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import com.nhn.pinpoint.testweb.DBUnitSupport; +import com.nhn.pinpoint.testweb.domain.Member; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({"/applicationContext-testweb.xml", "/servlet-context.xml" }) +@Transactional +public class MemberDaoIbatisTest extends DBUnitSupport { + + @Autowired + MemberDaoIbatis memberDao; + + @Test + public void di() { + assertThat(memberDao, is(notNullValue())); + } + + @Test + public void crud() { + Member member = new Member(); + member.setId(1); + member.setName("netspider"); + member.setJoined(new Date()); + memberDao.add(member); + assertThat(memberDao.list().size(), is(1)); + + member.setName("chisu"); + memberDao.update(member); + assertThat(memberDao.get(1).getName(), is("chisu")); + + memberDao.delete(1); + assertThat(memberDao.list().size(), is(0)); + } + +} diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbcTest.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbcTest.java index 8c66d1e63095..4ad7bd8a9506 100755 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbcTest.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/repository/MemberDaoJdbcTest.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.testweb.repository; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; - -import java.util.Date; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.transaction.annotation.Transactional; - -import com.nhn.pinpoint.testweb.DBUnitSupport; -import com.nhn.pinpoint.testweb.domain.Member; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration({ "/root-context.xml", "/servlet-context.xml" }) -@Transactional -public class MemberDaoJdbcTest extends DBUnitSupport { - - @Autowired - MemberDaoJdbc memberDao; - - @Test - public void di() { - assertThat(memberDao, is(notNullValue())); - } - - @Test - public void crud() { - Member member = new Member(); - member.setId(1); - member.setName("netspider"); - member.setJoined(new Date()); - memberDao.add(member); - assertThat(memberDao.list().size(), is(1)); - - member.setName("chisu"); - memberDao.update(member); - assertThat(memberDao.get(1).getName(), is("chisu")); - - memberDao.delete(1); - assertThat(memberDao.list().size(), is(0)); - } - - @Test - public void searchByName() { - insertXmlData("/testData.xml"); - assertThat(memberDao.list().size(), is(2)); - } - -} +package com.nhn.pinpoint.testweb.repository; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.util.Date; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import com.nhn.pinpoint.testweb.DBUnitSupport; +import com.nhn.pinpoint.testweb.domain.Member; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({"/applicationContext-testweb.xml", "/servlet-context.xml" }) +@Transactional +public class MemberDaoJdbcTest extends DBUnitSupport { + + @Autowired + MemberDaoJdbc memberDao; + + @Test + public void di() { + assertThat(memberDao, is(notNullValue())); + } + + @Test + public void crud() { + Member member = new Member(); + member.setId(1); + member.setName("netspider"); + member.setJoined(new Date()); + memberDao.add(member); + assertThat(memberDao.list().size(), is(1)); + + member.setName("chisu"); + memberDao.update(member); + assertThat(memberDao.get(1).getName(), is("chisu")); + + memberDao.delete(1); + assertThat(memberDao.list().size(), is(0)); + } + + @Test + public void searchByName() { + insertXmlData("/testData.xml"); + assertThat(memberDao.list().size(), is(2)); + } + +} diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/service/MemberServiceImplTest.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/service/MemberServiceImplTest.java index 2fcf62014df4..05aa095d2092 100755 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/service/MemberServiceImplTest.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/service/MemberServiceImplTest.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.testweb.service; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.verify; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import com.nhn.pinpoint.testweb.domain.Member; -import com.nhn.pinpoint.testweb.repository.MemberDao; - -@RunWith(MockitoJUnitRunner.class) -public class MemberServiceImplTest { - - MemberServiceImpl memberService; - @Mock - MemberDao dao; - - @Before - public void setUp() { - memberService = new MemberServiceImpl(); - memberService.setDao(dao); - } - - @Test - public void mockup() { - assertThat(memberService.getDao(), is(notNullValue())); - } - - /** - * http://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito - * .html - */ - @Test - public void add() { - Member member = new Member(); - member.setId(1); - member.setName("keesun"); - memberService.add(member); - verify(dao).add(member); - } - -} +package com.nhn.pinpoint.testweb.service; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.nhn.pinpoint.testweb.domain.Member; +import com.nhn.pinpoint.testweb.repository.MemberDao; + +@RunWith(MockitoJUnitRunner.class) +public class MemberServiceImplTest { + + MemberServiceImpl memberService; + @Mock + MemberDao dao; + + @Before + public void setUp() { + memberService = new MemberServiceImpl(); + memberService.setDao(dao); + } + + @Test + public void mockup() { + assertThat(memberService.getDao(), is(notNullValue())); + } + + /** + * http://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito + * .html + */ + @Test + public void add() { + Member member = new Member(); + member.setId(1); + member.setName("keesun"); + memberService.add(member); + verify(dao).add(member); + } + +} diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/service/http/ApacheClosableAsyncHttpClientTest.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/service/http/ApacheClosableAsyncHttpClientTest.java index 99d54ad98880..63e8a6a97862 100644 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/service/http/ApacheClosableAsyncHttpClientTest.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/service/http/ApacheClosableAsyncHttpClientTest.java @@ -2,6 +2,8 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -14,8 +16,9 @@ * */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration({ "/root-context.xml", "/servlet-context.xml" }) +@ContextConfiguration({"/applicationContext-testweb.xml", "/servlet-context.xml" }) public class ApacheClosableAsyncHttpClientTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private ApacheClosableAsyncHttpClient apacheClosableAsyncHttpClient; @@ -23,6 +26,6 @@ public class ApacheClosableAsyncHttpClientTest { @Test public void requestPost() { String requestPost = apacheClosableAsyncHttpClient.post(); - System.out.println(requestPost); + logger.debug(requestPost); } } \ No newline at end of file diff --git a/testweb/src/test/java/com/nhn/pinpoint/testweb/util/HTClientTest.java b/testweb/src/test/java/com/nhn/pinpoint/testweb/util/HTClientTest.java index 6370c69f6f50..3d3226f9ef9b 100644 --- a/testweb/src/test/java/com/nhn/pinpoint/testweb/util/HTClientTest.java +++ b/testweb/src/test/java/com/nhn/pinpoint/testweb/util/HTClientTest.java @@ -6,14 +6,18 @@ import com.nhn.pinpoint.testweb.connector.apachehttp4.HttpConnectorOptions; import com.nhn.pinpoint.testweb.connector.apachehttp4.ApacheHttpClient4; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HTClientTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Test public void test() { ApacheHttpClient4 client = new ApacheHttpClient4(new HttpConnectorOptions()); String executeToBloc = client.execute("http://localhost:9080/", new HashMap()); - System.out.println(executeToBloc); + logger.debug(executeToBloc); } } diff --git a/testweb/src/test/resources/testData.xml b/testweb/src/test/resources/testData.xml index 04d00c41bb41..4bc4c9ef3dda 100755 --- a/testweb/src/test/resources/testData.xml +++ b/testweb/src/test/resources/testData.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/thrift/build.xml b/thrift/build.xml index bd02c6303781..573710a22a93 100644 --- a/thrift/build.xml +++ b/thrift/build.xml @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/thrift/findbugs-exclude.xml b/thrift/findbugs-exclude.xml index a4b4e8251d57..0193409a64e7 100644 --- a/thrift/findbugs-exclude.xml +++ b/thrift/findbugs-exclude.xml @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/thrift/pom.xml b/thrift/pom.xml index be2ee6bc05c7..7b6f5a616c7d 100644 --- a/thrift/pom.xml +++ b/thrift/pom.xml @@ -1,210 +1,210 @@ - - 4.0.0 - - com.nhn.pinpoint - pom - 1.0.3-SNAPSHOT - - - pinpoint-thrift - pinpoint-thrift - jar - - - - org.apache.thrift - libthrift - true - - - org.apache.httpcomponents - httpclient - - - org.apache.httpcomponents - httpcore - - - org.slf4j - slf4j-api - - - - - - - - org.slf4j - slf4j-api - true - - - - org.slf4j - jcl-over-slf4j - test - - - org.slf4j - slf4j-log4j12 - test - - - log4j - log4j - test - - - - - - - - - ${basedir}/src/main/java - - **/*.java - - - - true - ${basedir}/src/main/resources - - - - - - ${basedir}/src/test/java - - **/*.java - - - - true - ${basedir}/src/test/resources - - - - - - maven-resources-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - - - - - - org.codehaus.mojo - findbugs-maven-plugin - - - com.atlassian.maven.plugins - maven-clover2-plugin - - - - - - - with-thrift - - ${thrift.executable} - - - - - maven-antrun-plugin - 1.7 - - - generate-sources - generate-sources - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - run - - - - - - - - - klocwork - - - - com.klocwork.ps - kwmaven - - - - - - + + 4.0.0 + + com.nhn.pinpoint + pom + 1.0.3-SNAPSHOT + + + pinpoint-thrift + pinpoint-thrift + jar + + + + org.apache.thrift + libthrift + true + + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpcore + + + org.slf4j + slf4j-api + + + + + + + + org.slf4j + slf4j-api + true + + + + org.slf4j + jcl-over-slf4j + test + + + org.slf4j + slf4j-log4j12 + test + + + log4j + log4j + test + + + + + + + + + ${basedir}/src/main/java + + **/*.java + + + + true + ${basedir}/src/main/resources + + + + + + ${basedir}/src/test/java + + **/*.java + + + + true + ${basedir}/src/test/resources + + + + + + maven-resources-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + + + + + org.codehaus.mojo + findbugs-maven-plugin + + + com.atlassian.maven.plugins + maven-clover2-plugin + + + + + + + with-thrift + + ${thrift.executable} + + + + + maven-antrun-plugin + 1.7 + + + generate-sources + generate-sources + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + run + + + + + + + + + klocwork + + + + com.klocwork.ps + kwmaven + + + + + + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentInfo.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentInfo.java index cbe7487c98a5..8fb4ca7f4580 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentInfo.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentInfo.java @@ -1,1352 +1,1352 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TAgentInfo implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAgentInfo"); - - private static final org.apache.thrift.protocol.TField HOSTNAME_FIELD_DESC = new org.apache.thrift.protocol.TField("hostname", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField IP_FIELD_DESC = new org.apache.thrift.protocol.TField("ip", org.apache.thrift.protocol.TType.STRING, (short)2); - private static final org.apache.thrift.protocol.TField PORTS_FIELD_DESC = new org.apache.thrift.protocol.TField("ports", org.apache.thrift.protocol.TType.STRING, (short)3); - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)4); - private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)5); - private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)6); - private static final org.apache.thrift.protocol.TField PID_FIELD_DESC = new org.apache.thrift.protocol.TField("pid", org.apache.thrift.protocol.TType.I32, (short)7); - private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.STRING, (short)8); - private static final org.apache.thrift.protocol.TField START_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("startTimestamp", org.apache.thrift.protocol.TType.I64, (short)10); - private static final org.apache.thrift.protocol.TField END_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("endTimestamp", org.apache.thrift.protocol.TType.I64, (short)11); - private static final org.apache.thrift.protocol.TField END_STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("endStatus", org.apache.thrift.protocol.TType.I32, (short)12); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TAgentInfoStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TAgentInfoTupleSchemeFactory()); - } - - private String hostname; // required - private String ip; // required - private String ports; // required - private String agentId; // required - private String applicationName; // required - private short serviceType; // required - private int pid; // required - private String version; // required - private long startTimestamp; // required - private long endTimestamp; // optional - private int endStatus; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - HOSTNAME((short)1, "hostname"), - IP((short)2, "ip"), - PORTS((short)3, "ports"), - AGENT_ID((short)4, "agentId"), - APPLICATION_NAME((short)5, "applicationName"), - SERVICE_TYPE((short)6, "serviceType"), - PID((short)7, "pid"), - VERSION((short)8, "version"), - START_TIMESTAMP((short)10, "startTimestamp"), - END_TIMESTAMP((short)11, "endTimestamp"), - END_STATUS((short)12, "endStatus"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // HOSTNAME - return HOSTNAME; - case 2: // IP - return IP; - case 3: // PORTS - return PORTS; - case 4: // AGENT_ID - return AGENT_ID; - case 5: // APPLICATION_NAME - return APPLICATION_NAME; - case 6: // SERVICE_TYPE - return SERVICE_TYPE; - case 7: // PID - return PID; - case 8: // VERSION - return VERSION; - case 10: // START_TIMESTAMP - return START_TIMESTAMP; - case 11: // END_TIMESTAMP - return END_TIMESTAMP; - case 12: // END_STATUS - return END_STATUS; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __SERVICETYPE_ISSET_ID = 0; - private static final int __PID_ISSET_ID = 1; - private static final int __STARTTIMESTAMP_ISSET_ID = 2; - private static final int __ENDTIMESTAMP_ISSET_ID = 3; - private static final int __ENDSTATUS_ISSET_ID = 4; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.END_TIMESTAMP,_Fields.END_STATUS}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.HOSTNAME, new org.apache.thrift.meta_data.FieldMetaData("hostname", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.IP, new org.apache.thrift.meta_data.FieldMetaData("ip", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.PORTS, new org.apache.thrift.meta_data.FieldMetaData("ports", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.PID, new org.apache.thrift.meta_data.FieldMetaData("pid", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.START_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("startTimestamp", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.END_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("endTimestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.END_STATUS, new org.apache.thrift.meta_data.FieldMetaData("endStatus", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAgentInfo.class, metaDataMap); - } - - public TAgentInfo() { - } - - public TAgentInfo( - String hostname, - String ip, - String ports, - String agentId, - String applicationName, - short serviceType, - int pid, - String version, - long startTimestamp) - { - this(); - this.hostname = hostname; - this.ip = ip; - this.ports = ports; - this.agentId = agentId; - this.applicationName = applicationName; - this.serviceType = serviceType; - setServiceTypeIsSet(true); - this.pid = pid; - setPidIsSet(true); - this.version = version; - this.startTimestamp = startTimestamp; - setStartTimestampIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TAgentInfo(TAgentInfo other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetHostname()) { - this.hostname = other.hostname; - } - if (other.isSetIp()) { - this.ip = other.ip; - } - if (other.isSetPorts()) { - this.ports = other.ports; - } - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - if (other.isSetApplicationName()) { - this.applicationName = other.applicationName; - } - this.serviceType = other.serviceType; - this.pid = other.pid; - if (other.isSetVersion()) { - this.version = other.version; - } - this.startTimestamp = other.startTimestamp; - this.endTimestamp = other.endTimestamp; - this.endStatus = other.endStatus; - } - - public TAgentInfo deepCopy() { - return new TAgentInfo(this); - } - - @Override - public void clear() { - this.hostname = null; - this.ip = null; - this.ports = null; - this.agentId = null; - this.applicationName = null; - setServiceTypeIsSet(false); - this.serviceType = 0; - setPidIsSet(false); - this.pid = 0; - this.version = null; - setStartTimestampIsSet(false); - this.startTimestamp = 0; - setEndTimestampIsSet(false); - this.endTimestamp = 0; - setEndStatusIsSet(false); - this.endStatus = 0; - } - - public String getHostname() { - return this.hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public void unsetHostname() { - this.hostname = null; - } - - /** Returns true if field hostname is set (has been assigned a value) and false otherwise */ - public boolean isSetHostname() { - return this.hostname != null; - } - - public void setHostnameIsSet(boolean value) { - if (!value) { - this.hostname = null; - } - } - - public String getIp() { - return this.ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public void unsetIp() { - this.ip = null; - } - - /** Returns true if field ip is set (has been assigned a value) and false otherwise */ - public boolean isSetIp() { - return this.ip != null; - } - - public void setIpIsSet(boolean value) { - if (!value) { - this.ip = null; - } - } - - public String getPorts() { - return this.ports; - } - - public void setPorts(String ports) { - this.ports = ports; - } - - public void unsetPorts() { - this.ports = null; - } - - /** Returns true if field ports is set (has been assigned a value) and false otherwise */ - public boolean isSetPorts() { - return this.ports != null; - } - - public void setPortsIsSet(boolean value) { - if (!value) { - this.ports = null; - } - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public String getApplicationName() { - return this.applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public void unsetApplicationName() { - this.applicationName = null; - } - - /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ - public boolean isSetApplicationName() { - return this.applicationName != null; - } - - public void setApplicationNameIsSet(boolean value) { - if (!value) { - this.applicationName = null; - } - } - - public short getServiceType() { - return this.serviceType; - } - - public void setServiceType(short serviceType) { - this.serviceType = serviceType; - setServiceTypeIsSet(true); - } - - public void unsetServiceType() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ - public boolean isSetServiceType() { - return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - public void setServiceTypeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); - } - - public int getPid() { - return this.pid; - } - - public void setPid(int pid) { - this.pid = pid; - setPidIsSet(true); - } - - public void unsetPid() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PID_ISSET_ID); - } - - /** Returns true if field pid is set (has been assigned a value) and false otherwise */ - public boolean isSetPid() { - return EncodingUtils.testBit(__isset_bitfield, __PID_ISSET_ID); - } - - public void setPidIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PID_ISSET_ID, value); - } - - public String getVersion() { - return this.version; - } - - public void setVersion(String version) { - this.version = version; - } - - public void unsetVersion() { - this.version = null; - } - - /** Returns true if field version is set (has been assigned a value) and false otherwise */ - public boolean isSetVersion() { - return this.version != null; - } - - public void setVersionIsSet(boolean value) { - if (!value) { - this.version = null; - } - } - - public long getStartTimestamp() { - return this.startTimestamp; - } - - public void setStartTimestamp(long startTimestamp) { - this.startTimestamp = startTimestamp; - setStartTimestampIsSet(true); - } - - public void unsetStartTimestamp() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); - } - - /** Returns true if field startTimestamp is set (has been assigned a value) and false otherwise */ - public boolean isSetStartTimestamp() { - return EncodingUtils.testBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); - } - - public void setStartTimestampIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID, value); - } - - public long getEndTimestamp() { - return this.endTimestamp; - } - - public void setEndTimestamp(long endTimestamp) { - this.endTimestamp = endTimestamp; - setEndTimestampIsSet(true); - } - - public void unsetEndTimestamp() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENDTIMESTAMP_ISSET_ID); - } - - /** Returns true if field endTimestamp is set (has been assigned a value) and false otherwise */ - public boolean isSetEndTimestamp() { - return EncodingUtils.testBit(__isset_bitfield, __ENDTIMESTAMP_ISSET_ID); - } - - public void setEndTimestampIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENDTIMESTAMP_ISSET_ID, value); - } - - public int getEndStatus() { - return this.endStatus; - } - - public void setEndStatus(int endStatus) { - this.endStatus = endStatus; - setEndStatusIsSet(true); - } - - public void unsetEndStatus() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENDSTATUS_ISSET_ID); - } - - /** Returns true if field endStatus is set (has been assigned a value) and false otherwise */ - public boolean isSetEndStatus() { - return EncodingUtils.testBit(__isset_bitfield, __ENDSTATUS_ISSET_ID); - } - - public void setEndStatusIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENDSTATUS_ISSET_ID, value); - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case HOSTNAME: - if (value == null) { - unsetHostname(); - } else { - setHostname((String)value); - } - break; - - case IP: - if (value == null) { - unsetIp(); - } else { - setIp((String)value); - } - break; - - case PORTS: - if (value == null) { - unsetPorts(); - } else { - setPorts((String)value); - } - break; - - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case APPLICATION_NAME: - if (value == null) { - unsetApplicationName(); - } else { - setApplicationName((String)value); - } - break; - - case SERVICE_TYPE: - if (value == null) { - unsetServiceType(); - } else { - setServiceType((Short)value); - } - break; - - case PID: - if (value == null) { - unsetPid(); - } else { - setPid((Integer)value); - } - break; - - case VERSION: - if (value == null) { - unsetVersion(); - } else { - setVersion((String)value); - } - break; - - case START_TIMESTAMP: - if (value == null) { - unsetStartTimestamp(); - } else { - setStartTimestamp((Long)value); - } - break; - - case END_TIMESTAMP: - if (value == null) { - unsetEndTimestamp(); - } else { - setEndTimestamp((Long)value); - } - break; - - case END_STATUS: - if (value == null) { - unsetEndStatus(); - } else { - setEndStatus((Integer)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case HOSTNAME: - return getHostname(); - - case IP: - return getIp(); - - case PORTS: - return getPorts(); - - case AGENT_ID: - return getAgentId(); - - case APPLICATION_NAME: - return getApplicationName(); - - case SERVICE_TYPE: - return Short.valueOf(getServiceType()); - - case PID: - return Integer.valueOf(getPid()); - - case VERSION: - return getVersion(); - - case START_TIMESTAMP: - return Long.valueOf(getStartTimestamp()); - - case END_TIMESTAMP: - return Long.valueOf(getEndTimestamp()); - - case END_STATUS: - return Integer.valueOf(getEndStatus()); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case HOSTNAME: - return isSetHostname(); - case IP: - return isSetIp(); - case PORTS: - return isSetPorts(); - case AGENT_ID: - return isSetAgentId(); - case APPLICATION_NAME: - return isSetApplicationName(); - case SERVICE_TYPE: - return isSetServiceType(); - case PID: - return isSetPid(); - case VERSION: - return isSetVersion(); - case START_TIMESTAMP: - return isSetStartTimestamp(); - case END_TIMESTAMP: - return isSetEndTimestamp(); - case END_STATUS: - return isSetEndStatus(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TAgentInfo) - return this.equals((TAgentInfo)that); - return false; - } - - public boolean equals(TAgentInfo that) { - if (that == null) - return false; - - boolean this_present_hostname = true && this.isSetHostname(); - boolean that_present_hostname = true && that.isSetHostname(); - if (this_present_hostname || that_present_hostname) { - if (!(this_present_hostname && that_present_hostname)) - return false; - if (!this.hostname.equals(that.hostname)) - return false; - } - - boolean this_present_ip = true && this.isSetIp(); - boolean that_present_ip = true && that.isSetIp(); - if (this_present_ip || that_present_ip) { - if (!(this_present_ip && that_present_ip)) - return false; - if (!this.ip.equals(that.ip)) - return false; - } - - boolean this_present_ports = true && this.isSetPorts(); - boolean that_present_ports = true && that.isSetPorts(); - if (this_present_ports || that_present_ports) { - if (!(this_present_ports && that_present_ports)) - return false; - if (!this.ports.equals(that.ports)) - return false; - } - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_applicationName = true && this.isSetApplicationName(); - boolean that_present_applicationName = true && that.isSetApplicationName(); - if (this_present_applicationName || that_present_applicationName) { - if (!(this_present_applicationName && that_present_applicationName)) - return false; - if (!this.applicationName.equals(that.applicationName)) - return false; - } - - boolean this_present_serviceType = true; - boolean that_present_serviceType = true; - if (this_present_serviceType || that_present_serviceType) { - if (!(this_present_serviceType && that_present_serviceType)) - return false; - if (this.serviceType != that.serviceType) - return false; - } - - boolean this_present_pid = true; - boolean that_present_pid = true; - if (this_present_pid || that_present_pid) { - if (!(this_present_pid && that_present_pid)) - return false; - if (this.pid != that.pid) - return false; - } - - boolean this_present_version = true && this.isSetVersion(); - boolean that_present_version = true && that.isSetVersion(); - if (this_present_version || that_present_version) { - if (!(this_present_version && that_present_version)) - return false; - if (!this.version.equals(that.version)) - return false; - } - - boolean this_present_startTimestamp = true; - boolean that_present_startTimestamp = true; - if (this_present_startTimestamp || that_present_startTimestamp) { - if (!(this_present_startTimestamp && that_present_startTimestamp)) - return false; - if (this.startTimestamp != that.startTimestamp) - return false; - } - - boolean this_present_endTimestamp = true && this.isSetEndTimestamp(); - boolean that_present_endTimestamp = true && that.isSetEndTimestamp(); - if (this_present_endTimestamp || that_present_endTimestamp) { - if (!(this_present_endTimestamp && that_present_endTimestamp)) - return false; - if (this.endTimestamp != that.endTimestamp) - return false; - } - - boolean this_present_endStatus = true && this.isSetEndStatus(); - boolean that_present_endStatus = true && that.isSetEndStatus(); - if (this_present_endStatus || that_present_endStatus) { - if (!(this_present_endStatus && that_present_endStatus)) - return false; - if (this.endStatus != that.endStatus) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TAgentInfo other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetHostname()).compareTo(other.isSetHostname()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetHostname()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.hostname, other.hostname); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetIp()).compareTo(other.isSetIp()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetIp()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ip, other.ip); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetPorts()).compareTo(other.isSetPorts()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetPorts()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ports, other.ports); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetApplicationName()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetServiceType()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetPid()).compareTo(other.isSetPid()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetPid()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pid, other.pid); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetVersion()).compareTo(other.isSetVersion()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetVersion()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, other.version); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStartTimestamp()).compareTo(other.isSetStartTimestamp()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStartTimestamp()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTimestamp, other.startTimestamp); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetEndTimestamp()).compareTo(other.isSetEndTimestamp()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetEndTimestamp()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endTimestamp, other.endTimestamp); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetEndStatus()).compareTo(other.isSetEndStatus()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetEndStatus()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endStatus, other.endStatus); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TAgentInfo("); - boolean first = true; - - sb.append("hostname:"); - if (this.hostname == null) { - sb.append("null"); - } else { - sb.append(this.hostname); - } - first = false; - if (!first) sb.append(", "); - sb.append("ip:"); - if (this.ip == null) { - sb.append("null"); - } else { - sb.append(this.ip); - } - first = false; - if (!first) sb.append(", "); - sb.append("ports:"); - if (this.ports == null) { - sb.append("null"); - } else { - sb.append(this.ports); - } - first = false; - if (!first) sb.append(", "); - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - if (!first) sb.append(", "); - sb.append("applicationName:"); - if (this.applicationName == null) { - sb.append("null"); - } else { - sb.append(this.applicationName); - } - first = false; - if (!first) sb.append(", "); - sb.append("serviceType:"); - sb.append(this.serviceType); - first = false; - if (!first) sb.append(", "); - sb.append("pid:"); - sb.append(this.pid); - first = false; - if (!first) sb.append(", "); - sb.append("version:"); - if (this.version == null) { - sb.append("null"); - } else { - sb.append(this.version); - } - first = false; - if (!first) sb.append(", "); - sb.append("startTimestamp:"); - sb.append(this.startTimestamp); - first = false; - if (isSetEndTimestamp()) { - if (!first) sb.append(", "); - sb.append("endTimestamp:"); - sb.append(this.endTimestamp); - first = false; - } - if (isSetEndStatus()) { - if (!first) sb.append(", "); - sb.append("endStatus:"); - sb.append(this.endStatus); - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TAgentInfoStandardSchemeFactory implements SchemeFactory { - public TAgentInfoStandardScheme getScheme() { - return new TAgentInfoStandardScheme(); - } - } - - private static class TAgentInfoStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TAgentInfo struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // HOSTNAME - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.hostname = iprot.readString(); - struct.setHostnameIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // IP - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.ip = iprot.readString(); - struct.setIpIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // PORTS - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.ports = iprot.readString(); - struct.setPortsIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 4: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 5: // APPLICATION_NAME - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.applicationName = iprot.readString(); - struct.setApplicationNameIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 6: // SERVICE_TYPE - if (schemeField.type == org.apache.thrift.protocol.TType.I16) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 7: // PID - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.pid = iprot.readI32(); - struct.setPidIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 8: // VERSION - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.version = iprot.readString(); - struct.setVersionIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 10: // START_TIMESTAMP - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.startTimestamp = iprot.readI64(); - struct.setStartTimestampIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 11: // END_TIMESTAMP - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.endTimestamp = iprot.readI64(); - struct.setEndTimestampIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 12: // END_STATUS - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.endStatus = iprot.readI32(); - struct.setEndStatusIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TAgentInfo struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.hostname != null) { - oprot.writeFieldBegin(HOSTNAME_FIELD_DESC); - oprot.writeString(struct.hostname); - oprot.writeFieldEnd(); - } - if (struct.ip != null) { - oprot.writeFieldBegin(IP_FIELD_DESC); - oprot.writeString(struct.ip); - oprot.writeFieldEnd(); - } - if (struct.ports != null) { - oprot.writeFieldBegin(PORTS_FIELD_DESC); - oprot.writeString(struct.ports); - oprot.writeFieldEnd(); - } - if (struct.agentId != null) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - if (struct.applicationName != null) { - oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); - oprot.writeString(struct.applicationName); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); - oprot.writeI16(struct.serviceType); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(PID_FIELD_DESC); - oprot.writeI32(struct.pid); - oprot.writeFieldEnd(); - if (struct.version != null) { - oprot.writeFieldBegin(VERSION_FIELD_DESC); - oprot.writeString(struct.version); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(START_TIMESTAMP_FIELD_DESC); - oprot.writeI64(struct.startTimestamp); - oprot.writeFieldEnd(); - if (struct.isSetEndTimestamp()) { - oprot.writeFieldBegin(END_TIMESTAMP_FIELD_DESC); - oprot.writeI64(struct.endTimestamp); - oprot.writeFieldEnd(); - } - if (struct.isSetEndStatus()) { - oprot.writeFieldBegin(END_STATUS_FIELD_DESC); - oprot.writeI32(struct.endStatus); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TAgentInfoTupleSchemeFactory implements SchemeFactory { - public TAgentInfoTupleScheme getScheme() { - return new TAgentInfoTupleScheme(); - } - } - - private static class TAgentInfoTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TAgentInfo struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetHostname()) { - optionals.set(0); - } - if (struct.isSetIp()) { - optionals.set(1); - } - if (struct.isSetPorts()) { - optionals.set(2); - } - if (struct.isSetAgentId()) { - optionals.set(3); - } - if (struct.isSetApplicationName()) { - optionals.set(4); - } - if (struct.isSetServiceType()) { - optionals.set(5); - } - if (struct.isSetPid()) { - optionals.set(6); - } - if (struct.isSetVersion()) { - optionals.set(7); - } - if (struct.isSetStartTimestamp()) { - optionals.set(8); - } - if (struct.isSetEndTimestamp()) { - optionals.set(9); - } - if (struct.isSetEndStatus()) { - optionals.set(10); - } - oprot.writeBitSet(optionals, 11); - if (struct.isSetHostname()) { - oprot.writeString(struct.hostname); - } - if (struct.isSetIp()) { - oprot.writeString(struct.ip); - } - if (struct.isSetPorts()) { - oprot.writeString(struct.ports); - } - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetApplicationName()) { - oprot.writeString(struct.applicationName); - } - if (struct.isSetServiceType()) { - oprot.writeI16(struct.serviceType); - } - if (struct.isSetPid()) { - oprot.writeI32(struct.pid); - } - if (struct.isSetVersion()) { - oprot.writeString(struct.version); - } - if (struct.isSetStartTimestamp()) { - oprot.writeI64(struct.startTimestamp); - } - if (struct.isSetEndTimestamp()) { - oprot.writeI64(struct.endTimestamp); - } - if (struct.isSetEndStatus()) { - oprot.writeI32(struct.endStatus); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TAgentInfo struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(11); - if (incoming.get(0)) { - struct.hostname = iprot.readString(); - struct.setHostnameIsSet(true); - } - if (incoming.get(1)) { - struct.ip = iprot.readString(); - struct.setIpIsSet(true); - } - if (incoming.get(2)) { - struct.ports = iprot.readString(); - struct.setPortsIsSet(true); - } - if (incoming.get(3)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(4)) { - struct.applicationName = iprot.readString(); - struct.setApplicationNameIsSet(true); - } - if (incoming.get(5)) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } - if (incoming.get(6)) { - struct.pid = iprot.readI32(); - struct.setPidIsSet(true); - } - if (incoming.get(7)) { - struct.version = iprot.readString(); - struct.setVersionIsSet(true); - } - if (incoming.get(8)) { - struct.startTimestamp = iprot.readI64(); - struct.setStartTimestampIsSet(true); - } - if (incoming.get(9)) { - struct.endTimestamp = iprot.readI64(); - struct.setEndTimestampIsSet(true); - } - if (incoming.get(10)) { - struct.endStatus = iprot.readI32(); - struct.setEndStatusIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TAgentInfo implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAgentInfo"); + + private static final org.apache.thrift.protocol.TField HOSTNAME_FIELD_DESC = new org.apache.thrift.protocol.TField("hostname", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField IP_FIELD_DESC = new org.apache.thrift.protocol.TField("ip", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField PORTS_FIELD_DESC = new org.apache.thrift.protocol.TField("ports", org.apache.thrift.protocol.TType.STRING, (short)3); + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)4); + private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)5); + private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)6); + private static final org.apache.thrift.protocol.TField PID_FIELD_DESC = new org.apache.thrift.protocol.TField("pid", org.apache.thrift.protocol.TType.I32, (short)7); + private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.STRING, (short)8); + private static final org.apache.thrift.protocol.TField START_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("startTimestamp", org.apache.thrift.protocol.TType.I64, (short)10); + private static final org.apache.thrift.protocol.TField END_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("endTimestamp", org.apache.thrift.protocol.TType.I64, (short)11); + private static final org.apache.thrift.protocol.TField END_STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("endStatus", org.apache.thrift.protocol.TType.I32, (short)12); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TAgentInfoStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TAgentInfoTupleSchemeFactory()); + } + + private String hostname; // required + private String ip; // required + private String ports; // required + private String agentId; // required + private String applicationName; // required + private short serviceType; // required + private int pid; // required + private String version; // required + private long startTimestamp; // required + private long endTimestamp; // optional + private int endStatus; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HOSTNAME((short)1, "hostname"), + IP((short)2, "ip"), + PORTS((short)3, "ports"), + AGENT_ID((short)4, "agentId"), + APPLICATION_NAME((short)5, "applicationName"), + SERVICE_TYPE((short)6, "serviceType"), + PID((short)7, "pid"), + VERSION((short)8, "version"), + START_TIMESTAMP((short)10, "startTimestamp"), + END_TIMESTAMP((short)11, "endTimestamp"), + END_STATUS((short)12, "endStatus"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HOSTNAME + return HOSTNAME; + case 2: // IP + return IP; + case 3: // PORTS + return PORTS; + case 4: // AGENT_ID + return AGENT_ID; + case 5: // APPLICATION_NAME + return APPLICATION_NAME; + case 6: // SERVICE_TYPE + return SERVICE_TYPE; + case 7: // PID + return PID; + case 8: // VERSION + return VERSION; + case 10: // START_TIMESTAMP + return START_TIMESTAMP; + case 11: // END_TIMESTAMP + return END_TIMESTAMP; + case 12: // END_STATUS + return END_STATUS; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __SERVICETYPE_ISSET_ID = 0; + private static final int __PID_ISSET_ID = 1; + private static final int __STARTTIMESTAMP_ISSET_ID = 2; + private static final int __ENDTIMESTAMP_ISSET_ID = 3; + private static final int __ENDSTATUS_ISSET_ID = 4; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.END_TIMESTAMP,_Fields.END_STATUS}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HOSTNAME, new org.apache.thrift.meta_data.FieldMetaData("hostname", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.IP, new org.apache.thrift.meta_data.FieldMetaData("ip", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.PORTS, new org.apache.thrift.meta_data.FieldMetaData("ports", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.PID, new org.apache.thrift.meta_data.FieldMetaData("pid", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.START_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("startTimestamp", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.END_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("endTimestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.END_STATUS, new org.apache.thrift.meta_data.FieldMetaData("endStatus", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAgentInfo.class, metaDataMap); + } + + public TAgentInfo() { + } + + public TAgentInfo( + String hostname, + String ip, + String ports, + String agentId, + String applicationName, + short serviceType, + int pid, + String version, + long startTimestamp) + { + this(); + this.hostname = hostname; + this.ip = ip; + this.ports = ports; + this.agentId = agentId; + this.applicationName = applicationName; + this.serviceType = serviceType; + setServiceTypeIsSet(true); + this.pid = pid; + setPidIsSet(true); + this.version = version; + this.startTimestamp = startTimestamp; + setStartTimestampIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TAgentInfo(TAgentInfo other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetHostname()) { + this.hostname = other.hostname; + } + if (other.isSetIp()) { + this.ip = other.ip; + } + if (other.isSetPorts()) { + this.ports = other.ports; + } + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + if (other.isSetApplicationName()) { + this.applicationName = other.applicationName; + } + this.serviceType = other.serviceType; + this.pid = other.pid; + if (other.isSetVersion()) { + this.version = other.version; + } + this.startTimestamp = other.startTimestamp; + this.endTimestamp = other.endTimestamp; + this.endStatus = other.endStatus; + } + + public TAgentInfo deepCopy() { + return new TAgentInfo(this); + } + + @Override + public void clear() { + this.hostname = null; + this.ip = null; + this.ports = null; + this.agentId = null; + this.applicationName = null; + setServiceTypeIsSet(false); + this.serviceType = 0; + setPidIsSet(false); + this.pid = 0; + this.version = null; + setStartTimestampIsSet(false); + this.startTimestamp = 0; + setEndTimestampIsSet(false); + this.endTimestamp = 0; + setEndStatusIsSet(false); + this.endStatus = 0; + } + + public String getHostname() { + return this.hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public void unsetHostname() { + this.hostname = null; + } + + /** Returns true if field hostname is set (has been assigned a value) and false otherwise */ + public boolean isSetHostname() { + return this.hostname != null; + } + + public void setHostnameIsSet(boolean value) { + if (!value) { + this.hostname = null; + } + } + + public String getIp() { + return this.ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public void unsetIp() { + this.ip = null; + } + + /** Returns true if field ip is set (has been assigned a value) and false otherwise */ + public boolean isSetIp() { + return this.ip != null; + } + + public void setIpIsSet(boolean value) { + if (!value) { + this.ip = null; + } + } + + public String getPorts() { + return this.ports; + } + + public void setPorts(String ports) { + this.ports = ports; + } + + public void unsetPorts() { + this.ports = null; + } + + /** Returns true if field ports is set (has been assigned a value) and false otherwise */ + public boolean isSetPorts() { + return this.ports != null; + } + + public void setPortsIsSet(boolean value) { + if (!value) { + this.ports = null; + } + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public String getApplicationName() { + return this.applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public void unsetApplicationName() { + this.applicationName = null; + } + + /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ + public boolean isSetApplicationName() { + return this.applicationName != null; + } + + public void setApplicationNameIsSet(boolean value) { + if (!value) { + this.applicationName = null; + } + } + + public short getServiceType() { + return this.serviceType; + } + + public void setServiceType(short serviceType) { + this.serviceType = serviceType; + setServiceTypeIsSet(true); + } + + public void unsetServiceType() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ + public boolean isSetServiceType() { + return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + public void setServiceTypeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); + } + + public int getPid() { + return this.pid; + } + + public void setPid(int pid) { + this.pid = pid; + setPidIsSet(true); + } + + public void unsetPid() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PID_ISSET_ID); + } + + /** Returns true if field pid is set (has been assigned a value) and false otherwise */ + public boolean isSetPid() { + return EncodingUtils.testBit(__isset_bitfield, __PID_ISSET_ID); + } + + public void setPidIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PID_ISSET_ID, value); + } + + public String getVersion() { + return this.version; + } + + public void setVersion(String version) { + this.version = version; + } + + public void unsetVersion() { + this.version = null; + } + + /** Returns true if field version is set (has been assigned a value) and false otherwise */ + public boolean isSetVersion() { + return this.version != null; + } + + public void setVersionIsSet(boolean value) { + if (!value) { + this.version = null; + } + } + + public long getStartTimestamp() { + return this.startTimestamp; + } + + public void setStartTimestamp(long startTimestamp) { + this.startTimestamp = startTimestamp; + setStartTimestampIsSet(true); + } + + public void unsetStartTimestamp() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); + } + + /** Returns true if field startTimestamp is set (has been assigned a value) and false otherwise */ + public boolean isSetStartTimestamp() { + return EncodingUtils.testBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); + } + + public void setStartTimestampIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID, value); + } + + public long getEndTimestamp() { + return this.endTimestamp; + } + + public void setEndTimestamp(long endTimestamp) { + this.endTimestamp = endTimestamp; + setEndTimestampIsSet(true); + } + + public void unsetEndTimestamp() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENDTIMESTAMP_ISSET_ID); + } + + /** Returns true if field endTimestamp is set (has been assigned a value) and false otherwise */ + public boolean isSetEndTimestamp() { + return EncodingUtils.testBit(__isset_bitfield, __ENDTIMESTAMP_ISSET_ID); + } + + public void setEndTimestampIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENDTIMESTAMP_ISSET_ID, value); + } + + public int getEndStatus() { + return this.endStatus; + } + + public void setEndStatus(int endStatus) { + this.endStatus = endStatus; + setEndStatusIsSet(true); + } + + public void unsetEndStatus() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENDSTATUS_ISSET_ID); + } + + /** Returns true if field endStatus is set (has been assigned a value) and false otherwise */ + public boolean isSetEndStatus() { + return EncodingUtils.testBit(__isset_bitfield, __ENDSTATUS_ISSET_ID); + } + + public void setEndStatusIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENDSTATUS_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HOSTNAME: + if (value == null) { + unsetHostname(); + } else { + setHostname((String)value); + } + break; + + case IP: + if (value == null) { + unsetIp(); + } else { + setIp((String)value); + } + break; + + case PORTS: + if (value == null) { + unsetPorts(); + } else { + setPorts((String)value); + } + break; + + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case APPLICATION_NAME: + if (value == null) { + unsetApplicationName(); + } else { + setApplicationName((String)value); + } + break; + + case SERVICE_TYPE: + if (value == null) { + unsetServiceType(); + } else { + setServiceType((Short)value); + } + break; + + case PID: + if (value == null) { + unsetPid(); + } else { + setPid((Integer)value); + } + break; + + case VERSION: + if (value == null) { + unsetVersion(); + } else { + setVersion((String)value); + } + break; + + case START_TIMESTAMP: + if (value == null) { + unsetStartTimestamp(); + } else { + setStartTimestamp((Long)value); + } + break; + + case END_TIMESTAMP: + if (value == null) { + unsetEndTimestamp(); + } else { + setEndTimestamp((Long)value); + } + break; + + case END_STATUS: + if (value == null) { + unsetEndStatus(); + } else { + setEndStatus((Integer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HOSTNAME: + return getHostname(); + + case IP: + return getIp(); + + case PORTS: + return getPorts(); + + case AGENT_ID: + return getAgentId(); + + case APPLICATION_NAME: + return getApplicationName(); + + case SERVICE_TYPE: + return Short.valueOf(getServiceType()); + + case PID: + return Integer.valueOf(getPid()); + + case VERSION: + return getVersion(); + + case START_TIMESTAMP: + return Long.valueOf(getStartTimestamp()); + + case END_TIMESTAMP: + return Long.valueOf(getEndTimestamp()); + + case END_STATUS: + return Integer.valueOf(getEndStatus()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HOSTNAME: + return isSetHostname(); + case IP: + return isSetIp(); + case PORTS: + return isSetPorts(); + case AGENT_ID: + return isSetAgentId(); + case APPLICATION_NAME: + return isSetApplicationName(); + case SERVICE_TYPE: + return isSetServiceType(); + case PID: + return isSetPid(); + case VERSION: + return isSetVersion(); + case START_TIMESTAMP: + return isSetStartTimestamp(); + case END_TIMESTAMP: + return isSetEndTimestamp(); + case END_STATUS: + return isSetEndStatus(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TAgentInfo) + return this.equals((TAgentInfo)that); + return false; + } + + public boolean equals(TAgentInfo that) { + if (that == null) + return false; + + boolean this_present_hostname = true && this.isSetHostname(); + boolean that_present_hostname = true && that.isSetHostname(); + if (this_present_hostname || that_present_hostname) { + if (!(this_present_hostname && that_present_hostname)) + return false; + if (!this.hostname.equals(that.hostname)) + return false; + } + + boolean this_present_ip = true && this.isSetIp(); + boolean that_present_ip = true && that.isSetIp(); + if (this_present_ip || that_present_ip) { + if (!(this_present_ip && that_present_ip)) + return false; + if (!this.ip.equals(that.ip)) + return false; + } + + boolean this_present_ports = true && this.isSetPorts(); + boolean that_present_ports = true && that.isSetPorts(); + if (this_present_ports || that_present_ports) { + if (!(this_present_ports && that_present_ports)) + return false; + if (!this.ports.equals(that.ports)) + return false; + } + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_applicationName = true && this.isSetApplicationName(); + boolean that_present_applicationName = true && that.isSetApplicationName(); + if (this_present_applicationName || that_present_applicationName) { + if (!(this_present_applicationName && that_present_applicationName)) + return false; + if (!this.applicationName.equals(that.applicationName)) + return false; + } + + boolean this_present_serviceType = true; + boolean that_present_serviceType = true; + if (this_present_serviceType || that_present_serviceType) { + if (!(this_present_serviceType && that_present_serviceType)) + return false; + if (this.serviceType != that.serviceType) + return false; + } + + boolean this_present_pid = true; + boolean that_present_pid = true; + if (this_present_pid || that_present_pid) { + if (!(this_present_pid && that_present_pid)) + return false; + if (this.pid != that.pid) + return false; + } + + boolean this_present_version = true && this.isSetVersion(); + boolean that_present_version = true && that.isSetVersion(); + if (this_present_version || that_present_version) { + if (!(this_present_version && that_present_version)) + return false; + if (!this.version.equals(that.version)) + return false; + } + + boolean this_present_startTimestamp = true; + boolean that_present_startTimestamp = true; + if (this_present_startTimestamp || that_present_startTimestamp) { + if (!(this_present_startTimestamp && that_present_startTimestamp)) + return false; + if (this.startTimestamp != that.startTimestamp) + return false; + } + + boolean this_present_endTimestamp = true && this.isSetEndTimestamp(); + boolean that_present_endTimestamp = true && that.isSetEndTimestamp(); + if (this_present_endTimestamp || that_present_endTimestamp) { + if (!(this_present_endTimestamp && that_present_endTimestamp)) + return false; + if (this.endTimestamp != that.endTimestamp) + return false; + } + + boolean this_present_endStatus = true && this.isSetEndStatus(); + boolean that_present_endStatus = true && that.isSetEndStatus(); + if (this_present_endStatus || that_present_endStatus) { + if (!(this_present_endStatus && that_present_endStatus)) + return false; + if (this.endStatus != that.endStatus) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TAgentInfo other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetHostname()).compareTo(other.isSetHostname()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHostname()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.hostname, other.hostname); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetIp()).compareTo(other.isSetIp()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetIp()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ip, other.ip); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPorts()).compareTo(other.isSetPorts()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPorts()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ports, other.ports); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApplicationName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetServiceType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPid()).compareTo(other.isSetPid()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPid()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pid, other.pid); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetVersion()).compareTo(other.isSetVersion()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersion()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, other.version); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStartTimestamp()).compareTo(other.isSetStartTimestamp()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStartTimestamp()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTimestamp, other.startTimestamp); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEndTimestamp()).compareTo(other.isSetEndTimestamp()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEndTimestamp()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endTimestamp, other.endTimestamp); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEndStatus()).compareTo(other.isSetEndStatus()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEndStatus()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endStatus, other.endStatus); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TAgentInfo("); + boolean first = true; + + sb.append("hostname:"); + if (this.hostname == null) { + sb.append("null"); + } else { + sb.append(this.hostname); + } + first = false; + if (!first) sb.append(", "); + sb.append("ip:"); + if (this.ip == null) { + sb.append("null"); + } else { + sb.append(this.ip); + } + first = false; + if (!first) sb.append(", "); + sb.append("ports:"); + if (this.ports == null) { + sb.append("null"); + } else { + sb.append(this.ports); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("applicationName:"); + if (this.applicationName == null) { + sb.append("null"); + } else { + sb.append(this.applicationName); + } + first = false; + if (!first) sb.append(", "); + sb.append("serviceType:"); + sb.append(this.serviceType); + first = false; + if (!first) sb.append(", "); + sb.append("pid:"); + sb.append(this.pid); + first = false; + if (!first) sb.append(", "); + sb.append("version:"); + if (this.version == null) { + sb.append("null"); + } else { + sb.append(this.version); + } + first = false; + if (!first) sb.append(", "); + sb.append("startTimestamp:"); + sb.append(this.startTimestamp); + first = false; + if (isSetEndTimestamp()) { + if (!first) sb.append(", "); + sb.append("endTimestamp:"); + sb.append(this.endTimestamp); + first = false; + } + if (isSetEndStatus()) { + if (!first) sb.append(", "); + sb.append("endStatus:"); + sb.append(this.endStatus); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TAgentInfoStandardSchemeFactory implements SchemeFactory { + public TAgentInfoStandardScheme getScheme() { + return new TAgentInfoStandardScheme(); + } + } + + private static class TAgentInfoStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TAgentInfo struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // HOSTNAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.hostname = iprot.readString(); + struct.setHostnameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // IP + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.ip = iprot.readString(); + struct.setIpIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // PORTS + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.ports = iprot.readString(); + struct.setPortsIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 5: // APPLICATION_NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 6: // SERVICE_TYPE + if (schemeField.type == org.apache.thrift.protocol.TType.I16) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 7: // PID + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.pid = iprot.readI32(); + struct.setPidIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 8: // VERSION + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.version = iprot.readString(); + struct.setVersionIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // START_TIMESTAMP + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.startTimestamp = iprot.readI64(); + struct.setStartTimestampIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 11: // END_TIMESTAMP + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.endTimestamp = iprot.readI64(); + struct.setEndTimestampIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 12: // END_STATUS + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.endStatus = iprot.readI32(); + struct.setEndStatusIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TAgentInfo struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.hostname != null) { + oprot.writeFieldBegin(HOSTNAME_FIELD_DESC); + oprot.writeString(struct.hostname); + oprot.writeFieldEnd(); + } + if (struct.ip != null) { + oprot.writeFieldBegin(IP_FIELD_DESC); + oprot.writeString(struct.ip); + oprot.writeFieldEnd(); + } + if (struct.ports != null) { + oprot.writeFieldBegin(PORTS_FIELD_DESC); + oprot.writeString(struct.ports); + oprot.writeFieldEnd(); + } + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + if (struct.applicationName != null) { + oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); + oprot.writeString(struct.applicationName); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); + oprot.writeI16(struct.serviceType); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(PID_FIELD_DESC); + oprot.writeI32(struct.pid); + oprot.writeFieldEnd(); + if (struct.version != null) { + oprot.writeFieldBegin(VERSION_FIELD_DESC); + oprot.writeString(struct.version); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(START_TIMESTAMP_FIELD_DESC); + oprot.writeI64(struct.startTimestamp); + oprot.writeFieldEnd(); + if (struct.isSetEndTimestamp()) { + oprot.writeFieldBegin(END_TIMESTAMP_FIELD_DESC); + oprot.writeI64(struct.endTimestamp); + oprot.writeFieldEnd(); + } + if (struct.isSetEndStatus()) { + oprot.writeFieldBegin(END_STATUS_FIELD_DESC); + oprot.writeI32(struct.endStatus); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TAgentInfoTupleSchemeFactory implements SchemeFactory { + public TAgentInfoTupleScheme getScheme() { + return new TAgentInfoTupleScheme(); + } + } + + private static class TAgentInfoTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TAgentInfo struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetHostname()) { + optionals.set(0); + } + if (struct.isSetIp()) { + optionals.set(1); + } + if (struct.isSetPorts()) { + optionals.set(2); + } + if (struct.isSetAgentId()) { + optionals.set(3); + } + if (struct.isSetApplicationName()) { + optionals.set(4); + } + if (struct.isSetServiceType()) { + optionals.set(5); + } + if (struct.isSetPid()) { + optionals.set(6); + } + if (struct.isSetVersion()) { + optionals.set(7); + } + if (struct.isSetStartTimestamp()) { + optionals.set(8); + } + if (struct.isSetEndTimestamp()) { + optionals.set(9); + } + if (struct.isSetEndStatus()) { + optionals.set(10); + } + oprot.writeBitSet(optionals, 11); + if (struct.isSetHostname()) { + oprot.writeString(struct.hostname); + } + if (struct.isSetIp()) { + oprot.writeString(struct.ip); + } + if (struct.isSetPorts()) { + oprot.writeString(struct.ports); + } + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetApplicationName()) { + oprot.writeString(struct.applicationName); + } + if (struct.isSetServiceType()) { + oprot.writeI16(struct.serviceType); + } + if (struct.isSetPid()) { + oprot.writeI32(struct.pid); + } + if (struct.isSetVersion()) { + oprot.writeString(struct.version); + } + if (struct.isSetStartTimestamp()) { + oprot.writeI64(struct.startTimestamp); + } + if (struct.isSetEndTimestamp()) { + oprot.writeI64(struct.endTimestamp); + } + if (struct.isSetEndStatus()) { + oprot.writeI32(struct.endStatus); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TAgentInfo struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(11); + if (incoming.get(0)) { + struct.hostname = iprot.readString(); + struct.setHostnameIsSet(true); + } + if (incoming.get(1)) { + struct.ip = iprot.readString(); + struct.setIpIsSet(true); + } + if (incoming.get(2)) { + struct.ports = iprot.readString(); + struct.setPortsIsSet(true); + } + if (incoming.get(3)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(4)) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } + if (incoming.get(5)) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } + if (incoming.get(6)) { + struct.pid = iprot.readI32(); + struct.setPidIsSet(true); + } + if (incoming.get(7)) { + struct.version = iprot.readString(); + struct.setVersionIsSet(true); + } + if (incoming.get(8)) { + struct.startTimestamp = iprot.readI64(); + struct.setStartTimestampIsSet(true); + } + if (incoming.get(9)) { + struct.endTimestamp = iprot.readI64(); + struct.setEndTimestampIsSet(true); + } + if (incoming.get(10)) { + struct.endStatus = iprot.readI32(); + struct.setEndStatusIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStat.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStat.java index aa57a65e723e..e7a1f7a90ce2 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStat.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStat.java @@ -1,888 +1,888 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TAgentStat implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAgentStat"); - - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField START_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("startTimestamp", org.apache.thrift.protocol.TType.I64, (short)2); - private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short)3); - private static final org.apache.thrift.protocol.TField GC_FIELD_DESC = new org.apache.thrift.protocol.TField("gc", org.apache.thrift.protocol.TType.STRUCT, (short)10); - private static final org.apache.thrift.protocol.TField CPU_LOAD_FIELD_DESC = new org.apache.thrift.protocol.TField("cpuLoad", org.apache.thrift.protocol.TType.STRUCT, (short)20); - private static final org.apache.thrift.protocol.TField METADATA_FIELD_DESC = new org.apache.thrift.protocol.TField("metadata", org.apache.thrift.protocol.TType.STRING, (short)200); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TAgentStatStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TAgentStatTupleSchemeFactory()); - } - - private String agentId; // optional - private long startTimestamp; // optional - private long timestamp; // optional - private TJvmGc gc; // optional - private TCpuLoad cpuLoad; // optional - private String metadata; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - AGENT_ID((short)1, "agentId"), - START_TIMESTAMP((short)2, "startTimestamp"), - TIMESTAMP((short)3, "timestamp"), - GC((short)10, "gc"), - CPU_LOAD((short)20, "cpuLoad"), - METADATA((short)200, "metadata"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // AGENT_ID - return AGENT_ID; - case 2: // START_TIMESTAMP - return START_TIMESTAMP; - case 3: // TIMESTAMP - return TIMESTAMP; - case 10: // GC - return GC; - case 20: // CPU_LOAD - return CPU_LOAD; - case 200: // METADATA - return METADATA; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __STARTTIMESTAMP_ISSET_ID = 0; - private static final int __TIMESTAMP_ISSET_ID = 1; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.AGENT_ID,_Fields.START_TIMESTAMP,_Fields.TIMESTAMP,_Fields.GC,_Fields.CPU_LOAD,_Fields.METADATA}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.START_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("startTimestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.GC, new org.apache.thrift.meta_data.FieldMetaData("gc", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TJvmGc.class))); - tmpMap.put(_Fields.CPU_LOAD, new org.apache.thrift.meta_data.FieldMetaData("cpuLoad", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TCpuLoad.class))); - tmpMap.put(_Fields.METADATA, new org.apache.thrift.meta_data.FieldMetaData("metadata", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAgentStat.class, metaDataMap); - } - - public TAgentStat() { - } - - /** - * Performs a deep copy on other. - */ - public TAgentStat(TAgentStat other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - this.startTimestamp = other.startTimestamp; - this.timestamp = other.timestamp; - if (other.isSetGc()) { - this.gc = new TJvmGc(other.gc); - } - if (other.isSetCpuLoad()) { - this.cpuLoad = new TCpuLoad(other.cpuLoad); - } - if (other.isSetMetadata()) { - this.metadata = other.metadata; - } - } - - public TAgentStat deepCopy() { - return new TAgentStat(this); - } - - @Override - public void clear() { - this.agentId = null; - setStartTimestampIsSet(false); - this.startTimestamp = 0; - setTimestampIsSet(false); - this.timestamp = 0; - this.gc = null; - this.cpuLoad = null; - this.metadata = null; - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public long getStartTimestamp() { - return this.startTimestamp; - } - - public void setStartTimestamp(long startTimestamp) { - this.startTimestamp = startTimestamp; - setStartTimestampIsSet(true); - } - - public void unsetStartTimestamp() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); - } - - /** Returns true if field startTimestamp is set (has been assigned a value) and false otherwise */ - public boolean isSetStartTimestamp() { - return EncodingUtils.testBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); - } - - public void setStartTimestampIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID, value); - } - - public long getTimestamp() { - return this.timestamp; - } - - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; - setTimestampIsSet(true); - } - - public void unsetTimestamp() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID); - } - - /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */ - public boolean isSetTimestamp() { - return EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID); - } - - public void setTimestampIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value); - } - - public TJvmGc getGc() { - return this.gc; - } - - public void setGc(TJvmGc gc) { - this.gc = gc; - } - - public void unsetGc() { - this.gc = null; - } - - /** Returns true if field gc is set (has been assigned a value) and false otherwise */ - public boolean isSetGc() { - return this.gc != null; - } - - public void setGcIsSet(boolean value) { - if (!value) { - this.gc = null; - } - } - - public TCpuLoad getCpuLoad() { - return this.cpuLoad; - } - - public void setCpuLoad(TCpuLoad cpuLoad) { - this.cpuLoad = cpuLoad; - } - - public void unsetCpuLoad() { - this.cpuLoad = null; - } - - /** Returns true if field cpuLoad is set (has been assigned a value) and false otherwise */ - public boolean isSetCpuLoad() { - return this.cpuLoad != null; - } - - public void setCpuLoadIsSet(boolean value) { - if (!value) { - this.cpuLoad = null; - } - } - - public String getMetadata() { - return this.metadata; - } - - public void setMetadata(String metadata) { - this.metadata = metadata; - } - - public void unsetMetadata() { - this.metadata = null; - } - - /** Returns true if field metadata is set (has been assigned a value) and false otherwise */ - public boolean isSetMetadata() { - return this.metadata != null; - } - - public void setMetadataIsSet(boolean value) { - if (!value) { - this.metadata = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case START_TIMESTAMP: - if (value == null) { - unsetStartTimestamp(); - } else { - setStartTimestamp((Long)value); - } - break; - - case TIMESTAMP: - if (value == null) { - unsetTimestamp(); - } else { - setTimestamp((Long)value); - } - break; - - case GC: - if (value == null) { - unsetGc(); - } else { - setGc((TJvmGc)value); - } - break; - - case CPU_LOAD: - if (value == null) { - unsetCpuLoad(); - } else { - setCpuLoad((TCpuLoad)value); - } - break; - - case METADATA: - if (value == null) { - unsetMetadata(); - } else { - setMetadata((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case AGENT_ID: - return getAgentId(); - - case START_TIMESTAMP: - return Long.valueOf(getStartTimestamp()); - - case TIMESTAMP: - return Long.valueOf(getTimestamp()); - - case GC: - return getGc(); - - case CPU_LOAD: - return getCpuLoad(); - - case METADATA: - return getMetadata(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case AGENT_ID: - return isSetAgentId(); - case START_TIMESTAMP: - return isSetStartTimestamp(); - case TIMESTAMP: - return isSetTimestamp(); - case GC: - return isSetGc(); - case CPU_LOAD: - return isSetCpuLoad(); - case METADATA: - return isSetMetadata(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TAgentStat) - return this.equals((TAgentStat)that); - return false; - } - - public boolean equals(TAgentStat that) { - if (that == null) - return false; - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_startTimestamp = true && this.isSetStartTimestamp(); - boolean that_present_startTimestamp = true && that.isSetStartTimestamp(); - if (this_present_startTimestamp || that_present_startTimestamp) { - if (!(this_present_startTimestamp && that_present_startTimestamp)) - return false; - if (this.startTimestamp != that.startTimestamp) - return false; - } - - boolean this_present_timestamp = true && this.isSetTimestamp(); - boolean that_present_timestamp = true && that.isSetTimestamp(); - if (this_present_timestamp || that_present_timestamp) { - if (!(this_present_timestamp && that_present_timestamp)) - return false; - if (this.timestamp != that.timestamp) - return false; - } - - boolean this_present_gc = true && this.isSetGc(); - boolean that_present_gc = true && that.isSetGc(); - if (this_present_gc || that_present_gc) { - if (!(this_present_gc && that_present_gc)) - return false; - if (!this.gc.equals(that.gc)) - return false; - } - - boolean this_present_cpuLoad = true && this.isSetCpuLoad(); - boolean that_present_cpuLoad = true && that.isSetCpuLoad(); - if (this_present_cpuLoad || that_present_cpuLoad) { - if (!(this_present_cpuLoad && that_present_cpuLoad)) - return false; - if (!this.cpuLoad.equals(that.cpuLoad)) - return false; - } - - boolean this_present_metadata = true && this.isSetMetadata(); - boolean that_present_metadata = true && that.isSetMetadata(); - if (this_present_metadata || that_present_metadata) { - if (!(this_present_metadata && that_present_metadata)) - return false; - if (!this.metadata.equals(that.metadata)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TAgentStat other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStartTimestamp()).compareTo(other.isSetStartTimestamp()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStartTimestamp()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTimestamp, other.startTimestamp); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetTimestamp()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timestamp, other.timestamp); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetGc()).compareTo(other.isSetGc()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetGc()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gc, other.gc); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetCpuLoad()).compareTo(other.isSetCpuLoad()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetCpuLoad()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cpuLoad, other.cpuLoad); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetMetadata()).compareTo(other.isSetMetadata()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetMetadata()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.metadata, other.metadata); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TAgentStat("); - boolean first = true; - - if (isSetAgentId()) { - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - } - if (isSetStartTimestamp()) { - if (!first) sb.append(", "); - sb.append("startTimestamp:"); - sb.append(this.startTimestamp); - first = false; - } - if (isSetTimestamp()) { - if (!first) sb.append(", "); - sb.append("timestamp:"); - sb.append(this.timestamp); - first = false; - } - if (isSetGc()) { - if (!first) sb.append(", "); - sb.append("gc:"); - if (this.gc == null) { - sb.append("null"); - } else { - sb.append(this.gc); - } - first = false; - } - if (isSetCpuLoad()) { - if (!first) sb.append(", "); - sb.append("cpuLoad:"); - if (this.cpuLoad == null) { - sb.append("null"); - } else { - sb.append(this.cpuLoad); - } - first = false; - } - if (isSetMetadata()) { - if (!first) sb.append(", "); - sb.append("metadata:"); - if (this.metadata == null) { - sb.append("null"); - } else { - sb.append(this.metadata); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - if (gc != null) { - gc.validate(); - } - if (cpuLoad != null) { - cpuLoad.validate(); - } - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TAgentStatStandardSchemeFactory implements SchemeFactory { - public TAgentStatStandardScheme getScheme() { - return new TAgentStatStandardScheme(); - } - } - - private static class TAgentStatStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TAgentStat struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // START_TIMESTAMP - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.startTimestamp = iprot.readI64(); - struct.setStartTimestampIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // TIMESTAMP - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.timestamp = iprot.readI64(); - struct.setTimestampIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 10: // GC - if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { - struct.gc = new TJvmGc(); - struct.gc.read(iprot); - struct.setGcIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 20: // CPU_LOAD - if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { - struct.cpuLoad = new TCpuLoad(); - struct.cpuLoad.read(iprot); - struct.setCpuLoadIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 200: // METADATA - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.metadata = iprot.readString(); - struct.setMetadataIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TAgentStat struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.agentId != null) { - if (struct.isSetAgentId()) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - } - if (struct.isSetStartTimestamp()) { - oprot.writeFieldBegin(START_TIMESTAMP_FIELD_DESC); - oprot.writeI64(struct.startTimestamp); - oprot.writeFieldEnd(); - } - if (struct.isSetTimestamp()) { - oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC); - oprot.writeI64(struct.timestamp); - oprot.writeFieldEnd(); - } - if (struct.gc != null) { - if (struct.isSetGc()) { - oprot.writeFieldBegin(GC_FIELD_DESC); - struct.gc.write(oprot); - oprot.writeFieldEnd(); - } - } - if (struct.cpuLoad != null) { - if (struct.isSetCpuLoad()) { - oprot.writeFieldBegin(CPU_LOAD_FIELD_DESC); - struct.cpuLoad.write(oprot); - oprot.writeFieldEnd(); - } - } - if (struct.metadata != null) { - if (struct.isSetMetadata()) { - oprot.writeFieldBegin(METADATA_FIELD_DESC); - oprot.writeString(struct.metadata); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TAgentStatTupleSchemeFactory implements SchemeFactory { - public TAgentStatTupleScheme getScheme() { - return new TAgentStatTupleScheme(); - } - } - - private static class TAgentStatTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TAgentStat struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetAgentId()) { - optionals.set(0); - } - if (struct.isSetStartTimestamp()) { - optionals.set(1); - } - if (struct.isSetTimestamp()) { - optionals.set(2); - } - if (struct.isSetGc()) { - optionals.set(3); - } - if (struct.isSetCpuLoad()) { - optionals.set(4); - } - if (struct.isSetMetadata()) { - optionals.set(5); - } - oprot.writeBitSet(optionals, 6); - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetStartTimestamp()) { - oprot.writeI64(struct.startTimestamp); - } - if (struct.isSetTimestamp()) { - oprot.writeI64(struct.timestamp); - } - if (struct.isSetGc()) { - struct.gc.write(oprot); - } - if (struct.isSetCpuLoad()) { - struct.cpuLoad.write(oprot); - } - if (struct.isSetMetadata()) { - oprot.writeString(struct.metadata); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TAgentStat struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(6); - if (incoming.get(0)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(1)) { - struct.startTimestamp = iprot.readI64(); - struct.setStartTimestampIsSet(true); - } - if (incoming.get(2)) { - struct.timestamp = iprot.readI64(); - struct.setTimestampIsSet(true); - } - if (incoming.get(3)) { - struct.gc = new TJvmGc(); - struct.gc.read(iprot); - struct.setGcIsSet(true); - } - if (incoming.get(4)) { - struct.cpuLoad = new TCpuLoad(); - struct.cpuLoad.read(iprot); - struct.setCpuLoadIsSet(true); - } - if (incoming.get(5)) { - struct.metadata = iprot.readString(); - struct.setMetadataIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TAgentStat implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAgentStat"); + + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField START_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("startTimestamp", org.apache.thrift.protocol.TType.I64, (short)2); + private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short)3); + private static final org.apache.thrift.protocol.TField GC_FIELD_DESC = new org.apache.thrift.protocol.TField("gc", org.apache.thrift.protocol.TType.STRUCT, (short)10); + private static final org.apache.thrift.protocol.TField CPU_LOAD_FIELD_DESC = new org.apache.thrift.protocol.TField("cpuLoad", org.apache.thrift.protocol.TType.STRUCT, (short)20); + private static final org.apache.thrift.protocol.TField METADATA_FIELD_DESC = new org.apache.thrift.protocol.TField("metadata", org.apache.thrift.protocol.TType.STRING, (short)200); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TAgentStatStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TAgentStatTupleSchemeFactory()); + } + + private String agentId; // optional + private long startTimestamp; // optional + private long timestamp; // optional + private TJvmGc gc; // optional + private TCpuLoad cpuLoad; // optional + private String metadata; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + AGENT_ID((short)1, "agentId"), + START_TIMESTAMP((short)2, "startTimestamp"), + TIMESTAMP((short)3, "timestamp"), + GC((short)10, "gc"), + CPU_LOAD((short)20, "cpuLoad"), + METADATA((short)200, "metadata"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // AGENT_ID + return AGENT_ID; + case 2: // START_TIMESTAMP + return START_TIMESTAMP; + case 3: // TIMESTAMP + return TIMESTAMP; + case 10: // GC + return GC; + case 20: // CPU_LOAD + return CPU_LOAD; + case 200: // METADATA + return METADATA; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __STARTTIMESTAMP_ISSET_ID = 0; + private static final int __TIMESTAMP_ISSET_ID = 1; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.AGENT_ID,_Fields.START_TIMESTAMP,_Fields.TIMESTAMP,_Fields.GC,_Fields.CPU_LOAD,_Fields.METADATA}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.START_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("startTimestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.GC, new org.apache.thrift.meta_data.FieldMetaData("gc", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TJvmGc.class))); + tmpMap.put(_Fields.CPU_LOAD, new org.apache.thrift.meta_data.FieldMetaData("cpuLoad", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TCpuLoad.class))); + tmpMap.put(_Fields.METADATA, new org.apache.thrift.meta_data.FieldMetaData("metadata", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAgentStat.class, metaDataMap); + } + + public TAgentStat() { + } + + /** + * Performs a deep copy on other. + */ + public TAgentStat(TAgentStat other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + this.startTimestamp = other.startTimestamp; + this.timestamp = other.timestamp; + if (other.isSetGc()) { + this.gc = new TJvmGc(other.gc); + } + if (other.isSetCpuLoad()) { + this.cpuLoad = new TCpuLoad(other.cpuLoad); + } + if (other.isSetMetadata()) { + this.metadata = other.metadata; + } + } + + public TAgentStat deepCopy() { + return new TAgentStat(this); + } + + @Override + public void clear() { + this.agentId = null; + setStartTimestampIsSet(false); + this.startTimestamp = 0; + setTimestampIsSet(false); + this.timestamp = 0; + this.gc = null; + this.cpuLoad = null; + this.metadata = null; + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public long getStartTimestamp() { + return this.startTimestamp; + } + + public void setStartTimestamp(long startTimestamp) { + this.startTimestamp = startTimestamp; + setStartTimestampIsSet(true); + } + + public void unsetStartTimestamp() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); + } + + /** Returns true if field startTimestamp is set (has been assigned a value) and false otherwise */ + public boolean isSetStartTimestamp() { + return EncodingUtils.testBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); + } + + public void setStartTimestampIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID, value); + } + + public long getTimestamp() { + return this.timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + setTimestampIsSet(true); + } + + public void unsetTimestamp() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID); + } + + /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */ + public boolean isSetTimestamp() { + return EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID); + } + + public void setTimestampIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value); + } + + public TJvmGc getGc() { + return this.gc; + } + + public void setGc(TJvmGc gc) { + this.gc = gc; + } + + public void unsetGc() { + this.gc = null; + } + + /** Returns true if field gc is set (has been assigned a value) and false otherwise */ + public boolean isSetGc() { + return this.gc != null; + } + + public void setGcIsSet(boolean value) { + if (!value) { + this.gc = null; + } + } + + public TCpuLoad getCpuLoad() { + return this.cpuLoad; + } + + public void setCpuLoad(TCpuLoad cpuLoad) { + this.cpuLoad = cpuLoad; + } + + public void unsetCpuLoad() { + this.cpuLoad = null; + } + + /** Returns true if field cpuLoad is set (has been assigned a value) and false otherwise */ + public boolean isSetCpuLoad() { + return this.cpuLoad != null; + } + + public void setCpuLoadIsSet(boolean value) { + if (!value) { + this.cpuLoad = null; + } + } + + public String getMetadata() { + return this.metadata; + } + + public void setMetadata(String metadata) { + this.metadata = metadata; + } + + public void unsetMetadata() { + this.metadata = null; + } + + /** Returns true if field metadata is set (has been assigned a value) and false otherwise */ + public boolean isSetMetadata() { + return this.metadata != null; + } + + public void setMetadataIsSet(boolean value) { + if (!value) { + this.metadata = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case START_TIMESTAMP: + if (value == null) { + unsetStartTimestamp(); + } else { + setStartTimestamp((Long)value); + } + break; + + case TIMESTAMP: + if (value == null) { + unsetTimestamp(); + } else { + setTimestamp((Long)value); + } + break; + + case GC: + if (value == null) { + unsetGc(); + } else { + setGc((TJvmGc)value); + } + break; + + case CPU_LOAD: + if (value == null) { + unsetCpuLoad(); + } else { + setCpuLoad((TCpuLoad)value); + } + break; + + case METADATA: + if (value == null) { + unsetMetadata(); + } else { + setMetadata((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case AGENT_ID: + return getAgentId(); + + case START_TIMESTAMP: + return Long.valueOf(getStartTimestamp()); + + case TIMESTAMP: + return Long.valueOf(getTimestamp()); + + case GC: + return getGc(); + + case CPU_LOAD: + return getCpuLoad(); + + case METADATA: + return getMetadata(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case AGENT_ID: + return isSetAgentId(); + case START_TIMESTAMP: + return isSetStartTimestamp(); + case TIMESTAMP: + return isSetTimestamp(); + case GC: + return isSetGc(); + case CPU_LOAD: + return isSetCpuLoad(); + case METADATA: + return isSetMetadata(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TAgentStat) + return this.equals((TAgentStat)that); + return false; + } + + public boolean equals(TAgentStat that) { + if (that == null) + return false; + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_startTimestamp = true && this.isSetStartTimestamp(); + boolean that_present_startTimestamp = true && that.isSetStartTimestamp(); + if (this_present_startTimestamp || that_present_startTimestamp) { + if (!(this_present_startTimestamp && that_present_startTimestamp)) + return false; + if (this.startTimestamp != that.startTimestamp) + return false; + } + + boolean this_present_timestamp = true && this.isSetTimestamp(); + boolean that_present_timestamp = true && that.isSetTimestamp(); + if (this_present_timestamp || that_present_timestamp) { + if (!(this_present_timestamp && that_present_timestamp)) + return false; + if (this.timestamp != that.timestamp) + return false; + } + + boolean this_present_gc = true && this.isSetGc(); + boolean that_present_gc = true && that.isSetGc(); + if (this_present_gc || that_present_gc) { + if (!(this_present_gc && that_present_gc)) + return false; + if (!this.gc.equals(that.gc)) + return false; + } + + boolean this_present_cpuLoad = true && this.isSetCpuLoad(); + boolean that_present_cpuLoad = true && that.isSetCpuLoad(); + if (this_present_cpuLoad || that_present_cpuLoad) { + if (!(this_present_cpuLoad && that_present_cpuLoad)) + return false; + if (!this.cpuLoad.equals(that.cpuLoad)) + return false; + } + + boolean this_present_metadata = true && this.isSetMetadata(); + boolean that_present_metadata = true && that.isSetMetadata(); + if (this_present_metadata || that_present_metadata) { + if (!(this_present_metadata && that_present_metadata)) + return false; + if (!this.metadata.equals(that.metadata)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TAgentStat other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStartTimestamp()).compareTo(other.isSetStartTimestamp()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStartTimestamp()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTimestamp, other.startTimestamp); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetTimestamp()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timestamp, other.timestamp); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetGc()).compareTo(other.isSetGc()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetGc()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gc, other.gc); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCpuLoad()).compareTo(other.isSetCpuLoad()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCpuLoad()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cpuLoad, other.cpuLoad); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetMetadata()).compareTo(other.isSetMetadata()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetMetadata()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.metadata, other.metadata); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TAgentStat("); + boolean first = true; + + if (isSetAgentId()) { + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + } + if (isSetStartTimestamp()) { + if (!first) sb.append(", "); + sb.append("startTimestamp:"); + sb.append(this.startTimestamp); + first = false; + } + if (isSetTimestamp()) { + if (!first) sb.append(", "); + sb.append("timestamp:"); + sb.append(this.timestamp); + first = false; + } + if (isSetGc()) { + if (!first) sb.append(", "); + sb.append("gc:"); + if (this.gc == null) { + sb.append("null"); + } else { + sb.append(this.gc); + } + first = false; + } + if (isSetCpuLoad()) { + if (!first) sb.append(", "); + sb.append("cpuLoad:"); + if (this.cpuLoad == null) { + sb.append("null"); + } else { + sb.append(this.cpuLoad); + } + first = false; + } + if (isSetMetadata()) { + if (!first) sb.append(", "); + sb.append("metadata:"); + if (this.metadata == null) { + sb.append("null"); + } else { + sb.append(this.metadata); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + if (gc != null) { + gc.validate(); + } + if (cpuLoad != null) { + cpuLoad.validate(); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TAgentStatStandardSchemeFactory implements SchemeFactory { + public TAgentStatStandardScheme getScheme() { + return new TAgentStatStandardScheme(); + } + } + + private static class TAgentStatStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TAgentStat struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // START_TIMESTAMP + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.startTimestamp = iprot.readI64(); + struct.setStartTimestampIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // TIMESTAMP + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.timestamp = iprot.readI64(); + struct.setTimestampIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // GC + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.gc = new TJvmGc(); + struct.gc.read(iprot); + struct.setGcIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 20: // CPU_LOAD + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.cpuLoad = new TCpuLoad(); + struct.cpuLoad.read(iprot); + struct.setCpuLoadIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 200: // METADATA + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.metadata = iprot.readString(); + struct.setMetadataIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TAgentStat struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.agentId != null) { + if (struct.isSetAgentId()) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + } + if (struct.isSetStartTimestamp()) { + oprot.writeFieldBegin(START_TIMESTAMP_FIELD_DESC); + oprot.writeI64(struct.startTimestamp); + oprot.writeFieldEnd(); + } + if (struct.isSetTimestamp()) { + oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC); + oprot.writeI64(struct.timestamp); + oprot.writeFieldEnd(); + } + if (struct.gc != null) { + if (struct.isSetGc()) { + oprot.writeFieldBegin(GC_FIELD_DESC); + struct.gc.write(oprot); + oprot.writeFieldEnd(); + } + } + if (struct.cpuLoad != null) { + if (struct.isSetCpuLoad()) { + oprot.writeFieldBegin(CPU_LOAD_FIELD_DESC); + struct.cpuLoad.write(oprot); + oprot.writeFieldEnd(); + } + } + if (struct.metadata != null) { + if (struct.isSetMetadata()) { + oprot.writeFieldBegin(METADATA_FIELD_DESC); + oprot.writeString(struct.metadata); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TAgentStatTupleSchemeFactory implements SchemeFactory { + public TAgentStatTupleScheme getScheme() { + return new TAgentStatTupleScheme(); + } + } + + private static class TAgentStatTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TAgentStat struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetAgentId()) { + optionals.set(0); + } + if (struct.isSetStartTimestamp()) { + optionals.set(1); + } + if (struct.isSetTimestamp()) { + optionals.set(2); + } + if (struct.isSetGc()) { + optionals.set(3); + } + if (struct.isSetCpuLoad()) { + optionals.set(4); + } + if (struct.isSetMetadata()) { + optionals.set(5); + } + oprot.writeBitSet(optionals, 6); + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetStartTimestamp()) { + oprot.writeI64(struct.startTimestamp); + } + if (struct.isSetTimestamp()) { + oprot.writeI64(struct.timestamp); + } + if (struct.isSetGc()) { + struct.gc.write(oprot); + } + if (struct.isSetCpuLoad()) { + struct.cpuLoad.write(oprot); + } + if (struct.isSetMetadata()) { + oprot.writeString(struct.metadata); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TAgentStat struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(6); + if (incoming.get(0)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(1)) { + struct.startTimestamp = iprot.readI64(); + struct.setStartTimestampIsSet(true); + } + if (incoming.get(2)) { + struct.timestamp = iprot.readI64(); + struct.setTimestampIsSet(true); + } + if (incoming.get(3)) { + struct.gc = new TJvmGc(); + struct.gc.read(iprot); + struct.setGcIsSet(true); + } + if (incoming.get(4)) { + struct.cpuLoad = new TCpuLoad(); + struct.cpuLoad.read(iprot); + struct.setCpuLoadIsSet(true); + } + if (incoming.get(5)) { + struct.metadata = iprot.readString(); + struct.setMetadataIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStatBatch.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStatBatch.java index ac1a0d9600e4..b16ac2a2795f 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStatBatch.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAgentStatBatch.java @@ -1,635 +1,635 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TAgentStatBatch implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAgentStatBatch"); - - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField START_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("startTimestamp", org.apache.thrift.protocol.TType.I64, (short)2); - private static final org.apache.thrift.protocol.TField AGENT_STATS_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStats", org.apache.thrift.protocol.TType.LIST, (short)10); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TAgentStatBatchStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TAgentStatBatchTupleSchemeFactory()); - } - - private String agentId; // required - private long startTimestamp; // required - private List agentStats; // required - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - AGENT_ID((short)1, "agentId"), - START_TIMESTAMP((short)2, "startTimestamp"), - AGENT_STATS((short)10, "agentStats"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // AGENT_ID - return AGENT_ID; - case 2: // START_TIMESTAMP - return START_TIMESTAMP; - case 10: // AGENT_STATS - return AGENT_STATS; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __STARTTIMESTAMP_ISSET_ID = 0; - private byte __isset_bitfield = 0; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.START_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("startTimestamp", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.AGENT_STATS, new org.apache.thrift.meta_data.FieldMetaData("agentStats", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAgentStat.class)))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAgentStatBatch.class, metaDataMap); - } - - public TAgentStatBatch() { - } - - public TAgentStatBatch( - String agentId, - long startTimestamp, - List agentStats) - { - this(); - this.agentId = agentId; - this.startTimestamp = startTimestamp; - setStartTimestampIsSet(true); - this.agentStats = agentStats; - } - - /** - * Performs a deep copy on other. - */ - public TAgentStatBatch(TAgentStatBatch other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - this.startTimestamp = other.startTimestamp; - if (other.isSetAgentStats()) { - List __this__agentStats = new ArrayList(other.agentStats.size()); - for (TAgentStat other_element : other.agentStats) { - __this__agentStats.add(new TAgentStat(other_element)); - } - this.agentStats = __this__agentStats; - } - } - - public TAgentStatBatch deepCopy() { - return new TAgentStatBatch(this); - } - - @Override - public void clear() { - this.agentId = null; - setStartTimestampIsSet(false); - this.startTimestamp = 0; - this.agentStats = null; - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public long getStartTimestamp() { - return this.startTimestamp; - } - - public void setStartTimestamp(long startTimestamp) { - this.startTimestamp = startTimestamp; - setStartTimestampIsSet(true); - } - - public void unsetStartTimestamp() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); - } - - /** Returns true if field startTimestamp is set (has been assigned a value) and false otherwise */ - public boolean isSetStartTimestamp() { - return EncodingUtils.testBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); - } - - public void setStartTimestampIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID, value); - } - - public int getAgentStatsSize() { - return (this.agentStats == null) ? 0 : this.agentStats.size(); - } - - public java.util.Iterator getAgentStatsIterator() { - return (this.agentStats == null) ? null : this.agentStats.iterator(); - } - - public void addToAgentStats(TAgentStat elem) { - if (this.agentStats == null) { - this.agentStats = new ArrayList(); - } - this.agentStats.add(elem); - } - - public List getAgentStats() { - return this.agentStats; - } - - public void setAgentStats(List agentStats) { - this.agentStats = agentStats; - } - - public void unsetAgentStats() { - this.agentStats = null; - } - - /** Returns true if field agentStats is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentStats() { - return this.agentStats != null; - } - - public void setAgentStatsIsSet(boolean value) { - if (!value) { - this.agentStats = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case START_TIMESTAMP: - if (value == null) { - unsetStartTimestamp(); - } else { - setStartTimestamp((Long)value); - } - break; - - case AGENT_STATS: - if (value == null) { - unsetAgentStats(); - } else { - setAgentStats((List)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case AGENT_ID: - return getAgentId(); - - case START_TIMESTAMP: - return Long.valueOf(getStartTimestamp()); - - case AGENT_STATS: - return getAgentStats(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case AGENT_ID: - return isSetAgentId(); - case START_TIMESTAMP: - return isSetStartTimestamp(); - case AGENT_STATS: - return isSetAgentStats(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TAgentStatBatch) - return this.equals((TAgentStatBatch)that); - return false; - } - - public boolean equals(TAgentStatBatch that) { - if (that == null) - return false; - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_startTimestamp = true; - boolean that_present_startTimestamp = true; - if (this_present_startTimestamp || that_present_startTimestamp) { - if (!(this_present_startTimestamp && that_present_startTimestamp)) - return false; - if (this.startTimestamp != that.startTimestamp) - return false; - } - - boolean this_present_agentStats = true && this.isSetAgentStats(); - boolean that_present_agentStats = true && that.isSetAgentStats(); - if (this_present_agentStats || that_present_agentStats) { - if (!(this_present_agentStats && that_present_agentStats)) - return false; - if (!this.agentStats.equals(that.agentStats)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TAgentStatBatch other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStartTimestamp()).compareTo(other.isSetStartTimestamp()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStartTimestamp()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTimestamp, other.startTimestamp); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAgentStats()).compareTo(other.isSetAgentStats()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentStats()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStats, other.agentStats); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TAgentStatBatch("); - boolean first = true; - - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - if (!first) sb.append(", "); - sb.append("startTimestamp:"); - sb.append(this.startTimestamp); - first = false; - if (!first) sb.append(", "); - sb.append("agentStats:"); - if (this.agentStats == null) { - sb.append("null"); - } else { - sb.append(this.agentStats); - } - first = false; - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TAgentStatBatchStandardSchemeFactory implements SchemeFactory { - public TAgentStatBatchStandardScheme getScheme() { - return new TAgentStatBatchStandardScheme(); - } - } - - private static class TAgentStatBatchStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TAgentStatBatch struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // START_TIMESTAMP - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.startTimestamp = iprot.readI64(); - struct.setStartTimestampIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 10: // AGENT_STATS - if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { - { - org.apache.thrift.protocol.TList _list0 = iprot.readListBegin(); - struct.agentStats = new ArrayList(_list0.size); - for (int _i1 = 0; _i1 < _list0.size; ++_i1) - { - TAgentStat _elem2; - _elem2 = new TAgentStat(); - _elem2.read(iprot); - struct.agentStats.add(_elem2); - } - iprot.readListEnd(); - } - struct.setAgentStatsIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TAgentStatBatch struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.agentId != null) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(START_TIMESTAMP_FIELD_DESC); - oprot.writeI64(struct.startTimestamp); - oprot.writeFieldEnd(); - if (struct.agentStats != null) { - oprot.writeFieldBegin(AGENT_STATS_FIELD_DESC); - { - oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.agentStats.size())); - for (TAgentStat _iter3 : struct.agentStats) - { - _iter3.write(oprot); - } - oprot.writeListEnd(); - } - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TAgentStatBatchTupleSchemeFactory implements SchemeFactory { - public TAgentStatBatchTupleScheme getScheme() { - return new TAgentStatBatchTupleScheme(); - } - } - - private static class TAgentStatBatchTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TAgentStatBatch struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetAgentId()) { - optionals.set(0); - } - if (struct.isSetStartTimestamp()) { - optionals.set(1); - } - if (struct.isSetAgentStats()) { - optionals.set(2); - } - oprot.writeBitSet(optionals, 3); - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetStartTimestamp()) { - oprot.writeI64(struct.startTimestamp); - } - if (struct.isSetAgentStats()) { - { - oprot.writeI32(struct.agentStats.size()); - for (TAgentStat _iter4 : struct.agentStats) - { - _iter4.write(oprot); - } - } - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TAgentStatBatch struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(3); - if (incoming.get(0)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(1)) { - struct.startTimestamp = iprot.readI64(); - struct.setStartTimestampIsSet(true); - } - if (incoming.get(2)) { - { - org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); - struct.agentStats = new ArrayList(_list5.size); - for (int _i6 = 0; _i6 < _list5.size; ++_i6) - { - TAgentStat _elem7; - _elem7 = new TAgentStat(); - _elem7.read(iprot); - struct.agentStats.add(_elem7); - } - } - struct.setAgentStatsIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TAgentStatBatch implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAgentStatBatch"); + + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField START_TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("startTimestamp", org.apache.thrift.protocol.TType.I64, (short)2); + private static final org.apache.thrift.protocol.TField AGENT_STATS_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStats", org.apache.thrift.protocol.TType.LIST, (short)10); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TAgentStatBatchStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TAgentStatBatchTupleSchemeFactory()); + } + + private String agentId; // required + private long startTimestamp; // required + private List agentStats; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + AGENT_ID((short)1, "agentId"), + START_TIMESTAMP((short)2, "startTimestamp"), + AGENT_STATS((short)10, "agentStats"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // AGENT_ID + return AGENT_ID; + case 2: // START_TIMESTAMP + return START_TIMESTAMP; + case 10: // AGENT_STATS + return AGENT_STATS; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __STARTTIMESTAMP_ISSET_ID = 0; + private byte __isset_bitfield = 0; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.START_TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("startTimestamp", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.AGENT_STATS, new org.apache.thrift.meta_data.FieldMetaData("agentStats", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAgentStat.class)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAgentStatBatch.class, metaDataMap); + } + + public TAgentStatBatch() { + } + + public TAgentStatBatch( + String agentId, + long startTimestamp, + List agentStats) + { + this(); + this.agentId = agentId; + this.startTimestamp = startTimestamp; + setStartTimestampIsSet(true); + this.agentStats = agentStats; + } + + /** + * Performs a deep copy on other. + */ + public TAgentStatBatch(TAgentStatBatch other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + this.startTimestamp = other.startTimestamp; + if (other.isSetAgentStats()) { + List __this__agentStats = new ArrayList(other.agentStats.size()); + for (TAgentStat other_element : other.agentStats) { + __this__agentStats.add(new TAgentStat(other_element)); + } + this.agentStats = __this__agentStats; + } + } + + public TAgentStatBatch deepCopy() { + return new TAgentStatBatch(this); + } + + @Override + public void clear() { + this.agentId = null; + setStartTimestampIsSet(false); + this.startTimestamp = 0; + this.agentStats = null; + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public long getStartTimestamp() { + return this.startTimestamp; + } + + public void setStartTimestamp(long startTimestamp) { + this.startTimestamp = startTimestamp; + setStartTimestampIsSet(true); + } + + public void unsetStartTimestamp() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); + } + + /** Returns true if field startTimestamp is set (has been assigned a value) and false otherwise */ + public boolean isSetStartTimestamp() { + return EncodingUtils.testBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID); + } + + public void setStartTimestampIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIMESTAMP_ISSET_ID, value); + } + + public int getAgentStatsSize() { + return (this.agentStats == null) ? 0 : this.agentStats.size(); + } + + public java.util.Iterator getAgentStatsIterator() { + return (this.agentStats == null) ? null : this.agentStats.iterator(); + } + + public void addToAgentStats(TAgentStat elem) { + if (this.agentStats == null) { + this.agentStats = new ArrayList(); + } + this.agentStats.add(elem); + } + + public List getAgentStats() { + return this.agentStats; + } + + public void setAgentStats(List agentStats) { + this.agentStats = agentStats; + } + + public void unsetAgentStats() { + this.agentStats = null; + } + + /** Returns true if field agentStats is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentStats() { + return this.agentStats != null; + } + + public void setAgentStatsIsSet(boolean value) { + if (!value) { + this.agentStats = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case START_TIMESTAMP: + if (value == null) { + unsetStartTimestamp(); + } else { + setStartTimestamp((Long)value); + } + break; + + case AGENT_STATS: + if (value == null) { + unsetAgentStats(); + } else { + setAgentStats((List)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case AGENT_ID: + return getAgentId(); + + case START_TIMESTAMP: + return Long.valueOf(getStartTimestamp()); + + case AGENT_STATS: + return getAgentStats(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case AGENT_ID: + return isSetAgentId(); + case START_TIMESTAMP: + return isSetStartTimestamp(); + case AGENT_STATS: + return isSetAgentStats(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TAgentStatBatch) + return this.equals((TAgentStatBatch)that); + return false; + } + + public boolean equals(TAgentStatBatch that) { + if (that == null) + return false; + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_startTimestamp = true; + boolean that_present_startTimestamp = true; + if (this_present_startTimestamp || that_present_startTimestamp) { + if (!(this_present_startTimestamp && that_present_startTimestamp)) + return false; + if (this.startTimestamp != that.startTimestamp) + return false; + } + + boolean this_present_agentStats = true && this.isSetAgentStats(); + boolean that_present_agentStats = true && that.isSetAgentStats(); + if (this_present_agentStats || that_present_agentStats) { + if (!(this_present_agentStats && that_present_agentStats)) + return false; + if (!this.agentStats.equals(that.agentStats)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TAgentStatBatch other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStartTimestamp()).compareTo(other.isSetStartTimestamp()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStartTimestamp()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTimestamp, other.startTimestamp); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentStats()).compareTo(other.isSetAgentStats()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentStats()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStats, other.agentStats); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TAgentStatBatch("); + boolean first = true; + + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("startTimestamp:"); + sb.append(this.startTimestamp); + first = false; + if (!first) sb.append(", "); + sb.append("agentStats:"); + if (this.agentStats == null) { + sb.append("null"); + } else { + sb.append(this.agentStats); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TAgentStatBatchStandardSchemeFactory implements SchemeFactory { + public TAgentStatBatchStandardScheme getScheme() { + return new TAgentStatBatchStandardScheme(); + } + } + + private static class TAgentStatBatchStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TAgentStatBatch struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // START_TIMESTAMP + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.startTimestamp = iprot.readI64(); + struct.setStartTimestampIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // AGENT_STATS + if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list0 = iprot.readListBegin(); + struct.agentStats = new ArrayList(_list0.size); + for (int _i1 = 0; _i1 < _list0.size; ++_i1) + { + TAgentStat _elem2; + _elem2 = new TAgentStat(); + _elem2.read(iprot); + struct.agentStats.add(_elem2); + } + iprot.readListEnd(); + } + struct.setAgentStatsIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TAgentStatBatch struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(START_TIMESTAMP_FIELD_DESC); + oprot.writeI64(struct.startTimestamp); + oprot.writeFieldEnd(); + if (struct.agentStats != null) { + oprot.writeFieldBegin(AGENT_STATS_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.agentStats.size())); + for (TAgentStat _iter3 : struct.agentStats) + { + _iter3.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TAgentStatBatchTupleSchemeFactory implements SchemeFactory { + public TAgentStatBatchTupleScheme getScheme() { + return new TAgentStatBatchTupleScheme(); + } + } + + private static class TAgentStatBatchTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TAgentStatBatch struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetAgentId()) { + optionals.set(0); + } + if (struct.isSetStartTimestamp()) { + optionals.set(1); + } + if (struct.isSetAgentStats()) { + optionals.set(2); + } + oprot.writeBitSet(optionals, 3); + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetStartTimestamp()) { + oprot.writeI64(struct.startTimestamp); + } + if (struct.isSetAgentStats()) { + { + oprot.writeI32(struct.agentStats.size()); + for (TAgentStat _iter4 : struct.agentStats) + { + _iter4.write(oprot); + } + } + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TAgentStatBatch struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(3); + if (incoming.get(0)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(1)) { + struct.startTimestamp = iprot.readI64(); + struct.setStartTimestampIsSet(true); + } + if (incoming.get(2)) { + { + org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); + struct.agentStats = new ArrayList(_list5.size); + for (int _i6 = 0; _i6 < _list5.size; ++_i6) + { + TAgentStat _elem7; + _elem7 = new TAgentStat(); + _elem7.read(iprot); + struct.agentStats.add(_elem7); + } + } + struct.setAgentStatsIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotation.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotation.java index eb1f16d7e779..0315926628f7 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotation.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotation.java @@ -1,487 +1,487 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TAnnotation implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAnnotation"); - - private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.I32, (short)1); - private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRUCT, (short)2); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TAnnotationStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TAnnotationTupleSchemeFactory()); - } - - private int key; // required - private TAnnotationValue value; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - KEY((short)1, "key"), - VALUE((short)2, "value"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // KEY - return KEY; - case 2: // VALUE - return VALUE; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __KEY_ISSET_ID = 0; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.VALUE}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAnnotationValue.class))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAnnotation.class, metaDataMap); - } - - public TAnnotation() { - } - - public TAnnotation( - int key) - { - this(); - this.key = key; - setKeyIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TAnnotation(TAnnotation other) { - __isset_bitfield = other.__isset_bitfield; - this.key = other.key; - if (other.isSetValue()) { - this.value = new TAnnotationValue(other.value); - } - } - - public TAnnotation deepCopy() { - return new TAnnotation(this); - } - - @Override - public void clear() { - setKeyIsSet(false); - this.key = 0; - this.value = null; - } - - public int getKey() { - return this.key; - } - - public void setKey(int key) { - this.key = key; - setKeyIsSet(true); - } - - public void unsetKey() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __KEY_ISSET_ID); - } - - /** Returns true if field key is set (has been assigned a value) and false otherwise */ - public boolean isSetKey() { - return EncodingUtils.testBit(__isset_bitfield, __KEY_ISSET_ID); - } - - public void setKeyIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __KEY_ISSET_ID, value); - } - - public TAnnotationValue getValue() { - return this.value; - } - - public void setValue(TAnnotationValue value) { - this.value = value; - } - - public void unsetValue() { - this.value = null; - } - - /** Returns true if field value is set (has been assigned a value) and false otherwise */ - public boolean isSetValue() { - return this.value != null; - } - - public void setValueIsSet(boolean value) { - if (!value) { - this.value = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case KEY: - if (value == null) { - unsetKey(); - } else { - setKey((Integer)value); - } - break; - - case VALUE: - if (value == null) { - unsetValue(); - } else { - setValue((TAnnotationValue)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case KEY: - return Integer.valueOf(getKey()); - - case VALUE: - return getValue(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case KEY: - return isSetKey(); - case VALUE: - return isSetValue(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TAnnotation) - return this.equals((TAnnotation)that); - return false; - } - - public boolean equals(TAnnotation that) { - if (that == null) - return false; - - boolean this_present_key = true; - boolean that_present_key = true; - if (this_present_key || that_present_key) { - if (!(this_present_key && that_present_key)) - return false; - if (this.key != that.key) - return false; - } - - boolean this_present_value = true && this.isSetValue(); - boolean that_present_value = true && that.isSetValue(); - if (this_present_value || that_present_value) { - if (!(this_present_value && that_present_value)) - return false; - if (!this.value.equals(that.value)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TAnnotation other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetKey()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetValue()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TAnnotation("); - boolean first = true; - - sb.append("key:"); - sb.append(this.key); - first = false; - if (isSetValue()) { - if (!first) sb.append(", "); - sb.append("value:"); - if (this.value == null) { - sb.append("null"); - } else { - sb.append(this.value); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TAnnotationStandardSchemeFactory implements SchemeFactory { - public TAnnotationStandardScheme getScheme() { - return new TAnnotationStandardScheme(); - } - } - - private static class TAnnotationStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TAnnotation struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // KEY - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.key = iprot.readI32(); - struct.setKeyIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // VALUE - if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { - struct.value = new TAnnotationValue(); - struct.value.read(iprot); - struct.setValueIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TAnnotation struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - oprot.writeFieldBegin(KEY_FIELD_DESC); - oprot.writeI32(struct.key); - oprot.writeFieldEnd(); - if (struct.value != null) { - if (struct.isSetValue()) { - oprot.writeFieldBegin(VALUE_FIELD_DESC); - struct.value.write(oprot); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TAnnotationTupleSchemeFactory implements SchemeFactory { - public TAnnotationTupleScheme getScheme() { - return new TAnnotationTupleScheme(); - } - } - - private static class TAnnotationTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TAnnotation struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetKey()) { - optionals.set(0); - } - if (struct.isSetValue()) { - optionals.set(1); - } - oprot.writeBitSet(optionals, 2); - if (struct.isSetKey()) { - oprot.writeI32(struct.key); - } - if (struct.isSetValue()) { - struct.value.write(oprot); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TAnnotation struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(2); - if (incoming.get(0)) { - struct.key = iprot.readI32(); - struct.setKeyIsSet(true); - } - if (incoming.get(1)) { - struct.value = new TAnnotationValue(); - struct.value.read(iprot); - struct.setValueIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TAnnotation implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAnnotation"); + + private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRUCT, (short)2); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TAnnotationStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TAnnotationTupleSchemeFactory()); + } + + private int key; // required + private TAnnotationValue value; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + KEY((short)1, "key"), + VALUE((short)2, "value"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // KEY + return KEY; + case 2: // VALUE + return VALUE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __KEY_ISSET_ID = 0; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.VALUE}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAnnotationValue.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAnnotation.class, metaDataMap); + } + + public TAnnotation() { + } + + public TAnnotation( + int key) + { + this(); + this.key = key; + setKeyIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TAnnotation(TAnnotation other) { + __isset_bitfield = other.__isset_bitfield; + this.key = other.key; + if (other.isSetValue()) { + this.value = new TAnnotationValue(other.value); + } + } + + public TAnnotation deepCopy() { + return new TAnnotation(this); + } + + @Override + public void clear() { + setKeyIsSet(false); + this.key = 0; + this.value = null; + } + + public int getKey() { + return this.key; + } + + public void setKey(int key) { + this.key = key; + setKeyIsSet(true); + } + + public void unsetKey() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __KEY_ISSET_ID); + } + + /** Returns true if field key is set (has been assigned a value) and false otherwise */ + public boolean isSetKey() { + return EncodingUtils.testBit(__isset_bitfield, __KEY_ISSET_ID); + } + + public void setKeyIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __KEY_ISSET_ID, value); + } + + public TAnnotationValue getValue() { + return this.value; + } + + public void setValue(TAnnotationValue value) { + this.value = value; + } + + public void unsetValue() { + this.value = null; + } + + /** Returns true if field value is set (has been assigned a value) and false otherwise */ + public boolean isSetValue() { + return this.value != null; + } + + public void setValueIsSet(boolean value) { + if (!value) { + this.value = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case KEY: + if (value == null) { + unsetKey(); + } else { + setKey((Integer)value); + } + break; + + case VALUE: + if (value == null) { + unsetValue(); + } else { + setValue((TAnnotationValue)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case KEY: + return Integer.valueOf(getKey()); + + case VALUE: + return getValue(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case KEY: + return isSetKey(); + case VALUE: + return isSetValue(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TAnnotation) + return this.equals((TAnnotation)that); + return false; + } + + public boolean equals(TAnnotation that) { + if (that == null) + return false; + + boolean this_present_key = true; + boolean that_present_key = true; + if (this_present_key || that_present_key) { + if (!(this_present_key && that_present_key)) + return false; + if (this.key != that.key) + return false; + } + + boolean this_present_value = true && this.isSetValue(); + boolean that_present_value = true && that.isSetValue(); + if (this_present_value || that_present_value) { + if (!(this_present_value && that_present_value)) + return false; + if (!this.value.equals(that.value)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TAnnotation other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TAnnotation("); + boolean first = true; + + sb.append("key:"); + sb.append(this.key); + first = false; + if (isSetValue()) { + if (!first) sb.append(", "); + sb.append("value:"); + if (this.value == null) { + sb.append("null"); + } else { + sb.append(this.value); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TAnnotationStandardSchemeFactory implements SchemeFactory { + public TAnnotationStandardScheme getScheme() { + return new TAnnotationStandardScheme(); + } + } + + private static class TAnnotationStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TAnnotation struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // KEY + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.key = iprot.readI32(); + struct.setKeyIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // VALUE + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.value = new TAnnotationValue(); + struct.value.read(iprot); + struct.setValueIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TAnnotation struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeI32(struct.key); + oprot.writeFieldEnd(); + if (struct.value != null) { + if (struct.isSetValue()) { + oprot.writeFieldBegin(VALUE_FIELD_DESC); + struct.value.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TAnnotationTupleSchemeFactory implements SchemeFactory { + public TAnnotationTupleScheme getScheme() { + return new TAnnotationTupleScheme(); + } + } + + private static class TAnnotationTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TAnnotation struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetKey()) { + optionals.set(0); + } + if (struct.isSetValue()) { + optionals.set(1); + } + oprot.writeBitSet(optionals, 2); + if (struct.isSetKey()) { + oprot.writeI32(struct.key); + } + if (struct.isSetValue()) { + struct.value.write(oprot); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TAnnotation struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(2); + if (incoming.get(0)) { + struct.key = iprot.readI32(); + struct.setKeyIsSet(true); + } + if (incoming.get(1)) { + struct.value = new TAnnotationValue(); + struct.value.read(iprot); + struct.setValueIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotationValue.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotationValue.java index 00e43df17ffe..d50681d13d3a 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotationValue.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TAnnotationValue.java @@ -1,842 +1,842 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TAnnotationValue extends org.apache.thrift.TUnion { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAnnotationValue"); - private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField BOOL_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("boolValue", org.apache.thrift.protocol.TType.BOOL, (short)2); - private static final org.apache.thrift.protocol.TField INT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intValue", org.apache.thrift.protocol.TType.I32, (short)3); - private static final org.apache.thrift.protocol.TField LONG_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("longValue", org.apache.thrift.protocol.TType.I64, (short)4); - private static final org.apache.thrift.protocol.TField SHORT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("shortValue", org.apache.thrift.protocol.TType.I16, (short)5); - private static final org.apache.thrift.protocol.TField DOUBLE_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("doubleValue", org.apache.thrift.protocol.TType.DOUBLE, (short)6); - private static final org.apache.thrift.protocol.TField BINARY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("binaryValue", org.apache.thrift.protocol.TType.STRING, (short)7); - private static final org.apache.thrift.protocol.TField BYTE_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("byteValue", org.apache.thrift.protocol.TType.BYTE, (short)8); - private static final org.apache.thrift.protocol.TField INT_STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intStringValue", org.apache.thrift.protocol.TType.STRUCT, (short)9); - private static final org.apache.thrift.protocol.TField INT_STRING_STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intStringStringValue", org.apache.thrift.protocol.TType.STRUCT, (short)10); - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - STRING_VALUE((short)1, "stringValue"), - BOOL_VALUE((short)2, "boolValue"), - INT_VALUE((short)3, "intValue"), - LONG_VALUE((short)4, "longValue"), - SHORT_VALUE((short)5, "shortValue"), - DOUBLE_VALUE((short)6, "doubleValue"), - BINARY_VALUE((short)7, "binaryValue"), - BYTE_VALUE((short)8, "byteValue"), - INT_STRING_VALUE((short)9, "intStringValue"), - INT_STRING_STRING_VALUE((short)10, "intStringStringValue"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // STRING_VALUE - return STRING_VALUE; - case 2: // BOOL_VALUE - return BOOL_VALUE; - case 3: // INT_VALUE - return INT_VALUE; - case 4: // LONG_VALUE - return LONG_VALUE; - case 5: // SHORT_VALUE - return SHORT_VALUE; - case 6: // DOUBLE_VALUE - return DOUBLE_VALUE; - case 7: // BINARY_VALUE - return BINARY_VALUE; - case 8: // BYTE_VALUE - return BYTE_VALUE; - case 9: // INT_STRING_VALUE - return INT_STRING_VALUE; - case 10: // INT_STRING_STRING_VALUE - return INT_STRING_STRING_VALUE; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.BOOL_VALUE, new org.apache.thrift.meta_data.FieldMetaData("boolValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); - tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.LONG_VALUE, new org.apache.thrift.meta_data.FieldMetaData("longValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.SHORT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("shortValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.DOUBLE_VALUE, new org.apache.thrift.meta_data.FieldMetaData("doubleValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))); - tmpMap.put(_Fields.BINARY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("binaryValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); - tmpMap.put(_Fields.BYTE_VALUE, new org.apache.thrift.meta_data.FieldMetaData("byteValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE))); - tmpMap.put(_Fields.INT_STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intStringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringValue.class))); - tmpMap.put(_Fields.INT_STRING_STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intStringStringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringStringValue.class))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAnnotationValue.class, metaDataMap); - } - - public TAnnotationValue() { - super(); - } - - public TAnnotationValue(_Fields setField, Object value) { - super(setField, value); - } - - public TAnnotationValue(TAnnotationValue other) { - super(other); - } - public TAnnotationValue deepCopy() { - return new TAnnotationValue(this); - } - - public static TAnnotationValue stringValue(String value) { - TAnnotationValue x = new TAnnotationValue(); - x.setStringValue(value); - return x; - } - - public static TAnnotationValue boolValue(boolean value) { - TAnnotationValue x = new TAnnotationValue(); - x.setBoolValue(value); - return x; - } - - public static TAnnotationValue intValue(int value) { - TAnnotationValue x = new TAnnotationValue(); - x.setIntValue(value); - return x; - } - - public static TAnnotationValue longValue(long value) { - TAnnotationValue x = new TAnnotationValue(); - x.setLongValue(value); - return x; - } - - public static TAnnotationValue shortValue(short value) { - TAnnotationValue x = new TAnnotationValue(); - x.setShortValue(value); - return x; - } - - public static TAnnotationValue doubleValue(double value) { - TAnnotationValue x = new TAnnotationValue(); - x.setDoubleValue(value); - return x; - } - - public static TAnnotationValue binaryValue(ByteBuffer value) { - TAnnotationValue x = new TAnnotationValue(); - x.setBinaryValue(value); - return x; - } - - public static TAnnotationValue binaryValue(byte[] value) { - TAnnotationValue x = new TAnnotationValue(); - x.setBinaryValue(ByteBuffer.wrap(value)); - return x; - } - - public static TAnnotationValue byteValue(byte value) { - TAnnotationValue x = new TAnnotationValue(); - x.setByteValue(value); - return x; - } - - public static TAnnotationValue intStringValue(TIntStringValue value) { - TAnnotationValue x = new TAnnotationValue(); - x.setIntStringValue(value); - return x; - } - - public static TAnnotationValue intStringStringValue(TIntStringStringValue value) { - TAnnotationValue x = new TAnnotationValue(); - x.setIntStringStringValue(value); - return x; - } - - - @Override - protected void checkType(_Fields setField, Object value) throws ClassCastException { - switch (setField) { - case STRING_VALUE: - if (value instanceof String) { - break; - } - throw new ClassCastException("Was expecting value of type String for field 'stringValue', but got " + value.getClass().getSimpleName()); - case BOOL_VALUE: - if (value instanceof Boolean) { - break; - } - throw new ClassCastException("Was expecting value of type Boolean for field 'boolValue', but got " + value.getClass().getSimpleName()); - case INT_VALUE: - if (value instanceof Integer) { - break; - } - throw new ClassCastException("Was expecting value of type Integer for field 'intValue', but got " + value.getClass().getSimpleName()); - case LONG_VALUE: - if (value instanceof Long) { - break; - } - throw new ClassCastException("Was expecting value of type Long for field 'longValue', but got " + value.getClass().getSimpleName()); - case SHORT_VALUE: - if (value instanceof Short) { - break; - } - throw new ClassCastException("Was expecting value of type Short for field 'shortValue', but got " + value.getClass().getSimpleName()); - case DOUBLE_VALUE: - if (value instanceof Double) { - break; - } - throw new ClassCastException("Was expecting value of type Double for field 'doubleValue', but got " + value.getClass().getSimpleName()); - case BINARY_VALUE: - if (value instanceof ByteBuffer) { - break; - } - throw new ClassCastException("Was expecting value of type ByteBuffer for field 'binaryValue', but got " + value.getClass().getSimpleName()); - case BYTE_VALUE: - if (value instanceof Byte) { - break; - } - throw new ClassCastException("Was expecting value of type Byte for field 'byteValue', but got " + value.getClass().getSimpleName()); - case INT_STRING_VALUE: - if (value instanceof TIntStringValue) { - break; - } - throw new ClassCastException("Was expecting value of type TIntStringValue for field 'intStringValue', but got " + value.getClass().getSimpleName()); - case INT_STRING_STRING_VALUE: - if (value instanceof TIntStringStringValue) { - break; - } - throw new ClassCastException("Was expecting value of type TIntStringStringValue for field 'intStringStringValue', but got " + value.getClass().getSimpleName()); - default: - throw new IllegalArgumentException("Unknown field id " + setField); - } - } - - @Override - protected Object standardSchemeReadValue(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TField field) throws org.apache.thrift.TException { - _Fields setField = _Fields.findByThriftId(field.id); - if (setField != null) { - switch (setField) { - case STRING_VALUE: - if (field.type == STRING_VALUE_FIELD_DESC.type) { - String stringValue; - stringValue = iprot.readString(); - return stringValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case BOOL_VALUE: - if (field.type == BOOL_VALUE_FIELD_DESC.type) { - Boolean boolValue; - boolValue = iprot.readBool(); - return boolValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case INT_VALUE: - if (field.type == INT_VALUE_FIELD_DESC.type) { - Integer intValue; - intValue = iprot.readI32(); - return intValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case LONG_VALUE: - if (field.type == LONG_VALUE_FIELD_DESC.type) { - Long longValue; - longValue = iprot.readI64(); - return longValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case SHORT_VALUE: - if (field.type == SHORT_VALUE_FIELD_DESC.type) { - Short shortValue; - shortValue = iprot.readI16(); - return shortValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case DOUBLE_VALUE: - if (field.type == DOUBLE_VALUE_FIELD_DESC.type) { - Double doubleValue; - doubleValue = iprot.readDouble(); - return doubleValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case BINARY_VALUE: - if (field.type == BINARY_VALUE_FIELD_DESC.type) { - ByteBuffer binaryValue; - binaryValue = iprot.readBinary(); - return binaryValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case BYTE_VALUE: - if (field.type == BYTE_VALUE_FIELD_DESC.type) { - Byte byteValue; - byteValue = iprot.readByte(); - return byteValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case INT_STRING_VALUE: - if (field.type == INT_STRING_VALUE_FIELD_DESC.type) { - TIntStringValue intStringValue; - intStringValue = new TIntStringValue(); - intStringValue.read(iprot); - return intStringValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - case INT_STRING_STRING_VALUE: - if (field.type == INT_STRING_STRING_VALUE_FIELD_DESC.type) { - TIntStringStringValue intStringStringValue; - intStringStringValue = new TIntStringStringValue(); - intStringStringValue.read(iprot); - return intStringStringValue; - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - default: - throw new IllegalStateException("setField wasn't null, but didn't match any of the case statements!"); - } - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); - return null; - } - } - - @Override - protected void standardSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - switch (setField_) { - case STRING_VALUE: - String stringValue = (String)value_; - oprot.writeString(stringValue); - return; - case BOOL_VALUE: - Boolean boolValue = (Boolean)value_; - oprot.writeBool(boolValue); - return; - case INT_VALUE: - Integer intValue = (Integer)value_; - oprot.writeI32(intValue); - return; - case LONG_VALUE: - Long longValue = (Long)value_; - oprot.writeI64(longValue); - return; - case SHORT_VALUE: - Short shortValue = (Short)value_; - oprot.writeI16(shortValue); - return; - case DOUBLE_VALUE: - Double doubleValue = (Double)value_; - oprot.writeDouble(doubleValue); - return; - case BINARY_VALUE: - ByteBuffer binaryValue = (ByteBuffer)value_; - oprot.writeBinary(binaryValue); - return; - case BYTE_VALUE: - Byte byteValue = (Byte)value_; - oprot.writeByte(byteValue); - return; - case INT_STRING_VALUE: - TIntStringValue intStringValue = (TIntStringValue)value_; - intStringValue.write(oprot); - return; - case INT_STRING_STRING_VALUE: - TIntStringStringValue intStringStringValue = (TIntStringStringValue)value_; - intStringStringValue.write(oprot); - return; - default: - throw new IllegalStateException("Cannot write union with unknown field " + setField_); - } - } - - @Override - protected Object tupleSchemeReadValue(org.apache.thrift.protocol.TProtocol iprot, short fieldID) throws org.apache.thrift.TException { - _Fields setField = _Fields.findByThriftId(fieldID); - if (setField != null) { - switch (setField) { - case STRING_VALUE: - String stringValue; - stringValue = iprot.readString(); - return stringValue; - case BOOL_VALUE: - Boolean boolValue; - boolValue = iprot.readBool(); - return boolValue; - case INT_VALUE: - Integer intValue; - intValue = iprot.readI32(); - return intValue; - case LONG_VALUE: - Long longValue; - longValue = iprot.readI64(); - return longValue; - case SHORT_VALUE: - Short shortValue; - shortValue = iprot.readI16(); - return shortValue; - case DOUBLE_VALUE: - Double doubleValue; - doubleValue = iprot.readDouble(); - return doubleValue; - case BINARY_VALUE: - ByteBuffer binaryValue; - binaryValue = iprot.readBinary(); - return binaryValue; - case BYTE_VALUE: - Byte byteValue; - byteValue = iprot.readByte(); - return byteValue; - case INT_STRING_VALUE: - TIntStringValue intStringValue; - intStringValue = new TIntStringValue(); - intStringValue.read(iprot); - return intStringValue; - case INT_STRING_STRING_VALUE: - TIntStringStringValue intStringStringValue; - intStringStringValue = new TIntStringStringValue(); - intStringStringValue.read(iprot); - return intStringStringValue; - default: - throw new IllegalStateException("setField wasn't null, but didn't match any of the case statements!"); - } - } else { - throw new TProtocolException("Couldn't find a field with field id " + fieldID); - } - } - - @Override - protected void tupleSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - switch (setField_) { - case STRING_VALUE: - String stringValue = (String)value_; - oprot.writeString(stringValue); - return; - case BOOL_VALUE: - Boolean boolValue = (Boolean)value_; - oprot.writeBool(boolValue); - return; - case INT_VALUE: - Integer intValue = (Integer)value_; - oprot.writeI32(intValue); - return; - case LONG_VALUE: - Long longValue = (Long)value_; - oprot.writeI64(longValue); - return; - case SHORT_VALUE: - Short shortValue = (Short)value_; - oprot.writeI16(shortValue); - return; - case DOUBLE_VALUE: - Double doubleValue = (Double)value_; - oprot.writeDouble(doubleValue); - return; - case BINARY_VALUE: - ByteBuffer binaryValue = (ByteBuffer)value_; - oprot.writeBinary(binaryValue); - return; - case BYTE_VALUE: - Byte byteValue = (Byte)value_; - oprot.writeByte(byteValue); - return; - case INT_STRING_VALUE: - TIntStringValue intStringValue = (TIntStringValue)value_; - intStringValue.write(oprot); - return; - case INT_STRING_STRING_VALUE: - TIntStringStringValue intStringStringValue = (TIntStringStringValue)value_; - intStringStringValue.write(oprot); - return; - default: - throw new IllegalStateException("Cannot write union with unknown field " + setField_); - } - } - - @Override - protected org.apache.thrift.protocol.TField getFieldDesc(_Fields setField) { - switch (setField) { - case STRING_VALUE: - return STRING_VALUE_FIELD_DESC; - case BOOL_VALUE: - return BOOL_VALUE_FIELD_DESC; - case INT_VALUE: - return INT_VALUE_FIELD_DESC; - case LONG_VALUE: - return LONG_VALUE_FIELD_DESC; - case SHORT_VALUE: - return SHORT_VALUE_FIELD_DESC; - case DOUBLE_VALUE: - return DOUBLE_VALUE_FIELD_DESC; - case BINARY_VALUE: - return BINARY_VALUE_FIELD_DESC; - case BYTE_VALUE: - return BYTE_VALUE_FIELD_DESC; - case INT_STRING_VALUE: - return INT_STRING_VALUE_FIELD_DESC; - case INT_STRING_STRING_VALUE: - return INT_STRING_STRING_VALUE_FIELD_DESC; - default: - throw new IllegalArgumentException("Unknown field id " + setField); - } - } - - @Override - protected org.apache.thrift.protocol.TStruct getStructDesc() { - return STRUCT_DESC; - } - - @Override - protected _Fields enumForId(short id) { - return _Fields.findByThriftIdOrThrow(id); - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - - public String getStringValue() { - if (getSetField() == _Fields.STRING_VALUE) { - return (String)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'stringValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setStringValue(String value) { - if (value == null) throw new NullPointerException(); - setField_ = _Fields.STRING_VALUE; - value_ = value; - } - - public boolean getBoolValue() { - if (getSetField() == _Fields.BOOL_VALUE) { - return (Boolean)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'boolValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setBoolValue(boolean value) { - setField_ = _Fields.BOOL_VALUE; - value_ = value; - } - - public int getIntValue() { - if (getSetField() == _Fields.INT_VALUE) { - return (Integer)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'intValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setIntValue(int value) { - setField_ = _Fields.INT_VALUE; - value_ = value; - } - - public long getLongValue() { - if (getSetField() == _Fields.LONG_VALUE) { - return (Long)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'longValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setLongValue(long value) { - setField_ = _Fields.LONG_VALUE; - value_ = value; - } - - public short getShortValue() { - if (getSetField() == _Fields.SHORT_VALUE) { - return (Short)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'shortValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setShortValue(short value) { - setField_ = _Fields.SHORT_VALUE; - value_ = value; - } - - public double getDoubleValue() { - if (getSetField() == _Fields.DOUBLE_VALUE) { - return (Double)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'doubleValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setDoubleValue(double value) { - setField_ = _Fields.DOUBLE_VALUE; - value_ = value; - } - - public byte[] getBinaryValue() { - setBinaryValue(org.apache.thrift.TBaseHelper.rightSize(bufferForBinaryValue())); - ByteBuffer b = bufferForBinaryValue(); - return b == null ? null : b.array(); - } - - public ByteBuffer bufferForBinaryValue() { - if (getSetField() == _Fields.BINARY_VALUE) { - return (ByteBuffer)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'binaryValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setBinaryValue(byte[] value) { - setBinaryValue(ByteBuffer.wrap(value)); - } - - public void setBinaryValue(ByteBuffer value) { - if (value == null) throw new NullPointerException(); - setField_ = _Fields.BINARY_VALUE; - value_ = value; - } - - public byte getByteValue() { - if (getSetField() == _Fields.BYTE_VALUE) { - return (Byte)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'byteValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setByteValue(byte value) { - setField_ = _Fields.BYTE_VALUE; - value_ = value; - } - - public TIntStringValue getIntStringValue() { - if (getSetField() == _Fields.INT_STRING_VALUE) { - return (TIntStringValue)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'intStringValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setIntStringValue(TIntStringValue value) { - if (value == null) throw new NullPointerException(); - setField_ = _Fields.INT_STRING_VALUE; - value_ = value; - } - - public TIntStringStringValue getIntStringStringValue() { - if (getSetField() == _Fields.INT_STRING_STRING_VALUE) { - return (TIntStringStringValue)getFieldValue(); - } else { - throw new RuntimeException("Cannot get field 'intStringStringValue' because union is currently set to " + getFieldDesc(getSetField()).name); - } - } - - public void setIntStringStringValue(TIntStringStringValue value) { - if (value == null) throw new NullPointerException(); - setField_ = _Fields.INT_STRING_STRING_VALUE; - value_ = value; - } - - public boolean isSetStringValue() { - return setField_ == _Fields.STRING_VALUE; - } - - - public boolean isSetBoolValue() { - return setField_ == _Fields.BOOL_VALUE; - } - - - public boolean isSetIntValue() { - return setField_ == _Fields.INT_VALUE; - } - - - public boolean isSetLongValue() { - return setField_ == _Fields.LONG_VALUE; - } - - - public boolean isSetShortValue() { - return setField_ == _Fields.SHORT_VALUE; - } - - - public boolean isSetDoubleValue() { - return setField_ == _Fields.DOUBLE_VALUE; - } - - - public boolean isSetBinaryValue() { - return setField_ == _Fields.BINARY_VALUE; - } - - - public boolean isSetByteValue() { - return setField_ == _Fields.BYTE_VALUE; - } - - - public boolean isSetIntStringValue() { - return setField_ == _Fields.INT_STRING_VALUE; - } - - - public boolean isSetIntStringStringValue() { - return setField_ == _Fields.INT_STRING_STRING_VALUE; - } - - - public boolean equals(Object other) { - if (other instanceof TAnnotationValue) { - return equals((TAnnotationValue)other); - } else { - return false; - } - } - - public boolean equals(TAnnotationValue other) { - return other != null && getSetField() == other.getSetField() && getFieldValue().equals(other.getFieldValue()); - } - - @Override - public int compareTo(TAnnotationValue other) { - int lastComparison = org.apache.thrift.TBaseHelper.compareTo(getSetField(), other.getSetField()); - if (lastComparison == 0) { - return org.apache.thrift.TBaseHelper.compareTo(getFieldValue(), other.getFieldValue()); - } - return lastComparison; - } - - - /** - * If you'd like this to perform more respectably, use the hashcode generator option. - */ - @Override - public int hashCode() { - return 0; - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - -} +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TAnnotationValue extends org.apache.thrift.TUnion { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TAnnotationValue"); + private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField BOOL_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("boolValue", org.apache.thrift.protocol.TType.BOOL, (short)2); + private static final org.apache.thrift.protocol.TField INT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intValue", org.apache.thrift.protocol.TType.I32, (short)3); + private static final org.apache.thrift.protocol.TField LONG_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("longValue", org.apache.thrift.protocol.TType.I64, (short)4); + private static final org.apache.thrift.protocol.TField SHORT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("shortValue", org.apache.thrift.protocol.TType.I16, (short)5); + private static final org.apache.thrift.protocol.TField DOUBLE_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("doubleValue", org.apache.thrift.protocol.TType.DOUBLE, (short)6); + private static final org.apache.thrift.protocol.TField BINARY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("binaryValue", org.apache.thrift.protocol.TType.STRING, (short)7); + private static final org.apache.thrift.protocol.TField BYTE_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("byteValue", org.apache.thrift.protocol.TType.BYTE, (short)8); + private static final org.apache.thrift.protocol.TField INT_STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intStringValue", org.apache.thrift.protocol.TType.STRUCT, (short)9); + private static final org.apache.thrift.protocol.TField INT_STRING_STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intStringStringValue", org.apache.thrift.protocol.TType.STRUCT, (short)10); + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + STRING_VALUE((short)1, "stringValue"), + BOOL_VALUE((short)2, "boolValue"), + INT_VALUE((short)3, "intValue"), + LONG_VALUE((short)4, "longValue"), + SHORT_VALUE((short)5, "shortValue"), + DOUBLE_VALUE((short)6, "doubleValue"), + BINARY_VALUE((short)7, "binaryValue"), + BYTE_VALUE((short)8, "byteValue"), + INT_STRING_VALUE((short)9, "intStringValue"), + INT_STRING_STRING_VALUE((short)10, "intStringStringValue"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // STRING_VALUE + return STRING_VALUE; + case 2: // BOOL_VALUE + return BOOL_VALUE; + case 3: // INT_VALUE + return INT_VALUE; + case 4: // LONG_VALUE + return LONG_VALUE; + case 5: // SHORT_VALUE + return SHORT_VALUE; + case 6: // DOUBLE_VALUE + return DOUBLE_VALUE; + case 7: // BINARY_VALUE + return BINARY_VALUE; + case 8: // BYTE_VALUE + return BYTE_VALUE; + case 9: // INT_STRING_VALUE + return INT_STRING_VALUE; + case 10: // INT_STRING_STRING_VALUE + return INT_STRING_STRING_VALUE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.BOOL_VALUE, new org.apache.thrift.meta_data.FieldMetaData("boolValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); + tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.LONG_VALUE, new org.apache.thrift.meta_data.FieldMetaData("longValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.SHORT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("shortValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.DOUBLE_VALUE, new org.apache.thrift.meta_data.FieldMetaData("doubleValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))); + tmpMap.put(_Fields.BINARY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("binaryValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.BYTE_VALUE, new org.apache.thrift.meta_data.FieldMetaData("byteValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE))); + tmpMap.put(_Fields.INT_STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intStringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringValue.class))); + tmpMap.put(_Fields.INT_STRING_STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intStringStringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringStringValue.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TAnnotationValue.class, metaDataMap); + } + + public TAnnotationValue() { + super(); + } + + public TAnnotationValue(_Fields setField, Object value) { + super(setField, value); + } + + public TAnnotationValue(TAnnotationValue other) { + super(other); + } + public TAnnotationValue deepCopy() { + return new TAnnotationValue(this); + } + + public static TAnnotationValue stringValue(String value) { + TAnnotationValue x = new TAnnotationValue(); + x.setStringValue(value); + return x; + } + + public static TAnnotationValue boolValue(boolean value) { + TAnnotationValue x = new TAnnotationValue(); + x.setBoolValue(value); + return x; + } + + public static TAnnotationValue intValue(int value) { + TAnnotationValue x = new TAnnotationValue(); + x.setIntValue(value); + return x; + } + + public static TAnnotationValue longValue(long value) { + TAnnotationValue x = new TAnnotationValue(); + x.setLongValue(value); + return x; + } + + public static TAnnotationValue shortValue(short value) { + TAnnotationValue x = new TAnnotationValue(); + x.setShortValue(value); + return x; + } + + public static TAnnotationValue doubleValue(double value) { + TAnnotationValue x = new TAnnotationValue(); + x.setDoubleValue(value); + return x; + } + + public static TAnnotationValue binaryValue(ByteBuffer value) { + TAnnotationValue x = new TAnnotationValue(); + x.setBinaryValue(value); + return x; + } + + public static TAnnotationValue binaryValue(byte[] value) { + TAnnotationValue x = new TAnnotationValue(); + x.setBinaryValue(ByteBuffer.wrap(value)); + return x; + } + + public static TAnnotationValue byteValue(byte value) { + TAnnotationValue x = new TAnnotationValue(); + x.setByteValue(value); + return x; + } + + public static TAnnotationValue intStringValue(TIntStringValue value) { + TAnnotationValue x = new TAnnotationValue(); + x.setIntStringValue(value); + return x; + } + + public static TAnnotationValue intStringStringValue(TIntStringStringValue value) { + TAnnotationValue x = new TAnnotationValue(); + x.setIntStringStringValue(value); + return x; + } + + + @Override + protected void checkType(_Fields setField, Object value) throws ClassCastException { + switch (setField) { + case STRING_VALUE: + if (value instanceof String) { + break; + } + throw new ClassCastException("Was expecting value of type String for field 'stringValue', but got " + value.getClass().getSimpleName()); + case BOOL_VALUE: + if (value instanceof Boolean) { + break; + } + throw new ClassCastException("Was expecting value of type Boolean for field 'boolValue', but got " + value.getClass().getSimpleName()); + case INT_VALUE: + if (value instanceof Integer) { + break; + } + throw new ClassCastException("Was expecting value of type Integer for field 'intValue', but got " + value.getClass().getSimpleName()); + case LONG_VALUE: + if (value instanceof Long) { + break; + } + throw new ClassCastException("Was expecting value of type Long for field 'longValue', but got " + value.getClass().getSimpleName()); + case SHORT_VALUE: + if (value instanceof Short) { + break; + } + throw new ClassCastException("Was expecting value of type Short for field 'shortValue', but got " + value.getClass().getSimpleName()); + case DOUBLE_VALUE: + if (value instanceof Double) { + break; + } + throw new ClassCastException("Was expecting value of type Double for field 'doubleValue', but got " + value.getClass().getSimpleName()); + case BINARY_VALUE: + if (value instanceof ByteBuffer) { + break; + } + throw new ClassCastException("Was expecting value of type ByteBuffer for field 'binaryValue', but got " + value.getClass().getSimpleName()); + case BYTE_VALUE: + if (value instanceof Byte) { + break; + } + throw new ClassCastException("Was expecting value of type Byte for field 'byteValue', but got " + value.getClass().getSimpleName()); + case INT_STRING_VALUE: + if (value instanceof TIntStringValue) { + break; + } + throw new ClassCastException("Was expecting value of type TIntStringValue for field 'intStringValue', but got " + value.getClass().getSimpleName()); + case INT_STRING_STRING_VALUE: + if (value instanceof TIntStringStringValue) { + break; + } + throw new ClassCastException("Was expecting value of type TIntStringStringValue for field 'intStringStringValue', but got " + value.getClass().getSimpleName()); + default: + throw new IllegalArgumentException("Unknown field id " + setField); + } + } + + @Override + protected Object standardSchemeReadValue(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TField field) throws org.apache.thrift.TException { + _Fields setField = _Fields.findByThriftId(field.id); + if (setField != null) { + switch (setField) { + case STRING_VALUE: + if (field.type == STRING_VALUE_FIELD_DESC.type) { + String stringValue; + stringValue = iprot.readString(); + return stringValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case BOOL_VALUE: + if (field.type == BOOL_VALUE_FIELD_DESC.type) { + Boolean boolValue; + boolValue = iprot.readBool(); + return boolValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case INT_VALUE: + if (field.type == INT_VALUE_FIELD_DESC.type) { + Integer intValue; + intValue = iprot.readI32(); + return intValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case LONG_VALUE: + if (field.type == LONG_VALUE_FIELD_DESC.type) { + Long longValue; + longValue = iprot.readI64(); + return longValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case SHORT_VALUE: + if (field.type == SHORT_VALUE_FIELD_DESC.type) { + Short shortValue; + shortValue = iprot.readI16(); + return shortValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case DOUBLE_VALUE: + if (field.type == DOUBLE_VALUE_FIELD_DESC.type) { + Double doubleValue; + doubleValue = iprot.readDouble(); + return doubleValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case BINARY_VALUE: + if (field.type == BINARY_VALUE_FIELD_DESC.type) { + ByteBuffer binaryValue; + binaryValue = iprot.readBinary(); + return binaryValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case BYTE_VALUE: + if (field.type == BYTE_VALUE_FIELD_DESC.type) { + Byte byteValue; + byteValue = iprot.readByte(); + return byteValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case INT_STRING_VALUE: + if (field.type == INT_STRING_VALUE_FIELD_DESC.type) { + TIntStringValue intStringValue; + intStringValue = new TIntStringValue(); + intStringValue.read(iprot); + return intStringValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + case INT_STRING_STRING_VALUE: + if (field.type == INT_STRING_STRING_VALUE_FIELD_DESC.type) { + TIntStringStringValue intStringStringValue; + intStringStringValue = new TIntStringStringValue(); + intStringStringValue.read(iprot); + return intStringStringValue; + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + default: + throw new IllegalStateException("setField wasn't null, but didn't match any of the case statements!"); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + return null; + } + } + + @Override + protected void standardSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + switch (setField_) { + case STRING_VALUE: + String stringValue = (String)value_; + oprot.writeString(stringValue); + return; + case BOOL_VALUE: + Boolean boolValue = (Boolean)value_; + oprot.writeBool(boolValue); + return; + case INT_VALUE: + Integer intValue = (Integer)value_; + oprot.writeI32(intValue); + return; + case LONG_VALUE: + Long longValue = (Long)value_; + oprot.writeI64(longValue); + return; + case SHORT_VALUE: + Short shortValue = (Short)value_; + oprot.writeI16(shortValue); + return; + case DOUBLE_VALUE: + Double doubleValue = (Double)value_; + oprot.writeDouble(doubleValue); + return; + case BINARY_VALUE: + ByteBuffer binaryValue = (ByteBuffer)value_; + oprot.writeBinary(binaryValue); + return; + case BYTE_VALUE: + Byte byteValue = (Byte)value_; + oprot.writeByte(byteValue); + return; + case INT_STRING_VALUE: + TIntStringValue intStringValue = (TIntStringValue)value_; + intStringValue.write(oprot); + return; + case INT_STRING_STRING_VALUE: + TIntStringStringValue intStringStringValue = (TIntStringStringValue)value_; + intStringStringValue.write(oprot); + return; + default: + throw new IllegalStateException("Cannot write union with unknown field " + setField_); + } + } + + @Override + protected Object tupleSchemeReadValue(org.apache.thrift.protocol.TProtocol iprot, short fieldID) throws org.apache.thrift.TException { + _Fields setField = _Fields.findByThriftId(fieldID); + if (setField != null) { + switch (setField) { + case STRING_VALUE: + String stringValue; + stringValue = iprot.readString(); + return stringValue; + case BOOL_VALUE: + Boolean boolValue; + boolValue = iprot.readBool(); + return boolValue; + case INT_VALUE: + Integer intValue; + intValue = iprot.readI32(); + return intValue; + case LONG_VALUE: + Long longValue; + longValue = iprot.readI64(); + return longValue; + case SHORT_VALUE: + Short shortValue; + shortValue = iprot.readI16(); + return shortValue; + case DOUBLE_VALUE: + Double doubleValue; + doubleValue = iprot.readDouble(); + return doubleValue; + case BINARY_VALUE: + ByteBuffer binaryValue; + binaryValue = iprot.readBinary(); + return binaryValue; + case BYTE_VALUE: + Byte byteValue; + byteValue = iprot.readByte(); + return byteValue; + case INT_STRING_VALUE: + TIntStringValue intStringValue; + intStringValue = new TIntStringValue(); + intStringValue.read(iprot); + return intStringValue; + case INT_STRING_STRING_VALUE: + TIntStringStringValue intStringStringValue; + intStringStringValue = new TIntStringStringValue(); + intStringStringValue.read(iprot); + return intStringStringValue; + default: + throw new IllegalStateException("setField wasn't null, but didn't match any of the case statements!"); + } + } else { + throw new TProtocolException("Couldn't find a field with field id " + fieldID); + } + } + + @Override + protected void tupleSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + switch (setField_) { + case STRING_VALUE: + String stringValue = (String)value_; + oprot.writeString(stringValue); + return; + case BOOL_VALUE: + Boolean boolValue = (Boolean)value_; + oprot.writeBool(boolValue); + return; + case INT_VALUE: + Integer intValue = (Integer)value_; + oprot.writeI32(intValue); + return; + case LONG_VALUE: + Long longValue = (Long)value_; + oprot.writeI64(longValue); + return; + case SHORT_VALUE: + Short shortValue = (Short)value_; + oprot.writeI16(shortValue); + return; + case DOUBLE_VALUE: + Double doubleValue = (Double)value_; + oprot.writeDouble(doubleValue); + return; + case BINARY_VALUE: + ByteBuffer binaryValue = (ByteBuffer)value_; + oprot.writeBinary(binaryValue); + return; + case BYTE_VALUE: + Byte byteValue = (Byte)value_; + oprot.writeByte(byteValue); + return; + case INT_STRING_VALUE: + TIntStringValue intStringValue = (TIntStringValue)value_; + intStringValue.write(oprot); + return; + case INT_STRING_STRING_VALUE: + TIntStringStringValue intStringStringValue = (TIntStringStringValue)value_; + intStringStringValue.write(oprot); + return; + default: + throw new IllegalStateException("Cannot write union with unknown field " + setField_); + } + } + + @Override + protected org.apache.thrift.protocol.TField getFieldDesc(_Fields setField) { + switch (setField) { + case STRING_VALUE: + return STRING_VALUE_FIELD_DESC; + case BOOL_VALUE: + return BOOL_VALUE_FIELD_DESC; + case INT_VALUE: + return INT_VALUE_FIELD_DESC; + case LONG_VALUE: + return LONG_VALUE_FIELD_DESC; + case SHORT_VALUE: + return SHORT_VALUE_FIELD_DESC; + case DOUBLE_VALUE: + return DOUBLE_VALUE_FIELD_DESC; + case BINARY_VALUE: + return BINARY_VALUE_FIELD_DESC; + case BYTE_VALUE: + return BYTE_VALUE_FIELD_DESC; + case INT_STRING_VALUE: + return INT_STRING_VALUE_FIELD_DESC; + case INT_STRING_STRING_VALUE: + return INT_STRING_STRING_VALUE_FIELD_DESC; + default: + throw new IllegalArgumentException("Unknown field id " + setField); + } + } + + @Override + protected org.apache.thrift.protocol.TStruct getStructDesc() { + return STRUCT_DESC; + } + + @Override + protected _Fields enumForId(short id) { + return _Fields.findByThriftIdOrThrow(id); + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + + public String getStringValue() { + if (getSetField() == _Fields.STRING_VALUE) { + return (String)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'stringValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setStringValue(String value) { + if (value == null) throw new NullPointerException(); + setField_ = _Fields.STRING_VALUE; + value_ = value; + } + + public boolean getBoolValue() { + if (getSetField() == _Fields.BOOL_VALUE) { + return (Boolean)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'boolValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setBoolValue(boolean value) { + setField_ = _Fields.BOOL_VALUE; + value_ = value; + } + + public int getIntValue() { + if (getSetField() == _Fields.INT_VALUE) { + return (Integer)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'intValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setIntValue(int value) { + setField_ = _Fields.INT_VALUE; + value_ = value; + } + + public long getLongValue() { + if (getSetField() == _Fields.LONG_VALUE) { + return (Long)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'longValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setLongValue(long value) { + setField_ = _Fields.LONG_VALUE; + value_ = value; + } + + public short getShortValue() { + if (getSetField() == _Fields.SHORT_VALUE) { + return (Short)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'shortValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setShortValue(short value) { + setField_ = _Fields.SHORT_VALUE; + value_ = value; + } + + public double getDoubleValue() { + if (getSetField() == _Fields.DOUBLE_VALUE) { + return (Double)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'doubleValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setDoubleValue(double value) { + setField_ = _Fields.DOUBLE_VALUE; + value_ = value; + } + + public byte[] getBinaryValue() { + setBinaryValue(org.apache.thrift.TBaseHelper.rightSize(bufferForBinaryValue())); + ByteBuffer b = bufferForBinaryValue(); + return b == null ? null : b.array(); + } + + public ByteBuffer bufferForBinaryValue() { + if (getSetField() == _Fields.BINARY_VALUE) { + return (ByteBuffer)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'binaryValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setBinaryValue(byte[] value) { + setBinaryValue(ByteBuffer.wrap(value)); + } + + public void setBinaryValue(ByteBuffer value) { + if (value == null) throw new NullPointerException(); + setField_ = _Fields.BINARY_VALUE; + value_ = value; + } + + public byte getByteValue() { + if (getSetField() == _Fields.BYTE_VALUE) { + return (Byte)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'byteValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setByteValue(byte value) { + setField_ = _Fields.BYTE_VALUE; + value_ = value; + } + + public TIntStringValue getIntStringValue() { + if (getSetField() == _Fields.INT_STRING_VALUE) { + return (TIntStringValue)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'intStringValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setIntStringValue(TIntStringValue value) { + if (value == null) throw new NullPointerException(); + setField_ = _Fields.INT_STRING_VALUE; + value_ = value; + } + + public TIntStringStringValue getIntStringStringValue() { + if (getSetField() == _Fields.INT_STRING_STRING_VALUE) { + return (TIntStringStringValue)getFieldValue(); + } else { + throw new RuntimeException("Cannot get field 'intStringStringValue' because union is currently set to " + getFieldDesc(getSetField()).name); + } + } + + public void setIntStringStringValue(TIntStringStringValue value) { + if (value == null) throw new NullPointerException(); + setField_ = _Fields.INT_STRING_STRING_VALUE; + value_ = value; + } + + public boolean isSetStringValue() { + return setField_ == _Fields.STRING_VALUE; + } + + + public boolean isSetBoolValue() { + return setField_ == _Fields.BOOL_VALUE; + } + + + public boolean isSetIntValue() { + return setField_ == _Fields.INT_VALUE; + } + + + public boolean isSetLongValue() { + return setField_ == _Fields.LONG_VALUE; + } + + + public boolean isSetShortValue() { + return setField_ == _Fields.SHORT_VALUE; + } + + + public boolean isSetDoubleValue() { + return setField_ == _Fields.DOUBLE_VALUE; + } + + + public boolean isSetBinaryValue() { + return setField_ == _Fields.BINARY_VALUE; + } + + + public boolean isSetByteValue() { + return setField_ == _Fields.BYTE_VALUE; + } + + + public boolean isSetIntStringValue() { + return setField_ == _Fields.INT_STRING_VALUE; + } + + + public boolean isSetIntStringStringValue() { + return setField_ == _Fields.INT_STRING_STRING_VALUE; + } + + + public boolean equals(Object other) { + if (other instanceof TAnnotationValue) { + return equals((TAnnotationValue)other); + } else { + return false; + } + } + + public boolean equals(TAnnotationValue other) { + return other != null && getSetField() == other.getSetField() && getFieldValue().equals(other.getFieldValue()); + } + + @Override + public int compareTo(TAnnotationValue other) { + int lastComparison = org.apache.thrift.TBaseHelper.compareTo(getSetField(), other.getSetField()); + if (lastComparison == 0) { + return org.apache.thrift.TBaseHelper.compareTo(getFieldValue(), other.getFieldValue()); + } + return lastComparison; + } + + + /** + * If you'd like this to perform more respectably, use the hashcode generator option. + */ + @Override + public int hashCode() { + return 0; + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TApiMetaData.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TApiMetaData.java index fae49f3147d4..1904b2b3e3f7 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TApiMetaData.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TApiMetaData.java @@ -1,769 +1,769 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TApiMetaData implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TApiMetaData"); - - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)2); - private static final org.apache.thrift.protocol.TField API_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("apiId", org.apache.thrift.protocol.TType.I32, (short)4); - private static final org.apache.thrift.protocol.TField API_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("apiInfo", org.apache.thrift.protocol.TType.STRING, (short)5); - private static final org.apache.thrift.protocol.TField LINE_FIELD_DESC = new org.apache.thrift.protocol.TField("line", org.apache.thrift.protocol.TType.I32, (short)6); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TApiMetaDataStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TApiMetaDataTupleSchemeFactory()); - } - - private String agentId; // required - private long agentStartTime; // required - private int apiId; // required - private String apiInfo; // required - private int line; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - AGENT_ID((short)1, "agentId"), - AGENT_START_TIME((short)2, "agentStartTime"), - API_ID((short)4, "apiId"), - API_INFO((short)5, "apiInfo"), - LINE((short)6, "line"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // AGENT_ID - return AGENT_ID; - case 2: // AGENT_START_TIME - return AGENT_START_TIME; - case 4: // API_ID - return API_ID; - case 5: // API_INFO - return API_INFO; - case 6: // LINE - return LINE; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __AGENTSTARTTIME_ISSET_ID = 0; - private static final int __APIID_ISSET_ID = 1; - private static final int __LINE_ISSET_ID = 2; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.LINE}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.API_ID, new org.apache.thrift.meta_data.FieldMetaData("apiId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.API_INFO, new org.apache.thrift.meta_data.FieldMetaData("apiInfo", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.LINE, new org.apache.thrift.meta_data.FieldMetaData("line", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TApiMetaData.class, metaDataMap); - } - - public TApiMetaData() { - } - - public TApiMetaData( - String agentId, - long agentStartTime, - int apiId, - String apiInfo) - { - this(); - this.agentId = agentId; - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - this.apiId = apiId; - setApiIdIsSet(true); - this.apiInfo = apiInfo; - } - - /** - * Performs a deep copy on other. - */ - public TApiMetaData(TApiMetaData other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - this.agentStartTime = other.agentStartTime; - this.apiId = other.apiId; - if (other.isSetApiInfo()) { - this.apiInfo = other.apiInfo; - } - this.line = other.line; - } - - public TApiMetaData deepCopy() { - return new TApiMetaData(this); - } - - @Override - public void clear() { - this.agentId = null; - setAgentStartTimeIsSet(false); - this.agentStartTime = 0; - setApiIdIsSet(false); - this.apiId = 0; - this.apiInfo = null; - setLineIsSet(false); - this.line = 0; - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public long getAgentStartTime() { - return this.agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - } - - public void unsetAgentStartTime() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentStartTime() { - return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - public void setAgentStartTimeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); - } - - public int getApiId() { - return this.apiId; - } - - public void setApiId(int apiId) { - this.apiId = apiId; - setApiIdIsSet(true); - } - - public void unsetApiId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __APIID_ISSET_ID); - } - - /** Returns true if field apiId is set (has been assigned a value) and false otherwise */ - public boolean isSetApiId() { - return EncodingUtils.testBit(__isset_bitfield, __APIID_ISSET_ID); - } - - public void setApiIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __APIID_ISSET_ID, value); - } - - public String getApiInfo() { - return this.apiInfo; - } - - public void setApiInfo(String apiInfo) { - this.apiInfo = apiInfo; - } - - public void unsetApiInfo() { - this.apiInfo = null; - } - - /** Returns true if field apiInfo is set (has been assigned a value) and false otherwise */ - public boolean isSetApiInfo() { - return this.apiInfo != null; - } - - public void setApiInfoIsSet(boolean value) { - if (!value) { - this.apiInfo = null; - } - } - - public int getLine() { - return this.line; - } - - public void setLine(int line) { - this.line = line; - setLineIsSet(true); - } - - public void unsetLine() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LINE_ISSET_ID); - } - - /** Returns true if field line is set (has been assigned a value) and false otherwise */ - public boolean isSetLine() { - return EncodingUtils.testBit(__isset_bitfield, __LINE_ISSET_ID); - } - - public void setLineIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LINE_ISSET_ID, value); - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case AGENT_START_TIME: - if (value == null) { - unsetAgentStartTime(); - } else { - setAgentStartTime((Long)value); - } - break; - - case API_ID: - if (value == null) { - unsetApiId(); - } else { - setApiId((Integer)value); - } - break; - - case API_INFO: - if (value == null) { - unsetApiInfo(); - } else { - setApiInfo((String)value); - } - break; - - case LINE: - if (value == null) { - unsetLine(); - } else { - setLine((Integer)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case AGENT_ID: - return getAgentId(); - - case AGENT_START_TIME: - return Long.valueOf(getAgentStartTime()); - - case API_ID: - return Integer.valueOf(getApiId()); - - case API_INFO: - return getApiInfo(); - - case LINE: - return Integer.valueOf(getLine()); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case AGENT_ID: - return isSetAgentId(); - case AGENT_START_TIME: - return isSetAgentStartTime(); - case API_ID: - return isSetApiId(); - case API_INFO: - return isSetApiInfo(); - case LINE: - return isSetLine(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TApiMetaData) - return this.equals((TApiMetaData)that); - return false; - } - - public boolean equals(TApiMetaData that) { - if (that == null) - return false; - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_agentStartTime = true; - boolean that_present_agentStartTime = true; - if (this_present_agentStartTime || that_present_agentStartTime) { - if (!(this_present_agentStartTime && that_present_agentStartTime)) - return false; - if (this.agentStartTime != that.agentStartTime) - return false; - } - - boolean this_present_apiId = true; - boolean that_present_apiId = true; - if (this_present_apiId || that_present_apiId) { - if (!(this_present_apiId && that_present_apiId)) - return false; - if (this.apiId != that.apiId) - return false; - } - - boolean this_present_apiInfo = true && this.isSetApiInfo(); - boolean that_present_apiInfo = true && that.isSetApiInfo(); - if (this_present_apiInfo || that_present_apiInfo) { - if (!(this_present_apiInfo && that_present_apiInfo)) - return false; - if (!this.apiInfo.equals(that.apiInfo)) - return false; - } - - boolean this_present_line = true && this.isSetLine(); - boolean that_present_line = true && that.isSetLine(); - if (this_present_line || that_present_line) { - if (!(this_present_line && that_present_line)) - return false; - if (this.line != that.line) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TApiMetaData other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentStartTime()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetApiId()).compareTo(other.isSetApiId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetApiId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiId, other.apiId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetApiInfo()).compareTo(other.isSetApiInfo()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetApiInfo()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiInfo, other.apiInfo); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetLine()).compareTo(other.isSetLine()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetLine()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.line, other.line); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TApiMetaData("); - boolean first = true; - - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - if (!first) sb.append(", "); - sb.append("agentStartTime:"); - sb.append(this.agentStartTime); - first = false; - if (!first) sb.append(", "); - sb.append("apiId:"); - sb.append(this.apiId); - first = false; - if (!first) sb.append(", "); - sb.append("apiInfo:"); - if (this.apiInfo == null) { - sb.append("null"); - } else { - sb.append(this.apiInfo); - } - first = false; - if (isSetLine()) { - if (!first) sb.append(", "); - sb.append("line:"); - sb.append(this.line); - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TApiMetaDataStandardSchemeFactory implements SchemeFactory { - public TApiMetaDataStandardScheme getScheme() { - return new TApiMetaDataStandardScheme(); - } - } - - private static class TApiMetaDataStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TApiMetaData struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // AGENT_START_TIME - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 4: // API_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.apiId = iprot.readI32(); - struct.setApiIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 5: // API_INFO - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.apiInfo = iprot.readString(); - struct.setApiInfoIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 6: // LINE - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.line = iprot.readI32(); - struct.setLineIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TApiMetaData struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.agentId != null) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); - oprot.writeI64(struct.agentStartTime); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(API_ID_FIELD_DESC); - oprot.writeI32(struct.apiId); - oprot.writeFieldEnd(); - if (struct.apiInfo != null) { - oprot.writeFieldBegin(API_INFO_FIELD_DESC); - oprot.writeString(struct.apiInfo); - oprot.writeFieldEnd(); - } - if (struct.isSetLine()) { - oprot.writeFieldBegin(LINE_FIELD_DESC); - oprot.writeI32(struct.line); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TApiMetaDataTupleSchemeFactory implements SchemeFactory { - public TApiMetaDataTupleScheme getScheme() { - return new TApiMetaDataTupleScheme(); - } - } - - private static class TApiMetaDataTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TApiMetaData struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetAgentId()) { - optionals.set(0); - } - if (struct.isSetAgentStartTime()) { - optionals.set(1); - } - if (struct.isSetApiId()) { - optionals.set(2); - } - if (struct.isSetApiInfo()) { - optionals.set(3); - } - if (struct.isSetLine()) { - optionals.set(4); - } - oprot.writeBitSet(optionals, 5); - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetAgentStartTime()) { - oprot.writeI64(struct.agentStartTime); - } - if (struct.isSetApiId()) { - oprot.writeI32(struct.apiId); - } - if (struct.isSetApiInfo()) { - oprot.writeString(struct.apiInfo); - } - if (struct.isSetLine()) { - oprot.writeI32(struct.line); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TApiMetaData struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(5); - if (incoming.get(0)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(1)) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } - if (incoming.get(2)) { - struct.apiId = iprot.readI32(); - struct.setApiIdIsSet(true); - } - if (incoming.get(3)) { - struct.apiInfo = iprot.readString(); - struct.setApiInfoIsSet(true); - } - if (incoming.get(4)) { - struct.line = iprot.readI32(); - struct.setLineIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TApiMetaData implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TApiMetaData"); + + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)2); + private static final org.apache.thrift.protocol.TField API_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("apiId", org.apache.thrift.protocol.TType.I32, (short)4); + private static final org.apache.thrift.protocol.TField API_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("apiInfo", org.apache.thrift.protocol.TType.STRING, (short)5); + private static final org.apache.thrift.protocol.TField LINE_FIELD_DESC = new org.apache.thrift.protocol.TField("line", org.apache.thrift.protocol.TType.I32, (short)6); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TApiMetaDataStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TApiMetaDataTupleSchemeFactory()); + } + + private String agentId; // required + private long agentStartTime; // required + private int apiId; // required + private String apiInfo; // required + private int line; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + AGENT_ID((short)1, "agentId"), + AGENT_START_TIME((short)2, "agentStartTime"), + API_ID((short)4, "apiId"), + API_INFO((short)5, "apiInfo"), + LINE((short)6, "line"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // AGENT_ID + return AGENT_ID; + case 2: // AGENT_START_TIME + return AGENT_START_TIME; + case 4: // API_ID + return API_ID; + case 5: // API_INFO + return API_INFO; + case 6: // LINE + return LINE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __AGENTSTARTTIME_ISSET_ID = 0; + private static final int __APIID_ISSET_ID = 1; + private static final int __LINE_ISSET_ID = 2; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.LINE}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.API_ID, new org.apache.thrift.meta_data.FieldMetaData("apiId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.API_INFO, new org.apache.thrift.meta_data.FieldMetaData("apiInfo", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.LINE, new org.apache.thrift.meta_data.FieldMetaData("line", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TApiMetaData.class, metaDataMap); + } + + public TApiMetaData() { + } + + public TApiMetaData( + String agentId, + long agentStartTime, + int apiId, + String apiInfo) + { + this(); + this.agentId = agentId; + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + this.apiId = apiId; + setApiIdIsSet(true); + this.apiInfo = apiInfo; + } + + /** + * Performs a deep copy on other. + */ + public TApiMetaData(TApiMetaData other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + this.agentStartTime = other.agentStartTime; + this.apiId = other.apiId; + if (other.isSetApiInfo()) { + this.apiInfo = other.apiInfo; + } + this.line = other.line; + } + + public TApiMetaData deepCopy() { + return new TApiMetaData(this); + } + + @Override + public void clear() { + this.agentId = null; + setAgentStartTimeIsSet(false); + this.agentStartTime = 0; + setApiIdIsSet(false); + this.apiId = 0; + this.apiInfo = null; + setLineIsSet(false); + this.line = 0; + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public long getAgentStartTime() { + return this.agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + } + + public void unsetAgentStartTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentStartTime() { + return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + public void setAgentStartTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); + } + + public int getApiId() { + return this.apiId; + } + + public void setApiId(int apiId) { + this.apiId = apiId; + setApiIdIsSet(true); + } + + public void unsetApiId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __APIID_ISSET_ID); + } + + /** Returns true if field apiId is set (has been assigned a value) and false otherwise */ + public boolean isSetApiId() { + return EncodingUtils.testBit(__isset_bitfield, __APIID_ISSET_ID); + } + + public void setApiIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __APIID_ISSET_ID, value); + } + + public String getApiInfo() { + return this.apiInfo; + } + + public void setApiInfo(String apiInfo) { + this.apiInfo = apiInfo; + } + + public void unsetApiInfo() { + this.apiInfo = null; + } + + /** Returns true if field apiInfo is set (has been assigned a value) and false otherwise */ + public boolean isSetApiInfo() { + return this.apiInfo != null; + } + + public void setApiInfoIsSet(boolean value) { + if (!value) { + this.apiInfo = null; + } + } + + public int getLine() { + return this.line; + } + + public void setLine(int line) { + this.line = line; + setLineIsSet(true); + } + + public void unsetLine() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LINE_ISSET_ID); + } + + /** Returns true if field line is set (has been assigned a value) and false otherwise */ + public boolean isSetLine() { + return EncodingUtils.testBit(__isset_bitfield, __LINE_ISSET_ID); + } + + public void setLineIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LINE_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case AGENT_START_TIME: + if (value == null) { + unsetAgentStartTime(); + } else { + setAgentStartTime((Long)value); + } + break; + + case API_ID: + if (value == null) { + unsetApiId(); + } else { + setApiId((Integer)value); + } + break; + + case API_INFO: + if (value == null) { + unsetApiInfo(); + } else { + setApiInfo((String)value); + } + break; + + case LINE: + if (value == null) { + unsetLine(); + } else { + setLine((Integer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case AGENT_ID: + return getAgentId(); + + case AGENT_START_TIME: + return Long.valueOf(getAgentStartTime()); + + case API_ID: + return Integer.valueOf(getApiId()); + + case API_INFO: + return getApiInfo(); + + case LINE: + return Integer.valueOf(getLine()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case AGENT_ID: + return isSetAgentId(); + case AGENT_START_TIME: + return isSetAgentStartTime(); + case API_ID: + return isSetApiId(); + case API_INFO: + return isSetApiInfo(); + case LINE: + return isSetLine(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TApiMetaData) + return this.equals((TApiMetaData)that); + return false; + } + + public boolean equals(TApiMetaData that) { + if (that == null) + return false; + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_agentStartTime = true; + boolean that_present_agentStartTime = true; + if (this_present_agentStartTime || that_present_agentStartTime) { + if (!(this_present_agentStartTime && that_present_agentStartTime)) + return false; + if (this.agentStartTime != that.agentStartTime) + return false; + } + + boolean this_present_apiId = true; + boolean that_present_apiId = true; + if (this_present_apiId || that_present_apiId) { + if (!(this_present_apiId && that_present_apiId)) + return false; + if (this.apiId != that.apiId) + return false; + } + + boolean this_present_apiInfo = true && this.isSetApiInfo(); + boolean that_present_apiInfo = true && that.isSetApiInfo(); + if (this_present_apiInfo || that_present_apiInfo) { + if (!(this_present_apiInfo && that_present_apiInfo)) + return false; + if (!this.apiInfo.equals(that.apiInfo)) + return false; + } + + boolean this_present_line = true && this.isSetLine(); + boolean that_present_line = true && that.isSetLine(); + if (this_present_line || that_present_line) { + if (!(this_present_line && that_present_line)) + return false; + if (this.line != that.line) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TApiMetaData other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApiId()).compareTo(other.isSetApiId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApiId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiId, other.apiId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApiInfo()).compareTo(other.isSetApiInfo()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApiInfo()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiInfo, other.apiInfo); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetLine()).compareTo(other.isSetLine()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetLine()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.line, other.line); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TApiMetaData("); + boolean first = true; + + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentStartTime:"); + sb.append(this.agentStartTime); + first = false; + if (!first) sb.append(", "); + sb.append("apiId:"); + sb.append(this.apiId); + first = false; + if (!first) sb.append(", "); + sb.append("apiInfo:"); + if (this.apiInfo == null) { + sb.append("null"); + } else { + sb.append(this.apiInfo); + } + first = false; + if (isSetLine()) { + if (!first) sb.append(", "); + sb.append("line:"); + sb.append(this.line); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TApiMetaDataStandardSchemeFactory implements SchemeFactory { + public TApiMetaDataStandardScheme getScheme() { + return new TApiMetaDataStandardScheme(); + } + } + + private static class TApiMetaDataStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TApiMetaData struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // AGENT_START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // API_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.apiId = iprot.readI32(); + struct.setApiIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 5: // API_INFO + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.apiInfo = iprot.readString(); + struct.setApiInfoIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 6: // LINE + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.line = iprot.readI32(); + struct.setLineIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TApiMetaData struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); + oprot.writeI64(struct.agentStartTime); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(API_ID_FIELD_DESC); + oprot.writeI32(struct.apiId); + oprot.writeFieldEnd(); + if (struct.apiInfo != null) { + oprot.writeFieldBegin(API_INFO_FIELD_DESC); + oprot.writeString(struct.apiInfo); + oprot.writeFieldEnd(); + } + if (struct.isSetLine()) { + oprot.writeFieldBegin(LINE_FIELD_DESC); + oprot.writeI32(struct.line); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TApiMetaDataTupleSchemeFactory implements SchemeFactory { + public TApiMetaDataTupleScheme getScheme() { + return new TApiMetaDataTupleScheme(); + } + } + + private static class TApiMetaDataTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TApiMetaData struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetAgentId()) { + optionals.set(0); + } + if (struct.isSetAgentStartTime()) { + optionals.set(1); + } + if (struct.isSetApiId()) { + optionals.set(2); + } + if (struct.isSetApiInfo()) { + optionals.set(3); + } + if (struct.isSetLine()) { + optionals.set(4); + } + oprot.writeBitSet(optionals, 5); + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetAgentStartTime()) { + oprot.writeI64(struct.agentStartTime); + } + if (struct.isSetApiId()) { + oprot.writeI32(struct.apiId); + } + if (struct.isSetApiInfo()) { + oprot.writeString(struct.apiInfo); + } + if (struct.isSetLine()) { + oprot.writeI32(struct.line); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TApiMetaData struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(5); + if (incoming.get(0)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(1)) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } + if (incoming.get(2)) { + struct.apiId = iprot.readI32(); + struct.setApiIdIsSet(true); + } + if (incoming.get(3)) { + struct.apiInfo = iprot.readString(); + struct.setApiInfoIsSet(true); + } + if (incoming.get(4)) { + struct.line = iprot.readI32(); + struct.setLineIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TCpuLoad.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TCpuLoad.java index eef4084e9917..c9a83a82a27c 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TCpuLoad.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TCpuLoad.java @@ -1,474 +1,474 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TCpuLoad implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TCpuLoad"); - - private static final org.apache.thrift.protocol.TField JVM_CPU_LOAD_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmCpuLoad", org.apache.thrift.protocol.TType.DOUBLE, (short)1); - private static final org.apache.thrift.protocol.TField SYSTEM_CPU_LOAD_FIELD_DESC = new org.apache.thrift.protocol.TField("systemCpuLoad", org.apache.thrift.protocol.TType.DOUBLE, (short)2); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TCpuLoadStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TCpuLoadTupleSchemeFactory()); - } - - private double jvmCpuLoad; // optional - private double systemCpuLoad; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - JVM_CPU_LOAD((short)1, "jvmCpuLoad"), - SYSTEM_CPU_LOAD((short)2, "systemCpuLoad"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // JVM_CPU_LOAD - return JVM_CPU_LOAD; - case 2: // SYSTEM_CPU_LOAD - return SYSTEM_CPU_LOAD; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __JVMCPULOAD_ISSET_ID = 0; - private static final int __SYSTEMCPULOAD_ISSET_ID = 1; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.JVM_CPU_LOAD,_Fields.SYSTEM_CPU_LOAD}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.JVM_CPU_LOAD, new org.apache.thrift.meta_data.FieldMetaData("jvmCpuLoad", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))); - tmpMap.put(_Fields.SYSTEM_CPU_LOAD, new org.apache.thrift.meta_data.FieldMetaData("systemCpuLoad", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TCpuLoad.class, metaDataMap); - } - - public TCpuLoad() { - } - - /** - * Performs a deep copy on other. - */ - public TCpuLoad(TCpuLoad other) { - __isset_bitfield = other.__isset_bitfield; - this.jvmCpuLoad = other.jvmCpuLoad; - this.systemCpuLoad = other.systemCpuLoad; - } - - public TCpuLoad deepCopy() { - return new TCpuLoad(this); - } - - @Override - public void clear() { - setJvmCpuLoadIsSet(false); - this.jvmCpuLoad = 0.0; - setSystemCpuLoadIsSet(false); - this.systemCpuLoad = 0.0; - } - - public double getJvmCpuLoad() { - return this.jvmCpuLoad; - } - - public void setJvmCpuLoad(double jvmCpuLoad) { - this.jvmCpuLoad = jvmCpuLoad; - setJvmCpuLoadIsSet(true); - } - - public void unsetJvmCpuLoad() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMCPULOAD_ISSET_ID); - } - - /** Returns true if field jvmCpuLoad is set (has been assigned a value) and false otherwise */ - public boolean isSetJvmCpuLoad() { - return EncodingUtils.testBit(__isset_bitfield, __JVMCPULOAD_ISSET_ID); - } - - public void setJvmCpuLoadIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMCPULOAD_ISSET_ID, value); - } - - public double getSystemCpuLoad() { - return this.systemCpuLoad; - } - - public void setSystemCpuLoad(double systemCpuLoad) { - this.systemCpuLoad = systemCpuLoad; - setSystemCpuLoadIsSet(true); - } - - public void unsetSystemCpuLoad() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SYSTEMCPULOAD_ISSET_ID); - } - - /** Returns true if field systemCpuLoad is set (has been assigned a value) and false otherwise */ - public boolean isSetSystemCpuLoad() { - return EncodingUtils.testBit(__isset_bitfield, __SYSTEMCPULOAD_ISSET_ID); - } - - public void setSystemCpuLoadIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SYSTEMCPULOAD_ISSET_ID, value); - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case JVM_CPU_LOAD: - if (value == null) { - unsetJvmCpuLoad(); - } else { - setJvmCpuLoad((Double)value); - } - break; - - case SYSTEM_CPU_LOAD: - if (value == null) { - unsetSystemCpuLoad(); - } else { - setSystemCpuLoad((Double)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case JVM_CPU_LOAD: - return Double.valueOf(getJvmCpuLoad()); - - case SYSTEM_CPU_LOAD: - return Double.valueOf(getSystemCpuLoad()); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case JVM_CPU_LOAD: - return isSetJvmCpuLoad(); - case SYSTEM_CPU_LOAD: - return isSetSystemCpuLoad(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TCpuLoad) - return this.equals((TCpuLoad)that); - return false; - } - - public boolean equals(TCpuLoad that) { - if (that == null) - return false; - - boolean this_present_jvmCpuLoad = true && this.isSetJvmCpuLoad(); - boolean that_present_jvmCpuLoad = true && that.isSetJvmCpuLoad(); - if (this_present_jvmCpuLoad || that_present_jvmCpuLoad) { - if (!(this_present_jvmCpuLoad && that_present_jvmCpuLoad)) - return false; - if (this.jvmCpuLoad != that.jvmCpuLoad) - return false; - } - - boolean this_present_systemCpuLoad = true && this.isSetSystemCpuLoad(); - boolean that_present_systemCpuLoad = true && that.isSetSystemCpuLoad(); - if (this_present_systemCpuLoad || that_present_systemCpuLoad) { - if (!(this_present_systemCpuLoad && that_present_systemCpuLoad)) - return false; - if (this.systemCpuLoad != that.systemCpuLoad) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TCpuLoad other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetJvmCpuLoad()).compareTo(other.isSetJvmCpuLoad()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetJvmCpuLoad()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmCpuLoad, other.jvmCpuLoad); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSystemCpuLoad()).compareTo(other.isSetSystemCpuLoad()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSystemCpuLoad()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.systemCpuLoad, other.systemCpuLoad); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TCpuLoad("); - boolean first = true; - - if (isSetJvmCpuLoad()) { - sb.append("jvmCpuLoad:"); - sb.append(this.jvmCpuLoad); - first = false; - } - if (isSetSystemCpuLoad()) { - if (!first) sb.append(", "); - sb.append("systemCpuLoad:"); - sb.append(this.systemCpuLoad); - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TCpuLoadStandardSchemeFactory implements SchemeFactory { - public TCpuLoadStandardScheme getScheme() { - return new TCpuLoadStandardScheme(); - } - } - - private static class TCpuLoadStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TCpuLoad struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // JVM_CPU_LOAD - if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) { - struct.jvmCpuLoad = iprot.readDouble(); - struct.setJvmCpuLoadIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // SYSTEM_CPU_LOAD - if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) { - struct.systemCpuLoad = iprot.readDouble(); - struct.setSystemCpuLoadIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TCpuLoad struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.isSetJvmCpuLoad()) { - oprot.writeFieldBegin(JVM_CPU_LOAD_FIELD_DESC); - oprot.writeDouble(struct.jvmCpuLoad); - oprot.writeFieldEnd(); - } - if (struct.isSetSystemCpuLoad()) { - oprot.writeFieldBegin(SYSTEM_CPU_LOAD_FIELD_DESC); - oprot.writeDouble(struct.systemCpuLoad); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TCpuLoadTupleSchemeFactory implements SchemeFactory { - public TCpuLoadTupleScheme getScheme() { - return new TCpuLoadTupleScheme(); - } - } - - private static class TCpuLoadTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TCpuLoad struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetJvmCpuLoad()) { - optionals.set(0); - } - if (struct.isSetSystemCpuLoad()) { - optionals.set(1); - } - oprot.writeBitSet(optionals, 2); - if (struct.isSetJvmCpuLoad()) { - oprot.writeDouble(struct.jvmCpuLoad); - } - if (struct.isSetSystemCpuLoad()) { - oprot.writeDouble(struct.systemCpuLoad); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TCpuLoad struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(2); - if (incoming.get(0)) { - struct.jvmCpuLoad = iprot.readDouble(); - struct.setJvmCpuLoadIsSet(true); - } - if (incoming.get(1)) { - struct.systemCpuLoad = iprot.readDouble(); - struct.setSystemCpuLoadIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TCpuLoad implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TCpuLoad"); + + private static final org.apache.thrift.protocol.TField JVM_CPU_LOAD_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmCpuLoad", org.apache.thrift.protocol.TType.DOUBLE, (short)1); + private static final org.apache.thrift.protocol.TField SYSTEM_CPU_LOAD_FIELD_DESC = new org.apache.thrift.protocol.TField("systemCpuLoad", org.apache.thrift.protocol.TType.DOUBLE, (short)2); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TCpuLoadStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TCpuLoadTupleSchemeFactory()); + } + + private double jvmCpuLoad; // optional + private double systemCpuLoad; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + JVM_CPU_LOAD((short)1, "jvmCpuLoad"), + SYSTEM_CPU_LOAD((short)2, "systemCpuLoad"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // JVM_CPU_LOAD + return JVM_CPU_LOAD; + case 2: // SYSTEM_CPU_LOAD + return SYSTEM_CPU_LOAD; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __JVMCPULOAD_ISSET_ID = 0; + private static final int __SYSTEMCPULOAD_ISSET_ID = 1; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.JVM_CPU_LOAD,_Fields.SYSTEM_CPU_LOAD}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.JVM_CPU_LOAD, new org.apache.thrift.meta_data.FieldMetaData("jvmCpuLoad", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))); + tmpMap.put(_Fields.SYSTEM_CPU_LOAD, new org.apache.thrift.meta_data.FieldMetaData("systemCpuLoad", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TCpuLoad.class, metaDataMap); + } + + public TCpuLoad() { + } + + /** + * Performs a deep copy on other. + */ + public TCpuLoad(TCpuLoad other) { + __isset_bitfield = other.__isset_bitfield; + this.jvmCpuLoad = other.jvmCpuLoad; + this.systemCpuLoad = other.systemCpuLoad; + } + + public TCpuLoad deepCopy() { + return new TCpuLoad(this); + } + + @Override + public void clear() { + setJvmCpuLoadIsSet(false); + this.jvmCpuLoad = 0.0; + setSystemCpuLoadIsSet(false); + this.systemCpuLoad = 0.0; + } + + public double getJvmCpuLoad() { + return this.jvmCpuLoad; + } + + public void setJvmCpuLoad(double jvmCpuLoad) { + this.jvmCpuLoad = jvmCpuLoad; + setJvmCpuLoadIsSet(true); + } + + public void unsetJvmCpuLoad() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMCPULOAD_ISSET_ID); + } + + /** Returns true if field jvmCpuLoad is set (has been assigned a value) and false otherwise */ + public boolean isSetJvmCpuLoad() { + return EncodingUtils.testBit(__isset_bitfield, __JVMCPULOAD_ISSET_ID); + } + + public void setJvmCpuLoadIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMCPULOAD_ISSET_ID, value); + } + + public double getSystemCpuLoad() { + return this.systemCpuLoad; + } + + public void setSystemCpuLoad(double systemCpuLoad) { + this.systemCpuLoad = systemCpuLoad; + setSystemCpuLoadIsSet(true); + } + + public void unsetSystemCpuLoad() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SYSTEMCPULOAD_ISSET_ID); + } + + /** Returns true if field systemCpuLoad is set (has been assigned a value) and false otherwise */ + public boolean isSetSystemCpuLoad() { + return EncodingUtils.testBit(__isset_bitfield, __SYSTEMCPULOAD_ISSET_ID); + } + + public void setSystemCpuLoadIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SYSTEMCPULOAD_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case JVM_CPU_LOAD: + if (value == null) { + unsetJvmCpuLoad(); + } else { + setJvmCpuLoad((Double)value); + } + break; + + case SYSTEM_CPU_LOAD: + if (value == null) { + unsetSystemCpuLoad(); + } else { + setSystemCpuLoad((Double)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case JVM_CPU_LOAD: + return Double.valueOf(getJvmCpuLoad()); + + case SYSTEM_CPU_LOAD: + return Double.valueOf(getSystemCpuLoad()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case JVM_CPU_LOAD: + return isSetJvmCpuLoad(); + case SYSTEM_CPU_LOAD: + return isSetSystemCpuLoad(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TCpuLoad) + return this.equals((TCpuLoad)that); + return false; + } + + public boolean equals(TCpuLoad that) { + if (that == null) + return false; + + boolean this_present_jvmCpuLoad = true && this.isSetJvmCpuLoad(); + boolean that_present_jvmCpuLoad = true && that.isSetJvmCpuLoad(); + if (this_present_jvmCpuLoad || that_present_jvmCpuLoad) { + if (!(this_present_jvmCpuLoad && that_present_jvmCpuLoad)) + return false; + if (this.jvmCpuLoad != that.jvmCpuLoad) + return false; + } + + boolean this_present_systemCpuLoad = true && this.isSetSystemCpuLoad(); + boolean that_present_systemCpuLoad = true && that.isSetSystemCpuLoad(); + if (this_present_systemCpuLoad || that_present_systemCpuLoad) { + if (!(this_present_systemCpuLoad && that_present_systemCpuLoad)) + return false; + if (this.systemCpuLoad != that.systemCpuLoad) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TCpuLoad other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetJvmCpuLoad()).compareTo(other.isSetJvmCpuLoad()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetJvmCpuLoad()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmCpuLoad, other.jvmCpuLoad); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSystemCpuLoad()).compareTo(other.isSetSystemCpuLoad()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSystemCpuLoad()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.systemCpuLoad, other.systemCpuLoad); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TCpuLoad("); + boolean first = true; + + if (isSetJvmCpuLoad()) { + sb.append("jvmCpuLoad:"); + sb.append(this.jvmCpuLoad); + first = false; + } + if (isSetSystemCpuLoad()) { + if (!first) sb.append(", "); + sb.append("systemCpuLoad:"); + sb.append(this.systemCpuLoad); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TCpuLoadStandardSchemeFactory implements SchemeFactory { + public TCpuLoadStandardScheme getScheme() { + return new TCpuLoadStandardScheme(); + } + } + + private static class TCpuLoadStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TCpuLoad struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // JVM_CPU_LOAD + if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) { + struct.jvmCpuLoad = iprot.readDouble(); + struct.setJvmCpuLoadIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // SYSTEM_CPU_LOAD + if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) { + struct.systemCpuLoad = iprot.readDouble(); + struct.setSystemCpuLoadIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TCpuLoad struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.isSetJvmCpuLoad()) { + oprot.writeFieldBegin(JVM_CPU_LOAD_FIELD_DESC); + oprot.writeDouble(struct.jvmCpuLoad); + oprot.writeFieldEnd(); + } + if (struct.isSetSystemCpuLoad()) { + oprot.writeFieldBegin(SYSTEM_CPU_LOAD_FIELD_DESC); + oprot.writeDouble(struct.systemCpuLoad); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TCpuLoadTupleSchemeFactory implements SchemeFactory { + public TCpuLoadTupleScheme getScheme() { + return new TCpuLoadTupleScheme(); + } + } + + private static class TCpuLoadTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TCpuLoad struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetJvmCpuLoad()) { + optionals.set(0); + } + if (struct.isSetSystemCpuLoad()) { + optionals.set(1); + } + oprot.writeBitSet(optionals, 2); + if (struct.isSetJvmCpuLoad()) { + oprot.writeDouble(struct.jvmCpuLoad); + } + if (struct.isSetSystemCpuLoad()) { + oprot.writeDouble(struct.systemCpuLoad); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TCpuLoad struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(2); + if (incoming.get(0)) { + struct.jvmCpuLoad = iprot.readDouble(); + struct.setJvmCpuLoadIsSet(true); + } + if (incoming.get(1)) { + struct.systemCpuLoad = iprot.readDouble(); + struct.setSystemCpuLoadIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TExceptionValue.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TExceptionValue.java index fa9191a23f94..a27043a6dfc4 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TExceptionValue.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TExceptionValue.java @@ -1,485 +1,485 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TExceptionValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TExceptionValue"); - - private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.I32, (short)1); - private static final org.apache.thrift.protocol.TField EXCEPTION_MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionMessage", org.apache.thrift.protocol.TType.STRING, (short)2); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TExceptionValueStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TExceptionValueTupleSchemeFactory()); - } - - private int id; // required - private String exceptionMessage; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - ID((short)1, "id"), - EXCEPTION_MESSAGE((short)2, "exceptionMessage"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // ID - return ID; - case 2: // EXCEPTION_MESSAGE - return EXCEPTION_MESSAGE; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __ID_ISSET_ID = 0; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.EXCEPTION_MESSAGE}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.ID, new org.apache.thrift.meta_data.FieldMetaData("id", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.EXCEPTION_MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("exceptionMessage", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TExceptionValue.class, metaDataMap); - } - - public TExceptionValue() { - } - - public TExceptionValue( - int id) - { - this(); - this.id = id; - setIdIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TExceptionValue(TExceptionValue other) { - __isset_bitfield = other.__isset_bitfield; - this.id = other.id; - if (other.isSetExceptionMessage()) { - this.exceptionMessage = other.exceptionMessage; - } - } - - public TExceptionValue deepCopy() { - return new TExceptionValue(this); - } - - @Override - public void clear() { - setIdIsSet(false); - this.id = 0; - this.exceptionMessage = null; - } - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id = id; - setIdIsSet(true); - } - - public void unsetId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ID_ISSET_ID); - } - - /** Returns true if field id is set (has been assigned a value) and false otherwise */ - public boolean isSetId() { - return EncodingUtils.testBit(__isset_bitfield, __ID_ISSET_ID); - } - - public void setIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ID_ISSET_ID, value); - } - - public String getExceptionMessage() { - return this.exceptionMessage; - } - - public void setExceptionMessage(String exceptionMessage) { - this.exceptionMessage = exceptionMessage; - } - - public void unsetExceptionMessage() { - this.exceptionMessage = null; - } - - /** Returns true if field exceptionMessage is set (has been assigned a value) and false otherwise */ - public boolean isSetExceptionMessage() { - return this.exceptionMessage != null; - } - - public void setExceptionMessageIsSet(boolean value) { - if (!value) { - this.exceptionMessage = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case ID: - if (value == null) { - unsetId(); - } else { - setId((Integer)value); - } - break; - - case EXCEPTION_MESSAGE: - if (value == null) { - unsetExceptionMessage(); - } else { - setExceptionMessage((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case ID: - return Integer.valueOf(getId()); - - case EXCEPTION_MESSAGE: - return getExceptionMessage(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case ID: - return isSetId(); - case EXCEPTION_MESSAGE: - return isSetExceptionMessage(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TExceptionValue) - return this.equals((TExceptionValue)that); - return false; - } - - public boolean equals(TExceptionValue that) { - if (that == null) - return false; - - boolean this_present_id = true; - boolean that_present_id = true; - if (this_present_id || that_present_id) { - if (!(this_present_id && that_present_id)) - return false; - if (this.id != that.id) - return false; - } - - boolean this_present_exceptionMessage = true && this.isSetExceptionMessage(); - boolean that_present_exceptionMessage = true && that.isSetExceptionMessage(); - if (this_present_exceptionMessage || that_present_exceptionMessage) { - if (!(this_present_exceptionMessage && that_present_exceptionMessage)) - return false; - if (!this.exceptionMessage.equals(that.exceptionMessage)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TExceptionValue other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetId()).compareTo(other.isSetId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.id, other.id); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetExceptionMessage()).compareTo(other.isSetExceptionMessage()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetExceptionMessage()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exceptionMessage, other.exceptionMessage); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TExceptionValue("); - boolean first = true; - - sb.append("id:"); - sb.append(this.id); - first = false; - if (isSetExceptionMessage()) { - if (!first) sb.append(", "); - sb.append("exceptionMessage:"); - if (this.exceptionMessage == null) { - sb.append("null"); - } else { - sb.append(this.exceptionMessage); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TExceptionValueStandardSchemeFactory implements SchemeFactory { - public TExceptionValueStandardScheme getScheme() { - return new TExceptionValueStandardScheme(); - } - } - - private static class TExceptionValueStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TExceptionValue struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // ID - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.id = iprot.readI32(); - struct.setIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // EXCEPTION_MESSAGE - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.exceptionMessage = iprot.readString(); - struct.setExceptionMessageIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TExceptionValue struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - oprot.writeFieldBegin(ID_FIELD_DESC); - oprot.writeI32(struct.id); - oprot.writeFieldEnd(); - if (struct.exceptionMessage != null) { - if (struct.isSetExceptionMessage()) { - oprot.writeFieldBegin(EXCEPTION_MESSAGE_FIELD_DESC); - oprot.writeString(struct.exceptionMessage); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TExceptionValueTupleSchemeFactory implements SchemeFactory { - public TExceptionValueTupleScheme getScheme() { - return new TExceptionValueTupleScheme(); - } - } - - private static class TExceptionValueTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TExceptionValue struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetId()) { - optionals.set(0); - } - if (struct.isSetExceptionMessage()) { - optionals.set(1); - } - oprot.writeBitSet(optionals, 2); - if (struct.isSetId()) { - oprot.writeI32(struct.id); - } - if (struct.isSetExceptionMessage()) { - oprot.writeString(struct.exceptionMessage); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TExceptionValue struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(2); - if (incoming.get(0)) { - struct.id = iprot.readI32(); - struct.setIdIsSet(true); - } - if (incoming.get(1)) { - struct.exceptionMessage = iprot.readString(); - struct.setExceptionMessageIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TExceptionValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TExceptionValue"); + + private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField EXCEPTION_MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionMessage", org.apache.thrift.protocol.TType.STRING, (short)2); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TExceptionValueStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TExceptionValueTupleSchemeFactory()); + } + + private int id; // required + private String exceptionMessage; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + ID((short)1, "id"), + EXCEPTION_MESSAGE((short)2, "exceptionMessage"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // ID + return ID; + case 2: // EXCEPTION_MESSAGE + return EXCEPTION_MESSAGE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __ID_ISSET_ID = 0; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.EXCEPTION_MESSAGE}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.ID, new org.apache.thrift.meta_data.FieldMetaData("id", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.EXCEPTION_MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("exceptionMessage", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TExceptionValue.class, metaDataMap); + } + + public TExceptionValue() { + } + + public TExceptionValue( + int id) + { + this(); + this.id = id; + setIdIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TExceptionValue(TExceptionValue other) { + __isset_bitfield = other.__isset_bitfield; + this.id = other.id; + if (other.isSetExceptionMessage()) { + this.exceptionMessage = other.exceptionMessage; + } + } + + public TExceptionValue deepCopy() { + return new TExceptionValue(this); + } + + @Override + public void clear() { + setIdIsSet(false); + this.id = 0; + this.exceptionMessage = null; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + setIdIsSet(true); + } + + public void unsetId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ID_ISSET_ID); + } + + /** Returns true if field id is set (has been assigned a value) and false otherwise */ + public boolean isSetId() { + return EncodingUtils.testBit(__isset_bitfield, __ID_ISSET_ID); + } + + public void setIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ID_ISSET_ID, value); + } + + public String getExceptionMessage() { + return this.exceptionMessage; + } + + public void setExceptionMessage(String exceptionMessage) { + this.exceptionMessage = exceptionMessage; + } + + public void unsetExceptionMessage() { + this.exceptionMessage = null; + } + + /** Returns true if field exceptionMessage is set (has been assigned a value) and false otherwise */ + public boolean isSetExceptionMessage() { + return this.exceptionMessage != null; + } + + public void setExceptionMessageIsSet(boolean value) { + if (!value) { + this.exceptionMessage = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case ID: + if (value == null) { + unsetId(); + } else { + setId((Integer)value); + } + break; + + case EXCEPTION_MESSAGE: + if (value == null) { + unsetExceptionMessage(); + } else { + setExceptionMessage((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case ID: + return Integer.valueOf(getId()); + + case EXCEPTION_MESSAGE: + return getExceptionMessage(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case ID: + return isSetId(); + case EXCEPTION_MESSAGE: + return isSetExceptionMessage(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TExceptionValue) + return this.equals((TExceptionValue)that); + return false; + } + + public boolean equals(TExceptionValue that) { + if (that == null) + return false; + + boolean this_present_id = true; + boolean that_present_id = true; + if (this_present_id || that_present_id) { + if (!(this_present_id && that_present_id)) + return false; + if (this.id != that.id) + return false; + } + + boolean this_present_exceptionMessage = true && this.isSetExceptionMessage(); + boolean that_present_exceptionMessage = true && that.isSetExceptionMessage(); + if (this_present_exceptionMessage || that_present_exceptionMessage) { + if (!(this_present_exceptionMessage && that_present_exceptionMessage)) + return false; + if (!this.exceptionMessage.equals(that.exceptionMessage)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TExceptionValue other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetId()).compareTo(other.isSetId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.id, other.id); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetExceptionMessage()).compareTo(other.isSetExceptionMessage()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetExceptionMessage()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exceptionMessage, other.exceptionMessage); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TExceptionValue("); + boolean first = true; + + sb.append("id:"); + sb.append(this.id); + first = false; + if (isSetExceptionMessage()) { + if (!first) sb.append(", "); + sb.append("exceptionMessage:"); + if (this.exceptionMessage == null) { + sb.append("null"); + } else { + sb.append(this.exceptionMessage); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TExceptionValueStandardSchemeFactory implements SchemeFactory { + public TExceptionValueStandardScheme getScheme() { + return new TExceptionValueStandardScheme(); + } + } + + private static class TExceptionValueStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TExceptionValue struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // ID + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.id = iprot.readI32(); + struct.setIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // EXCEPTION_MESSAGE + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.exceptionMessage = iprot.readString(); + struct.setExceptionMessageIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TExceptionValue struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + oprot.writeFieldBegin(ID_FIELD_DESC); + oprot.writeI32(struct.id); + oprot.writeFieldEnd(); + if (struct.exceptionMessage != null) { + if (struct.isSetExceptionMessage()) { + oprot.writeFieldBegin(EXCEPTION_MESSAGE_FIELD_DESC); + oprot.writeString(struct.exceptionMessage); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TExceptionValueTupleSchemeFactory implements SchemeFactory { + public TExceptionValueTupleScheme getScheme() { + return new TExceptionValueTupleScheme(); + } + } + + private static class TExceptionValueTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TExceptionValue struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetId()) { + optionals.set(0); + } + if (struct.isSetExceptionMessage()) { + optionals.set(1); + } + oprot.writeBitSet(optionals, 2); + if (struct.isSetId()) { + oprot.writeI32(struct.id); + } + if (struct.isSetExceptionMessage()) { + oprot.writeString(struct.exceptionMessage); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TExceptionValue struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(2); + if (incoming.get(0)) { + struct.id = iprot.readI32(); + struct.setIdIsSet(true); + } + if (incoming.get(1)) { + struct.exceptionMessage = iprot.readString(); + struct.setExceptionMessageIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringStringValue.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringStringValue.java index e788febf645b..4abfe54c101e 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringStringValue.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringStringValue.java @@ -1,586 +1,586 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TIntStringStringValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TIntStringStringValue"); - - private static final org.apache.thrift.protocol.TField INT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intValue", org.apache.thrift.protocol.TType.I32, (short)1); - private static final org.apache.thrift.protocol.TField STRING_VALUE1_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue1", org.apache.thrift.protocol.TType.STRING, (short)2); - private static final org.apache.thrift.protocol.TField STRING_VALUE2_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue2", org.apache.thrift.protocol.TType.STRING, (short)3); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TIntStringStringValueStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TIntStringStringValueTupleSchemeFactory()); - } - - private int intValue; // required - private String stringValue1; // optional - private String stringValue2; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - INT_VALUE((short)1, "intValue"), - STRING_VALUE1((short)2, "stringValue1"), - STRING_VALUE2((short)3, "stringValue2"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // INT_VALUE - return INT_VALUE; - case 2: // STRING_VALUE1 - return STRING_VALUE1; - case 3: // STRING_VALUE2 - return STRING_VALUE2; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __INTVALUE_ISSET_ID = 0; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.STRING_VALUE1,_Fields.STRING_VALUE2}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.STRING_VALUE1, new org.apache.thrift.meta_data.FieldMetaData("stringValue1", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.STRING_VALUE2, new org.apache.thrift.meta_data.FieldMetaData("stringValue2", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TIntStringStringValue.class, metaDataMap); - } - - public TIntStringStringValue() { - } - - public TIntStringStringValue( - int intValue) - { - this(); - this.intValue = intValue; - setIntValueIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TIntStringStringValue(TIntStringStringValue other) { - __isset_bitfield = other.__isset_bitfield; - this.intValue = other.intValue; - if (other.isSetStringValue1()) { - this.stringValue1 = other.stringValue1; - } - if (other.isSetStringValue2()) { - this.stringValue2 = other.stringValue2; - } - } - - public TIntStringStringValue deepCopy() { - return new TIntStringStringValue(this); - } - - @Override - public void clear() { - setIntValueIsSet(false); - this.intValue = 0; - this.stringValue1 = null; - this.stringValue2 = null; - } - - public int getIntValue() { - return this.intValue; - } - - public void setIntValue(int intValue) { - this.intValue = intValue; - setIntValueIsSet(true); - } - - public void unsetIntValue() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __INTVALUE_ISSET_ID); - } - - /** Returns true if field intValue is set (has been assigned a value) and false otherwise */ - public boolean isSetIntValue() { - return EncodingUtils.testBit(__isset_bitfield, __INTVALUE_ISSET_ID); - } - - public void setIntValueIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __INTVALUE_ISSET_ID, value); - } - - public String getStringValue1() { - return this.stringValue1; - } - - public void setStringValue1(String stringValue1) { - this.stringValue1 = stringValue1; - } - - public void unsetStringValue1() { - this.stringValue1 = null; - } - - /** Returns true if field stringValue1 is set (has been assigned a value) and false otherwise */ - public boolean isSetStringValue1() { - return this.stringValue1 != null; - } - - public void setStringValue1IsSet(boolean value) { - if (!value) { - this.stringValue1 = null; - } - } - - public String getStringValue2() { - return this.stringValue2; - } - - public void setStringValue2(String stringValue2) { - this.stringValue2 = stringValue2; - } - - public void unsetStringValue2() { - this.stringValue2 = null; - } - - /** Returns true if field stringValue2 is set (has been assigned a value) and false otherwise */ - public boolean isSetStringValue2() { - return this.stringValue2 != null; - } - - public void setStringValue2IsSet(boolean value) { - if (!value) { - this.stringValue2 = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case INT_VALUE: - if (value == null) { - unsetIntValue(); - } else { - setIntValue((Integer)value); - } - break; - - case STRING_VALUE1: - if (value == null) { - unsetStringValue1(); - } else { - setStringValue1((String)value); - } - break; - - case STRING_VALUE2: - if (value == null) { - unsetStringValue2(); - } else { - setStringValue2((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case INT_VALUE: - return Integer.valueOf(getIntValue()); - - case STRING_VALUE1: - return getStringValue1(); - - case STRING_VALUE2: - return getStringValue2(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case INT_VALUE: - return isSetIntValue(); - case STRING_VALUE1: - return isSetStringValue1(); - case STRING_VALUE2: - return isSetStringValue2(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TIntStringStringValue) - return this.equals((TIntStringStringValue)that); - return false; - } - - public boolean equals(TIntStringStringValue that) { - if (that == null) - return false; - - boolean this_present_intValue = true; - boolean that_present_intValue = true; - if (this_present_intValue || that_present_intValue) { - if (!(this_present_intValue && that_present_intValue)) - return false; - if (this.intValue != that.intValue) - return false; - } - - boolean this_present_stringValue1 = true && this.isSetStringValue1(); - boolean that_present_stringValue1 = true && that.isSetStringValue1(); - if (this_present_stringValue1 || that_present_stringValue1) { - if (!(this_present_stringValue1 && that_present_stringValue1)) - return false; - if (!this.stringValue1.equals(that.stringValue1)) - return false; - } - - boolean this_present_stringValue2 = true && this.isSetStringValue2(); - boolean that_present_stringValue2 = true && that.isSetStringValue2(); - if (this_present_stringValue2 || that_present_stringValue2) { - if (!(this_present_stringValue2 && that_present_stringValue2)) - return false; - if (!this.stringValue2.equals(that.stringValue2)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TIntStringStringValue other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetIntValue()).compareTo(other.isSetIntValue()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetIntValue()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.intValue, other.intValue); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStringValue1()).compareTo(other.isSetStringValue1()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStringValue1()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue1, other.stringValue1); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStringValue2()).compareTo(other.isSetStringValue2()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStringValue2()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue2, other.stringValue2); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TIntStringStringValue("); - boolean first = true; - - sb.append("intValue:"); - sb.append(this.intValue); - first = false; - if (isSetStringValue1()) { - if (!first) sb.append(", "); - sb.append("stringValue1:"); - if (this.stringValue1 == null) { - sb.append("null"); - } else { - sb.append(this.stringValue1); - } - first = false; - } - if (isSetStringValue2()) { - if (!first) sb.append(", "); - sb.append("stringValue2:"); - if (this.stringValue2 == null) { - sb.append("null"); - } else { - sb.append(this.stringValue2); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TIntStringStringValueStandardSchemeFactory implements SchemeFactory { - public TIntStringStringValueStandardScheme getScheme() { - return new TIntStringStringValueStandardScheme(); - } - } - - private static class TIntStringStringValueStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TIntStringStringValue struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // INT_VALUE - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.intValue = iprot.readI32(); - struct.setIntValueIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // STRING_VALUE1 - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.stringValue1 = iprot.readString(); - struct.setStringValue1IsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // STRING_VALUE2 - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.stringValue2 = iprot.readString(); - struct.setStringValue2IsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TIntStringStringValue struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - oprot.writeFieldBegin(INT_VALUE_FIELD_DESC); - oprot.writeI32(struct.intValue); - oprot.writeFieldEnd(); - if (struct.stringValue1 != null) { - if (struct.isSetStringValue1()) { - oprot.writeFieldBegin(STRING_VALUE1_FIELD_DESC); - oprot.writeString(struct.stringValue1); - oprot.writeFieldEnd(); - } - } - if (struct.stringValue2 != null) { - if (struct.isSetStringValue2()) { - oprot.writeFieldBegin(STRING_VALUE2_FIELD_DESC); - oprot.writeString(struct.stringValue2); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TIntStringStringValueTupleSchemeFactory implements SchemeFactory { - public TIntStringStringValueTupleScheme getScheme() { - return new TIntStringStringValueTupleScheme(); - } - } - - private static class TIntStringStringValueTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TIntStringStringValue struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetIntValue()) { - optionals.set(0); - } - if (struct.isSetStringValue1()) { - optionals.set(1); - } - if (struct.isSetStringValue2()) { - optionals.set(2); - } - oprot.writeBitSet(optionals, 3); - if (struct.isSetIntValue()) { - oprot.writeI32(struct.intValue); - } - if (struct.isSetStringValue1()) { - oprot.writeString(struct.stringValue1); - } - if (struct.isSetStringValue2()) { - oprot.writeString(struct.stringValue2); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TIntStringStringValue struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(3); - if (incoming.get(0)) { - struct.intValue = iprot.readI32(); - struct.setIntValueIsSet(true); - } - if (incoming.get(1)) { - struct.stringValue1 = iprot.readString(); - struct.setStringValue1IsSet(true); - } - if (incoming.get(2)) { - struct.stringValue2 = iprot.readString(); - struct.setStringValue2IsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TIntStringStringValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TIntStringStringValue"); + + private static final org.apache.thrift.protocol.TField INT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intValue", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField STRING_VALUE1_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue1", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField STRING_VALUE2_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue2", org.apache.thrift.protocol.TType.STRING, (short)3); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TIntStringStringValueStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TIntStringStringValueTupleSchemeFactory()); + } + + private int intValue; // required + private String stringValue1; // optional + private String stringValue2; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + INT_VALUE((short)1, "intValue"), + STRING_VALUE1((short)2, "stringValue1"), + STRING_VALUE2((short)3, "stringValue2"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // INT_VALUE + return INT_VALUE; + case 2: // STRING_VALUE1 + return STRING_VALUE1; + case 3: // STRING_VALUE2 + return STRING_VALUE2; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __INTVALUE_ISSET_ID = 0; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.STRING_VALUE1,_Fields.STRING_VALUE2}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.STRING_VALUE1, new org.apache.thrift.meta_data.FieldMetaData("stringValue1", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.STRING_VALUE2, new org.apache.thrift.meta_data.FieldMetaData("stringValue2", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TIntStringStringValue.class, metaDataMap); + } + + public TIntStringStringValue() { + } + + public TIntStringStringValue( + int intValue) + { + this(); + this.intValue = intValue; + setIntValueIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TIntStringStringValue(TIntStringStringValue other) { + __isset_bitfield = other.__isset_bitfield; + this.intValue = other.intValue; + if (other.isSetStringValue1()) { + this.stringValue1 = other.stringValue1; + } + if (other.isSetStringValue2()) { + this.stringValue2 = other.stringValue2; + } + } + + public TIntStringStringValue deepCopy() { + return new TIntStringStringValue(this); + } + + @Override + public void clear() { + setIntValueIsSet(false); + this.intValue = 0; + this.stringValue1 = null; + this.stringValue2 = null; + } + + public int getIntValue() { + return this.intValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + setIntValueIsSet(true); + } + + public void unsetIntValue() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __INTVALUE_ISSET_ID); + } + + /** Returns true if field intValue is set (has been assigned a value) and false otherwise */ + public boolean isSetIntValue() { + return EncodingUtils.testBit(__isset_bitfield, __INTVALUE_ISSET_ID); + } + + public void setIntValueIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __INTVALUE_ISSET_ID, value); + } + + public String getStringValue1() { + return this.stringValue1; + } + + public void setStringValue1(String stringValue1) { + this.stringValue1 = stringValue1; + } + + public void unsetStringValue1() { + this.stringValue1 = null; + } + + /** Returns true if field stringValue1 is set (has been assigned a value) and false otherwise */ + public boolean isSetStringValue1() { + return this.stringValue1 != null; + } + + public void setStringValue1IsSet(boolean value) { + if (!value) { + this.stringValue1 = null; + } + } + + public String getStringValue2() { + return this.stringValue2; + } + + public void setStringValue2(String stringValue2) { + this.stringValue2 = stringValue2; + } + + public void unsetStringValue2() { + this.stringValue2 = null; + } + + /** Returns true if field stringValue2 is set (has been assigned a value) and false otherwise */ + public boolean isSetStringValue2() { + return this.stringValue2 != null; + } + + public void setStringValue2IsSet(boolean value) { + if (!value) { + this.stringValue2 = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case INT_VALUE: + if (value == null) { + unsetIntValue(); + } else { + setIntValue((Integer)value); + } + break; + + case STRING_VALUE1: + if (value == null) { + unsetStringValue1(); + } else { + setStringValue1((String)value); + } + break; + + case STRING_VALUE2: + if (value == null) { + unsetStringValue2(); + } else { + setStringValue2((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case INT_VALUE: + return Integer.valueOf(getIntValue()); + + case STRING_VALUE1: + return getStringValue1(); + + case STRING_VALUE2: + return getStringValue2(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case INT_VALUE: + return isSetIntValue(); + case STRING_VALUE1: + return isSetStringValue1(); + case STRING_VALUE2: + return isSetStringValue2(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TIntStringStringValue) + return this.equals((TIntStringStringValue)that); + return false; + } + + public boolean equals(TIntStringStringValue that) { + if (that == null) + return false; + + boolean this_present_intValue = true; + boolean that_present_intValue = true; + if (this_present_intValue || that_present_intValue) { + if (!(this_present_intValue && that_present_intValue)) + return false; + if (this.intValue != that.intValue) + return false; + } + + boolean this_present_stringValue1 = true && this.isSetStringValue1(); + boolean that_present_stringValue1 = true && that.isSetStringValue1(); + if (this_present_stringValue1 || that_present_stringValue1) { + if (!(this_present_stringValue1 && that_present_stringValue1)) + return false; + if (!this.stringValue1.equals(that.stringValue1)) + return false; + } + + boolean this_present_stringValue2 = true && this.isSetStringValue2(); + boolean that_present_stringValue2 = true && that.isSetStringValue2(); + if (this_present_stringValue2 || that_present_stringValue2) { + if (!(this_present_stringValue2 && that_present_stringValue2)) + return false; + if (!this.stringValue2.equals(that.stringValue2)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TIntStringStringValue other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetIntValue()).compareTo(other.isSetIntValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetIntValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.intValue, other.intValue); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStringValue1()).compareTo(other.isSetStringValue1()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStringValue1()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue1, other.stringValue1); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStringValue2()).compareTo(other.isSetStringValue2()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStringValue2()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue2, other.stringValue2); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TIntStringStringValue("); + boolean first = true; + + sb.append("intValue:"); + sb.append(this.intValue); + first = false; + if (isSetStringValue1()) { + if (!first) sb.append(", "); + sb.append("stringValue1:"); + if (this.stringValue1 == null) { + sb.append("null"); + } else { + sb.append(this.stringValue1); + } + first = false; + } + if (isSetStringValue2()) { + if (!first) sb.append(", "); + sb.append("stringValue2:"); + if (this.stringValue2 == null) { + sb.append("null"); + } else { + sb.append(this.stringValue2); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TIntStringStringValueStandardSchemeFactory implements SchemeFactory { + public TIntStringStringValueStandardScheme getScheme() { + return new TIntStringStringValueStandardScheme(); + } + } + + private static class TIntStringStringValueStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TIntStringStringValue struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // INT_VALUE + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.intValue = iprot.readI32(); + struct.setIntValueIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // STRING_VALUE1 + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.stringValue1 = iprot.readString(); + struct.setStringValue1IsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // STRING_VALUE2 + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.stringValue2 = iprot.readString(); + struct.setStringValue2IsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TIntStringStringValue struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + oprot.writeFieldBegin(INT_VALUE_FIELD_DESC); + oprot.writeI32(struct.intValue); + oprot.writeFieldEnd(); + if (struct.stringValue1 != null) { + if (struct.isSetStringValue1()) { + oprot.writeFieldBegin(STRING_VALUE1_FIELD_DESC); + oprot.writeString(struct.stringValue1); + oprot.writeFieldEnd(); + } + } + if (struct.stringValue2 != null) { + if (struct.isSetStringValue2()) { + oprot.writeFieldBegin(STRING_VALUE2_FIELD_DESC); + oprot.writeString(struct.stringValue2); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TIntStringStringValueTupleSchemeFactory implements SchemeFactory { + public TIntStringStringValueTupleScheme getScheme() { + return new TIntStringStringValueTupleScheme(); + } + } + + private static class TIntStringStringValueTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TIntStringStringValue struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetIntValue()) { + optionals.set(0); + } + if (struct.isSetStringValue1()) { + optionals.set(1); + } + if (struct.isSetStringValue2()) { + optionals.set(2); + } + oprot.writeBitSet(optionals, 3); + if (struct.isSetIntValue()) { + oprot.writeI32(struct.intValue); + } + if (struct.isSetStringValue1()) { + oprot.writeString(struct.stringValue1); + } + if (struct.isSetStringValue2()) { + oprot.writeString(struct.stringValue2); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TIntStringStringValue struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(3); + if (incoming.get(0)) { + struct.intValue = iprot.readI32(); + struct.setIntValueIsSet(true); + } + if (incoming.get(1)) { + struct.stringValue1 = iprot.readString(); + struct.setStringValue1IsSet(true); + } + if (incoming.get(2)) { + struct.stringValue2 = iprot.readString(); + struct.setStringValue2IsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringValue.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringValue.java index e4aece83fdbe..3048fced01f7 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringValue.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TIntStringValue.java @@ -1,485 +1,485 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TIntStringValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TIntStringValue"); - - private static final org.apache.thrift.protocol.TField INT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intValue", org.apache.thrift.protocol.TType.I32, (short)1); - private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)2); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TIntStringValueStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TIntStringValueTupleSchemeFactory()); - } - - private int intValue; // required - private String stringValue; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - INT_VALUE((short)1, "intValue"), - STRING_VALUE((short)2, "stringValue"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // INT_VALUE - return INT_VALUE; - case 2: // STRING_VALUE - return STRING_VALUE; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __INTVALUE_ISSET_ID = 0; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.STRING_VALUE}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TIntStringValue.class, metaDataMap); - } - - public TIntStringValue() { - } - - public TIntStringValue( - int intValue) - { - this(); - this.intValue = intValue; - setIntValueIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TIntStringValue(TIntStringValue other) { - __isset_bitfield = other.__isset_bitfield; - this.intValue = other.intValue; - if (other.isSetStringValue()) { - this.stringValue = other.stringValue; - } - } - - public TIntStringValue deepCopy() { - return new TIntStringValue(this); - } - - @Override - public void clear() { - setIntValueIsSet(false); - this.intValue = 0; - this.stringValue = null; - } - - public int getIntValue() { - return this.intValue; - } - - public void setIntValue(int intValue) { - this.intValue = intValue; - setIntValueIsSet(true); - } - - public void unsetIntValue() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __INTVALUE_ISSET_ID); - } - - /** Returns true if field intValue is set (has been assigned a value) and false otherwise */ - public boolean isSetIntValue() { - return EncodingUtils.testBit(__isset_bitfield, __INTVALUE_ISSET_ID); - } - - public void setIntValueIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __INTVALUE_ISSET_ID, value); - } - - public String getStringValue() { - return this.stringValue; - } - - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - public void unsetStringValue() { - this.stringValue = null; - } - - /** Returns true if field stringValue is set (has been assigned a value) and false otherwise */ - public boolean isSetStringValue() { - return this.stringValue != null; - } - - public void setStringValueIsSet(boolean value) { - if (!value) { - this.stringValue = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case INT_VALUE: - if (value == null) { - unsetIntValue(); - } else { - setIntValue((Integer)value); - } - break; - - case STRING_VALUE: - if (value == null) { - unsetStringValue(); - } else { - setStringValue((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case INT_VALUE: - return Integer.valueOf(getIntValue()); - - case STRING_VALUE: - return getStringValue(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case INT_VALUE: - return isSetIntValue(); - case STRING_VALUE: - return isSetStringValue(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TIntStringValue) - return this.equals((TIntStringValue)that); - return false; - } - - public boolean equals(TIntStringValue that) { - if (that == null) - return false; - - boolean this_present_intValue = true; - boolean that_present_intValue = true; - if (this_present_intValue || that_present_intValue) { - if (!(this_present_intValue && that_present_intValue)) - return false; - if (this.intValue != that.intValue) - return false; - } - - boolean this_present_stringValue = true && this.isSetStringValue(); - boolean that_present_stringValue = true && that.isSetStringValue(); - if (this_present_stringValue || that_present_stringValue) { - if (!(this_present_stringValue && that_present_stringValue)) - return false; - if (!this.stringValue.equals(that.stringValue)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TIntStringValue other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetIntValue()).compareTo(other.isSetIntValue()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetIntValue()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.intValue, other.intValue); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStringValue()).compareTo(other.isSetStringValue()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStringValue()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue, other.stringValue); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TIntStringValue("); - boolean first = true; - - sb.append("intValue:"); - sb.append(this.intValue); - first = false; - if (isSetStringValue()) { - if (!first) sb.append(", "); - sb.append("stringValue:"); - if (this.stringValue == null) { - sb.append("null"); - } else { - sb.append(this.stringValue); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TIntStringValueStandardSchemeFactory implements SchemeFactory { - public TIntStringValueStandardScheme getScheme() { - return new TIntStringValueStandardScheme(); - } - } - - private static class TIntStringValueStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TIntStringValue struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // INT_VALUE - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.intValue = iprot.readI32(); - struct.setIntValueIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // STRING_VALUE - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.stringValue = iprot.readString(); - struct.setStringValueIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TIntStringValue struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - oprot.writeFieldBegin(INT_VALUE_FIELD_DESC); - oprot.writeI32(struct.intValue); - oprot.writeFieldEnd(); - if (struct.stringValue != null) { - if (struct.isSetStringValue()) { - oprot.writeFieldBegin(STRING_VALUE_FIELD_DESC); - oprot.writeString(struct.stringValue); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TIntStringValueTupleSchemeFactory implements SchemeFactory { - public TIntStringValueTupleScheme getScheme() { - return new TIntStringValueTupleScheme(); - } - } - - private static class TIntStringValueTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TIntStringValue struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetIntValue()) { - optionals.set(0); - } - if (struct.isSetStringValue()) { - optionals.set(1); - } - oprot.writeBitSet(optionals, 2); - if (struct.isSetIntValue()) { - oprot.writeI32(struct.intValue); - } - if (struct.isSetStringValue()) { - oprot.writeString(struct.stringValue); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TIntStringValue struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(2); - if (incoming.get(0)) { - struct.intValue = iprot.readI32(); - struct.setIntValueIsSet(true); - } - if (incoming.get(1)) { - struct.stringValue = iprot.readString(); - struct.setStringValueIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TIntStringValue implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TIntStringValue"); + + private static final org.apache.thrift.protocol.TField INT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intValue", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)2); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TIntStringValueStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TIntStringValueTupleSchemeFactory()); + } + + private int intValue; // required + private String stringValue; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + INT_VALUE((short)1, "intValue"), + STRING_VALUE((short)2, "stringValue"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // INT_VALUE + return INT_VALUE; + case 2: // STRING_VALUE + return STRING_VALUE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __INTVALUE_ISSET_ID = 0; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.STRING_VALUE}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.INT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TIntStringValue.class, metaDataMap); + } + + public TIntStringValue() { + } + + public TIntStringValue( + int intValue) + { + this(); + this.intValue = intValue; + setIntValueIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TIntStringValue(TIntStringValue other) { + __isset_bitfield = other.__isset_bitfield; + this.intValue = other.intValue; + if (other.isSetStringValue()) { + this.stringValue = other.stringValue; + } + } + + public TIntStringValue deepCopy() { + return new TIntStringValue(this); + } + + @Override + public void clear() { + setIntValueIsSet(false); + this.intValue = 0; + this.stringValue = null; + } + + public int getIntValue() { + return this.intValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + setIntValueIsSet(true); + } + + public void unsetIntValue() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __INTVALUE_ISSET_ID); + } + + /** Returns true if field intValue is set (has been assigned a value) and false otherwise */ + public boolean isSetIntValue() { + return EncodingUtils.testBit(__isset_bitfield, __INTVALUE_ISSET_ID); + } + + public void setIntValueIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __INTVALUE_ISSET_ID, value); + } + + public String getStringValue() { + return this.stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + public void unsetStringValue() { + this.stringValue = null; + } + + /** Returns true if field stringValue is set (has been assigned a value) and false otherwise */ + public boolean isSetStringValue() { + return this.stringValue != null; + } + + public void setStringValueIsSet(boolean value) { + if (!value) { + this.stringValue = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case INT_VALUE: + if (value == null) { + unsetIntValue(); + } else { + setIntValue((Integer)value); + } + break; + + case STRING_VALUE: + if (value == null) { + unsetStringValue(); + } else { + setStringValue((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case INT_VALUE: + return Integer.valueOf(getIntValue()); + + case STRING_VALUE: + return getStringValue(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case INT_VALUE: + return isSetIntValue(); + case STRING_VALUE: + return isSetStringValue(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TIntStringValue) + return this.equals((TIntStringValue)that); + return false; + } + + public boolean equals(TIntStringValue that) { + if (that == null) + return false; + + boolean this_present_intValue = true; + boolean that_present_intValue = true; + if (this_present_intValue || that_present_intValue) { + if (!(this_present_intValue && that_present_intValue)) + return false; + if (this.intValue != that.intValue) + return false; + } + + boolean this_present_stringValue = true && this.isSetStringValue(); + boolean that_present_stringValue = true && that.isSetStringValue(); + if (this_present_stringValue || that_present_stringValue) { + if (!(this_present_stringValue && that_present_stringValue)) + return false; + if (!this.stringValue.equals(that.stringValue)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TIntStringValue other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetIntValue()).compareTo(other.isSetIntValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetIntValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.intValue, other.intValue); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStringValue()).compareTo(other.isSetStringValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStringValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue, other.stringValue); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TIntStringValue("); + boolean first = true; + + sb.append("intValue:"); + sb.append(this.intValue); + first = false; + if (isSetStringValue()) { + if (!first) sb.append(", "); + sb.append("stringValue:"); + if (this.stringValue == null) { + sb.append("null"); + } else { + sb.append(this.stringValue); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TIntStringValueStandardSchemeFactory implements SchemeFactory { + public TIntStringValueStandardScheme getScheme() { + return new TIntStringValueStandardScheme(); + } + } + + private static class TIntStringValueStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TIntStringValue struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // INT_VALUE + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.intValue = iprot.readI32(); + struct.setIntValueIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // STRING_VALUE + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.stringValue = iprot.readString(); + struct.setStringValueIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TIntStringValue struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + oprot.writeFieldBegin(INT_VALUE_FIELD_DESC); + oprot.writeI32(struct.intValue); + oprot.writeFieldEnd(); + if (struct.stringValue != null) { + if (struct.isSetStringValue()) { + oprot.writeFieldBegin(STRING_VALUE_FIELD_DESC); + oprot.writeString(struct.stringValue); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TIntStringValueTupleSchemeFactory implements SchemeFactory { + public TIntStringValueTupleScheme getScheme() { + return new TIntStringValueTupleScheme(); + } + } + + private static class TIntStringValueTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TIntStringValue struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetIntValue()) { + optionals.set(0); + } + if (struct.isSetStringValue()) { + optionals.set(1); + } + oprot.writeBitSet(optionals, 2); + if (struct.isSetIntValue()) { + oprot.writeI32(struct.intValue); + } + if (struct.isSetStringValue()) { + oprot.writeString(struct.stringValue); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TIntStringValue struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(2); + if (incoming.get(0)) { + struct.intValue = iprot.readI32(); + struct.setIntValueIsSet(true); + } + if (incoming.get(1)) { + struct.stringValue = iprot.readString(); + struct.setStringValueIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGc.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGc.java index d341cc6965a8..0d928c38b238 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGc.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGc.java @@ -1,962 +1,962 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TJvmGc implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TJvmGc"); - - private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)1); - private static final org.apache.thrift.protocol.TField JVM_MEMORY_HEAP_USED_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryHeapUsed", org.apache.thrift.protocol.TType.I64, (short)2); - private static final org.apache.thrift.protocol.TField JVM_MEMORY_HEAP_MAX_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryHeapMax", org.apache.thrift.protocol.TType.I64, (short)3); - private static final org.apache.thrift.protocol.TField JVM_MEMORY_NON_HEAP_USED_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryNonHeapUsed", org.apache.thrift.protocol.TType.I64, (short)4); - private static final org.apache.thrift.protocol.TField JVM_MEMORY_NON_HEAP_MAX_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryNonHeapMax", org.apache.thrift.protocol.TType.I64, (short)5); - private static final org.apache.thrift.protocol.TField JVM_GC_OLD_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmGcOldCount", org.apache.thrift.protocol.TType.I64, (short)6); - private static final org.apache.thrift.protocol.TField JVM_GC_OLD_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmGcOldTime", org.apache.thrift.protocol.TType.I64, (short)7); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TJvmGcStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TJvmGcTupleSchemeFactory()); - } - - private TJvmGcType type; // required - private long jvmMemoryHeapUsed; // required - private long jvmMemoryHeapMax; // required - private long jvmMemoryNonHeapUsed; // required - private long jvmMemoryNonHeapMax; // required - private long jvmGcOldCount; // required - private long jvmGcOldTime; // required - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - /** - * - * @see TJvmGcType - */ - TYPE((short)1, "type"), - JVM_MEMORY_HEAP_USED((short)2, "jvmMemoryHeapUsed"), - JVM_MEMORY_HEAP_MAX((short)3, "jvmMemoryHeapMax"), - JVM_MEMORY_NON_HEAP_USED((short)4, "jvmMemoryNonHeapUsed"), - JVM_MEMORY_NON_HEAP_MAX((short)5, "jvmMemoryNonHeapMax"), - JVM_GC_OLD_COUNT((short)6, "jvmGcOldCount"), - JVM_GC_OLD_TIME((short)7, "jvmGcOldTime"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // TYPE - return TYPE; - case 2: // JVM_MEMORY_HEAP_USED - return JVM_MEMORY_HEAP_USED; - case 3: // JVM_MEMORY_HEAP_MAX - return JVM_MEMORY_HEAP_MAX; - case 4: // JVM_MEMORY_NON_HEAP_USED - return JVM_MEMORY_NON_HEAP_USED; - case 5: // JVM_MEMORY_NON_HEAP_MAX - return JVM_MEMORY_NON_HEAP_MAX; - case 6: // JVM_GC_OLD_COUNT - return JVM_GC_OLD_COUNT; - case 7: // JVM_GC_OLD_TIME - return JVM_GC_OLD_TIME; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __JVMMEMORYHEAPUSED_ISSET_ID = 0; - private static final int __JVMMEMORYHEAPMAX_ISSET_ID = 1; - private static final int __JVMMEMORYNONHEAPUSED_ISSET_ID = 2; - private static final int __JVMMEMORYNONHEAPMAX_ISSET_ID = 3; - private static final int __JVMGCOLDCOUNT_ISSET_ID = 4; - private static final int __JVMGCOLDTIME_ISSET_ID = 5; - private byte __isset_bitfield = 0; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TJvmGcType.class))); - tmpMap.put(_Fields.JVM_MEMORY_HEAP_USED, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryHeapUsed", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.JVM_MEMORY_HEAP_MAX, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryHeapMax", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.JVM_MEMORY_NON_HEAP_USED, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryNonHeapUsed", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.JVM_MEMORY_NON_HEAP_MAX, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryNonHeapMax", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.JVM_GC_OLD_COUNT, new org.apache.thrift.meta_data.FieldMetaData("jvmGcOldCount", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.JVM_GC_OLD_TIME, new org.apache.thrift.meta_data.FieldMetaData("jvmGcOldTime", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TJvmGc.class, metaDataMap); - } - - public TJvmGc() { - this.type = com.nhn.pinpoint.thrift.dto.TJvmGcType.UNKNOWN; - - } - - public TJvmGc( - TJvmGcType type, - long jvmMemoryHeapUsed, - long jvmMemoryHeapMax, - long jvmMemoryNonHeapUsed, - long jvmMemoryNonHeapMax, - long jvmGcOldCount, - long jvmGcOldTime) - { - this(); - this.type = type; - this.jvmMemoryHeapUsed = jvmMemoryHeapUsed; - setJvmMemoryHeapUsedIsSet(true); - this.jvmMemoryHeapMax = jvmMemoryHeapMax; - setJvmMemoryHeapMaxIsSet(true); - this.jvmMemoryNonHeapUsed = jvmMemoryNonHeapUsed; - setJvmMemoryNonHeapUsedIsSet(true); - this.jvmMemoryNonHeapMax = jvmMemoryNonHeapMax; - setJvmMemoryNonHeapMaxIsSet(true); - this.jvmGcOldCount = jvmGcOldCount; - setJvmGcOldCountIsSet(true); - this.jvmGcOldTime = jvmGcOldTime; - setJvmGcOldTimeIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TJvmGc(TJvmGc other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetType()) { - this.type = other.type; - } - this.jvmMemoryHeapUsed = other.jvmMemoryHeapUsed; - this.jvmMemoryHeapMax = other.jvmMemoryHeapMax; - this.jvmMemoryNonHeapUsed = other.jvmMemoryNonHeapUsed; - this.jvmMemoryNonHeapMax = other.jvmMemoryNonHeapMax; - this.jvmGcOldCount = other.jvmGcOldCount; - this.jvmGcOldTime = other.jvmGcOldTime; - } - - public TJvmGc deepCopy() { - return new TJvmGc(this); - } - - @Override - public void clear() { - this.type = com.nhn.pinpoint.thrift.dto.TJvmGcType.UNKNOWN; - - setJvmMemoryHeapUsedIsSet(false); - this.jvmMemoryHeapUsed = 0; - setJvmMemoryHeapMaxIsSet(false); - this.jvmMemoryHeapMax = 0; - setJvmMemoryNonHeapUsedIsSet(false); - this.jvmMemoryNonHeapUsed = 0; - setJvmMemoryNonHeapMaxIsSet(false); - this.jvmMemoryNonHeapMax = 0; - setJvmGcOldCountIsSet(false); - this.jvmGcOldCount = 0; - setJvmGcOldTimeIsSet(false); - this.jvmGcOldTime = 0; - } - - /** - * - * @see TJvmGcType - */ - public TJvmGcType getType() { - return this.type; - } - - /** - * - * @see TJvmGcType - */ - public void setType(TJvmGcType type) { - this.type = type; - } - - public void unsetType() { - this.type = null; - } - - /** Returns true if field type is set (has been assigned a value) and false otherwise */ - public boolean isSetType() { - return this.type != null; - } - - public void setTypeIsSet(boolean value) { - if (!value) { - this.type = null; - } - } - - public long getJvmMemoryHeapUsed() { - return this.jvmMemoryHeapUsed; - } - - public void setJvmMemoryHeapUsed(long jvmMemoryHeapUsed) { - this.jvmMemoryHeapUsed = jvmMemoryHeapUsed; - setJvmMemoryHeapUsedIsSet(true); - } - - public void unsetJvmMemoryHeapUsed() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYHEAPUSED_ISSET_ID); - } - - /** Returns true if field jvmMemoryHeapUsed is set (has been assigned a value) and false otherwise */ - public boolean isSetJvmMemoryHeapUsed() { - return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYHEAPUSED_ISSET_ID); - } - - public void setJvmMemoryHeapUsedIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYHEAPUSED_ISSET_ID, value); - } - - public long getJvmMemoryHeapMax() { - return this.jvmMemoryHeapMax; - } - - public void setJvmMemoryHeapMax(long jvmMemoryHeapMax) { - this.jvmMemoryHeapMax = jvmMemoryHeapMax; - setJvmMemoryHeapMaxIsSet(true); - } - - public void unsetJvmMemoryHeapMax() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYHEAPMAX_ISSET_ID); - } - - /** Returns true if field jvmMemoryHeapMax is set (has been assigned a value) and false otherwise */ - public boolean isSetJvmMemoryHeapMax() { - return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYHEAPMAX_ISSET_ID); - } - - public void setJvmMemoryHeapMaxIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYHEAPMAX_ISSET_ID, value); - } - - public long getJvmMemoryNonHeapUsed() { - return this.jvmMemoryNonHeapUsed; - } - - public void setJvmMemoryNonHeapUsed(long jvmMemoryNonHeapUsed) { - this.jvmMemoryNonHeapUsed = jvmMemoryNonHeapUsed; - setJvmMemoryNonHeapUsedIsSet(true); - } - - public void unsetJvmMemoryNonHeapUsed() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYNONHEAPUSED_ISSET_ID); - } - - /** Returns true if field jvmMemoryNonHeapUsed is set (has been assigned a value) and false otherwise */ - public boolean isSetJvmMemoryNonHeapUsed() { - return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYNONHEAPUSED_ISSET_ID); - } - - public void setJvmMemoryNonHeapUsedIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYNONHEAPUSED_ISSET_ID, value); - } - - public long getJvmMemoryNonHeapMax() { - return this.jvmMemoryNonHeapMax; - } - - public void setJvmMemoryNonHeapMax(long jvmMemoryNonHeapMax) { - this.jvmMemoryNonHeapMax = jvmMemoryNonHeapMax; - setJvmMemoryNonHeapMaxIsSet(true); - } - - public void unsetJvmMemoryNonHeapMax() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYNONHEAPMAX_ISSET_ID); - } - - /** Returns true if field jvmMemoryNonHeapMax is set (has been assigned a value) and false otherwise */ - public boolean isSetJvmMemoryNonHeapMax() { - return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYNONHEAPMAX_ISSET_ID); - } - - public void setJvmMemoryNonHeapMaxIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYNONHEAPMAX_ISSET_ID, value); - } - - public long getJvmGcOldCount() { - return this.jvmGcOldCount; - } - - public void setJvmGcOldCount(long jvmGcOldCount) { - this.jvmGcOldCount = jvmGcOldCount; - setJvmGcOldCountIsSet(true); - } - - public void unsetJvmGcOldCount() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMGCOLDCOUNT_ISSET_ID); - } - - /** Returns true if field jvmGcOldCount is set (has been assigned a value) and false otherwise */ - public boolean isSetJvmGcOldCount() { - return EncodingUtils.testBit(__isset_bitfield, __JVMGCOLDCOUNT_ISSET_ID); - } - - public void setJvmGcOldCountIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMGCOLDCOUNT_ISSET_ID, value); - } - - public long getJvmGcOldTime() { - return this.jvmGcOldTime; - } - - public void setJvmGcOldTime(long jvmGcOldTime) { - this.jvmGcOldTime = jvmGcOldTime; - setJvmGcOldTimeIsSet(true); - } - - public void unsetJvmGcOldTime() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMGCOLDTIME_ISSET_ID); - } - - /** Returns true if field jvmGcOldTime is set (has been assigned a value) and false otherwise */ - public boolean isSetJvmGcOldTime() { - return EncodingUtils.testBit(__isset_bitfield, __JVMGCOLDTIME_ISSET_ID); - } - - public void setJvmGcOldTimeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMGCOLDTIME_ISSET_ID, value); - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case TYPE: - if (value == null) { - unsetType(); - } else { - setType((TJvmGcType)value); - } - break; - - case JVM_MEMORY_HEAP_USED: - if (value == null) { - unsetJvmMemoryHeapUsed(); - } else { - setJvmMemoryHeapUsed((Long)value); - } - break; - - case JVM_MEMORY_HEAP_MAX: - if (value == null) { - unsetJvmMemoryHeapMax(); - } else { - setJvmMemoryHeapMax((Long)value); - } - break; - - case JVM_MEMORY_NON_HEAP_USED: - if (value == null) { - unsetJvmMemoryNonHeapUsed(); - } else { - setJvmMemoryNonHeapUsed((Long)value); - } - break; - - case JVM_MEMORY_NON_HEAP_MAX: - if (value == null) { - unsetJvmMemoryNonHeapMax(); - } else { - setJvmMemoryNonHeapMax((Long)value); - } - break; - - case JVM_GC_OLD_COUNT: - if (value == null) { - unsetJvmGcOldCount(); - } else { - setJvmGcOldCount((Long)value); - } - break; - - case JVM_GC_OLD_TIME: - if (value == null) { - unsetJvmGcOldTime(); - } else { - setJvmGcOldTime((Long)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case TYPE: - return getType(); - - case JVM_MEMORY_HEAP_USED: - return Long.valueOf(getJvmMemoryHeapUsed()); - - case JVM_MEMORY_HEAP_MAX: - return Long.valueOf(getJvmMemoryHeapMax()); - - case JVM_MEMORY_NON_HEAP_USED: - return Long.valueOf(getJvmMemoryNonHeapUsed()); - - case JVM_MEMORY_NON_HEAP_MAX: - return Long.valueOf(getJvmMemoryNonHeapMax()); - - case JVM_GC_OLD_COUNT: - return Long.valueOf(getJvmGcOldCount()); - - case JVM_GC_OLD_TIME: - return Long.valueOf(getJvmGcOldTime()); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case TYPE: - return isSetType(); - case JVM_MEMORY_HEAP_USED: - return isSetJvmMemoryHeapUsed(); - case JVM_MEMORY_HEAP_MAX: - return isSetJvmMemoryHeapMax(); - case JVM_MEMORY_NON_HEAP_USED: - return isSetJvmMemoryNonHeapUsed(); - case JVM_MEMORY_NON_HEAP_MAX: - return isSetJvmMemoryNonHeapMax(); - case JVM_GC_OLD_COUNT: - return isSetJvmGcOldCount(); - case JVM_GC_OLD_TIME: - return isSetJvmGcOldTime(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TJvmGc) - return this.equals((TJvmGc)that); - return false; - } - - public boolean equals(TJvmGc that) { - if (that == null) - return false; - - boolean this_present_type = true && this.isSetType(); - boolean that_present_type = true && that.isSetType(); - if (this_present_type || that_present_type) { - if (!(this_present_type && that_present_type)) - return false; - if (!this.type.equals(that.type)) - return false; - } - - boolean this_present_jvmMemoryHeapUsed = true; - boolean that_present_jvmMemoryHeapUsed = true; - if (this_present_jvmMemoryHeapUsed || that_present_jvmMemoryHeapUsed) { - if (!(this_present_jvmMemoryHeapUsed && that_present_jvmMemoryHeapUsed)) - return false; - if (this.jvmMemoryHeapUsed != that.jvmMemoryHeapUsed) - return false; - } - - boolean this_present_jvmMemoryHeapMax = true; - boolean that_present_jvmMemoryHeapMax = true; - if (this_present_jvmMemoryHeapMax || that_present_jvmMemoryHeapMax) { - if (!(this_present_jvmMemoryHeapMax && that_present_jvmMemoryHeapMax)) - return false; - if (this.jvmMemoryHeapMax != that.jvmMemoryHeapMax) - return false; - } - - boolean this_present_jvmMemoryNonHeapUsed = true; - boolean that_present_jvmMemoryNonHeapUsed = true; - if (this_present_jvmMemoryNonHeapUsed || that_present_jvmMemoryNonHeapUsed) { - if (!(this_present_jvmMemoryNonHeapUsed && that_present_jvmMemoryNonHeapUsed)) - return false; - if (this.jvmMemoryNonHeapUsed != that.jvmMemoryNonHeapUsed) - return false; - } - - boolean this_present_jvmMemoryNonHeapMax = true; - boolean that_present_jvmMemoryNonHeapMax = true; - if (this_present_jvmMemoryNonHeapMax || that_present_jvmMemoryNonHeapMax) { - if (!(this_present_jvmMemoryNonHeapMax && that_present_jvmMemoryNonHeapMax)) - return false; - if (this.jvmMemoryNonHeapMax != that.jvmMemoryNonHeapMax) - return false; - } - - boolean this_present_jvmGcOldCount = true; - boolean that_present_jvmGcOldCount = true; - if (this_present_jvmGcOldCount || that_present_jvmGcOldCount) { - if (!(this_present_jvmGcOldCount && that_present_jvmGcOldCount)) - return false; - if (this.jvmGcOldCount != that.jvmGcOldCount) - return false; - } - - boolean this_present_jvmGcOldTime = true; - boolean that_present_jvmGcOldTime = true; - if (this_present_jvmGcOldTime || that_present_jvmGcOldTime) { - if (!(this_present_jvmGcOldTime && that_present_jvmGcOldTime)) - return false; - if (this.jvmGcOldTime != that.jvmGcOldTime) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TJvmGc other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetType()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetJvmMemoryHeapUsed()).compareTo(other.isSetJvmMemoryHeapUsed()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetJvmMemoryHeapUsed()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryHeapUsed, other.jvmMemoryHeapUsed); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetJvmMemoryHeapMax()).compareTo(other.isSetJvmMemoryHeapMax()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetJvmMemoryHeapMax()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryHeapMax, other.jvmMemoryHeapMax); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetJvmMemoryNonHeapUsed()).compareTo(other.isSetJvmMemoryNonHeapUsed()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetJvmMemoryNonHeapUsed()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryNonHeapUsed, other.jvmMemoryNonHeapUsed); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetJvmMemoryNonHeapMax()).compareTo(other.isSetJvmMemoryNonHeapMax()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetJvmMemoryNonHeapMax()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryNonHeapMax, other.jvmMemoryNonHeapMax); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetJvmGcOldCount()).compareTo(other.isSetJvmGcOldCount()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetJvmGcOldCount()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmGcOldCount, other.jvmGcOldCount); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetJvmGcOldTime()).compareTo(other.isSetJvmGcOldTime()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetJvmGcOldTime()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmGcOldTime, other.jvmGcOldTime); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TJvmGc("); - boolean first = true; - - sb.append("type:"); - if (this.type == null) { - sb.append("null"); - } else { - sb.append(this.type); - } - first = false; - if (!first) sb.append(", "); - sb.append("jvmMemoryHeapUsed:"); - sb.append(this.jvmMemoryHeapUsed); - first = false; - if (!first) sb.append(", "); - sb.append("jvmMemoryHeapMax:"); - sb.append(this.jvmMemoryHeapMax); - first = false; - if (!first) sb.append(", "); - sb.append("jvmMemoryNonHeapUsed:"); - sb.append(this.jvmMemoryNonHeapUsed); - first = false; - if (!first) sb.append(", "); - sb.append("jvmMemoryNonHeapMax:"); - sb.append(this.jvmMemoryNonHeapMax); - first = false; - if (!first) sb.append(", "); - sb.append("jvmGcOldCount:"); - sb.append(this.jvmGcOldCount); - first = false; - if (!first) sb.append(", "); - sb.append("jvmGcOldTime:"); - sb.append(this.jvmGcOldTime); - first = false; - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TJvmGcStandardSchemeFactory implements SchemeFactory { - public TJvmGcStandardScheme getScheme() { - return new TJvmGcStandardScheme(); - } - } - - private static class TJvmGcStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TJvmGc struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // TYPE - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.type = TJvmGcType.findByValue(iprot.readI32()); - struct.setTypeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // JVM_MEMORY_HEAP_USED - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.jvmMemoryHeapUsed = iprot.readI64(); - struct.setJvmMemoryHeapUsedIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // JVM_MEMORY_HEAP_MAX - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.jvmMemoryHeapMax = iprot.readI64(); - struct.setJvmMemoryHeapMaxIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 4: // JVM_MEMORY_NON_HEAP_USED - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.jvmMemoryNonHeapUsed = iprot.readI64(); - struct.setJvmMemoryNonHeapUsedIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 5: // JVM_MEMORY_NON_HEAP_MAX - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.jvmMemoryNonHeapMax = iprot.readI64(); - struct.setJvmMemoryNonHeapMaxIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 6: // JVM_GC_OLD_COUNT - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.jvmGcOldCount = iprot.readI64(); - struct.setJvmGcOldCountIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 7: // JVM_GC_OLD_TIME - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.jvmGcOldTime = iprot.readI64(); - struct.setJvmGcOldTimeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TJvmGc struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.type != null) { - oprot.writeFieldBegin(TYPE_FIELD_DESC); - oprot.writeI32(struct.type.getValue()); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(JVM_MEMORY_HEAP_USED_FIELD_DESC); - oprot.writeI64(struct.jvmMemoryHeapUsed); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(JVM_MEMORY_HEAP_MAX_FIELD_DESC); - oprot.writeI64(struct.jvmMemoryHeapMax); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(JVM_MEMORY_NON_HEAP_USED_FIELD_DESC); - oprot.writeI64(struct.jvmMemoryNonHeapUsed); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(JVM_MEMORY_NON_HEAP_MAX_FIELD_DESC); - oprot.writeI64(struct.jvmMemoryNonHeapMax); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(JVM_GC_OLD_COUNT_FIELD_DESC); - oprot.writeI64(struct.jvmGcOldCount); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(JVM_GC_OLD_TIME_FIELD_DESC); - oprot.writeI64(struct.jvmGcOldTime); - oprot.writeFieldEnd(); - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TJvmGcTupleSchemeFactory implements SchemeFactory { - public TJvmGcTupleScheme getScheme() { - return new TJvmGcTupleScheme(); - } - } - - private static class TJvmGcTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TJvmGc struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetType()) { - optionals.set(0); - } - if (struct.isSetJvmMemoryHeapUsed()) { - optionals.set(1); - } - if (struct.isSetJvmMemoryHeapMax()) { - optionals.set(2); - } - if (struct.isSetJvmMemoryNonHeapUsed()) { - optionals.set(3); - } - if (struct.isSetJvmMemoryNonHeapMax()) { - optionals.set(4); - } - if (struct.isSetJvmGcOldCount()) { - optionals.set(5); - } - if (struct.isSetJvmGcOldTime()) { - optionals.set(6); - } - oprot.writeBitSet(optionals, 7); - if (struct.isSetType()) { - oprot.writeI32(struct.type.getValue()); - } - if (struct.isSetJvmMemoryHeapUsed()) { - oprot.writeI64(struct.jvmMemoryHeapUsed); - } - if (struct.isSetJvmMemoryHeapMax()) { - oprot.writeI64(struct.jvmMemoryHeapMax); - } - if (struct.isSetJvmMemoryNonHeapUsed()) { - oprot.writeI64(struct.jvmMemoryNonHeapUsed); - } - if (struct.isSetJvmMemoryNonHeapMax()) { - oprot.writeI64(struct.jvmMemoryNonHeapMax); - } - if (struct.isSetJvmGcOldCount()) { - oprot.writeI64(struct.jvmGcOldCount); - } - if (struct.isSetJvmGcOldTime()) { - oprot.writeI64(struct.jvmGcOldTime); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TJvmGc struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(7); - if (incoming.get(0)) { - struct.type = TJvmGcType.findByValue(iprot.readI32()); - struct.setTypeIsSet(true); - } - if (incoming.get(1)) { - struct.jvmMemoryHeapUsed = iprot.readI64(); - struct.setJvmMemoryHeapUsedIsSet(true); - } - if (incoming.get(2)) { - struct.jvmMemoryHeapMax = iprot.readI64(); - struct.setJvmMemoryHeapMaxIsSet(true); - } - if (incoming.get(3)) { - struct.jvmMemoryNonHeapUsed = iprot.readI64(); - struct.setJvmMemoryNonHeapUsedIsSet(true); - } - if (incoming.get(4)) { - struct.jvmMemoryNonHeapMax = iprot.readI64(); - struct.setJvmMemoryNonHeapMaxIsSet(true); - } - if (incoming.get(5)) { - struct.jvmGcOldCount = iprot.readI64(); - struct.setJvmGcOldCountIsSet(true); - } - if (incoming.get(6)) { - struct.jvmGcOldTime = iprot.readI64(); - struct.setJvmGcOldTimeIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TJvmGc implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TJvmGc"); + + private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField JVM_MEMORY_HEAP_USED_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryHeapUsed", org.apache.thrift.protocol.TType.I64, (short)2); + private static final org.apache.thrift.protocol.TField JVM_MEMORY_HEAP_MAX_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryHeapMax", org.apache.thrift.protocol.TType.I64, (short)3); + private static final org.apache.thrift.protocol.TField JVM_MEMORY_NON_HEAP_USED_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryNonHeapUsed", org.apache.thrift.protocol.TType.I64, (short)4); + private static final org.apache.thrift.protocol.TField JVM_MEMORY_NON_HEAP_MAX_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmMemoryNonHeapMax", org.apache.thrift.protocol.TType.I64, (short)5); + private static final org.apache.thrift.protocol.TField JVM_GC_OLD_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmGcOldCount", org.apache.thrift.protocol.TType.I64, (short)6); + private static final org.apache.thrift.protocol.TField JVM_GC_OLD_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("jvmGcOldTime", org.apache.thrift.protocol.TType.I64, (short)7); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TJvmGcStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TJvmGcTupleSchemeFactory()); + } + + private TJvmGcType type; // required + private long jvmMemoryHeapUsed; // required + private long jvmMemoryHeapMax; // required + private long jvmMemoryNonHeapUsed; // required + private long jvmMemoryNonHeapMax; // required + private long jvmGcOldCount; // required + private long jvmGcOldTime; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + /** + * + * @see TJvmGcType + */ + TYPE((short)1, "type"), + JVM_MEMORY_HEAP_USED((short)2, "jvmMemoryHeapUsed"), + JVM_MEMORY_HEAP_MAX((short)3, "jvmMemoryHeapMax"), + JVM_MEMORY_NON_HEAP_USED((short)4, "jvmMemoryNonHeapUsed"), + JVM_MEMORY_NON_HEAP_MAX((short)5, "jvmMemoryNonHeapMax"), + JVM_GC_OLD_COUNT((short)6, "jvmGcOldCount"), + JVM_GC_OLD_TIME((short)7, "jvmGcOldTime"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // TYPE + return TYPE; + case 2: // JVM_MEMORY_HEAP_USED + return JVM_MEMORY_HEAP_USED; + case 3: // JVM_MEMORY_HEAP_MAX + return JVM_MEMORY_HEAP_MAX; + case 4: // JVM_MEMORY_NON_HEAP_USED + return JVM_MEMORY_NON_HEAP_USED; + case 5: // JVM_MEMORY_NON_HEAP_MAX + return JVM_MEMORY_NON_HEAP_MAX; + case 6: // JVM_GC_OLD_COUNT + return JVM_GC_OLD_COUNT; + case 7: // JVM_GC_OLD_TIME + return JVM_GC_OLD_TIME; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __JVMMEMORYHEAPUSED_ISSET_ID = 0; + private static final int __JVMMEMORYHEAPMAX_ISSET_ID = 1; + private static final int __JVMMEMORYNONHEAPUSED_ISSET_ID = 2; + private static final int __JVMMEMORYNONHEAPMAX_ISSET_ID = 3; + private static final int __JVMGCOLDCOUNT_ISSET_ID = 4; + private static final int __JVMGCOLDTIME_ISSET_ID = 5; + private byte __isset_bitfield = 0; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TJvmGcType.class))); + tmpMap.put(_Fields.JVM_MEMORY_HEAP_USED, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryHeapUsed", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.JVM_MEMORY_HEAP_MAX, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryHeapMax", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.JVM_MEMORY_NON_HEAP_USED, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryNonHeapUsed", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.JVM_MEMORY_NON_HEAP_MAX, new org.apache.thrift.meta_data.FieldMetaData("jvmMemoryNonHeapMax", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.JVM_GC_OLD_COUNT, new org.apache.thrift.meta_data.FieldMetaData("jvmGcOldCount", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.JVM_GC_OLD_TIME, new org.apache.thrift.meta_data.FieldMetaData("jvmGcOldTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TJvmGc.class, metaDataMap); + } + + public TJvmGc() { + this.type = com.nhn.pinpoint.thrift.dto.TJvmGcType.UNKNOWN; + + } + + public TJvmGc( + TJvmGcType type, + long jvmMemoryHeapUsed, + long jvmMemoryHeapMax, + long jvmMemoryNonHeapUsed, + long jvmMemoryNonHeapMax, + long jvmGcOldCount, + long jvmGcOldTime) + { + this(); + this.type = type; + this.jvmMemoryHeapUsed = jvmMemoryHeapUsed; + setJvmMemoryHeapUsedIsSet(true); + this.jvmMemoryHeapMax = jvmMemoryHeapMax; + setJvmMemoryHeapMaxIsSet(true); + this.jvmMemoryNonHeapUsed = jvmMemoryNonHeapUsed; + setJvmMemoryNonHeapUsedIsSet(true); + this.jvmMemoryNonHeapMax = jvmMemoryNonHeapMax; + setJvmMemoryNonHeapMaxIsSet(true); + this.jvmGcOldCount = jvmGcOldCount; + setJvmGcOldCountIsSet(true); + this.jvmGcOldTime = jvmGcOldTime; + setJvmGcOldTimeIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TJvmGc(TJvmGc other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetType()) { + this.type = other.type; + } + this.jvmMemoryHeapUsed = other.jvmMemoryHeapUsed; + this.jvmMemoryHeapMax = other.jvmMemoryHeapMax; + this.jvmMemoryNonHeapUsed = other.jvmMemoryNonHeapUsed; + this.jvmMemoryNonHeapMax = other.jvmMemoryNonHeapMax; + this.jvmGcOldCount = other.jvmGcOldCount; + this.jvmGcOldTime = other.jvmGcOldTime; + } + + public TJvmGc deepCopy() { + return new TJvmGc(this); + } + + @Override + public void clear() { + this.type = com.nhn.pinpoint.thrift.dto.TJvmGcType.UNKNOWN; + + setJvmMemoryHeapUsedIsSet(false); + this.jvmMemoryHeapUsed = 0; + setJvmMemoryHeapMaxIsSet(false); + this.jvmMemoryHeapMax = 0; + setJvmMemoryNonHeapUsedIsSet(false); + this.jvmMemoryNonHeapUsed = 0; + setJvmMemoryNonHeapMaxIsSet(false); + this.jvmMemoryNonHeapMax = 0; + setJvmGcOldCountIsSet(false); + this.jvmGcOldCount = 0; + setJvmGcOldTimeIsSet(false); + this.jvmGcOldTime = 0; + } + + /** + * + * @see TJvmGcType + */ + public TJvmGcType getType() { + return this.type; + } + + /** + * + * @see TJvmGcType + */ + public void setType(TJvmGcType type) { + this.type = type; + } + + public void unsetType() { + this.type = null; + } + + /** Returns true if field type is set (has been assigned a value) and false otherwise */ + public boolean isSetType() { + return this.type != null; + } + + public void setTypeIsSet(boolean value) { + if (!value) { + this.type = null; + } + } + + public long getJvmMemoryHeapUsed() { + return this.jvmMemoryHeapUsed; + } + + public void setJvmMemoryHeapUsed(long jvmMemoryHeapUsed) { + this.jvmMemoryHeapUsed = jvmMemoryHeapUsed; + setJvmMemoryHeapUsedIsSet(true); + } + + public void unsetJvmMemoryHeapUsed() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYHEAPUSED_ISSET_ID); + } + + /** Returns true if field jvmMemoryHeapUsed is set (has been assigned a value) and false otherwise */ + public boolean isSetJvmMemoryHeapUsed() { + return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYHEAPUSED_ISSET_ID); + } + + public void setJvmMemoryHeapUsedIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYHEAPUSED_ISSET_ID, value); + } + + public long getJvmMemoryHeapMax() { + return this.jvmMemoryHeapMax; + } + + public void setJvmMemoryHeapMax(long jvmMemoryHeapMax) { + this.jvmMemoryHeapMax = jvmMemoryHeapMax; + setJvmMemoryHeapMaxIsSet(true); + } + + public void unsetJvmMemoryHeapMax() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYHEAPMAX_ISSET_ID); + } + + /** Returns true if field jvmMemoryHeapMax is set (has been assigned a value) and false otherwise */ + public boolean isSetJvmMemoryHeapMax() { + return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYHEAPMAX_ISSET_ID); + } + + public void setJvmMemoryHeapMaxIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYHEAPMAX_ISSET_ID, value); + } + + public long getJvmMemoryNonHeapUsed() { + return this.jvmMemoryNonHeapUsed; + } + + public void setJvmMemoryNonHeapUsed(long jvmMemoryNonHeapUsed) { + this.jvmMemoryNonHeapUsed = jvmMemoryNonHeapUsed; + setJvmMemoryNonHeapUsedIsSet(true); + } + + public void unsetJvmMemoryNonHeapUsed() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYNONHEAPUSED_ISSET_ID); + } + + /** Returns true if field jvmMemoryNonHeapUsed is set (has been assigned a value) and false otherwise */ + public boolean isSetJvmMemoryNonHeapUsed() { + return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYNONHEAPUSED_ISSET_ID); + } + + public void setJvmMemoryNonHeapUsedIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYNONHEAPUSED_ISSET_ID, value); + } + + public long getJvmMemoryNonHeapMax() { + return this.jvmMemoryNonHeapMax; + } + + public void setJvmMemoryNonHeapMax(long jvmMemoryNonHeapMax) { + this.jvmMemoryNonHeapMax = jvmMemoryNonHeapMax; + setJvmMemoryNonHeapMaxIsSet(true); + } + + public void unsetJvmMemoryNonHeapMax() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMMEMORYNONHEAPMAX_ISSET_ID); + } + + /** Returns true if field jvmMemoryNonHeapMax is set (has been assigned a value) and false otherwise */ + public boolean isSetJvmMemoryNonHeapMax() { + return EncodingUtils.testBit(__isset_bitfield, __JVMMEMORYNONHEAPMAX_ISSET_ID); + } + + public void setJvmMemoryNonHeapMaxIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMMEMORYNONHEAPMAX_ISSET_ID, value); + } + + public long getJvmGcOldCount() { + return this.jvmGcOldCount; + } + + public void setJvmGcOldCount(long jvmGcOldCount) { + this.jvmGcOldCount = jvmGcOldCount; + setJvmGcOldCountIsSet(true); + } + + public void unsetJvmGcOldCount() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMGCOLDCOUNT_ISSET_ID); + } + + /** Returns true if field jvmGcOldCount is set (has been assigned a value) and false otherwise */ + public boolean isSetJvmGcOldCount() { + return EncodingUtils.testBit(__isset_bitfield, __JVMGCOLDCOUNT_ISSET_ID); + } + + public void setJvmGcOldCountIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMGCOLDCOUNT_ISSET_ID, value); + } + + public long getJvmGcOldTime() { + return this.jvmGcOldTime; + } + + public void setJvmGcOldTime(long jvmGcOldTime) { + this.jvmGcOldTime = jvmGcOldTime; + setJvmGcOldTimeIsSet(true); + } + + public void unsetJvmGcOldTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __JVMGCOLDTIME_ISSET_ID); + } + + /** Returns true if field jvmGcOldTime is set (has been assigned a value) and false otherwise */ + public boolean isSetJvmGcOldTime() { + return EncodingUtils.testBit(__isset_bitfield, __JVMGCOLDTIME_ISSET_ID); + } + + public void setJvmGcOldTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __JVMGCOLDTIME_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case TYPE: + if (value == null) { + unsetType(); + } else { + setType((TJvmGcType)value); + } + break; + + case JVM_MEMORY_HEAP_USED: + if (value == null) { + unsetJvmMemoryHeapUsed(); + } else { + setJvmMemoryHeapUsed((Long)value); + } + break; + + case JVM_MEMORY_HEAP_MAX: + if (value == null) { + unsetJvmMemoryHeapMax(); + } else { + setJvmMemoryHeapMax((Long)value); + } + break; + + case JVM_MEMORY_NON_HEAP_USED: + if (value == null) { + unsetJvmMemoryNonHeapUsed(); + } else { + setJvmMemoryNonHeapUsed((Long)value); + } + break; + + case JVM_MEMORY_NON_HEAP_MAX: + if (value == null) { + unsetJvmMemoryNonHeapMax(); + } else { + setJvmMemoryNonHeapMax((Long)value); + } + break; + + case JVM_GC_OLD_COUNT: + if (value == null) { + unsetJvmGcOldCount(); + } else { + setJvmGcOldCount((Long)value); + } + break; + + case JVM_GC_OLD_TIME: + if (value == null) { + unsetJvmGcOldTime(); + } else { + setJvmGcOldTime((Long)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case TYPE: + return getType(); + + case JVM_MEMORY_HEAP_USED: + return Long.valueOf(getJvmMemoryHeapUsed()); + + case JVM_MEMORY_HEAP_MAX: + return Long.valueOf(getJvmMemoryHeapMax()); + + case JVM_MEMORY_NON_HEAP_USED: + return Long.valueOf(getJvmMemoryNonHeapUsed()); + + case JVM_MEMORY_NON_HEAP_MAX: + return Long.valueOf(getJvmMemoryNonHeapMax()); + + case JVM_GC_OLD_COUNT: + return Long.valueOf(getJvmGcOldCount()); + + case JVM_GC_OLD_TIME: + return Long.valueOf(getJvmGcOldTime()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case TYPE: + return isSetType(); + case JVM_MEMORY_HEAP_USED: + return isSetJvmMemoryHeapUsed(); + case JVM_MEMORY_HEAP_MAX: + return isSetJvmMemoryHeapMax(); + case JVM_MEMORY_NON_HEAP_USED: + return isSetJvmMemoryNonHeapUsed(); + case JVM_MEMORY_NON_HEAP_MAX: + return isSetJvmMemoryNonHeapMax(); + case JVM_GC_OLD_COUNT: + return isSetJvmGcOldCount(); + case JVM_GC_OLD_TIME: + return isSetJvmGcOldTime(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TJvmGc) + return this.equals((TJvmGc)that); + return false; + } + + public boolean equals(TJvmGc that) { + if (that == null) + return false; + + boolean this_present_type = true && this.isSetType(); + boolean that_present_type = true && that.isSetType(); + if (this_present_type || that_present_type) { + if (!(this_present_type && that_present_type)) + return false; + if (!this.type.equals(that.type)) + return false; + } + + boolean this_present_jvmMemoryHeapUsed = true; + boolean that_present_jvmMemoryHeapUsed = true; + if (this_present_jvmMemoryHeapUsed || that_present_jvmMemoryHeapUsed) { + if (!(this_present_jvmMemoryHeapUsed && that_present_jvmMemoryHeapUsed)) + return false; + if (this.jvmMemoryHeapUsed != that.jvmMemoryHeapUsed) + return false; + } + + boolean this_present_jvmMemoryHeapMax = true; + boolean that_present_jvmMemoryHeapMax = true; + if (this_present_jvmMemoryHeapMax || that_present_jvmMemoryHeapMax) { + if (!(this_present_jvmMemoryHeapMax && that_present_jvmMemoryHeapMax)) + return false; + if (this.jvmMemoryHeapMax != that.jvmMemoryHeapMax) + return false; + } + + boolean this_present_jvmMemoryNonHeapUsed = true; + boolean that_present_jvmMemoryNonHeapUsed = true; + if (this_present_jvmMemoryNonHeapUsed || that_present_jvmMemoryNonHeapUsed) { + if (!(this_present_jvmMemoryNonHeapUsed && that_present_jvmMemoryNonHeapUsed)) + return false; + if (this.jvmMemoryNonHeapUsed != that.jvmMemoryNonHeapUsed) + return false; + } + + boolean this_present_jvmMemoryNonHeapMax = true; + boolean that_present_jvmMemoryNonHeapMax = true; + if (this_present_jvmMemoryNonHeapMax || that_present_jvmMemoryNonHeapMax) { + if (!(this_present_jvmMemoryNonHeapMax && that_present_jvmMemoryNonHeapMax)) + return false; + if (this.jvmMemoryNonHeapMax != that.jvmMemoryNonHeapMax) + return false; + } + + boolean this_present_jvmGcOldCount = true; + boolean that_present_jvmGcOldCount = true; + if (this_present_jvmGcOldCount || that_present_jvmGcOldCount) { + if (!(this_present_jvmGcOldCount && that_present_jvmGcOldCount)) + return false; + if (this.jvmGcOldCount != that.jvmGcOldCount) + return false; + } + + boolean this_present_jvmGcOldTime = true; + boolean that_present_jvmGcOldTime = true; + if (this_present_jvmGcOldTime || that_present_jvmGcOldTime) { + if (!(this_present_jvmGcOldTime && that_present_jvmGcOldTime)) + return false; + if (this.jvmGcOldTime != that.jvmGcOldTime) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TJvmGc other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetJvmMemoryHeapUsed()).compareTo(other.isSetJvmMemoryHeapUsed()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetJvmMemoryHeapUsed()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryHeapUsed, other.jvmMemoryHeapUsed); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetJvmMemoryHeapMax()).compareTo(other.isSetJvmMemoryHeapMax()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetJvmMemoryHeapMax()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryHeapMax, other.jvmMemoryHeapMax); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetJvmMemoryNonHeapUsed()).compareTo(other.isSetJvmMemoryNonHeapUsed()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetJvmMemoryNonHeapUsed()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryNonHeapUsed, other.jvmMemoryNonHeapUsed); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetJvmMemoryNonHeapMax()).compareTo(other.isSetJvmMemoryNonHeapMax()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetJvmMemoryNonHeapMax()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmMemoryNonHeapMax, other.jvmMemoryNonHeapMax); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetJvmGcOldCount()).compareTo(other.isSetJvmGcOldCount()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetJvmGcOldCount()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmGcOldCount, other.jvmGcOldCount); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetJvmGcOldTime()).compareTo(other.isSetJvmGcOldTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetJvmGcOldTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jvmGcOldTime, other.jvmGcOldTime); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TJvmGc("); + boolean first = true; + + sb.append("type:"); + if (this.type == null) { + sb.append("null"); + } else { + sb.append(this.type); + } + first = false; + if (!first) sb.append(", "); + sb.append("jvmMemoryHeapUsed:"); + sb.append(this.jvmMemoryHeapUsed); + first = false; + if (!first) sb.append(", "); + sb.append("jvmMemoryHeapMax:"); + sb.append(this.jvmMemoryHeapMax); + first = false; + if (!first) sb.append(", "); + sb.append("jvmMemoryNonHeapUsed:"); + sb.append(this.jvmMemoryNonHeapUsed); + first = false; + if (!first) sb.append(", "); + sb.append("jvmMemoryNonHeapMax:"); + sb.append(this.jvmMemoryNonHeapMax); + first = false; + if (!first) sb.append(", "); + sb.append("jvmGcOldCount:"); + sb.append(this.jvmGcOldCount); + first = false; + if (!first) sb.append(", "); + sb.append("jvmGcOldTime:"); + sb.append(this.jvmGcOldTime); + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TJvmGcStandardSchemeFactory implements SchemeFactory { + public TJvmGcStandardScheme getScheme() { + return new TJvmGcStandardScheme(); + } + } + + private static class TJvmGcStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TJvmGc struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // TYPE + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.type = TJvmGcType.findByValue(iprot.readI32()); + struct.setTypeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // JVM_MEMORY_HEAP_USED + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.jvmMemoryHeapUsed = iprot.readI64(); + struct.setJvmMemoryHeapUsedIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // JVM_MEMORY_HEAP_MAX + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.jvmMemoryHeapMax = iprot.readI64(); + struct.setJvmMemoryHeapMaxIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // JVM_MEMORY_NON_HEAP_USED + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.jvmMemoryNonHeapUsed = iprot.readI64(); + struct.setJvmMemoryNonHeapUsedIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 5: // JVM_MEMORY_NON_HEAP_MAX + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.jvmMemoryNonHeapMax = iprot.readI64(); + struct.setJvmMemoryNonHeapMaxIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 6: // JVM_GC_OLD_COUNT + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.jvmGcOldCount = iprot.readI64(); + struct.setJvmGcOldCountIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 7: // JVM_GC_OLD_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.jvmGcOldTime = iprot.readI64(); + struct.setJvmGcOldTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TJvmGc struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.type != null) { + oprot.writeFieldBegin(TYPE_FIELD_DESC); + oprot.writeI32(struct.type.getValue()); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(JVM_MEMORY_HEAP_USED_FIELD_DESC); + oprot.writeI64(struct.jvmMemoryHeapUsed); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(JVM_MEMORY_HEAP_MAX_FIELD_DESC); + oprot.writeI64(struct.jvmMemoryHeapMax); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(JVM_MEMORY_NON_HEAP_USED_FIELD_DESC); + oprot.writeI64(struct.jvmMemoryNonHeapUsed); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(JVM_MEMORY_NON_HEAP_MAX_FIELD_DESC); + oprot.writeI64(struct.jvmMemoryNonHeapMax); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(JVM_GC_OLD_COUNT_FIELD_DESC); + oprot.writeI64(struct.jvmGcOldCount); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(JVM_GC_OLD_TIME_FIELD_DESC); + oprot.writeI64(struct.jvmGcOldTime); + oprot.writeFieldEnd(); + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TJvmGcTupleSchemeFactory implements SchemeFactory { + public TJvmGcTupleScheme getScheme() { + return new TJvmGcTupleScheme(); + } + } + + private static class TJvmGcTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TJvmGc struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetType()) { + optionals.set(0); + } + if (struct.isSetJvmMemoryHeapUsed()) { + optionals.set(1); + } + if (struct.isSetJvmMemoryHeapMax()) { + optionals.set(2); + } + if (struct.isSetJvmMemoryNonHeapUsed()) { + optionals.set(3); + } + if (struct.isSetJvmMemoryNonHeapMax()) { + optionals.set(4); + } + if (struct.isSetJvmGcOldCount()) { + optionals.set(5); + } + if (struct.isSetJvmGcOldTime()) { + optionals.set(6); + } + oprot.writeBitSet(optionals, 7); + if (struct.isSetType()) { + oprot.writeI32(struct.type.getValue()); + } + if (struct.isSetJvmMemoryHeapUsed()) { + oprot.writeI64(struct.jvmMemoryHeapUsed); + } + if (struct.isSetJvmMemoryHeapMax()) { + oprot.writeI64(struct.jvmMemoryHeapMax); + } + if (struct.isSetJvmMemoryNonHeapUsed()) { + oprot.writeI64(struct.jvmMemoryNonHeapUsed); + } + if (struct.isSetJvmMemoryNonHeapMax()) { + oprot.writeI64(struct.jvmMemoryNonHeapMax); + } + if (struct.isSetJvmGcOldCount()) { + oprot.writeI64(struct.jvmGcOldCount); + } + if (struct.isSetJvmGcOldTime()) { + oprot.writeI64(struct.jvmGcOldTime); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TJvmGc struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(7); + if (incoming.get(0)) { + struct.type = TJvmGcType.findByValue(iprot.readI32()); + struct.setTypeIsSet(true); + } + if (incoming.get(1)) { + struct.jvmMemoryHeapUsed = iprot.readI64(); + struct.setJvmMemoryHeapUsedIsSet(true); + } + if (incoming.get(2)) { + struct.jvmMemoryHeapMax = iprot.readI64(); + struct.setJvmMemoryHeapMaxIsSet(true); + } + if (incoming.get(3)) { + struct.jvmMemoryNonHeapUsed = iprot.readI64(); + struct.setJvmMemoryNonHeapUsedIsSet(true); + } + if (incoming.get(4)) { + struct.jvmMemoryNonHeapMax = iprot.readI64(); + struct.setJvmMemoryNonHeapMaxIsSet(true); + } + if (incoming.get(5)) { + struct.jvmGcOldCount = iprot.readI64(); + struct.setJvmGcOldCountIsSet(true); + } + if (incoming.get(6)) { + struct.jvmGcOldTime = iprot.readI64(); + struct.setJvmGcOldTimeIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGcType.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGcType.java index f763c23ac994..71e8ad0a4261 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGcType.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TJvmGcType.java @@ -1,54 +1,54 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - - -import java.util.Map; -import java.util.HashMap; -import org.apache.thrift.TEnum; - -public enum TJvmGcType implements org.apache.thrift.TEnum { - UNKNOWN(0), - SERIAL(1), - PARALLEL(2), - CMS(3), - G1(4); - - private final int value; - - private TJvmGcType(int value) { - this.value = value; - } - - /** - * Get the integer value of this enum value, as defined in the Thrift IDL. - */ - public int getValue() { - return value; - } - - /** - * Find a the enum type by its integer value, as defined in the Thrift IDL. - * @return null if the value is not found. - */ - public static TJvmGcType findByValue(int value) { - switch (value) { - case 0: - return UNKNOWN; - case 1: - return SERIAL; - case 2: - return PARALLEL; - case 3: - return CMS; - case 4: - return G1; - default: - return null; - } - } -} +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + + +import java.util.Map; +import java.util.HashMap; +import org.apache.thrift.TEnum; + +public enum TJvmGcType implements org.apache.thrift.TEnum { + UNKNOWN(0), + SERIAL(1), + PARALLEL(2), + CMS(3), + G1(4); + + private final int value; + + private TJvmGcType(int value) { + this.value = value; + } + + /** + * Get the integer value of this enum value, as defined in the Thrift IDL. + */ + public int getValue() { + return value; + } + + /** + * Find a the enum type by its integer value, as defined in the Thrift IDL. + * @return null if the value is not found. + */ + public static TJvmGcType findByValue(int value) { + switch (value) { + case 0: + return UNKNOWN; + case 1: + return SERIAL; + case 2: + return PARALLEL; + case 3: + return CMS; + case 4: + return G1; + default: + return null; + } + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TResult.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TResult.java index 2ff269b53c3c..010c7b9dc966 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TResult.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TResult.java @@ -1,485 +1,485 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TResult implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TResult"); - - private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)1); - private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("message", org.apache.thrift.protocol.TType.STRING, (short)2); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TResultStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TResultTupleSchemeFactory()); - } - - private boolean success; // required - private String message; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - SUCCESS((short)1, "success"), - MESSAGE((short)2, "message"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // SUCCESS - return SUCCESS; - case 2: // MESSAGE - return MESSAGE; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __SUCCESS_ISSET_ID = 0; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.MESSAGE}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); - tmpMap.put(_Fields.MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("message", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TResult.class, metaDataMap); - } - - public TResult() { - } - - public TResult( - boolean success) - { - this(); - this.success = success; - setSuccessIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TResult(TResult other) { - __isset_bitfield = other.__isset_bitfield; - this.success = other.success; - if (other.isSetMessage()) { - this.message = other.message; - } - } - - public TResult deepCopy() { - return new TResult(this); - } - - @Override - public void clear() { - setSuccessIsSet(false); - this.success = false; - this.message = null; - } - - public boolean isSuccess() { - return this.success; - } - - public void setSuccess(boolean success) { - this.success = success; - setSuccessIsSet(true); - } - - public void unsetSuccess() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID); - } - - /** Returns true if field success is set (has been assigned a value) and false otherwise */ - public boolean isSetSuccess() { - return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID); - } - - public void setSuccessIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value); - } - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - public void unsetMessage() { - this.message = null; - } - - /** Returns true if field message is set (has been assigned a value) and false otherwise */ - public boolean isSetMessage() { - return this.message != null; - } - - public void setMessageIsSet(boolean value) { - if (!value) { - this.message = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case SUCCESS: - if (value == null) { - unsetSuccess(); - } else { - setSuccess((Boolean)value); - } - break; - - case MESSAGE: - if (value == null) { - unsetMessage(); - } else { - setMessage((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case SUCCESS: - return Boolean.valueOf(isSuccess()); - - case MESSAGE: - return getMessage(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case SUCCESS: - return isSetSuccess(); - case MESSAGE: - return isSetMessage(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TResult) - return this.equals((TResult)that); - return false; - } - - public boolean equals(TResult that) { - if (that == null) - return false; - - boolean this_present_success = true; - boolean that_present_success = true; - if (this_present_success || that_present_success) { - if (!(this_present_success && that_present_success)) - return false; - if (this.success != that.success) - return false; - } - - boolean this_present_message = true && this.isSetMessage(); - boolean that_present_message = true && that.isSetMessage(); - if (this_present_message || that_present_message) { - if (!(this_present_message && that_present_message)) - return false; - if (!this.message.equals(that.message)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TResult other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSuccess()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetMessage()).compareTo(other.isSetMessage()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetMessage()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, other.message); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TResult("); - boolean first = true; - - sb.append("success:"); - sb.append(this.success); - first = false; - if (isSetMessage()) { - if (!first) sb.append(", "); - sb.append("message:"); - if (this.message == null) { - sb.append("null"); - } else { - sb.append(this.message); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TResultStandardSchemeFactory implements SchemeFactory { - public TResultStandardScheme getScheme() { - return new TResultStandardScheme(); - } - } - - private static class TResultStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TResult struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // SUCCESS - if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) { - struct.success = iprot.readBool(); - struct.setSuccessIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // MESSAGE - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.message = iprot.readString(); - struct.setMessageIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TResult struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - oprot.writeFieldBegin(SUCCESS_FIELD_DESC); - oprot.writeBool(struct.success); - oprot.writeFieldEnd(); - if (struct.message != null) { - if (struct.isSetMessage()) { - oprot.writeFieldBegin(MESSAGE_FIELD_DESC); - oprot.writeString(struct.message); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TResultTupleSchemeFactory implements SchemeFactory { - public TResultTupleScheme getScheme() { - return new TResultTupleScheme(); - } - } - - private static class TResultTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TResult struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetSuccess()) { - optionals.set(0); - } - if (struct.isSetMessage()) { - optionals.set(1); - } - oprot.writeBitSet(optionals, 2); - if (struct.isSetSuccess()) { - oprot.writeBool(struct.success); - } - if (struct.isSetMessage()) { - oprot.writeString(struct.message); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TResult struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(2); - if (incoming.get(0)) { - struct.success = iprot.readBool(); - struct.setSuccessIsSet(true); - } - if (incoming.get(1)) { - struct.message = iprot.readString(); - struct.setMessageIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TResult implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TResult"); + + private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)1); + private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("message", org.apache.thrift.protocol.TType.STRING, (short)2); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TResultStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TResultTupleSchemeFactory()); + } + + private boolean success; // required + private String message; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + SUCCESS((short)1, "success"), + MESSAGE((short)2, "message"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // SUCCESS + return SUCCESS; + case 2: // MESSAGE + return MESSAGE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __SUCCESS_ISSET_ID = 0; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.MESSAGE}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); + tmpMap.put(_Fields.MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("message", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TResult.class, metaDataMap); + } + + public TResult() { + } + + public TResult( + boolean success) + { + this(); + this.success = success; + setSuccessIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TResult(TResult other) { + __isset_bitfield = other.__isset_bitfield; + this.success = other.success; + if (other.isSetMessage()) { + this.message = other.message; + } + } + + public TResult deepCopy() { + return new TResult(this); + } + + @Override + public void clear() { + setSuccessIsSet(false); + this.success = false; + this.message = null; + } + + public boolean isSuccess() { + return this.success; + } + + public void setSuccess(boolean success) { + this.success = success; + setSuccessIsSet(true); + } + + public void unsetSuccess() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID); + } + + /** Returns true if field success is set (has been assigned a value) and false otherwise */ + public boolean isSetSuccess() { + return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID); + } + + public void setSuccessIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value); + } + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + + public void unsetMessage() { + this.message = null; + } + + /** Returns true if field message is set (has been assigned a value) and false otherwise */ + public boolean isSetMessage() { + return this.message != null; + } + + public void setMessageIsSet(boolean value) { + if (!value) { + this.message = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case SUCCESS: + if (value == null) { + unsetSuccess(); + } else { + setSuccess((Boolean)value); + } + break; + + case MESSAGE: + if (value == null) { + unsetMessage(); + } else { + setMessage((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case SUCCESS: + return Boolean.valueOf(isSuccess()); + + case MESSAGE: + return getMessage(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case SUCCESS: + return isSetSuccess(); + case MESSAGE: + return isSetMessage(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TResult) + return this.equals((TResult)that); + return false; + } + + public boolean equals(TResult that) { + if (that == null) + return false; + + boolean this_present_success = true; + boolean that_present_success = true; + if (this_present_success || that_present_success) { + if (!(this_present_success && that_present_success)) + return false; + if (this.success != that.success) + return false; + } + + boolean this_present_message = true && this.isSetMessage(); + boolean that_present_message = true && that.isSetMessage(); + if (this_present_message || that_present_message) { + if (!(this_present_message && that_present_message)) + return false; + if (!this.message.equals(that.message)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TResult other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSuccess()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetMessage()).compareTo(other.isSetMessage()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetMessage()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, other.message); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TResult("); + boolean first = true; + + sb.append("success:"); + sb.append(this.success); + first = false; + if (isSetMessage()) { + if (!first) sb.append(", "); + sb.append("message:"); + if (this.message == null) { + sb.append("null"); + } else { + sb.append(this.message); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TResultStandardSchemeFactory implements SchemeFactory { + public TResultStandardScheme getScheme() { + return new TResultStandardScheme(); + } + } + + private static class TResultStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TResult struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // SUCCESS + if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) { + struct.success = iprot.readBool(); + struct.setSuccessIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // MESSAGE + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.message = iprot.readString(); + struct.setMessageIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TResult struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + oprot.writeFieldBegin(SUCCESS_FIELD_DESC); + oprot.writeBool(struct.success); + oprot.writeFieldEnd(); + if (struct.message != null) { + if (struct.isSetMessage()) { + oprot.writeFieldBegin(MESSAGE_FIELD_DESC); + oprot.writeString(struct.message); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TResultTupleSchemeFactory implements SchemeFactory { + public TResultTupleScheme getScheme() { + return new TResultTupleScheme(); + } + } + + private static class TResultTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TResult struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetSuccess()) { + optionals.set(0); + } + if (struct.isSetMessage()) { + optionals.set(1); + } + oprot.writeBitSet(optionals, 2); + if (struct.isSetSuccess()) { + oprot.writeBool(struct.success); + } + if (struct.isSetMessage()) { + oprot.writeString(struct.message); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TResult struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(2); + if (incoming.get(0)) { + struct.success = iprot.readBool(); + struct.setSuccessIsSet(true); + } + if (incoming.get(1)) { + struct.message = iprot.readString(); + struct.setMessageIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java index dbbe5f3e8d51..a6c69993f648 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java @@ -1,2461 +1,2461 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TSpan implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSpan"); - - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)2); - private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)3); - private static final org.apache.thrift.protocol.TField TRANSACTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("transactionId", org.apache.thrift.protocol.TType.STRING, (short)4); - private static final org.apache.thrift.protocol.TField SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("spanId", org.apache.thrift.protocol.TType.I64, (short)7); - private static final org.apache.thrift.protocol.TField PARENT_SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("parentSpanId", org.apache.thrift.protocol.TType.I64, (short)8); - private static final org.apache.thrift.protocol.TField START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("startTime", org.apache.thrift.protocol.TType.I64, (short)9); - private static final org.apache.thrift.protocol.TField ELAPSED_FIELD_DESC = new org.apache.thrift.protocol.TField("elapsed", org.apache.thrift.protocol.TType.I32, (short)10); - private static final org.apache.thrift.protocol.TField RPC_FIELD_DESC = new org.apache.thrift.protocol.TField("rpc", org.apache.thrift.protocol.TType.STRING, (short)11); - private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)12); - private static final org.apache.thrift.protocol.TField END_POINT_FIELD_DESC = new org.apache.thrift.protocol.TField("endPoint", org.apache.thrift.protocol.TType.STRING, (short)13); - private static final org.apache.thrift.protocol.TField REMOTE_ADDR_FIELD_DESC = new org.apache.thrift.protocol.TField("remoteAddr", org.apache.thrift.protocol.TType.STRING, (short)14); - private static final org.apache.thrift.protocol.TField ANNOTATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("annotations", org.apache.thrift.protocol.TType.LIST, (short)15); - private static final org.apache.thrift.protocol.TField FLAG_FIELD_DESC = new org.apache.thrift.protocol.TField("flag", org.apache.thrift.protocol.TType.I16, (short)16); - private static final org.apache.thrift.protocol.TField ERR_FIELD_DESC = new org.apache.thrift.protocol.TField("err", org.apache.thrift.protocol.TType.I32, (short)17); - private static final org.apache.thrift.protocol.TField SPAN_EVENT_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("spanEventList", org.apache.thrift.protocol.TType.LIST, (short)18); - private static final org.apache.thrift.protocol.TField PARENT_APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("parentApplicationName", org.apache.thrift.protocol.TType.STRING, (short)19); - private static final org.apache.thrift.protocol.TField PARENT_APPLICATION_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("parentApplicationType", org.apache.thrift.protocol.TType.I16, (short)20); - private static final org.apache.thrift.protocol.TField ACCEPTOR_HOST_FIELD_DESC = new org.apache.thrift.protocol.TField("acceptorHost", org.apache.thrift.protocol.TType.STRING, (short)21); - private static final org.apache.thrift.protocol.TField API_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("apiId", org.apache.thrift.protocol.TType.I32, (short)25); - private static final org.apache.thrift.protocol.TField EXCEPTION_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionInfo", org.apache.thrift.protocol.TType.STRUCT, (short)26); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TSpanStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TSpanTupleSchemeFactory()); - } - - private String agentId; // required - private String applicationName; // required - private long agentStartTime; // required - private ByteBuffer transactionId; // required - private long spanId; // required - private long parentSpanId; // optional - private long startTime; // required - private int elapsed; // optional - private String rpc; // optional - private short serviceType; // required - private String endPoint; // optional - private String remoteAddr; // optional - private List annotations; // optional - private short flag; // optional - private int err; // optional - private List spanEventList; // optional - private String parentApplicationName; // optional - private short parentApplicationType; // optional - private String acceptorHost; // optional - private int apiId; // optional - private TIntStringValue exceptionInfo; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - AGENT_ID((short)1, "agentId"), - APPLICATION_NAME((short)2, "applicationName"), - AGENT_START_TIME((short)3, "agentStartTime"), - TRANSACTION_ID((short)4, "transactionId"), - SPAN_ID((short)7, "spanId"), - PARENT_SPAN_ID((short)8, "parentSpanId"), - START_TIME((short)9, "startTime"), - ELAPSED((short)10, "elapsed"), - RPC((short)11, "rpc"), - SERVICE_TYPE((short)12, "serviceType"), - END_POINT((short)13, "endPoint"), - REMOTE_ADDR((short)14, "remoteAddr"), - ANNOTATIONS((short)15, "annotations"), - FLAG((short)16, "flag"), - ERR((short)17, "err"), - SPAN_EVENT_LIST((short)18, "spanEventList"), - PARENT_APPLICATION_NAME((short)19, "parentApplicationName"), - PARENT_APPLICATION_TYPE((short)20, "parentApplicationType"), - ACCEPTOR_HOST((short)21, "acceptorHost"), - API_ID((short)25, "apiId"), - EXCEPTION_INFO((short)26, "exceptionInfo"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // AGENT_ID - return AGENT_ID; - case 2: // APPLICATION_NAME - return APPLICATION_NAME; - case 3: // AGENT_START_TIME - return AGENT_START_TIME; - case 4: // TRANSACTION_ID - return TRANSACTION_ID; - case 7: // SPAN_ID - return SPAN_ID; - case 8: // PARENT_SPAN_ID - return PARENT_SPAN_ID; - case 9: // START_TIME - return START_TIME; - case 10: // ELAPSED - return ELAPSED; - case 11: // RPC - return RPC; - case 12: // SERVICE_TYPE - return SERVICE_TYPE; - case 13: // END_POINT - return END_POINT; - case 14: // REMOTE_ADDR - return REMOTE_ADDR; - case 15: // ANNOTATIONS - return ANNOTATIONS; - case 16: // FLAG - return FLAG; - case 17: // ERR - return ERR; - case 18: // SPAN_EVENT_LIST - return SPAN_EVENT_LIST; - case 19: // PARENT_APPLICATION_NAME - return PARENT_APPLICATION_NAME; - case 20: // PARENT_APPLICATION_TYPE - return PARENT_APPLICATION_TYPE; - case 21: // ACCEPTOR_HOST - return ACCEPTOR_HOST; - case 25: // API_ID - return API_ID; - case 26: // EXCEPTION_INFO - return EXCEPTION_INFO; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __AGENTSTARTTIME_ISSET_ID = 0; - private static final int __SPANID_ISSET_ID = 1; - private static final int __PARENTSPANID_ISSET_ID = 2; - private static final int __STARTTIME_ISSET_ID = 3; - private static final int __ELAPSED_ISSET_ID = 4; - private static final int __SERVICETYPE_ISSET_ID = 5; - private static final int __FLAG_ISSET_ID = 6; - private static final int __ERR_ISSET_ID = 7; - private static final int __PARENTAPPLICATIONTYPE_ISSET_ID = 8; - private static final int __APIID_ISSET_ID = 9; - private short __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.PARENT_SPAN_ID,_Fields.ELAPSED,_Fields.RPC,_Fields.END_POINT,_Fields.REMOTE_ADDR,_Fields.ANNOTATIONS,_Fields.FLAG,_Fields.ERR,_Fields.SPAN_EVENT_LIST,_Fields.PARENT_APPLICATION_NAME,_Fields.PARENT_APPLICATION_TYPE,_Fields.ACCEPTOR_HOST,_Fields.API_ID,_Fields.EXCEPTION_INFO}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.TRANSACTION_ID, new org.apache.thrift.meta_data.FieldMetaData("transactionId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); - tmpMap.put(_Fields.SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("spanId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.PARENT_SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("parentSpanId", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.START_TIME, new org.apache.thrift.meta_data.FieldMetaData("startTime", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.ELAPSED, new org.apache.thrift.meta_data.FieldMetaData("elapsed", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.RPC, new org.apache.thrift.meta_data.FieldMetaData("rpc", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.END_POINT, new org.apache.thrift.meta_data.FieldMetaData("endPoint", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.REMOTE_ADDR, new org.apache.thrift.meta_data.FieldMetaData("remoteAddr", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.ANNOTATIONS, new org.apache.thrift.meta_data.FieldMetaData("annotations", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAnnotation.class)))); - tmpMap.put(_Fields.FLAG, new org.apache.thrift.meta_data.FieldMetaData("flag", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.ERR, new org.apache.thrift.meta_data.FieldMetaData("err", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.SPAN_EVENT_LIST, new org.apache.thrift.meta_data.FieldMetaData("spanEventList", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSpanEvent.class)))); - tmpMap.put(_Fields.PARENT_APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("parentApplicationName", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.PARENT_APPLICATION_TYPE, new org.apache.thrift.meta_data.FieldMetaData("parentApplicationType", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.ACCEPTOR_HOST, new org.apache.thrift.meta_data.FieldMetaData("acceptorHost", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.API_ID, new org.apache.thrift.meta_data.FieldMetaData("apiId", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.EXCEPTION_INFO, new org.apache.thrift.meta_data.FieldMetaData("exceptionInfo", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringValue.class))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpan.class, metaDataMap); - } - - public TSpan() { - this.parentSpanId = -1L; - - this.elapsed = 0; - - this.flag = (short)0; - - } - - public TSpan( - String agentId, - String applicationName, - long agentStartTime, - ByteBuffer transactionId, - long spanId, - long startTime, - short serviceType) - { - this(); - this.agentId = agentId; - this.applicationName = applicationName; - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - this.transactionId = transactionId; - this.spanId = spanId; - setSpanIdIsSet(true); - this.startTime = startTime; - setStartTimeIsSet(true); - this.serviceType = serviceType; - setServiceTypeIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TSpan(TSpan other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - if (other.isSetApplicationName()) { - this.applicationName = other.applicationName; - } - this.agentStartTime = other.agentStartTime; - if (other.isSetTransactionId()) { - this.transactionId = org.apache.thrift.TBaseHelper.copyBinary(other.transactionId); -; - } - this.spanId = other.spanId; - this.parentSpanId = other.parentSpanId; - this.startTime = other.startTime; - this.elapsed = other.elapsed; - if (other.isSetRpc()) { - this.rpc = other.rpc; - } - this.serviceType = other.serviceType; - if (other.isSetEndPoint()) { - this.endPoint = other.endPoint; - } - if (other.isSetRemoteAddr()) { - this.remoteAddr = other.remoteAddr; - } - if (other.isSetAnnotations()) { - List __this__annotations = new ArrayList(other.annotations.size()); - for (TAnnotation other_element : other.annotations) { - __this__annotations.add(new TAnnotation(other_element)); - } - this.annotations = __this__annotations; - } - this.flag = other.flag; - this.err = other.err; - if (other.isSetSpanEventList()) { - List __this__spanEventList = new ArrayList(other.spanEventList.size()); - for (TSpanEvent other_element : other.spanEventList) { - __this__spanEventList.add(new TSpanEvent(other_element)); - } - this.spanEventList = __this__spanEventList; - } - if (other.isSetParentApplicationName()) { - this.parentApplicationName = other.parentApplicationName; - } - this.parentApplicationType = other.parentApplicationType; - if (other.isSetAcceptorHost()) { - this.acceptorHost = other.acceptorHost; - } - this.apiId = other.apiId; - if (other.isSetExceptionInfo()) { - this.exceptionInfo = new TIntStringValue(other.exceptionInfo); - } - } - - public TSpan deepCopy() { - return new TSpan(this); - } - - @Override - public void clear() { - this.agentId = null; - this.applicationName = null; - setAgentStartTimeIsSet(false); - this.agentStartTime = 0; - this.transactionId = null; - setSpanIdIsSet(false); - this.spanId = 0; - this.parentSpanId = -1L; - - setStartTimeIsSet(false); - this.startTime = 0; - this.elapsed = 0; - - this.rpc = null; - setServiceTypeIsSet(false); - this.serviceType = 0; - this.endPoint = null; - this.remoteAddr = null; - this.annotations = null; - this.flag = (short)0; - - setErrIsSet(false); - this.err = 0; - this.spanEventList = null; - this.parentApplicationName = null; - setParentApplicationTypeIsSet(false); - this.parentApplicationType = 0; - this.acceptorHost = null; - setApiIdIsSet(false); - this.apiId = 0; - this.exceptionInfo = null; - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public String getApplicationName() { - return this.applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public void unsetApplicationName() { - this.applicationName = null; - } - - /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ - public boolean isSetApplicationName() { - return this.applicationName != null; - } - - public void setApplicationNameIsSet(boolean value) { - if (!value) { - this.applicationName = null; - } - } - - public long getAgentStartTime() { - return this.agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - } - - public void unsetAgentStartTime() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentStartTime() { - return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - public void setAgentStartTimeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); - } - - public byte[] getTransactionId() { - setTransactionId(org.apache.thrift.TBaseHelper.rightSize(transactionId)); - return transactionId == null ? null : transactionId.array(); - } - - public ByteBuffer bufferForTransactionId() { - return transactionId; - } - - public void setTransactionId(byte[] transactionId) { - setTransactionId(transactionId == null ? (ByteBuffer)null : ByteBuffer.wrap(transactionId)); - } - - public void setTransactionId(ByteBuffer transactionId) { - this.transactionId = transactionId; - } - - public void unsetTransactionId() { - this.transactionId = null; - } - - /** Returns true if field transactionId is set (has been assigned a value) and false otherwise */ - public boolean isSetTransactionId() { - return this.transactionId != null; - } - - public void setTransactionIdIsSet(boolean value) { - if (!value) { - this.transactionId = null; - } - } - - public long getSpanId() { - return this.spanId; - } - - public void setSpanId(long spanId) { - this.spanId = spanId; - setSpanIdIsSet(true); - } - - public void unsetSpanId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SPANID_ISSET_ID); - } - - /** Returns true if field spanId is set (has been assigned a value) and false otherwise */ - public boolean isSetSpanId() { - return EncodingUtils.testBit(__isset_bitfield, __SPANID_ISSET_ID); - } - - public void setSpanIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SPANID_ISSET_ID, value); - } - - public long getParentSpanId() { - return this.parentSpanId; - } - - public void setParentSpanId(long parentSpanId) { - this.parentSpanId = parentSpanId; - setParentSpanIdIsSet(true); - } - - public void unsetParentSpanId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PARENTSPANID_ISSET_ID); - } - - /** Returns true if field parentSpanId is set (has been assigned a value) and false otherwise */ - public boolean isSetParentSpanId() { - return EncodingUtils.testBit(__isset_bitfield, __PARENTSPANID_ISSET_ID); - } - - public void setParentSpanIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PARENTSPANID_ISSET_ID, value); - } - - public long getStartTime() { - return this.startTime; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - setStartTimeIsSet(true); - } - - public void unsetStartTime() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIME_ISSET_ID); - } - - /** Returns true if field startTime is set (has been assigned a value) and false otherwise */ - public boolean isSetStartTime() { - return EncodingUtils.testBit(__isset_bitfield, __STARTTIME_ISSET_ID); - } - - public void setStartTimeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIME_ISSET_ID, value); - } - - public int getElapsed() { - return this.elapsed; - } - - public void setElapsed(int elapsed) { - this.elapsed = elapsed; - setElapsedIsSet(true); - } - - public void unsetElapsed() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ELAPSED_ISSET_ID); - } - - /** Returns true if field elapsed is set (has been assigned a value) and false otherwise */ - public boolean isSetElapsed() { - return EncodingUtils.testBit(__isset_bitfield, __ELAPSED_ISSET_ID); - } - - public void setElapsedIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ELAPSED_ISSET_ID, value); - } - - public String getRpc() { - return this.rpc; - } - - public void setRpc(String rpc) { - this.rpc = rpc; - } - - public void unsetRpc() { - this.rpc = null; - } - - /** Returns true if field rpc is set (has been assigned a value) and false otherwise */ - public boolean isSetRpc() { - return this.rpc != null; - } - - public void setRpcIsSet(boolean value) { - if (!value) { - this.rpc = null; - } - } - - public short getServiceType() { - return this.serviceType; - } - - public void setServiceType(short serviceType) { - this.serviceType = serviceType; - setServiceTypeIsSet(true); - } - - public void unsetServiceType() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ - public boolean isSetServiceType() { - return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - public void setServiceTypeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); - } - - public String getEndPoint() { - return this.endPoint; - } - - public void setEndPoint(String endPoint) { - this.endPoint = endPoint; - } - - public void unsetEndPoint() { - this.endPoint = null; - } - - /** Returns true if field endPoint is set (has been assigned a value) and false otherwise */ - public boolean isSetEndPoint() { - return this.endPoint != null; - } - - public void setEndPointIsSet(boolean value) { - if (!value) { - this.endPoint = null; - } - } - - public String getRemoteAddr() { - return this.remoteAddr; - } - - public void setRemoteAddr(String remoteAddr) { - this.remoteAddr = remoteAddr; - } - - public void unsetRemoteAddr() { - this.remoteAddr = null; - } - - /** Returns true if field remoteAddr is set (has been assigned a value) and false otherwise */ - public boolean isSetRemoteAddr() { - return this.remoteAddr != null; - } - - public void setRemoteAddrIsSet(boolean value) { - if (!value) { - this.remoteAddr = null; - } - } - - public int getAnnotationsSize() { - return (this.annotations == null) ? 0 : this.annotations.size(); - } - - public java.util.Iterator getAnnotationsIterator() { - return (this.annotations == null) ? null : this.annotations.iterator(); - } - - public void addToAnnotations(TAnnotation elem) { - if (this.annotations == null) { - this.annotations = new ArrayList(); - } - this.annotations.add(elem); - } - - public List getAnnotations() { - return this.annotations; - } - - public void setAnnotations(List annotations) { - this.annotations = annotations; - } - - public void unsetAnnotations() { - this.annotations = null; - } - - /** Returns true if field annotations is set (has been assigned a value) and false otherwise */ - public boolean isSetAnnotations() { - return this.annotations != null; - } - - public void setAnnotationsIsSet(boolean value) { - if (!value) { - this.annotations = null; - } - } - - public short getFlag() { - return this.flag; - } - - public void setFlag(short flag) { - this.flag = flag; - setFlagIsSet(true); - } - - public void unsetFlag() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FLAG_ISSET_ID); - } - - /** Returns true if field flag is set (has been assigned a value) and false otherwise */ - public boolean isSetFlag() { - return EncodingUtils.testBit(__isset_bitfield, __FLAG_ISSET_ID); - } - - public void setFlagIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FLAG_ISSET_ID, value); - } - - public int getErr() { - return this.err; - } - - public void setErr(int err) { - this.err = err; - setErrIsSet(true); - } - - public void unsetErr() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ERR_ISSET_ID); - } - - /** Returns true if field err is set (has been assigned a value) and false otherwise */ - public boolean isSetErr() { - return EncodingUtils.testBit(__isset_bitfield, __ERR_ISSET_ID); - } - - public void setErrIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ERR_ISSET_ID, value); - } - - public int getSpanEventListSize() { - return (this.spanEventList == null) ? 0 : this.spanEventList.size(); - } - - public java.util.Iterator getSpanEventListIterator() { - return (this.spanEventList == null) ? null : this.spanEventList.iterator(); - } - - public void addToSpanEventList(TSpanEvent elem) { - if (this.spanEventList == null) { - this.spanEventList = new ArrayList(); - } - this.spanEventList.add(elem); - } - - public List getSpanEventList() { - return this.spanEventList; - } - - public void setSpanEventList(List spanEventList) { - this.spanEventList = spanEventList; - } - - public void unsetSpanEventList() { - this.spanEventList = null; - } - - /** Returns true if field spanEventList is set (has been assigned a value) and false otherwise */ - public boolean isSetSpanEventList() { - return this.spanEventList != null; - } - - public void setSpanEventListIsSet(boolean value) { - if (!value) { - this.spanEventList = null; - } - } - - public String getParentApplicationName() { - return this.parentApplicationName; - } - - public void setParentApplicationName(String parentApplicationName) { - this.parentApplicationName = parentApplicationName; - } - - public void unsetParentApplicationName() { - this.parentApplicationName = null; - } - - /** Returns true if field parentApplicationName is set (has been assigned a value) and false otherwise */ - public boolean isSetParentApplicationName() { - return this.parentApplicationName != null; - } - - public void setParentApplicationNameIsSet(boolean value) { - if (!value) { - this.parentApplicationName = null; - } - } - - public short getParentApplicationType() { - return this.parentApplicationType; - } - - public void setParentApplicationType(short parentApplicationType) { - this.parentApplicationType = parentApplicationType; - setParentApplicationTypeIsSet(true); - } - - public void unsetParentApplicationType() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PARENTAPPLICATIONTYPE_ISSET_ID); - } - - /** Returns true if field parentApplicationType is set (has been assigned a value) and false otherwise */ - public boolean isSetParentApplicationType() { - return EncodingUtils.testBit(__isset_bitfield, __PARENTAPPLICATIONTYPE_ISSET_ID); - } - - public void setParentApplicationTypeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PARENTAPPLICATIONTYPE_ISSET_ID, value); - } - - public String getAcceptorHost() { - return this.acceptorHost; - } - - public void setAcceptorHost(String acceptorHost) { - this.acceptorHost = acceptorHost; - } - - public void unsetAcceptorHost() { - this.acceptorHost = null; - } - - /** Returns true if field acceptorHost is set (has been assigned a value) and false otherwise */ - public boolean isSetAcceptorHost() { - return this.acceptorHost != null; - } - - public void setAcceptorHostIsSet(boolean value) { - if (!value) { - this.acceptorHost = null; - } - } - - public int getApiId() { - return this.apiId; - } - - public void setApiId(int apiId) { - this.apiId = apiId; - setApiIdIsSet(true); - } - - public void unsetApiId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __APIID_ISSET_ID); - } - - /** Returns true if field apiId is set (has been assigned a value) and false otherwise */ - public boolean isSetApiId() { - return EncodingUtils.testBit(__isset_bitfield, __APIID_ISSET_ID); - } - - public void setApiIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __APIID_ISSET_ID, value); - } - - public TIntStringValue getExceptionInfo() { - return this.exceptionInfo; - } - - public void setExceptionInfo(TIntStringValue exceptionInfo) { - this.exceptionInfo = exceptionInfo; - } - - public void unsetExceptionInfo() { - this.exceptionInfo = null; - } - - /** Returns true if field exceptionInfo is set (has been assigned a value) and false otherwise */ - public boolean isSetExceptionInfo() { - return this.exceptionInfo != null; - } - - public void setExceptionInfoIsSet(boolean value) { - if (!value) { - this.exceptionInfo = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case APPLICATION_NAME: - if (value == null) { - unsetApplicationName(); - } else { - setApplicationName((String)value); - } - break; - - case AGENT_START_TIME: - if (value == null) { - unsetAgentStartTime(); - } else { - setAgentStartTime((Long)value); - } - break; - - case TRANSACTION_ID: - if (value == null) { - unsetTransactionId(); - } else { - setTransactionId((ByteBuffer)value); - } - break; - - case SPAN_ID: - if (value == null) { - unsetSpanId(); - } else { - setSpanId((Long)value); - } - break; - - case PARENT_SPAN_ID: - if (value == null) { - unsetParentSpanId(); - } else { - setParentSpanId((Long)value); - } - break; - - case START_TIME: - if (value == null) { - unsetStartTime(); - } else { - setStartTime((Long)value); - } - break; - - case ELAPSED: - if (value == null) { - unsetElapsed(); - } else { - setElapsed((Integer)value); - } - break; - - case RPC: - if (value == null) { - unsetRpc(); - } else { - setRpc((String)value); - } - break; - - case SERVICE_TYPE: - if (value == null) { - unsetServiceType(); - } else { - setServiceType((Short)value); - } - break; - - case END_POINT: - if (value == null) { - unsetEndPoint(); - } else { - setEndPoint((String)value); - } - break; - - case REMOTE_ADDR: - if (value == null) { - unsetRemoteAddr(); - } else { - setRemoteAddr((String)value); - } - break; - - case ANNOTATIONS: - if (value == null) { - unsetAnnotations(); - } else { - setAnnotations((List)value); - } - break; - - case FLAG: - if (value == null) { - unsetFlag(); - } else { - setFlag((Short)value); - } - break; - - case ERR: - if (value == null) { - unsetErr(); - } else { - setErr((Integer)value); - } - break; - - case SPAN_EVENT_LIST: - if (value == null) { - unsetSpanEventList(); - } else { - setSpanEventList((List)value); - } - break; - - case PARENT_APPLICATION_NAME: - if (value == null) { - unsetParentApplicationName(); - } else { - setParentApplicationName((String)value); - } - break; - - case PARENT_APPLICATION_TYPE: - if (value == null) { - unsetParentApplicationType(); - } else { - setParentApplicationType((Short)value); - } - break; - - case ACCEPTOR_HOST: - if (value == null) { - unsetAcceptorHost(); - } else { - setAcceptorHost((String)value); - } - break; - - case API_ID: - if (value == null) { - unsetApiId(); - } else { - setApiId((Integer)value); - } - break; - - case EXCEPTION_INFO: - if (value == null) { - unsetExceptionInfo(); - } else { - setExceptionInfo((TIntStringValue)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case AGENT_ID: - return getAgentId(); - - case APPLICATION_NAME: - return getApplicationName(); - - case AGENT_START_TIME: - return Long.valueOf(getAgentStartTime()); - - case TRANSACTION_ID: - return getTransactionId(); - - case SPAN_ID: - return Long.valueOf(getSpanId()); - - case PARENT_SPAN_ID: - return Long.valueOf(getParentSpanId()); - - case START_TIME: - return Long.valueOf(getStartTime()); - - case ELAPSED: - return Integer.valueOf(getElapsed()); - - case RPC: - return getRpc(); - - case SERVICE_TYPE: - return Short.valueOf(getServiceType()); - - case END_POINT: - return getEndPoint(); - - case REMOTE_ADDR: - return getRemoteAddr(); - - case ANNOTATIONS: - return getAnnotations(); - - case FLAG: - return Short.valueOf(getFlag()); - - case ERR: - return Integer.valueOf(getErr()); - - case SPAN_EVENT_LIST: - return getSpanEventList(); - - case PARENT_APPLICATION_NAME: - return getParentApplicationName(); - - case PARENT_APPLICATION_TYPE: - return Short.valueOf(getParentApplicationType()); - - case ACCEPTOR_HOST: - return getAcceptorHost(); - - case API_ID: - return Integer.valueOf(getApiId()); - - case EXCEPTION_INFO: - return getExceptionInfo(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case AGENT_ID: - return isSetAgentId(); - case APPLICATION_NAME: - return isSetApplicationName(); - case AGENT_START_TIME: - return isSetAgentStartTime(); - case TRANSACTION_ID: - return isSetTransactionId(); - case SPAN_ID: - return isSetSpanId(); - case PARENT_SPAN_ID: - return isSetParentSpanId(); - case START_TIME: - return isSetStartTime(); - case ELAPSED: - return isSetElapsed(); - case RPC: - return isSetRpc(); - case SERVICE_TYPE: - return isSetServiceType(); - case END_POINT: - return isSetEndPoint(); - case REMOTE_ADDR: - return isSetRemoteAddr(); - case ANNOTATIONS: - return isSetAnnotations(); - case FLAG: - return isSetFlag(); - case ERR: - return isSetErr(); - case SPAN_EVENT_LIST: - return isSetSpanEventList(); - case PARENT_APPLICATION_NAME: - return isSetParentApplicationName(); - case PARENT_APPLICATION_TYPE: - return isSetParentApplicationType(); - case ACCEPTOR_HOST: - return isSetAcceptorHost(); - case API_ID: - return isSetApiId(); - case EXCEPTION_INFO: - return isSetExceptionInfo(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TSpan) - return this.equals((TSpan)that); - return false; - } - - public boolean equals(TSpan that) { - if (that == null) - return false; - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_applicationName = true && this.isSetApplicationName(); - boolean that_present_applicationName = true && that.isSetApplicationName(); - if (this_present_applicationName || that_present_applicationName) { - if (!(this_present_applicationName && that_present_applicationName)) - return false; - if (!this.applicationName.equals(that.applicationName)) - return false; - } - - boolean this_present_agentStartTime = true; - boolean that_present_agentStartTime = true; - if (this_present_agentStartTime || that_present_agentStartTime) { - if (!(this_present_agentStartTime && that_present_agentStartTime)) - return false; - if (this.agentStartTime != that.agentStartTime) - return false; - } - - boolean this_present_transactionId = true && this.isSetTransactionId(); - boolean that_present_transactionId = true && that.isSetTransactionId(); - if (this_present_transactionId || that_present_transactionId) { - if (!(this_present_transactionId && that_present_transactionId)) - return false; - if (!this.transactionId.equals(that.transactionId)) - return false; - } - - boolean this_present_spanId = true; - boolean that_present_spanId = true; - if (this_present_spanId || that_present_spanId) { - if (!(this_present_spanId && that_present_spanId)) - return false; - if (this.spanId != that.spanId) - return false; - } - - boolean this_present_parentSpanId = true && this.isSetParentSpanId(); - boolean that_present_parentSpanId = true && that.isSetParentSpanId(); - if (this_present_parentSpanId || that_present_parentSpanId) { - if (!(this_present_parentSpanId && that_present_parentSpanId)) - return false; - if (this.parentSpanId != that.parentSpanId) - return false; - } - - boolean this_present_startTime = true; - boolean that_present_startTime = true; - if (this_present_startTime || that_present_startTime) { - if (!(this_present_startTime && that_present_startTime)) - return false; - if (this.startTime != that.startTime) - return false; - } - - boolean this_present_elapsed = true && this.isSetElapsed(); - boolean that_present_elapsed = true && that.isSetElapsed(); - if (this_present_elapsed || that_present_elapsed) { - if (!(this_present_elapsed && that_present_elapsed)) - return false; - if (this.elapsed != that.elapsed) - return false; - } - - boolean this_present_rpc = true && this.isSetRpc(); - boolean that_present_rpc = true && that.isSetRpc(); - if (this_present_rpc || that_present_rpc) { - if (!(this_present_rpc && that_present_rpc)) - return false; - if (!this.rpc.equals(that.rpc)) - return false; - } - - boolean this_present_serviceType = true; - boolean that_present_serviceType = true; - if (this_present_serviceType || that_present_serviceType) { - if (!(this_present_serviceType && that_present_serviceType)) - return false; - if (this.serviceType != that.serviceType) - return false; - } - - boolean this_present_endPoint = true && this.isSetEndPoint(); - boolean that_present_endPoint = true && that.isSetEndPoint(); - if (this_present_endPoint || that_present_endPoint) { - if (!(this_present_endPoint && that_present_endPoint)) - return false; - if (!this.endPoint.equals(that.endPoint)) - return false; - } - - boolean this_present_remoteAddr = true && this.isSetRemoteAddr(); - boolean that_present_remoteAddr = true && that.isSetRemoteAddr(); - if (this_present_remoteAddr || that_present_remoteAddr) { - if (!(this_present_remoteAddr && that_present_remoteAddr)) - return false; - if (!this.remoteAddr.equals(that.remoteAddr)) - return false; - } - - boolean this_present_annotations = true && this.isSetAnnotations(); - boolean that_present_annotations = true && that.isSetAnnotations(); - if (this_present_annotations || that_present_annotations) { - if (!(this_present_annotations && that_present_annotations)) - return false; - if (!this.annotations.equals(that.annotations)) - return false; - } - - boolean this_present_flag = true && this.isSetFlag(); - boolean that_present_flag = true && that.isSetFlag(); - if (this_present_flag || that_present_flag) { - if (!(this_present_flag && that_present_flag)) - return false; - if (this.flag != that.flag) - return false; - } - - boolean this_present_err = true && this.isSetErr(); - boolean that_present_err = true && that.isSetErr(); - if (this_present_err || that_present_err) { - if (!(this_present_err && that_present_err)) - return false; - if (this.err != that.err) - return false; - } - - boolean this_present_spanEventList = true && this.isSetSpanEventList(); - boolean that_present_spanEventList = true && that.isSetSpanEventList(); - if (this_present_spanEventList || that_present_spanEventList) { - if (!(this_present_spanEventList && that_present_spanEventList)) - return false; - if (!this.spanEventList.equals(that.spanEventList)) - return false; - } - - boolean this_present_parentApplicationName = true && this.isSetParentApplicationName(); - boolean that_present_parentApplicationName = true && that.isSetParentApplicationName(); - if (this_present_parentApplicationName || that_present_parentApplicationName) { - if (!(this_present_parentApplicationName && that_present_parentApplicationName)) - return false; - if (!this.parentApplicationName.equals(that.parentApplicationName)) - return false; - } - - boolean this_present_parentApplicationType = true && this.isSetParentApplicationType(); - boolean that_present_parentApplicationType = true && that.isSetParentApplicationType(); - if (this_present_parentApplicationType || that_present_parentApplicationType) { - if (!(this_present_parentApplicationType && that_present_parentApplicationType)) - return false; - if (this.parentApplicationType != that.parentApplicationType) - return false; - } - - boolean this_present_acceptorHost = true && this.isSetAcceptorHost(); - boolean that_present_acceptorHost = true && that.isSetAcceptorHost(); - if (this_present_acceptorHost || that_present_acceptorHost) { - if (!(this_present_acceptorHost && that_present_acceptorHost)) - return false; - if (!this.acceptorHost.equals(that.acceptorHost)) - return false; - } - - boolean this_present_apiId = true && this.isSetApiId(); - boolean that_present_apiId = true && that.isSetApiId(); - if (this_present_apiId || that_present_apiId) { - if (!(this_present_apiId && that_present_apiId)) - return false; - if (this.apiId != that.apiId) - return false; - } - - boolean this_present_exceptionInfo = true && this.isSetExceptionInfo(); - boolean that_present_exceptionInfo = true && that.isSetExceptionInfo(); - if (this_present_exceptionInfo || that_present_exceptionInfo) { - if (!(this_present_exceptionInfo && that_present_exceptionInfo)) - return false; - if (!this.exceptionInfo.equals(that.exceptionInfo)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TSpan other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetApplicationName()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentStartTime()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetTransactionId()).compareTo(other.isSetTransactionId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetTransactionId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transactionId, other.transactionId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSpanId()).compareTo(other.isSetSpanId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSpanId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanId, other.spanId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetParentSpanId()).compareTo(other.isSetParentSpanId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetParentSpanId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentSpanId, other.parentSpanId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStartTime()).compareTo(other.isSetStartTime()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStartTime()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTime, other.startTime); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetElapsed()).compareTo(other.isSetElapsed()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetElapsed()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.elapsed, other.elapsed); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetRpc()).compareTo(other.isSetRpc()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetRpc()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.rpc, other.rpc); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetServiceType()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetEndPoint()).compareTo(other.isSetEndPoint()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetEndPoint()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endPoint, other.endPoint); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetRemoteAddr()).compareTo(other.isSetRemoteAddr()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetRemoteAddr()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.remoteAddr, other.remoteAddr); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAnnotations()).compareTo(other.isSetAnnotations()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAnnotations()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.annotations, other.annotations); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetFlag()).compareTo(other.isSetFlag()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetFlag()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.flag, other.flag); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetErr()).compareTo(other.isSetErr()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetErr()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.err, other.err); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSpanEventList()).compareTo(other.isSetSpanEventList()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSpanEventList()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanEventList, other.spanEventList); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetParentApplicationName()).compareTo(other.isSetParentApplicationName()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetParentApplicationName()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentApplicationName, other.parentApplicationName); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetParentApplicationType()).compareTo(other.isSetParentApplicationType()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetParentApplicationType()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentApplicationType, other.parentApplicationType); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAcceptorHost()).compareTo(other.isSetAcceptorHost()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAcceptorHost()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.acceptorHost, other.acceptorHost); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetApiId()).compareTo(other.isSetApiId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetApiId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiId, other.apiId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetExceptionInfo()).compareTo(other.isSetExceptionInfo()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetExceptionInfo()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exceptionInfo, other.exceptionInfo); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TSpan("); - boolean first = true; - - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - if (!first) sb.append(", "); - sb.append("applicationName:"); - if (this.applicationName == null) { - sb.append("null"); - } else { - sb.append(this.applicationName); - } - first = false; - if (!first) sb.append(", "); - sb.append("agentStartTime:"); - sb.append(this.agentStartTime); - first = false; - if (!first) sb.append(", "); - sb.append("transactionId:"); - if (this.transactionId == null) { - sb.append("null"); - } else { - org.apache.thrift.TBaseHelper.toString(this.transactionId, sb); - } - first = false; - if (!first) sb.append(", "); - sb.append("spanId:"); - sb.append(this.spanId); - first = false; - if (isSetParentSpanId()) { - if (!first) sb.append(", "); - sb.append("parentSpanId:"); - sb.append(this.parentSpanId); - first = false; - } - if (!first) sb.append(", "); - sb.append("startTime:"); - sb.append(this.startTime); - first = false; - if (isSetElapsed()) { - if (!first) sb.append(", "); - sb.append("elapsed:"); - sb.append(this.elapsed); - first = false; - } - if (isSetRpc()) { - if (!first) sb.append(", "); - sb.append("rpc:"); - if (this.rpc == null) { - sb.append("null"); - } else { - sb.append(this.rpc); - } - first = false; - } - if (!first) sb.append(", "); - sb.append("serviceType:"); - sb.append(this.serviceType); - first = false; - if (isSetEndPoint()) { - if (!first) sb.append(", "); - sb.append("endPoint:"); - if (this.endPoint == null) { - sb.append("null"); - } else { - sb.append(this.endPoint); - } - first = false; - } - if (isSetRemoteAddr()) { - if (!first) sb.append(", "); - sb.append("remoteAddr:"); - if (this.remoteAddr == null) { - sb.append("null"); - } else { - sb.append(this.remoteAddr); - } - first = false; - } - if (isSetAnnotations()) { - if (!first) sb.append(", "); - sb.append("annotations:"); - if (this.annotations == null) { - sb.append("null"); - } else { - sb.append(this.annotations); - } - first = false; - } - if (isSetFlag()) { - if (!first) sb.append(", "); - sb.append("flag:"); - sb.append(this.flag); - first = false; - } - if (isSetErr()) { - if (!first) sb.append(", "); - sb.append("err:"); - sb.append(this.err); - first = false; - } - if (isSetSpanEventList()) { - if (!first) sb.append(", "); - sb.append("spanEventList:"); - if (this.spanEventList == null) { - sb.append("null"); - } else { - sb.append(this.spanEventList); - } - first = false; - } - if (isSetParentApplicationName()) { - if (!first) sb.append(", "); - sb.append("parentApplicationName:"); - if (this.parentApplicationName == null) { - sb.append("null"); - } else { - sb.append(this.parentApplicationName); - } - first = false; - } - if (isSetParentApplicationType()) { - if (!first) sb.append(", "); - sb.append("parentApplicationType:"); - sb.append(this.parentApplicationType); - first = false; - } - if (isSetAcceptorHost()) { - if (!first) sb.append(", "); - sb.append("acceptorHost:"); - if (this.acceptorHost == null) { - sb.append("null"); - } else { - sb.append(this.acceptorHost); - } - first = false; - } - if (isSetApiId()) { - if (!first) sb.append(", "); - sb.append("apiId:"); - sb.append(this.apiId); - first = false; - } - if (isSetExceptionInfo()) { - if (!first) sb.append(", "); - sb.append("exceptionInfo:"); - if (this.exceptionInfo == null) { - sb.append("null"); - } else { - sb.append(this.exceptionInfo); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - if (exceptionInfo != null) { - exceptionInfo.validate(); - } - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TSpanStandardSchemeFactory implements SchemeFactory { - public TSpanStandardScheme getScheme() { - return new TSpanStandardScheme(); - } - } - - private static class TSpanStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TSpan struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // APPLICATION_NAME - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.applicationName = iprot.readString(); - struct.setApplicationNameIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // AGENT_START_TIME - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 4: // TRANSACTION_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.transactionId = iprot.readBinary(); - struct.setTransactionIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 7: // SPAN_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.spanId = iprot.readI64(); - struct.setSpanIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 8: // PARENT_SPAN_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.parentSpanId = iprot.readI64(); - struct.setParentSpanIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 9: // START_TIME - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.startTime = iprot.readI64(); - struct.setStartTimeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 10: // ELAPSED - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.elapsed = iprot.readI32(); - struct.setElapsedIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 11: // RPC - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.rpc = iprot.readString(); - struct.setRpcIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 12: // SERVICE_TYPE - if (schemeField.type == org.apache.thrift.protocol.TType.I16) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 13: // END_POINT - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.endPoint = iprot.readString(); - struct.setEndPointIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 14: // REMOTE_ADDR - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.remoteAddr = iprot.readString(); - struct.setRemoteAddrIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 15: // ANNOTATIONS - if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { - { - org.apache.thrift.protocol.TList _list8 = iprot.readListBegin(); - struct.annotations = new ArrayList(_list8.size); - for (int _i9 = 0; _i9 < _list8.size; ++_i9) - { - TAnnotation _elem10; - _elem10 = new TAnnotation(); - _elem10.read(iprot); - struct.annotations.add(_elem10); - } - iprot.readListEnd(); - } - struct.setAnnotationsIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 16: // FLAG - if (schemeField.type == org.apache.thrift.protocol.TType.I16) { - struct.flag = iprot.readI16(); - struct.setFlagIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 17: // ERR - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.err = iprot.readI32(); - struct.setErrIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 18: // SPAN_EVENT_LIST - if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { - { - org.apache.thrift.protocol.TList _list11 = iprot.readListBegin(); - struct.spanEventList = new ArrayList(_list11.size); - for (int _i12 = 0; _i12 < _list11.size; ++_i12) - { - TSpanEvent _elem13; - _elem13 = new TSpanEvent(); - _elem13.read(iprot); - struct.spanEventList.add(_elem13); - } - iprot.readListEnd(); - } - struct.setSpanEventListIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 19: // PARENT_APPLICATION_NAME - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.parentApplicationName = iprot.readString(); - struct.setParentApplicationNameIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 20: // PARENT_APPLICATION_TYPE - if (schemeField.type == org.apache.thrift.protocol.TType.I16) { - struct.parentApplicationType = iprot.readI16(); - struct.setParentApplicationTypeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 21: // ACCEPTOR_HOST - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.acceptorHost = iprot.readString(); - struct.setAcceptorHostIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 25: // API_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.apiId = iprot.readI32(); - struct.setApiIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 26: // EXCEPTION_INFO - if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { - struct.exceptionInfo = new TIntStringValue(); - struct.exceptionInfo.read(iprot); - struct.setExceptionInfoIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TSpan struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.agentId != null) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - if (struct.applicationName != null) { - oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); - oprot.writeString(struct.applicationName); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); - oprot.writeI64(struct.agentStartTime); - oprot.writeFieldEnd(); - if (struct.transactionId != null) { - oprot.writeFieldBegin(TRANSACTION_ID_FIELD_DESC); - oprot.writeBinary(struct.transactionId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(SPAN_ID_FIELD_DESC); - oprot.writeI64(struct.spanId); - oprot.writeFieldEnd(); - if (struct.isSetParentSpanId()) { - oprot.writeFieldBegin(PARENT_SPAN_ID_FIELD_DESC); - oprot.writeI64(struct.parentSpanId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(START_TIME_FIELD_DESC); - oprot.writeI64(struct.startTime); - oprot.writeFieldEnd(); - if (struct.isSetElapsed()) { - oprot.writeFieldBegin(ELAPSED_FIELD_DESC); - oprot.writeI32(struct.elapsed); - oprot.writeFieldEnd(); - } - if (struct.rpc != null) { - if (struct.isSetRpc()) { - oprot.writeFieldBegin(RPC_FIELD_DESC); - oprot.writeString(struct.rpc); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); - oprot.writeI16(struct.serviceType); - oprot.writeFieldEnd(); - if (struct.endPoint != null) { - if (struct.isSetEndPoint()) { - oprot.writeFieldBegin(END_POINT_FIELD_DESC); - oprot.writeString(struct.endPoint); - oprot.writeFieldEnd(); - } - } - if (struct.remoteAddr != null) { - if (struct.isSetRemoteAddr()) { - oprot.writeFieldBegin(REMOTE_ADDR_FIELD_DESC); - oprot.writeString(struct.remoteAddr); - oprot.writeFieldEnd(); - } - } - if (struct.annotations != null) { - if (struct.isSetAnnotations()) { - oprot.writeFieldBegin(ANNOTATIONS_FIELD_DESC); - { - oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.annotations.size())); - for (TAnnotation _iter14 : struct.annotations) - { - _iter14.write(oprot); - } - oprot.writeListEnd(); - } - oprot.writeFieldEnd(); - } - } - if (struct.isSetFlag()) { - oprot.writeFieldBegin(FLAG_FIELD_DESC); - oprot.writeI16(struct.flag); - oprot.writeFieldEnd(); - } - if (struct.isSetErr()) { - oprot.writeFieldBegin(ERR_FIELD_DESC); - oprot.writeI32(struct.err); - oprot.writeFieldEnd(); - } - if (struct.spanEventList != null) { - if (struct.isSetSpanEventList()) { - oprot.writeFieldBegin(SPAN_EVENT_LIST_FIELD_DESC); - { - oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.spanEventList.size())); - for (TSpanEvent _iter15 : struct.spanEventList) - { - _iter15.write(oprot); - } - oprot.writeListEnd(); - } - oprot.writeFieldEnd(); - } - } - if (struct.parentApplicationName != null) { - if (struct.isSetParentApplicationName()) { - oprot.writeFieldBegin(PARENT_APPLICATION_NAME_FIELD_DESC); - oprot.writeString(struct.parentApplicationName); - oprot.writeFieldEnd(); - } - } - if (struct.isSetParentApplicationType()) { - oprot.writeFieldBegin(PARENT_APPLICATION_TYPE_FIELD_DESC); - oprot.writeI16(struct.parentApplicationType); - oprot.writeFieldEnd(); - } - if (struct.acceptorHost != null) { - if (struct.isSetAcceptorHost()) { - oprot.writeFieldBegin(ACCEPTOR_HOST_FIELD_DESC); - oprot.writeString(struct.acceptorHost); - oprot.writeFieldEnd(); - } - } - if (struct.isSetApiId()) { - oprot.writeFieldBegin(API_ID_FIELD_DESC); - oprot.writeI32(struct.apiId); - oprot.writeFieldEnd(); - } - if (struct.exceptionInfo != null) { - if (struct.isSetExceptionInfo()) { - oprot.writeFieldBegin(EXCEPTION_INFO_FIELD_DESC); - struct.exceptionInfo.write(oprot); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TSpanTupleSchemeFactory implements SchemeFactory { - public TSpanTupleScheme getScheme() { - return new TSpanTupleScheme(); - } - } - - private static class TSpanTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetAgentId()) { - optionals.set(0); - } - if (struct.isSetApplicationName()) { - optionals.set(1); - } - if (struct.isSetAgentStartTime()) { - optionals.set(2); - } - if (struct.isSetTransactionId()) { - optionals.set(3); - } - if (struct.isSetSpanId()) { - optionals.set(4); - } - if (struct.isSetParentSpanId()) { - optionals.set(5); - } - if (struct.isSetStartTime()) { - optionals.set(6); - } - if (struct.isSetElapsed()) { - optionals.set(7); - } - if (struct.isSetRpc()) { - optionals.set(8); - } - if (struct.isSetServiceType()) { - optionals.set(9); - } - if (struct.isSetEndPoint()) { - optionals.set(10); - } - if (struct.isSetRemoteAddr()) { - optionals.set(11); - } - if (struct.isSetAnnotations()) { - optionals.set(12); - } - if (struct.isSetFlag()) { - optionals.set(13); - } - if (struct.isSetErr()) { - optionals.set(14); - } - if (struct.isSetSpanEventList()) { - optionals.set(15); - } - if (struct.isSetParentApplicationName()) { - optionals.set(16); - } - if (struct.isSetParentApplicationType()) { - optionals.set(17); - } - if (struct.isSetAcceptorHost()) { - optionals.set(18); - } - if (struct.isSetApiId()) { - optionals.set(19); - } - if (struct.isSetExceptionInfo()) { - optionals.set(20); - } - oprot.writeBitSet(optionals, 21); - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetApplicationName()) { - oprot.writeString(struct.applicationName); - } - if (struct.isSetAgentStartTime()) { - oprot.writeI64(struct.agentStartTime); - } - if (struct.isSetTransactionId()) { - oprot.writeBinary(struct.transactionId); - } - if (struct.isSetSpanId()) { - oprot.writeI64(struct.spanId); - } - if (struct.isSetParentSpanId()) { - oprot.writeI64(struct.parentSpanId); - } - if (struct.isSetStartTime()) { - oprot.writeI64(struct.startTime); - } - if (struct.isSetElapsed()) { - oprot.writeI32(struct.elapsed); - } - if (struct.isSetRpc()) { - oprot.writeString(struct.rpc); - } - if (struct.isSetServiceType()) { - oprot.writeI16(struct.serviceType); - } - if (struct.isSetEndPoint()) { - oprot.writeString(struct.endPoint); - } - if (struct.isSetRemoteAddr()) { - oprot.writeString(struct.remoteAddr); - } - if (struct.isSetAnnotations()) { - { - oprot.writeI32(struct.annotations.size()); - for (TAnnotation _iter16 : struct.annotations) - { - _iter16.write(oprot); - } - } - } - if (struct.isSetFlag()) { - oprot.writeI16(struct.flag); - } - if (struct.isSetErr()) { - oprot.writeI32(struct.err); - } - if (struct.isSetSpanEventList()) { - { - oprot.writeI32(struct.spanEventList.size()); - for (TSpanEvent _iter17 : struct.spanEventList) - { - _iter17.write(oprot); - } - } - } - if (struct.isSetParentApplicationName()) { - oprot.writeString(struct.parentApplicationName); - } - if (struct.isSetParentApplicationType()) { - oprot.writeI16(struct.parentApplicationType); - } - if (struct.isSetAcceptorHost()) { - oprot.writeString(struct.acceptorHost); - } - if (struct.isSetApiId()) { - oprot.writeI32(struct.apiId); - } - if (struct.isSetExceptionInfo()) { - struct.exceptionInfo.write(oprot); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(21); - if (incoming.get(0)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(1)) { - struct.applicationName = iprot.readString(); - struct.setApplicationNameIsSet(true); - } - if (incoming.get(2)) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } - if (incoming.get(3)) { - struct.transactionId = iprot.readBinary(); - struct.setTransactionIdIsSet(true); - } - if (incoming.get(4)) { - struct.spanId = iprot.readI64(); - struct.setSpanIdIsSet(true); - } - if (incoming.get(5)) { - struct.parentSpanId = iprot.readI64(); - struct.setParentSpanIdIsSet(true); - } - if (incoming.get(6)) { - struct.startTime = iprot.readI64(); - struct.setStartTimeIsSet(true); - } - if (incoming.get(7)) { - struct.elapsed = iprot.readI32(); - struct.setElapsedIsSet(true); - } - if (incoming.get(8)) { - struct.rpc = iprot.readString(); - struct.setRpcIsSet(true); - } - if (incoming.get(9)) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } - if (incoming.get(10)) { - struct.endPoint = iprot.readString(); - struct.setEndPointIsSet(true); - } - if (incoming.get(11)) { - struct.remoteAddr = iprot.readString(); - struct.setRemoteAddrIsSet(true); - } - if (incoming.get(12)) { - { - org.apache.thrift.protocol.TList _list18 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); - struct.annotations = new ArrayList(_list18.size); - for (int _i19 = 0; _i19 < _list18.size; ++_i19) - { - TAnnotation _elem20; - _elem20 = new TAnnotation(); - _elem20.read(iprot); - struct.annotations.add(_elem20); - } - } - struct.setAnnotationsIsSet(true); - } - if (incoming.get(13)) { - struct.flag = iprot.readI16(); - struct.setFlagIsSet(true); - } - if (incoming.get(14)) { - struct.err = iprot.readI32(); - struct.setErrIsSet(true); - } - if (incoming.get(15)) { - { - org.apache.thrift.protocol.TList _list21 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); - struct.spanEventList = new ArrayList(_list21.size); - for (int _i22 = 0; _i22 < _list21.size; ++_i22) - { - TSpanEvent _elem23; - _elem23 = new TSpanEvent(); - _elem23.read(iprot); - struct.spanEventList.add(_elem23); - } - } - struct.setSpanEventListIsSet(true); - } - if (incoming.get(16)) { - struct.parentApplicationName = iprot.readString(); - struct.setParentApplicationNameIsSet(true); - } - if (incoming.get(17)) { - struct.parentApplicationType = iprot.readI16(); - struct.setParentApplicationTypeIsSet(true); - } - if (incoming.get(18)) { - struct.acceptorHost = iprot.readString(); - struct.setAcceptorHostIsSet(true); - } - if (incoming.get(19)) { - struct.apiId = iprot.readI32(); - struct.setApiIdIsSet(true); - } - if (incoming.get(20)) { - struct.exceptionInfo = new TIntStringValue(); - struct.exceptionInfo.read(iprot); - struct.setExceptionInfoIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TSpan implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSpan"); + + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)3); + private static final org.apache.thrift.protocol.TField TRANSACTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("transactionId", org.apache.thrift.protocol.TType.STRING, (short)4); + private static final org.apache.thrift.protocol.TField SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("spanId", org.apache.thrift.protocol.TType.I64, (short)7); + private static final org.apache.thrift.protocol.TField PARENT_SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("parentSpanId", org.apache.thrift.protocol.TType.I64, (short)8); + private static final org.apache.thrift.protocol.TField START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("startTime", org.apache.thrift.protocol.TType.I64, (short)9); + private static final org.apache.thrift.protocol.TField ELAPSED_FIELD_DESC = new org.apache.thrift.protocol.TField("elapsed", org.apache.thrift.protocol.TType.I32, (short)10); + private static final org.apache.thrift.protocol.TField RPC_FIELD_DESC = new org.apache.thrift.protocol.TField("rpc", org.apache.thrift.protocol.TType.STRING, (short)11); + private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)12); + private static final org.apache.thrift.protocol.TField END_POINT_FIELD_DESC = new org.apache.thrift.protocol.TField("endPoint", org.apache.thrift.protocol.TType.STRING, (short)13); + private static final org.apache.thrift.protocol.TField REMOTE_ADDR_FIELD_DESC = new org.apache.thrift.protocol.TField("remoteAddr", org.apache.thrift.protocol.TType.STRING, (short)14); + private static final org.apache.thrift.protocol.TField ANNOTATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("annotations", org.apache.thrift.protocol.TType.LIST, (short)15); + private static final org.apache.thrift.protocol.TField FLAG_FIELD_DESC = new org.apache.thrift.protocol.TField("flag", org.apache.thrift.protocol.TType.I16, (short)16); + private static final org.apache.thrift.protocol.TField ERR_FIELD_DESC = new org.apache.thrift.protocol.TField("err", org.apache.thrift.protocol.TType.I32, (short)17); + private static final org.apache.thrift.protocol.TField SPAN_EVENT_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("spanEventList", org.apache.thrift.protocol.TType.LIST, (short)18); + private static final org.apache.thrift.protocol.TField PARENT_APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("parentApplicationName", org.apache.thrift.protocol.TType.STRING, (short)19); + private static final org.apache.thrift.protocol.TField PARENT_APPLICATION_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("parentApplicationType", org.apache.thrift.protocol.TType.I16, (short)20); + private static final org.apache.thrift.protocol.TField ACCEPTOR_HOST_FIELD_DESC = new org.apache.thrift.protocol.TField("acceptorHost", org.apache.thrift.protocol.TType.STRING, (short)21); + private static final org.apache.thrift.protocol.TField API_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("apiId", org.apache.thrift.protocol.TType.I32, (short)25); + private static final org.apache.thrift.protocol.TField EXCEPTION_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionInfo", org.apache.thrift.protocol.TType.STRUCT, (short)26); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TSpanStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TSpanTupleSchemeFactory()); + } + + private String agentId; // required + private String applicationName; // required + private long agentStartTime; // required + private ByteBuffer transactionId; // required + private long spanId; // required + private long parentSpanId; // optional + private long startTime; // required + private int elapsed; // optional + private String rpc; // optional + private short serviceType; // required + private String endPoint; // optional + private String remoteAddr; // optional + private List annotations; // optional + private short flag; // optional + private int err; // optional + private List spanEventList; // optional + private String parentApplicationName; // optional + private short parentApplicationType; // optional + private String acceptorHost; // optional + private int apiId; // optional + private TIntStringValue exceptionInfo; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + AGENT_ID((short)1, "agentId"), + APPLICATION_NAME((short)2, "applicationName"), + AGENT_START_TIME((short)3, "agentStartTime"), + TRANSACTION_ID((short)4, "transactionId"), + SPAN_ID((short)7, "spanId"), + PARENT_SPAN_ID((short)8, "parentSpanId"), + START_TIME((short)9, "startTime"), + ELAPSED((short)10, "elapsed"), + RPC((short)11, "rpc"), + SERVICE_TYPE((short)12, "serviceType"), + END_POINT((short)13, "endPoint"), + REMOTE_ADDR((short)14, "remoteAddr"), + ANNOTATIONS((short)15, "annotations"), + FLAG((short)16, "flag"), + ERR((short)17, "err"), + SPAN_EVENT_LIST((short)18, "spanEventList"), + PARENT_APPLICATION_NAME((short)19, "parentApplicationName"), + PARENT_APPLICATION_TYPE((short)20, "parentApplicationType"), + ACCEPTOR_HOST((short)21, "acceptorHost"), + API_ID((short)25, "apiId"), + EXCEPTION_INFO((short)26, "exceptionInfo"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // AGENT_ID + return AGENT_ID; + case 2: // APPLICATION_NAME + return APPLICATION_NAME; + case 3: // AGENT_START_TIME + return AGENT_START_TIME; + case 4: // TRANSACTION_ID + return TRANSACTION_ID; + case 7: // SPAN_ID + return SPAN_ID; + case 8: // PARENT_SPAN_ID + return PARENT_SPAN_ID; + case 9: // START_TIME + return START_TIME; + case 10: // ELAPSED + return ELAPSED; + case 11: // RPC + return RPC; + case 12: // SERVICE_TYPE + return SERVICE_TYPE; + case 13: // END_POINT + return END_POINT; + case 14: // REMOTE_ADDR + return REMOTE_ADDR; + case 15: // ANNOTATIONS + return ANNOTATIONS; + case 16: // FLAG + return FLAG; + case 17: // ERR + return ERR; + case 18: // SPAN_EVENT_LIST + return SPAN_EVENT_LIST; + case 19: // PARENT_APPLICATION_NAME + return PARENT_APPLICATION_NAME; + case 20: // PARENT_APPLICATION_TYPE + return PARENT_APPLICATION_TYPE; + case 21: // ACCEPTOR_HOST + return ACCEPTOR_HOST; + case 25: // API_ID + return API_ID; + case 26: // EXCEPTION_INFO + return EXCEPTION_INFO; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __AGENTSTARTTIME_ISSET_ID = 0; + private static final int __SPANID_ISSET_ID = 1; + private static final int __PARENTSPANID_ISSET_ID = 2; + private static final int __STARTTIME_ISSET_ID = 3; + private static final int __ELAPSED_ISSET_ID = 4; + private static final int __SERVICETYPE_ISSET_ID = 5; + private static final int __FLAG_ISSET_ID = 6; + private static final int __ERR_ISSET_ID = 7; + private static final int __PARENTAPPLICATIONTYPE_ISSET_ID = 8; + private static final int __APIID_ISSET_ID = 9; + private short __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.PARENT_SPAN_ID,_Fields.ELAPSED,_Fields.RPC,_Fields.END_POINT,_Fields.REMOTE_ADDR,_Fields.ANNOTATIONS,_Fields.FLAG,_Fields.ERR,_Fields.SPAN_EVENT_LIST,_Fields.PARENT_APPLICATION_NAME,_Fields.PARENT_APPLICATION_TYPE,_Fields.ACCEPTOR_HOST,_Fields.API_ID,_Fields.EXCEPTION_INFO}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.TRANSACTION_ID, new org.apache.thrift.meta_data.FieldMetaData("transactionId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("spanId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.PARENT_SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("parentSpanId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.START_TIME, new org.apache.thrift.meta_data.FieldMetaData("startTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.ELAPSED, new org.apache.thrift.meta_data.FieldMetaData("elapsed", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.RPC, new org.apache.thrift.meta_data.FieldMetaData("rpc", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.END_POINT, new org.apache.thrift.meta_data.FieldMetaData("endPoint", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.REMOTE_ADDR, new org.apache.thrift.meta_data.FieldMetaData("remoteAddr", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.ANNOTATIONS, new org.apache.thrift.meta_data.FieldMetaData("annotations", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAnnotation.class)))); + tmpMap.put(_Fields.FLAG, new org.apache.thrift.meta_data.FieldMetaData("flag", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.ERR, new org.apache.thrift.meta_data.FieldMetaData("err", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.SPAN_EVENT_LIST, new org.apache.thrift.meta_data.FieldMetaData("spanEventList", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSpanEvent.class)))); + tmpMap.put(_Fields.PARENT_APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("parentApplicationName", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.PARENT_APPLICATION_TYPE, new org.apache.thrift.meta_data.FieldMetaData("parentApplicationType", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.ACCEPTOR_HOST, new org.apache.thrift.meta_data.FieldMetaData("acceptorHost", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.API_ID, new org.apache.thrift.meta_data.FieldMetaData("apiId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.EXCEPTION_INFO, new org.apache.thrift.meta_data.FieldMetaData("exceptionInfo", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringValue.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpan.class, metaDataMap); + } + + public TSpan() { + this.parentSpanId = -1L; + + this.elapsed = 0; + + this.flag = (short)0; + + } + + public TSpan( + String agentId, + String applicationName, + long agentStartTime, + ByteBuffer transactionId, + long spanId, + long startTime, + short serviceType) + { + this(); + this.agentId = agentId; + this.applicationName = applicationName; + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + this.transactionId = transactionId; + this.spanId = spanId; + setSpanIdIsSet(true); + this.startTime = startTime; + setStartTimeIsSet(true); + this.serviceType = serviceType; + setServiceTypeIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TSpan(TSpan other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + if (other.isSetApplicationName()) { + this.applicationName = other.applicationName; + } + this.agentStartTime = other.agentStartTime; + if (other.isSetTransactionId()) { + this.transactionId = org.apache.thrift.TBaseHelper.copyBinary(other.transactionId); +; + } + this.spanId = other.spanId; + this.parentSpanId = other.parentSpanId; + this.startTime = other.startTime; + this.elapsed = other.elapsed; + if (other.isSetRpc()) { + this.rpc = other.rpc; + } + this.serviceType = other.serviceType; + if (other.isSetEndPoint()) { + this.endPoint = other.endPoint; + } + if (other.isSetRemoteAddr()) { + this.remoteAddr = other.remoteAddr; + } + if (other.isSetAnnotations()) { + List __this__annotations = new ArrayList(other.annotations.size()); + for (TAnnotation other_element : other.annotations) { + __this__annotations.add(new TAnnotation(other_element)); + } + this.annotations = __this__annotations; + } + this.flag = other.flag; + this.err = other.err; + if (other.isSetSpanEventList()) { + List __this__spanEventList = new ArrayList(other.spanEventList.size()); + for (TSpanEvent other_element : other.spanEventList) { + __this__spanEventList.add(new TSpanEvent(other_element)); + } + this.spanEventList = __this__spanEventList; + } + if (other.isSetParentApplicationName()) { + this.parentApplicationName = other.parentApplicationName; + } + this.parentApplicationType = other.parentApplicationType; + if (other.isSetAcceptorHost()) { + this.acceptorHost = other.acceptorHost; + } + this.apiId = other.apiId; + if (other.isSetExceptionInfo()) { + this.exceptionInfo = new TIntStringValue(other.exceptionInfo); + } + } + + public TSpan deepCopy() { + return new TSpan(this); + } + + @Override + public void clear() { + this.agentId = null; + this.applicationName = null; + setAgentStartTimeIsSet(false); + this.agentStartTime = 0; + this.transactionId = null; + setSpanIdIsSet(false); + this.spanId = 0; + this.parentSpanId = -1L; + + setStartTimeIsSet(false); + this.startTime = 0; + this.elapsed = 0; + + this.rpc = null; + setServiceTypeIsSet(false); + this.serviceType = 0; + this.endPoint = null; + this.remoteAddr = null; + this.annotations = null; + this.flag = (short)0; + + setErrIsSet(false); + this.err = 0; + this.spanEventList = null; + this.parentApplicationName = null; + setParentApplicationTypeIsSet(false); + this.parentApplicationType = 0; + this.acceptorHost = null; + setApiIdIsSet(false); + this.apiId = 0; + this.exceptionInfo = null; + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public String getApplicationName() { + return this.applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public void unsetApplicationName() { + this.applicationName = null; + } + + /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ + public boolean isSetApplicationName() { + return this.applicationName != null; + } + + public void setApplicationNameIsSet(boolean value) { + if (!value) { + this.applicationName = null; + } + } + + public long getAgentStartTime() { + return this.agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + } + + public void unsetAgentStartTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentStartTime() { + return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + public void setAgentStartTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); + } + + public byte[] getTransactionId() { + setTransactionId(org.apache.thrift.TBaseHelper.rightSize(transactionId)); + return transactionId == null ? null : transactionId.array(); + } + + public ByteBuffer bufferForTransactionId() { + return transactionId; + } + + public void setTransactionId(byte[] transactionId) { + setTransactionId(transactionId == null ? (ByteBuffer)null : ByteBuffer.wrap(transactionId)); + } + + public void setTransactionId(ByteBuffer transactionId) { + this.transactionId = transactionId; + } + + public void unsetTransactionId() { + this.transactionId = null; + } + + /** Returns true if field transactionId is set (has been assigned a value) and false otherwise */ + public boolean isSetTransactionId() { + return this.transactionId != null; + } + + public void setTransactionIdIsSet(boolean value) { + if (!value) { + this.transactionId = null; + } + } + + public long getSpanId() { + return this.spanId; + } + + public void setSpanId(long spanId) { + this.spanId = spanId; + setSpanIdIsSet(true); + } + + public void unsetSpanId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + /** Returns true if field spanId is set (has been assigned a value) and false otherwise */ + public boolean isSetSpanId() { + return EncodingUtils.testBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + public void setSpanIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SPANID_ISSET_ID, value); + } + + public long getParentSpanId() { + return this.parentSpanId; + } + + public void setParentSpanId(long parentSpanId) { + this.parentSpanId = parentSpanId; + setParentSpanIdIsSet(true); + } + + public void unsetParentSpanId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PARENTSPANID_ISSET_ID); + } + + /** Returns true if field parentSpanId is set (has been assigned a value) and false otherwise */ + public boolean isSetParentSpanId() { + return EncodingUtils.testBit(__isset_bitfield, __PARENTSPANID_ISSET_ID); + } + + public void setParentSpanIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PARENTSPANID_ISSET_ID, value); + } + + public long getStartTime() { + return this.startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + setStartTimeIsSet(true); + } + + public void unsetStartTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIME_ISSET_ID); + } + + /** Returns true if field startTime is set (has been assigned a value) and false otherwise */ + public boolean isSetStartTime() { + return EncodingUtils.testBit(__isset_bitfield, __STARTTIME_ISSET_ID); + } + + public void setStartTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIME_ISSET_ID, value); + } + + public int getElapsed() { + return this.elapsed; + } + + public void setElapsed(int elapsed) { + this.elapsed = elapsed; + setElapsedIsSet(true); + } + + public void unsetElapsed() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ELAPSED_ISSET_ID); + } + + /** Returns true if field elapsed is set (has been assigned a value) and false otherwise */ + public boolean isSetElapsed() { + return EncodingUtils.testBit(__isset_bitfield, __ELAPSED_ISSET_ID); + } + + public void setElapsedIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ELAPSED_ISSET_ID, value); + } + + public String getRpc() { + return this.rpc; + } + + public void setRpc(String rpc) { + this.rpc = rpc; + } + + public void unsetRpc() { + this.rpc = null; + } + + /** Returns true if field rpc is set (has been assigned a value) and false otherwise */ + public boolean isSetRpc() { + return this.rpc != null; + } + + public void setRpcIsSet(boolean value) { + if (!value) { + this.rpc = null; + } + } + + public short getServiceType() { + return this.serviceType; + } + + public void setServiceType(short serviceType) { + this.serviceType = serviceType; + setServiceTypeIsSet(true); + } + + public void unsetServiceType() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ + public boolean isSetServiceType() { + return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + public void setServiceTypeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); + } + + public String getEndPoint() { + return this.endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public void unsetEndPoint() { + this.endPoint = null; + } + + /** Returns true if field endPoint is set (has been assigned a value) and false otherwise */ + public boolean isSetEndPoint() { + return this.endPoint != null; + } + + public void setEndPointIsSet(boolean value) { + if (!value) { + this.endPoint = null; + } + } + + public String getRemoteAddr() { + return this.remoteAddr; + } + + public void setRemoteAddr(String remoteAddr) { + this.remoteAddr = remoteAddr; + } + + public void unsetRemoteAddr() { + this.remoteAddr = null; + } + + /** Returns true if field remoteAddr is set (has been assigned a value) and false otherwise */ + public boolean isSetRemoteAddr() { + return this.remoteAddr != null; + } + + public void setRemoteAddrIsSet(boolean value) { + if (!value) { + this.remoteAddr = null; + } + } + + public int getAnnotationsSize() { + return (this.annotations == null) ? 0 : this.annotations.size(); + } + + public java.util.Iterator getAnnotationsIterator() { + return (this.annotations == null) ? null : this.annotations.iterator(); + } + + public void addToAnnotations(TAnnotation elem) { + if (this.annotations == null) { + this.annotations = new ArrayList(); + } + this.annotations.add(elem); + } + + public List getAnnotations() { + return this.annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + public void unsetAnnotations() { + this.annotations = null; + } + + /** Returns true if field annotations is set (has been assigned a value) and false otherwise */ + public boolean isSetAnnotations() { + return this.annotations != null; + } + + public void setAnnotationsIsSet(boolean value) { + if (!value) { + this.annotations = null; + } + } + + public short getFlag() { + return this.flag; + } + + public void setFlag(short flag) { + this.flag = flag; + setFlagIsSet(true); + } + + public void unsetFlag() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FLAG_ISSET_ID); + } + + /** Returns true if field flag is set (has been assigned a value) and false otherwise */ + public boolean isSetFlag() { + return EncodingUtils.testBit(__isset_bitfield, __FLAG_ISSET_ID); + } + + public void setFlagIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FLAG_ISSET_ID, value); + } + + public int getErr() { + return this.err; + } + + public void setErr(int err) { + this.err = err; + setErrIsSet(true); + } + + public void unsetErr() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ERR_ISSET_ID); + } + + /** Returns true if field err is set (has been assigned a value) and false otherwise */ + public boolean isSetErr() { + return EncodingUtils.testBit(__isset_bitfield, __ERR_ISSET_ID); + } + + public void setErrIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ERR_ISSET_ID, value); + } + + public int getSpanEventListSize() { + return (this.spanEventList == null) ? 0 : this.spanEventList.size(); + } + + public java.util.Iterator getSpanEventListIterator() { + return (this.spanEventList == null) ? null : this.spanEventList.iterator(); + } + + public void addToSpanEventList(TSpanEvent elem) { + if (this.spanEventList == null) { + this.spanEventList = new ArrayList(); + } + this.spanEventList.add(elem); + } + + public List getSpanEventList() { + return this.spanEventList; + } + + public void setSpanEventList(List spanEventList) { + this.spanEventList = spanEventList; + } + + public void unsetSpanEventList() { + this.spanEventList = null; + } + + /** Returns true if field spanEventList is set (has been assigned a value) and false otherwise */ + public boolean isSetSpanEventList() { + return this.spanEventList != null; + } + + public void setSpanEventListIsSet(boolean value) { + if (!value) { + this.spanEventList = null; + } + } + + public String getParentApplicationName() { + return this.parentApplicationName; + } + + public void setParentApplicationName(String parentApplicationName) { + this.parentApplicationName = parentApplicationName; + } + + public void unsetParentApplicationName() { + this.parentApplicationName = null; + } + + /** Returns true if field parentApplicationName is set (has been assigned a value) and false otherwise */ + public boolean isSetParentApplicationName() { + return this.parentApplicationName != null; + } + + public void setParentApplicationNameIsSet(boolean value) { + if (!value) { + this.parentApplicationName = null; + } + } + + public short getParentApplicationType() { + return this.parentApplicationType; + } + + public void setParentApplicationType(short parentApplicationType) { + this.parentApplicationType = parentApplicationType; + setParentApplicationTypeIsSet(true); + } + + public void unsetParentApplicationType() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PARENTAPPLICATIONTYPE_ISSET_ID); + } + + /** Returns true if field parentApplicationType is set (has been assigned a value) and false otherwise */ + public boolean isSetParentApplicationType() { + return EncodingUtils.testBit(__isset_bitfield, __PARENTAPPLICATIONTYPE_ISSET_ID); + } + + public void setParentApplicationTypeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PARENTAPPLICATIONTYPE_ISSET_ID, value); + } + + public String getAcceptorHost() { + return this.acceptorHost; + } + + public void setAcceptorHost(String acceptorHost) { + this.acceptorHost = acceptorHost; + } + + public void unsetAcceptorHost() { + this.acceptorHost = null; + } + + /** Returns true if field acceptorHost is set (has been assigned a value) and false otherwise */ + public boolean isSetAcceptorHost() { + return this.acceptorHost != null; + } + + public void setAcceptorHostIsSet(boolean value) { + if (!value) { + this.acceptorHost = null; + } + } + + public int getApiId() { + return this.apiId; + } + + public void setApiId(int apiId) { + this.apiId = apiId; + setApiIdIsSet(true); + } + + public void unsetApiId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __APIID_ISSET_ID); + } + + /** Returns true if field apiId is set (has been assigned a value) and false otherwise */ + public boolean isSetApiId() { + return EncodingUtils.testBit(__isset_bitfield, __APIID_ISSET_ID); + } + + public void setApiIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __APIID_ISSET_ID, value); + } + + public TIntStringValue getExceptionInfo() { + return this.exceptionInfo; + } + + public void setExceptionInfo(TIntStringValue exceptionInfo) { + this.exceptionInfo = exceptionInfo; + } + + public void unsetExceptionInfo() { + this.exceptionInfo = null; + } + + /** Returns true if field exceptionInfo is set (has been assigned a value) and false otherwise */ + public boolean isSetExceptionInfo() { + return this.exceptionInfo != null; + } + + public void setExceptionInfoIsSet(boolean value) { + if (!value) { + this.exceptionInfo = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case APPLICATION_NAME: + if (value == null) { + unsetApplicationName(); + } else { + setApplicationName((String)value); + } + break; + + case AGENT_START_TIME: + if (value == null) { + unsetAgentStartTime(); + } else { + setAgentStartTime((Long)value); + } + break; + + case TRANSACTION_ID: + if (value == null) { + unsetTransactionId(); + } else { + setTransactionId((ByteBuffer)value); + } + break; + + case SPAN_ID: + if (value == null) { + unsetSpanId(); + } else { + setSpanId((Long)value); + } + break; + + case PARENT_SPAN_ID: + if (value == null) { + unsetParentSpanId(); + } else { + setParentSpanId((Long)value); + } + break; + + case START_TIME: + if (value == null) { + unsetStartTime(); + } else { + setStartTime((Long)value); + } + break; + + case ELAPSED: + if (value == null) { + unsetElapsed(); + } else { + setElapsed((Integer)value); + } + break; + + case RPC: + if (value == null) { + unsetRpc(); + } else { + setRpc((String)value); + } + break; + + case SERVICE_TYPE: + if (value == null) { + unsetServiceType(); + } else { + setServiceType((Short)value); + } + break; + + case END_POINT: + if (value == null) { + unsetEndPoint(); + } else { + setEndPoint((String)value); + } + break; + + case REMOTE_ADDR: + if (value == null) { + unsetRemoteAddr(); + } else { + setRemoteAddr((String)value); + } + break; + + case ANNOTATIONS: + if (value == null) { + unsetAnnotations(); + } else { + setAnnotations((List)value); + } + break; + + case FLAG: + if (value == null) { + unsetFlag(); + } else { + setFlag((Short)value); + } + break; + + case ERR: + if (value == null) { + unsetErr(); + } else { + setErr((Integer)value); + } + break; + + case SPAN_EVENT_LIST: + if (value == null) { + unsetSpanEventList(); + } else { + setSpanEventList((List)value); + } + break; + + case PARENT_APPLICATION_NAME: + if (value == null) { + unsetParentApplicationName(); + } else { + setParentApplicationName((String)value); + } + break; + + case PARENT_APPLICATION_TYPE: + if (value == null) { + unsetParentApplicationType(); + } else { + setParentApplicationType((Short)value); + } + break; + + case ACCEPTOR_HOST: + if (value == null) { + unsetAcceptorHost(); + } else { + setAcceptorHost((String)value); + } + break; + + case API_ID: + if (value == null) { + unsetApiId(); + } else { + setApiId((Integer)value); + } + break; + + case EXCEPTION_INFO: + if (value == null) { + unsetExceptionInfo(); + } else { + setExceptionInfo((TIntStringValue)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case AGENT_ID: + return getAgentId(); + + case APPLICATION_NAME: + return getApplicationName(); + + case AGENT_START_TIME: + return Long.valueOf(getAgentStartTime()); + + case TRANSACTION_ID: + return getTransactionId(); + + case SPAN_ID: + return Long.valueOf(getSpanId()); + + case PARENT_SPAN_ID: + return Long.valueOf(getParentSpanId()); + + case START_TIME: + return Long.valueOf(getStartTime()); + + case ELAPSED: + return Integer.valueOf(getElapsed()); + + case RPC: + return getRpc(); + + case SERVICE_TYPE: + return Short.valueOf(getServiceType()); + + case END_POINT: + return getEndPoint(); + + case REMOTE_ADDR: + return getRemoteAddr(); + + case ANNOTATIONS: + return getAnnotations(); + + case FLAG: + return Short.valueOf(getFlag()); + + case ERR: + return Integer.valueOf(getErr()); + + case SPAN_EVENT_LIST: + return getSpanEventList(); + + case PARENT_APPLICATION_NAME: + return getParentApplicationName(); + + case PARENT_APPLICATION_TYPE: + return Short.valueOf(getParentApplicationType()); + + case ACCEPTOR_HOST: + return getAcceptorHost(); + + case API_ID: + return Integer.valueOf(getApiId()); + + case EXCEPTION_INFO: + return getExceptionInfo(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case AGENT_ID: + return isSetAgentId(); + case APPLICATION_NAME: + return isSetApplicationName(); + case AGENT_START_TIME: + return isSetAgentStartTime(); + case TRANSACTION_ID: + return isSetTransactionId(); + case SPAN_ID: + return isSetSpanId(); + case PARENT_SPAN_ID: + return isSetParentSpanId(); + case START_TIME: + return isSetStartTime(); + case ELAPSED: + return isSetElapsed(); + case RPC: + return isSetRpc(); + case SERVICE_TYPE: + return isSetServiceType(); + case END_POINT: + return isSetEndPoint(); + case REMOTE_ADDR: + return isSetRemoteAddr(); + case ANNOTATIONS: + return isSetAnnotations(); + case FLAG: + return isSetFlag(); + case ERR: + return isSetErr(); + case SPAN_EVENT_LIST: + return isSetSpanEventList(); + case PARENT_APPLICATION_NAME: + return isSetParentApplicationName(); + case PARENT_APPLICATION_TYPE: + return isSetParentApplicationType(); + case ACCEPTOR_HOST: + return isSetAcceptorHost(); + case API_ID: + return isSetApiId(); + case EXCEPTION_INFO: + return isSetExceptionInfo(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TSpan) + return this.equals((TSpan)that); + return false; + } + + public boolean equals(TSpan that) { + if (that == null) + return false; + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_applicationName = true && this.isSetApplicationName(); + boolean that_present_applicationName = true && that.isSetApplicationName(); + if (this_present_applicationName || that_present_applicationName) { + if (!(this_present_applicationName && that_present_applicationName)) + return false; + if (!this.applicationName.equals(that.applicationName)) + return false; + } + + boolean this_present_agentStartTime = true; + boolean that_present_agentStartTime = true; + if (this_present_agentStartTime || that_present_agentStartTime) { + if (!(this_present_agentStartTime && that_present_agentStartTime)) + return false; + if (this.agentStartTime != that.agentStartTime) + return false; + } + + boolean this_present_transactionId = true && this.isSetTransactionId(); + boolean that_present_transactionId = true && that.isSetTransactionId(); + if (this_present_transactionId || that_present_transactionId) { + if (!(this_present_transactionId && that_present_transactionId)) + return false; + if (!this.transactionId.equals(that.transactionId)) + return false; + } + + boolean this_present_spanId = true; + boolean that_present_spanId = true; + if (this_present_spanId || that_present_spanId) { + if (!(this_present_spanId && that_present_spanId)) + return false; + if (this.spanId != that.spanId) + return false; + } + + boolean this_present_parentSpanId = true && this.isSetParentSpanId(); + boolean that_present_parentSpanId = true && that.isSetParentSpanId(); + if (this_present_parentSpanId || that_present_parentSpanId) { + if (!(this_present_parentSpanId && that_present_parentSpanId)) + return false; + if (this.parentSpanId != that.parentSpanId) + return false; + } + + boolean this_present_startTime = true; + boolean that_present_startTime = true; + if (this_present_startTime || that_present_startTime) { + if (!(this_present_startTime && that_present_startTime)) + return false; + if (this.startTime != that.startTime) + return false; + } + + boolean this_present_elapsed = true && this.isSetElapsed(); + boolean that_present_elapsed = true && that.isSetElapsed(); + if (this_present_elapsed || that_present_elapsed) { + if (!(this_present_elapsed && that_present_elapsed)) + return false; + if (this.elapsed != that.elapsed) + return false; + } + + boolean this_present_rpc = true && this.isSetRpc(); + boolean that_present_rpc = true && that.isSetRpc(); + if (this_present_rpc || that_present_rpc) { + if (!(this_present_rpc && that_present_rpc)) + return false; + if (!this.rpc.equals(that.rpc)) + return false; + } + + boolean this_present_serviceType = true; + boolean that_present_serviceType = true; + if (this_present_serviceType || that_present_serviceType) { + if (!(this_present_serviceType && that_present_serviceType)) + return false; + if (this.serviceType != that.serviceType) + return false; + } + + boolean this_present_endPoint = true && this.isSetEndPoint(); + boolean that_present_endPoint = true && that.isSetEndPoint(); + if (this_present_endPoint || that_present_endPoint) { + if (!(this_present_endPoint && that_present_endPoint)) + return false; + if (!this.endPoint.equals(that.endPoint)) + return false; + } + + boolean this_present_remoteAddr = true && this.isSetRemoteAddr(); + boolean that_present_remoteAddr = true && that.isSetRemoteAddr(); + if (this_present_remoteAddr || that_present_remoteAddr) { + if (!(this_present_remoteAddr && that_present_remoteAddr)) + return false; + if (!this.remoteAddr.equals(that.remoteAddr)) + return false; + } + + boolean this_present_annotations = true && this.isSetAnnotations(); + boolean that_present_annotations = true && that.isSetAnnotations(); + if (this_present_annotations || that_present_annotations) { + if (!(this_present_annotations && that_present_annotations)) + return false; + if (!this.annotations.equals(that.annotations)) + return false; + } + + boolean this_present_flag = true && this.isSetFlag(); + boolean that_present_flag = true && that.isSetFlag(); + if (this_present_flag || that_present_flag) { + if (!(this_present_flag && that_present_flag)) + return false; + if (this.flag != that.flag) + return false; + } + + boolean this_present_err = true && this.isSetErr(); + boolean that_present_err = true && that.isSetErr(); + if (this_present_err || that_present_err) { + if (!(this_present_err && that_present_err)) + return false; + if (this.err != that.err) + return false; + } + + boolean this_present_spanEventList = true && this.isSetSpanEventList(); + boolean that_present_spanEventList = true && that.isSetSpanEventList(); + if (this_present_spanEventList || that_present_spanEventList) { + if (!(this_present_spanEventList && that_present_spanEventList)) + return false; + if (!this.spanEventList.equals(that.spanEventList)) + return false; + } + + boolean this_present_parentApplicationName = true && this.isSetParentApplicationName(); + boolean that_present_parentApplicationName = true && that.isSetParentApplicationName(); + if (this_present_parentApplicationName || that_present_parentApplicationName) { + if (!(this_present_parentApplicationName && that_present_parentApplicationName)) + return false; + if (!this.parentApplicationName.equals(that.parentApplicationName)) + return false; + } + + boolean this_present_parentApplicationType = true && this.isSetParentApplicationType(); + boolean that_present_parentApplicationType = true && that.isSetParentApplicationType(); + if (this_present_parentApplicationType || that_present_parentApplicationType) { + if (!(this_present_parentApplicationType && that_present_parentApplicationType)) + return false; + if (this.parentApplicationType != that.parentApplicationType) + return false; + } + + boolean this_present_acceptorHost = true && this.isSetAcceptorHost(); + boolean that_present_acceptorHost = true && that.isSetAcceptorHost(); + if (this_present_acceptorHost || that_present_acceptorHost) { + if (!(this_present_acceptorHost && that_present_acceptorHost)) + return false; + if (!this.acceptorHost.equals(that.acceptorHost)) + return false; + } + + boolean this_present_apiId = true && this.isSetApiId(); + boolean that_present_apiId = true && that.isSetApiId(); + if (this_present_apiId || that_present_apiId) { + if (!(this_present_apiId && that_present_apiId)) + return false; + if (this.apiId != that.apiId) + return false; + } + + boolean this_present_exceptionInfo = true && this.isSetExceptionInfo(); + boolean that_present_exceptionInfo = true && that.isSetExceptionInfo(); + if (this_present_exceptionInfo || that_present_exceptionInfo) { + if (!(this_present_exceptionInfo && that_present_exceptionInfo)) + return false; + if (!this.exceptionInfo.equals(that.exceptionInfo)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TSpan other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApplicationName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetTransactionId()).compareTo(other.isSetTransactionId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetTransactionId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transactionId, other.transactionId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSpanId()).compareTo(other.isSetSpanId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSpanId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanId, other.spanId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetParentSpanId()).compareTo(other.isSetParentSpanId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetParentSpanId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentSpanId, other.parentSpanId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStartTime()).compareTo(other.isSetStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTime, other.startTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetElapsed()).compareTo(other.isSetElapsed()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetElapsed()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.elapsed, other.elapsed); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRpc()).compareTo(other.isSetRpc()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRpc()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.rpc, other.rpc); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetServiceType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEndPoint()).compareTo(other.isSetEndPoint()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEndPoint()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endPoint, other.endPoint); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRemoteAddr()).compareTo(other.isSetRemoteAddr()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRemoteAddr()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.remoteAddr, other.remoteAddr); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAnnotations()).compareTo(other.isSetAnnotations()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAnnotations()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.annotations, other.annotations); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetFlag()).compareTo(other.isSetFlag()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetFlag()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.flag, other.flag); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetErr()).compareTo(other.isSetErr()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetErr()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.err, other.err); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSpanEventList()).compareTo(other.isSetSpanEventList()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSpanEventList()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanEventList, other.spanEventList); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetParentApplicationName()).compareTo(other.isSetParentApplicationName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetParentApplicationName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentApplicationName, other.parentApplicationName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetParentApplicationType()).compareTo(other.isSetParentApplicationType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetParentApplicationType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentApplicationType, other.parentApplicationType); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAcceptorHost()).compareTo(other.isSetAcceptorHost()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAcceptorHost()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.acceptorHost, other.acceptorHost); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApiId()).compareTo(other.isSetApiId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApiId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiId, other.apiId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetExceptionInfo()).compareTo(other.isSetExceptionInfo()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetExceptionInfo()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exceptionInfo, other.exceptionInfo); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TSpan("); + boolean first = true; + + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("applicationName:"); + if (this.applicationName == null) { + sb.append("null"); + } else { + sb.append(this.applicationName); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentStartTime:"); + sb.append(this.agentStartTime); + first = false; + if (!first) sb.append(", "); + sb.append("transactionId:"); + if (this.transactionId == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.transactionId, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("spanId:"); + sb.append(this.spanId); + first = false; + if (isSetParentSpanId()) { + if (!first) sb.append(", "); + sb.append("parentSpanId:"); + sb.append(this.parentSpanId); + first = false; + } + if (!first) sb.append(", "); + sb.append("startTime:"); + sb.append(this.startTime); + first = false; + if (isSetElapsed()) { + if (!first) sb.append(", "); + sb.append("elapsed:"); + sb.append(this.elapsed); + first = false; + } + if (isSetRpc()) { + if (!first) sb.append(", "); + sb.append("rpc:"); + if (this.rpc == null) { + sb.append("null"); + } else { + sb.append(this.rpc); + } + first = false; + } + if (!first) sb.append(", "); + sb.append("serviceType:"); + sb.append(this.serviceType); + first = false; + if (isSetEndPoint()) { + if (!first) sb.append(", "); + sb.append("endPoint:"); + if (this.endPoint == null) { + sb.append("null"); + } else { + sb.append(this.endPoint); + } + first = false; + } + if (isSetRemoteAddr()) { + if (!first) sb.append(", "); + sb.append("remoteAddr:"); + if (this.remoteAddr == null) { + sb.append("null"); + } else { + sb.append(this.remoteAddr); + } + first = false; + } + if (isSetAnnotations()) { + if (!first) sb.append(", "); + sb.append("annotations:"); + if (this.annotations == null) { + sb.append("null"); + } else { + sb.append(this.annotations); + } + first = false; + } + if (isSetFlag()) { + if (!first) sb.append(", "); + sb.append("flag:"); + sb.append(this.flag); + first = false; + } + if (isSetErr()) { + if (!first) sb.append(", "); + sb.append("err:"); + sb.append(this.err); + first = false; + } + if (isSetSpanEventList()) { + if (!first) sb.append(", "); + sb.append("spanEventList:"); + if (this.spanEventList == null) { + sb.append("null"); + } else { + sb.append(this.spanEventList); + } + first = false; + } + if (isSetParentApplicationName()) { + if (!first) sb.append(", "); + sb.append("parentApplicationName:"); + if (this.parentApplicationName == null) { + sb.append("null"); + } else { + sb.append(this.parentApplicationName); + } + first = false; + } + if (isSetParentApplicationType()) { + if (!first) sb.append(", "); + sb.append("parentApplicationType:"); + sb.append(this.parentApplicationType); + first = false; + } + if (isSetAcceptorHost()) { + if (!first) sb.append(", "); + sb.append("acceptorHost:"); + if (this.acceptorHost == null) { + sb.append("null"); + } else { + sb.append(this.acceptorHost); + } + first = false; + } + if (isSetApiId()) { + if (!first) sb.append(", "); + sb.append("apiId:"); + sb.append(this.apiId); + first = false; + } + if (isSetExceptionInfo()) { + if (!first) sb.append(", "); + sb.append("exceptionInfo:"); + if (this.exceptionInfo == null) { + sb.append("null"); + } else { + sb.append(this.exceptionInfo); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + if (exceptionInfo != null) { + exceptionInfo.validate(); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TSpanStandardSchemeFactory implements SchemeFactory { + public TSpanStandardScheme getScheme() { + return new TSpanStandardScheme(); + } + } + + private static class TSpanStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TSpan struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // APPLICATION_NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // AGENT_START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // TRANSACTION_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.transactionId = iprot.readBinary(); + struct.setTransactionIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 7: // SPAN_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 8: // PARENT_SPAN_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.parentSpanId = iprot.readI64(); + struct.setParentSpanIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 9: // START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.startTime = iprot.readI64(); + struct.setStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // ELAPSED + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.elapsed = iprot.readI32(); + struct.setElapsedIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 11: // RPC + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.rpc = iprot.readString(); + struct.setRpcIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 12: // SERVICE_TYPE + if (schemeField.type == org.apache.thrift.protocol.TType.I16) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 13: // END_POINT + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.endPoint = iprot.readString(); + struct.setEndPointIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 14: // REMOTE_ADDR + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.remoteAddr = iprot.readString(); + struct.setRemoteAddrIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 15: // ANNOTATIONS + if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list8 = iprot.readListBegin(); + struct.annotations = new ArrayList(_list8.size); + for (int _i9 = 0; _i9 < _list8.size; ++_i9) + { + TAnnotation _elem10; + _elem10 = new TAnnotation(); + _elem10.read(iprot); + struct.annotations.add(_elem10); + } + iprot.readListEnd(); + } + struct.setAnnotationsIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 16: // FLAG + if (schemeField.type == org.apache.thrift.protocol.TType.I16) { + struct.flag = iprot.readI16(); + struct.setFlagIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 17: // ERR + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.err = iprot.readI32(); + struct.setErrIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 18: // SPAN_EVENT_LIST + if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list11 = iprot.readListBegin(); + struct.spanEventList = new ArrayList(_list11.size); + for (int _i12 = 0; _i12 < _list11.size; ++_i12) + { + TSpanEvent _elem13; + _elem13 = new TSpanEvent(); + _elem13.read(iprot); + struct.spanEventList.add(_elem13); + } + iprot.readListEnd(); + } + struct.setSpanEventListIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 19: // PARENT_APPLICATION_NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.parentApplicationName = iprot.readString(); + struct.setParentApplicationNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 20: // PARENT_APPLICATION_TYPE + if (schemeField.type == org.apache.thrift.protocol.TType.I16) { + struct.parentApplicationType = iprot.readI16(); + struct.setParentApplicationTypeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 21: // ACCEPTOR_HOST + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.acceptorHost = iprot.readString(); + struct.setAcceptorHostIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 25: // API_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.apiId = iprot.readI32(); + struct.setApiIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 26: // EXCEPTION_INFO + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.exceptionInfo = new TIntStringValue(); + struct.exceptionInfo.read(iprot); + struct.setExceptionInfoIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TSpan struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + if (struct.applicationName != null) { + oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); + oprot.writeString(struct.applicationName); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); + oprot.writeI64(struct.agentStartTime); + oprot.writeFieldEnd(); + if (struct.transactionId != null) { + oprot.writeFieldBegin(TRANSACTION_ID_FIELD_DESC); + oprot.writeBinary(struct.transactionId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(SPAN_ID_FIELD_DESC); + oprot.writeI64(struct.spanId); + oprot.writeFieldEnd(); + if (struct.isSetParentSpanId()) { + oprot.writeFieldBegin(PARENT_SPAN_ID_FIELD_DESC); + oprot.writeI64(struct.parentSpanId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(START_TIME_FIELD_DESC); + oprot.writeI64(struct.startTime); + oprot.writeFieldEnd(); + if (struct.isSetElapsed()) { + oprot.writeFieldBegin(ELAPSED_FIELD_DESC); + oprot.writeI32(struct.elapsed); + oprot.writeFieldEnd(); + } + if (struct.rpc != null) { + if (struct.isSetRpc()) { + oprot.writeFieldBegin(RPC_FIELD_DESC); + oprot.writeString(struct.rpc); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); + oprot.writeI16(struct.serviceType); + oprot.writeFieldEnd(); + if (struct.endPoint != null) { + if (struct.isSetEndPoint()) { + oprot.writeFieldBegin(END_POINT_FIELD_DESC); + oprot.writeString(struct.endPoint); + oprot.writeFieldEnd(); + } + } + if (struct.remoteAddr != null) { + if (struct.isSetRemoteAddr()) { + oprot.writeFieldBegin(REMOTE_ADDR_FIELD_DESC); + oprot.writeString(struct.remoteAddr); + oprot.writeFieldEnd(); + } + } + if (struct.annotations != null) { + if (struct.isSetAnnotations()) { + oprot.writeFieldBegin(ANNOTATIONS_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.annotations.size())); + for (TAnnotation _iter14 : struct.annotations) + { + _iter14.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + } + if (struct.isSetFlag()) { + oprot.writeFieldBegin(FLAG_FIELD_DESC); + oprot.writeI16(struct.flag); + oprot.writeFieldEnd(); + } + if (struct.isSetErr()) { + oprot.writeFieldBegin(ERR_FIELD_DESC); + oprot.writeI32(struct.err); + oprot.writeFieldEnd(); + } + if (struct.spanEventList != null) { + if (struct.isSetSpanEventList()) { + oprot.writeFieldBegin(SPAN_EVENT_LIST_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.spanEventList.size())); + for (TSpanEvent _iter15 : struct.spanEventList) + { + _iter15.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + } + if (struct.parentApplicationName != null) { + if (struct.isSetParentApplicationName()) { + oprot.writeFieldBegin(PARENT_APPLICATION_NAME_FIELD_DESC); + oprot.writeString(struct.parentApplicationName); + oprot.writeFieldEnd(); + } + } + if (struct.isSetParentApplicationType()) { + oprot.writeFieldBegin(PARENT_APPLICATION_TYPE_FIELD_DESC); + oprot.writeI16(struct.parentApplicationType); + oprot.writeFieldEnd(); + } + if (struct.acceptorHost != null) { + if (struct.isSetAcceptorHost()) { + oprot.writeFieldBegin(ACCEPTOR_HOST_FIELD_DESC); + oprot.writeString(struct.acceptorHost); + oprot.writeFieldEnd(); + } + } + if (struct.isSetApiId()) { + oprot.writeFieldBegin(API_ID_FIELD_DESC); + oprot.writeI32(struct.apiId); + oprot.writeFieldEnd(); + } + if (struct.exceptionInfo != null) { + if (struct.isSetExceptionInfo()) { + oprot.writeFieldBegin(EXCEPTION_INFO_FIELD_DESC); + struct.exceptionInfo.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TSpanTupleSchemeFactory implements SchemeFactory { + public TSpanTupleScheme getScheme() { + return new TSpanTupleScheme(); + } + } + + private static class TSpanTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetAgentId()) { + optionals.set(0); + } + if (struct.isSetApplicationName()) { + optionals.set(1); + } + if (struct.isSetAgentStartTime()) { + optionals.set(2); + } + if (struct.isSetTransactionId()) { + optionals.set(3); + } + if (struct.isSetSpanId()) { + optionals.set(4); + } + if (struct.isSetParentSpanId()) { + optionals.set(5); + } + if (struct.isSetStartTime()) { + optionals.set(6); + } + if (struct.isSetElapsed()) { + optionals.set(7); + } + if (struct.isSetRpc()) { + optionals.set(8); + } + if (struct.isSetServiceType()) { + optionals.set(9); + } + if (struct.isSetEndPoint()) { + optionals.set(10); + } + if (struct.isSetRemoteAddr()) { + optionals.set(11); + } + if (struct.isSetAnnotations()) { + optionals.set(12); + } + if (struct.isSetFlag()) { + optionals.set(13); + } + if (struct.isSetErr()) { + optionals.set(14); + } + if (struct.isSetSpanEventList()) { + optionals.set(15); + } + if (struct.isSetParentApplicationName()) { + optionals.set(16); + } + if (struct.isSetParentApplicationType()) { + optionals.set(17); + } + if (struct.isSetAcceptorHost()) { + optionals.set(18); + } + if (struct.isSetApiId()) { + optionals.set(19); + } + if (struct.isSetExceptionInfo()) { + optionals.set(20); + } + oprot.writeBitSet(optionals, 21); + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetApplicationName()) { + oprot.writeString(struct.applicationName); + } + if (struct.isSetAgentStartTime()) { + oprot.writeI64(struct.agentStartTime); + } + if (struct.isSetTransactionId()) { + oprot.writeBinary(struct.transactionId); + } + if (struct.isSetSpanId()) { + oprot.writeI64(struct.spanId); + } + if (struct.isSetParentSpanId()) { + oprot.writeI64(struct.parentSpanId); + } + if (struct.isSetStartTime()) { + oprot.writeI64(struct.startTime); + } + if (struct.isSetElapsed()) { + oprot.writeI32(struct.elapsed); + } + if (struct.isSetRpc()) { + oprot.writeString(struct.rpc); + } + if (struct.isSetServiceType()) { + oprot.writeI16(struct.serviceType); + } + if (struct.isSetEndPoint()) { + oprot.writeString(struct.endPoint); + } + if (struct.isSetRemoteAddr()) { + oprot.writeString(struct.remoteAddr); + } + if (struct.isSetAnnotations()) { + { + oprot.writeI32(struct.annotations.size()); + for (TAnnotation _iter16 : struct.annotations) + { + _iter16.write(oprot); + } + } + } + if (struct.isSetFlag()) { + oprot.writeI16(struct.flag); + } + if (struct.isSetErr()) { + oprot.writeI32(struct.err); + } + if (struct.isSetSpanEventList()) { + { + oprot.writeI32(struct.spanEventList.size()); + for (TSpanEvent _iter17 : struct.spanEventList) + { + _iter17.write(oprot); + } + } + } + if (struct.isSetParentApplicationName()) { + oprot.writeString(struct.parentApplicationName); + } + if (struct.isSetParentApplicationType()) { + oprot.writeI16(struct.parentApplicationType); + } + if (struct.isSetAcceptorHost()) { + oprot.writeString(struct.acceptorHost); + } + if (struct.isSetApiId()) { + oprot.writeI32(struct.apiId); + } + if (struct.isSetExceptionInfo()) { + struct.exceptionInfo.write(oprot); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(21); + if (incoming.get(0)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(1)) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } + if (incoming.get(2)) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } + if (incoming.get(3)) { + struct.transactionId = iprot.readBinary(); + struct.setTransactionIdIsSet(true); + } + if (incoming.get(4)) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } + if (incoming.get(5)) { + struct.parentSpanId = iprot.readI64(); + struct.setParentSpanIdIsSet(true); + } + if (incoming.get(6)) { + struct.startTime = iprot.readI64(); + struct.setStartTimeIsSet(true); + } + if (incoming.get(7)) { + struct.elapsed = iprot.readI32(); + struct.setElapsedIsSet(true); + } + if (incoming.get(8)) { + struct.rpc = iprot.readString(); + struct.setRpcIsSet(true); + } + if (incoming.get(9)) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } + if (incoming.get(10)) { + struct.endPoint = iprot.readString(); + struct.setEndPointIsSet(true); + } + if (incoming.get(11)) { + struct.remoteAddr = iprot.readString(); + struct.setRemoteAddrIsSet(true); + } + if (incoming.get(12)) { + { + org.apache.thrift.protocol.TList _list18 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); + struct.annotations = new ArrayList(_list18.size); + for (int _i19 = 0; _i19 < _list18.size; ++_i19) + { + TAnnotation _elem20; + _elem20 = new TAnnotation(); + _elem20.read(iprot); + struct.annotations.add(_elem20); + } + } + struct.setAnnotationsIsSet(true); + } + if (incoming.get(13)) { + struct.flag = iprot.readI16(); + struct.setFlagIsSet(true); + } + if (incoming.get(14)) { + struct.err = iprot.readI32(); + struct.setErrIsSet(true); + } + if (incoming.get(15)) { + { + org.apache.thrift.protocol.TList _list21 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); + struct.spanEventList = new ArrayList(_list21.size); + for (int _i22 = 0; _i22 < _list21.size; ++_i22) + { + TSpanEvent _elem23; + _elem23 = new TSpanEvent(); + _elem23.read(iprot); + struct.spanEventList.add(_elem23); + } + } + struct.setSpanEventListIsSet(true); + } + if (incoming.get(16)) { + struct.parentApplicationName = iprot.readString(); + struct.setParentApplicationNameIsSet(true); + } + if (incoming.get(17)) { + struct.parentApplicationType = iprot.readI16(); + struct.setParentApplicationTypeIsSet(true); + } + if (incoming.get(18)) { + struct.acceptorHost = iprot.readString(); + struct.setAcceptorHostIsSet(true); + } + if (incoming.get(19)) { + struct.apiId = iprot.readI32(); + struct.setApiIdIsSet(true); + } + if (incoming.get(20)) { + struct.exceptionInfo = new TIntStringValue(); + struct.exceptionInfo.read(iprot); + struct.setExceptionInfoIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java index ccba33f9f39c..699510e32e4a 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java @@ -1,1131 +1,1131 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TSpanChunk implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSpanChunk"); - - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)2); - private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)3); - private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)4); - private static final org.apache.thrift.protocol.TField TRANSACTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("transactionId", org.apache.thrift.protocol.TType.STRING, (short)5); - private static final org.apache.thrift.protocol.TField SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("spanId", org.apache.thrift.protocol.TType.I64, (short)8); - private static final org.apache.thrift.protocol.TField END_POINT_FIELD_DESC = new org.apache.thrift.protocol.TField("endPoint", org.apache.thrift.protocol.TType.STRING, (short)9); - private static final org.apache.thrift.protocol.TField SPAN_EVENT_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("spanEventList", org.apache.thrift.protocol.TType.LIST, (short)10); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TSpanChunkStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TSpanChunkTupleSchemeFactory()); - } - - private String agentId; // required - private String applicationName; // required - private long agentStartTime; // required - private short serviceType; // required - private ByteBuffer transactionId; // required - private long spanId; // required - private String endPoint; // optional - private List spanEventList; // required - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - AGENT_ID((short)1, "agentId"), - APPLICATION_NAME((short)2, "applicationName"), - AGENT_START_TIME((short)3, "agentStartTime"), - SERVICE_TYPE((short)4, "serviceType"), - TRANSACTION_ID((short)5, "transactionId"), - SPAN_ID((short)8, "spanId"), - END_POINT((short)9, "endPoint"), - SPAN_EVENT_LIST((short)10, "spanEventList"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // AGENT_ID - return AGENT_ID; - case 2: // APPLICATION_NAME - return APPLICATION_NAME; - case 3: // AGENT_START_TIME - return AGENT_START_TIME; - case 4: // SERVICE_TYPE - return SERVICE_TYPE; - case 5: // TRANSACTION_ID - return TRANSACTION_ID; - case 8: // SPAN_ID - return SPAN_ID; - case 9: // END_POINT - return END_POINT; - case 10: // SPAN_EVENT_LIST - return SPAN_EVENT_LIST; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __AGENTSTARTTIME_ISSET_ID = 0; - private static final int __SERVICETYPE_ISSET_ID = 1; - private static final int __SPANID_ISSET_ID = 2; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.END_POINT}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.TRANSACTION_ID, new org.apache.thrift.meta_data.FieldMetaData("transactionId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); - tmpMap.put(_Fields.SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("spanId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.END_POINT, new org.apache.thrift.meta_data.FieldMetaData("endPoint", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.SPAN_EVENT_LIST, new org.apache.thrift.meta_data.FieldMetaData("spanEventList", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSpanEvent.class)))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpanChunk.class, metaDataMap); - } - - public TSpanChunk() { - } - - public TSpanChunk( - String agentId, - String applicationName, - long agentStartTime, - short serviceType, - ByteBuffer transactionId, - long spanId, - List spanEventList) - { - this(); - this.agentId = agentId; - this.applicationName = applicationName; - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - this.serviceType = serviceType; - setServiceTypeIsSet(true); - this.transactionId = transactionId; - this.spanId = spanId; - setSpanIdIsSet(true); - this.spanEventList = spanEventList; - } - - /** - * Performs a deep copy on other. - */ - public TSpanChunk(TSpanChunk other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - if (other.isSetApplicationName()) { - this.applicationName = other.applicationName; - } - this.agentStartTime = other.agentStartTime; - this.serviceType = other.serviceType; - if (other.isSetTransactionId()) { - this.transactionId = org.apache.thrift.TBaseHelper.copyBinary(other.transactionId); -; - } - this.spanId = other.spanId; - if (other.isSetEndPoint()) { - this.endPoint = other.endPoint; - } - if (other.isSetSpanEventList()) { - List __this__spanEventList = new ArrayList(other.spanEventList.size()); - for (TSpanEvent other_element : other.spanEventList) { - __this__spanEventList.add(new TSpanEvent(other_element)); - } - this.spanEventList = __this__spanEventList; - } - } - - public TSpanChunk deepCopy() { - return new TSpanChunk(this); - } - - @Override - public void clear() { - this.agentId = null; - this.applicationName = null; - setAgentStartTimeIsSet(false); - this.agentStartTime = 0; - setServiceTypeIsSet(false); - this.serviceType = 0; - this.transactionId = null; - setSpanIdIsSet(false); - this.spanId = 0; - this.endPoint = null; - this.spanEventList = null; - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public String getApplicationName() { - return this.applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public void unsetApplicationName() { - this.applicationName = null; - } - - /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ - public boolean isSetApplicationName() { - return this.applicationName != null; - } - - public void setApplicationNameIsSet(boolean value) { - if (!value) { - this.applicationName = null; - } - } - - public long getAgentStartTime() { - return this.agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - } - - public void unsetAgentStartTime() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentStartTime() { - return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - public void setAgentStartTimeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); - } - - public short getServiceType() { - return this.serviceType; - } - - public void setServiceType(short serviceType) { - this.serviceType = serviceType; - setServiceTypeIsSet(true); - } - - public void unsetServiceType() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ - public boolean isSetServiceType() { - return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - public void setServiceTypeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); - } - - public byte[] getTransactionId() { - setTransactionId(org.apache.thrift.TBaseHelper.rightSize(transactionId)); - return transactionId == null ? null : transactionId.array(); - } - - public ByteBuffer bufferForTransactionId() { - return transactionId; - } - - public void setTransactionId(byte[] transactionId) { - setTransactionId(transactionId == null ? (ByteBuffer)null : ByteBuffer.wrap(transactionId)); - } - - public void setTransactionId(ByteBuffer transactionId) { - this.transactionId = transactionId; - } - - public void unsetTransactionId() { - this.transactionId = null; - } - - /** Returns true if field transactionId is set (has been assigned a value) and false otherwise */ - public boolean isSetTransactionId() { - return this.transactionId != null; - } - - public void setTransactionIdIsSet(boolean value) { - if (!value) { - this.transactionId = null; - } - } - - public long getSpanId() { - return this.spanId; - } - - public void setSpanId(long spanId) { - this.spanId = spanId; - setSpanIdIsSet(true); - } - - public void unsetSpanId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SPANID_ISSET_ID); - } - - /** Returns true if field spanId is set (has been assigned a value) and false otherwise */ - public boolean isSetSpanId() { - return EncodingUtils.testBit(__isset_bitfield, __SPANID_ISSET_ID); - } - - public void setSpanIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SPANID_ISSET_ID, value); - } - - public String getEndPoint() { - return this.endPoint; - } - - public void setEndPoint(String endPoint) { - this.endPoint = endPoint; - } - - public void unsetEndPoint() { - this.endPoint = null; - } - - /** Returns true if field endPoint is set (has been assigned a value) and false otherwise */ - public boolean isSetEndPoint() { - return this.endPoint != null; - } - - public void setEndPointIsSet(boolean value) { - if (!value) { - this.endPoint = null; - } - } - - public int getSpanEventListSize() { - return (this.spanEventList == null) ? 0 : this.spanEventList.size(); - } - - public java.util.Iterator getSpanEventListIterator() { - return (this.spanEventList == null) ? null : this.spanEventList.iterator(); - } - - public void addToSpanEventList(TSpanEvent elem) { - if (this.spanEventList == null) { - this.spanEventList = new ArrayList(); - } - this.spanEventList.add(elem); - } - - public List getSpanEventList() { - return this.spanEventList; - } - - public void setSpanEventList(List spanEventList) { - this.spanEventList = spanEventList; - } - - public void unsetSpanEventList() { - this.spanEventList = null; - } - - /** Returns true if field spanEventList is set (has been assigned a value) and false otherwise */ - public boolean isSetSpanEventList() { - return this.spanEventList != null; - } - - public void setSpanEventListIsSet(boolean value) { - if (!value) { - this.spanEventList = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case APPLICATION_NAME: - if (value == null) { - unsetApplicationName(); - } else { - setApplicationName((String)value); - } - break; - - case AGENT_START_TIME: - if (value == null) { - unsetAgentStartTime(); - } else { - setAgentStartTime((Long)value); - } - break; - - case SERVICE_TYPE: - if (value == null) { - unsetServiceType(); - } else { - setServiceType((Short)value); - } - break; - - case TRANSACTION_ID: - if (value == null) { - unsetTransactionId(); - } else { - setTransactionId((ByteBuffer)value); - } - break; - - case SPAN_ID: - if (value == null) { - unsetSpanId(); - } else { - setSpanId((Long)value); - } - break; - - case END_POINT: - if (value == null) { - unsetEndPoint(); - } else { - setEndPoint((String)value); - } - break; - - case SPAN_EVENT_LIST: - if (value == null) { - unsetSpanEventList(); - } else { - setSpanEventList((List)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case AGENT_ID: - return getAgentId(); - - case APPLICATION_NAME: - return getApplicationName(); - - case AGENT_START_TIME: - return Long.valueOf(getAgentStartTime()); - - case SERVICE_TYPE: - return Short.valueOf(getServiceType()); - - case TRANSACTION_ID: - return getTransactionId(); - - case SPAN_ID: - return Long.valueOf(getSpanId()); - - case END_POINT: - return getEndPoint(); - - case SPAN_EVENT_LIST: - return getSpanEventList(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case AGENT_ID: - return isSetAgentId(); - case APPLICATION_NAME: - return isSetApplicationName(); - case AGENT_START_TIME: - return isSetAgentStartTime(); - case SERVICE_TYPE: - return isSetServiceType(); - case TRANSACTION_ID: - return isSetTransactionId(); - case SPAN_ID: - return isSetSpanId(); - case END_POINT: - return isSetEndPoint(); - case SPAN_EVENT_LIST: - return isSetSpanEventList(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TSpanChunk) - return this.equals((TSpanChunk)that); - return false; - } - - public boolean equals(TSpanChunk that) { - if (that == null) - return false; - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_applicationName = true && this.isSetApplicationName(); - boolean that_present_applicationName = true && that.isSetApplicationName(); - if (this_present_applicationName || that_present_applicationName) { - if (!(this_present_applicationName && that_present_applicationName)) - return false; - if (!this.applicationName.equals(that.applicationName)) - return false; - } - - boolean this_present_agentStartTime = true; - boolean that_present_agentStartTime = true; - if (this_present_agentStartTime || that_present_agentStartTime) { - if (!(this_present_agentStartTime && that_present_agentStartTime)) - return false; - if (this.agentStartTime != that.agentStartTime) - return false; - } - - boolean this_present_serviceType = true; - boolean that_present_serviceType = true; - if (this_present_serviceType || that_present_serviceType) { - if (!(this_present_serviceType && that_present_serviceType)) - return false; - if (this.serviceType != that.serviceType) - return false; - } - - boolean this_present_transactionId = true && this.isSetTransactionId(); - boolean that_present_transactionId = true && that.isSetTransactionId(); - if (this_present_transactionId || that_present_transactionId) { - if (!(this_present_transactionId && that_present_transactionId)) - return false; - if (!this.transactionId.equals(that.transactionId)) - return false; - } - - boolean this_present_spanId = true; - boolean that_present_spanId = true; - if (this_present_spanId || that_present_spanId) { - if (!(this_present_spanId && that_present_spanId)) - return false; - if (this.spanId != that.spanId) - return false; - } - - boolean this_present_endPoint = true && this.isSetEndPoint(); - boolean that_present_endPoint = true && that.isSetEndPoint(); - if (this_present_endPoint || that_present_endPoint) { - if (!(this_present_endPoint && that_present_endPoint)) - return false; - if (!this.endPoint.equals(that.endPoint)) - return false; - } - - boolean this_present_spanEventList = true && this.isSetSpanEventList(); - boolean that_present_spanEventList = true && that.isSetSpanEventList(); - if (this_present_spanEventList || that_present_spanEventList) { - if (!(this_present_spanEventList && that_present_spanEventList)) - return false; - if (!this.spanEventList.equals(that.spanEventList)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TSpanChunk other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetApplicationName()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentStartTime()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetServiceType()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetTransactionId()).compareTo(other.isSetTransactionId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetTransactionId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transactionId, other.transactionId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSpanId()).compareTo(other.isSetSpanId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSpanId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanId, other.spanId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetEndPoint()).compareTo(other.isSetEndPoint()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetEndPoint()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endPoint, other.endPoint); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSpanEventList()).compareTo(other.isSetSpanEventList()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSpanEventList()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanEventList, other.spanEventList); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TSpanChunk("); - boolean first = true; - - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - if (!first) sb.append(", "); - sb.append("applicationName:"); - if (this.applicationName == null) { - sb.append("null"); - } else { - sb.append(this.applicationName); - } - first = false; - if (!first) sb.append(", "); - sb.append("agentStartTime:"); - sb.append(this.agentStartTime); - first = false; - if (!first) sb.append(", "); - sb.append("serviceType:"); - sb.append(this.serviceType); - first = false; - if (!first) sb.append(", "); - sb.append("transactionId:"); - if (this.transactionId == null) { - sb.append("null"); - } else { - org.apache.thrift.TBaseHelper.toString(this.transactionId, sb); - } - first = false; - if (!first) sb.append(", "); - sb.append("spanId:"); - sb.append(this.spanId); - first = false; - if (isSetEndPoint()) { - if (!first) sb.append(", "); - sb.append("endPoint:"); - if (this.endPoint == null) { - sb.append("null"); - } else { - sb.append(this.endPoint); - } - first = false; - } - if (!first) sb.append(", "); - sb.append("spanEventList:"); - if (this.spanEventList == null) { - sb.append("null"); - } else { - sb.append(this.spanEventList); - } - first = false; - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TSpanChunkStandardSchemeFactory implements SchemeFactory { - public TSpanChunkStandardScheme getScheme() { - return new TSpanChunkStandardScheme(); - } - } - - private static class TSpanChunkStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TSpanChunk struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // APPLICATION_NAME - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.applicationName = iprot.readString(); - struct.setApplicationNameIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // AGENT_START_TIME - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 4: // SERVICE_TYPE - if (schemeField.type == org.apache.thrift.protocol.TType.I16) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 5: // TRANSACTION_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.transactionId = iprot.readBinary(); - struct.setTransactionIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 8: // SPAN_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.spanId = iprot.readI64(); - struct.setSpanIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 9: // END_POINT - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.endPoint = iprot.readString(); - struct.setEndPointIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 10: // SPAN_EVENT_LIST - if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { - { - org.apache.thrift.protocol.TList _list24 = iprot.readListBegin(); - struct.spanEventList = new ArrayList(_list24.size); - for (int _i25 = 0; _i25 < _list24.size; ++_i25) - { - TSpanEvent _elem26; - _elem26 = new TSpanEvent(); - _elem26.read(iprot); - struct.spanEventList.add(_elem26); - } - iprot.readListEnd(); - } - struct.setSpanEventListIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TSpanChunk struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.agentId != null) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - if (struct.applicationName != null) { - oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); - oprot.writeString(struct.applicationName); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); - oprot.writeI64(struct.agentStartTime); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); - oprot.writeI16(struct.serviceType); - oprot.writeFieldEnd(); - if (struct.transactionId != null) { - oprot.writeFieldBegin(TRANSACTION_ID_FIELD_DESC); - oprot.writeBinary(struct.transactionId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(SPAN_ID_FIELD_DESC); - oprot.writeI64(struct.spanId); - oprot.writeFieldEnd(); - if (struct.endPoint != null) { - if (struct.isSetEndPoint()) { - oprot.writeFieldBegin(END_POINT_FIELD_DESC); - oprot.writeString(struct.endPoint); - oprot.writeFieldEnd(); - } - } - if (struct.spanEventList != null) { - oprot.writeFieldBegin(SPAN_EVENT_LIST_FIELD_DESC); - { - oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.spanEventList.size())); - for (TSpanEvent _iter27 : struct.spanEventList) - { - _iter27.write(oprot); - } - oprot.writeListEnd(); - } - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TSpanChunkTupleSchemeFactory implements SchemeFactory { - public TSpanChunkTupleScheme getScheme() { - return new TSpanChunkTupleScheme(); - } - } - - private static class TSpanChunkTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetAgentId()) { - optionals.set(0); - } - if (struct.isSetApplicationName()) { - optionals.set(1); - } - if (struct.isSetAgentStartTime()) { - optionals.set(2); - } - if (struct.isSetServiceType()) { - optionals.set(3); - } - if (struct.isSetTransactionId()) { - optionals.set(4); - } - if (struct.isSetSpanId()) { - optionals.set(5); - } - if (struct.isSetEndPoint()) { - optionals.set(6); - } - if (struct.isSetSpanEventList()) { - optionals.set(7); - } - oprot.writeBitSet(optionals, 8); - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetApplicationName()) { - oprot.writeString(struct.applicationName); - } - if (struct.isSetAgentStartTime()) { - oprot.writeI64(struct.agentStartTime); - } - if (struct.isSetServiceType()) { - oprot.writeI16(struct.serviceType); - } - if (struct.isSetTransactionId()) { - oprot.writeBinary(struct.transactionId); - } - if (struct.isSetSpanId()) { - oprot.writeI64(struct.spanId); - } - if (struct.isSetEndPoint()) { - oprot.writeString(struct.endPoint); - } - if (struct.isSetSpanEventList()) { - { - oprot.writeI32(struct.spanEventList.size()); - for (TSpanEvent _iter28 : struct.spanEventList) - { - _iter28.write(oprot); - } - } - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(8); - if (incoming.get(0)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(1)) { - struct.applicationName = iprot.readString(); - struct.setApplicationNameIsSet(true); - } - if (incoming.get(2)) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } - if (incoming.get(3)) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } - if (incoming.get(4)) { - struct.transactionId = iprot.readBinary(); - struct.setTransactionIdIsSet(true); - } - if (incoming.get(5)) { - struct.spanId = iprot.readI64(); - struct.setSpanIdIsSet(true); - } - if (incoming.get(6)) { - struct.endPoint = iprot.readString(); - struct.setEndPointIsSet(true); - } - if (incoming.get(7)) { - { - org.apache.thrift.protocol.TList _list29 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); - struct.spanEventList = new ArrayList(_list29.size); - for (int _i30 = 0; _i30 < _list29.size; ++_i30) - { - TSpanEvent _elem31; - _elem31 = new TSpanEvent(); - _elem31.read(iprot); - struct.spanEventList.add(_elem31); - } - } - struct.setSpanEventListIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TSpanChunk implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSpanChunk"); + + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)3); + private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)4); + private static final org.apache.thrift.protocol.TField TRANSACTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("transactionId", org.apache.thrift.protocol.TType.STRING, (short)5); + private static final org.apache.thrift.protocol.TField SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("spanId", org.apache.thrift.protocol.TType.I64, (short)8); + private static final org.apache.thrift.protocol.TField END_POINT_FIELD_DESC = new org.apache.thrift.protocol.TField("endPoint", org.apache.thrift.protocol.TType.STRING, (short)9); + private static final org.apache.thrift.protocol.TField SPAN_EVENT_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("spanEventList", org.apache.thrift.protocol.TType.LIST, (short)10); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TSpanChunkStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TSpanChunkTupleSchemeFactory()); + } + + private String agentId; // required + private String applicationName; // required + private long agentStartTime; // required + private short serviceType; // required + private ByteBuffer transactionId; // required + private long spanId; // required + private String endPoint; // optional + private List spanEventList; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + AGENT_ID((short)1, "agentId"), + APPLICATION_NAME((short)2, "applicationName"), + AGENT_START_TIME((short)3, "agentStartTime"), + SERVICE_TYPE((short)4, "serviceType"), + TRANSACTION_ID((short)5, "transactionId"), + SPAN_ID((short)8, "spanId"), + END_POINT((short)9, "endPoint"), + SPAN_EVENT_LIST((short)10, "spanEventList"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // AGENT_ID + return AGENT_ID; + case 2: // APPLICATION_NAME + return APPLICATION_NAME; + case 3: // AGENT_START_TIME + return AGENT_START_TIME; + case 4: // SERVICE_TYPE + return SERVICE_TYPE; + case 5: // TRANSACTION_ID + return TRANSACTION_ID; + case 8: // SPAN_ID + return SPAN_ID; + case 9: // END_POINT + return END_POINT; + case 10: // SPAN_EVENT_LIST + return SPAN_EVENT_LIST; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __AGENTSTARTTIME_ISSET_ID = 0; + private static final int __SERVICETYPE_ISSET_ID = 1; + private static final int __SPANID_ISSET_ID = 2; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.END_POINT}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.TRANSACTION_ID, new org.apache.thrift.meta_data.FieldMetaData("transactionId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("spanId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.END_POINT, new org.apache.thrift.meta_data.FieldMetaData("endPoint", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.SPAN_EVENT_LIST, new org.apache.thrift.meta_data.FieldMetaData("spanEventList", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSpanEvent.class)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpanChunk.class, metaDataMap); + } + + public TSpanChunk() { + } + + public TSpanChunk( + String agentId, + String applicationName, + long agentStartTime, + short serviceType, + ByteBuffer transactionId, + long spanId, + List spanEventList) + { + this(); + this.agentId = agentId; + this.applicationName = applicationName; + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + this.serviceType = serviceType; + setServiceTypeIsSet(true); + this.transactionId = transactionId; + this.spanId = spanId; + setSpanIdIsSet(true); + this.spanEventList = spanEventList; + } + + /** + * Performs a deep copy on other. + */ + public TSpanChunk(TSpanChunk other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + if (other.isSetApplicationName()) { + this.applicationName = other.applicationName; + } + this.agentStartTime = other.agentStartTime; + this.serviceType = other.serviceType; + if (other.isSetTransactionId()) { + this.transactionId = org.apache.thrift.TBaseHelper.copyBinary(other.transactionId); +; + } + this.spanId = other.spanId; + if (other.isSetEndPoint()) { + this.endPoint = other.endPoint; + } + if (other.isSetSpanEventList()) { + List __this__spanEventList = new ArrayList(other.spanEventList.size()); + for (TSpanEvent other_element : other.spanEventList) { + __this__spanEventList.add(new TSpanEvent(other_element)); + } + this.spanEventList = __this__spanEventList; + } + } + + public TSpanChunk deepCopy() { + return new TSpanChunk(this); + } + + @Override + public void clear() { + this.agentId = null; + this.applicationName = null; + setAgentStartTimeIsSet(false); + this.agentStartTime = 0; + setServiceTypeIsSet(false); + this.serviceType = 0; + this.transactionId = null; + setSpanIdIsSet(false); + this.spanId = 0; + this.endPoint = null; + this.spanEventList = null; + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public String getApplicationName() { + return this.applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public void unsetApplicationName() { + this.applicationName = null; + } + + /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ + public boolean isSetApplicationName() { + return this.applicationName != null; + } + + public void setApplicationNameIsSet(boolean value) { + if (!value) { + this.applicationName = null; + } + } + + public long getAgentStartTime() { + return this.agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + } + + public void unsetAgentStartTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentStartTime() { + return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + public void setAgentStartTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); + } + + public short getServiceType() { + return this.serviceType; + } + + public void setServiceType(short serviceType) { + this.serviceType = serviceType; + setServiceTypeIsSet(true); + } + + public void unsetServiceType() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ + public boolean isSetServiceType() { + return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + public void setServiceTypeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); + } + + public byte[] getTransactionId() { + setTransactionId(org.apache.thrift.TBaseHelper.rightSize(transactionId)); + return transactionId == null ? null : transactionId.array(); + } + + public ByteBuffer bufferForTransactionId() { + return transactionId; + } + + public void setTransactionId(byte[] transactionId) { + setTransactionId(transactionId == null ? (ByteBuffer)null : ByteBuffer.wrap(transactionId)); + } + + public void setTransactionId(ByteBuffer transactionId) { + this.transactionId = transactionId; + } + + public void unsetTransactionId() { + this.transactionId = null; + } + + /** Returns true if field transactionId is set (has been assigned a value) and false otherwise */ + public boolean isSetTransactionId() { + return this.transactionId != null; + } + + public void setTransactionIdIsSet(boolean value) { + if (!value) { + this.transactionId = null; + } + } + + public long getSpanId() { + return this.spanId; + } + + public void setSpanId(long spanId) { + this.spanId = spanId; + setSpanIdIsSet(true); + } + + public void unsetSpanId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + /** Returns true if field spanId is set (has been assigned a value) and false otherwise */ + public boolean isSetSpanId() { + return EncodingUtils.testBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + public void setSpanIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SPANID_ISSET_ID, value); + } + + public String getEndPoint() { + return this.endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public void unsetEndPoint() { + this.endPoint = null; + } + + /** Returns true if field endPoint is set (has been assigned a value) and false otherwise */ + public boolean isSetEndPoint() { + return this.endPoint != null; + } + + public void setEndPointIsSet(boolean value) { + if (!value) { + this.endPoint = null; + } + } + + public int getSpanEventListSize() { + return (this.spanEventList == null) ? 0 : this.spanEventList.size(); + } + + public java.util.Iterator getSpanEventListIterator() { + return (this.spanEventList == null) ? null : this.spanEventList.iterator(); + } + + public void addToSpanEventList(TSpanEvent elem) { + if (this.spanEventList == null) { + this.spanEventList = new ArrayList(); + } + this.spanEventList.add(elem); + } + + public List getSpanEventList() { + return this.spanEventList; + } + + public void setSpanEventList(List spanEventList) { + this.spanEventList = spanEventList; + } + + public void unsetSpanEventList() { + this.spanEventList = null; + } + + /** Returns true if field spanEventList is set (has been assigned a value) and false otherwise */ + public boolean isSetSpanEventList() { + return this.spanEventList != null; + } + + public void setSpanEventListIsSet(boolean value) { + if (!value) { + this.spanEventList = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case APPLICATION_NAME: + if (value == null) { + unsetApplicationName(); + } else { + setApplicationName((String)value); + } + break; + + case AGENT_START_TIME: + if (value == null) { + unsetAgentStartTime(); + } else { + setAgentStartTime((Long)value); + } + break; + + case SERVICE_TYPE: + if (value == null) { + unsetServiceType(); + } else { + setServiceType((Short)value); + } + break; + + case TRANSACTION_ID: + if (value == null) { + unsetTransactionId(); + } else { + setTransactionId((ByteBuffer)value); + } + break; + + case SPAN_ID: + if (value == null) { + unsetSpanId(); + } else { + setSpanId((Long)value); + } + break; + + case END_POINT: + if (value == null) { + unsetEndPoint(); + } else { + setEndPoint((String)value); + } + break; + + case SPAN_EVENT_LIST: + if (value == null) { + unsetSpanEventList(); + } else { + setSpanEventList((List)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case AGENT_ID: + return getAgentId(); + + case APPLICATION_NAME: + return getApplicationName(); + + case AGENT_START_TIME: + return Long.valueOf(getAgentStartTime()); + + case SERVICE_TYPE: + return Short.valueOf(getServiceType()); + + case TRANSACTION_ID: + return getTransactionId(); + + case SPAN_ID: + return Long.valueOf(getSpanId()); + + case END_POINT: + return getEndPoint(); + + case SPAN_EVENT_LIST: + return getSpanEventList(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case AGENT_ID: + return isSetAgentId(); + case APPLICATION_NAME: + return isSetApplicationName(); + case AGENT_START_TIME: + return isSetAgentStartTime(); + case SERVICE_TYPE: + return isSetServiceType(); + case TRANSACTION_ID: + return isSetTransactionId(); + case SPAN_ID: + return isSetSpanId(); + case END_POINT: + return isSetEndPoint(); + case SPAN_EVENT_LIST: + return isSetSpanEventList(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TSpanChunk) + return this.equals((TSpanChunk)that); + return false; + } + + public boolean equals(TSpanChunk that) { + if (that == null) + return false; + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_applicationName = true && this.isSetApplicationName(); + boolean that_present_applicationName = true && that.isSetApplicationName(); + if (this_present_applicationName || that_present_applicationName) { + if (!(this_present_applicationName && that_present_applicationName)) + return false; + if (!this.applicationName.equals(that.applicationName)) + return false; + } + + boolean this_present_agentStartTime = true; + boolean that_present_agentStartTime = true; + if (this_present_agentStartTime || that_present_agentStartTime) { + if (!(this_present_agentStartTime && that_present_agentStartTime)) + return false; + if (this.agentStartTime != that.agentStartTime) + return false; + } + + boolean this_present_serviceType = true; + boolean that_present_serviceType = true; + if (this_present_serviceType || that_present_serviceType) { + if (!(this_present_serviceType && that_present_serviceType)) + return false; + if (this.serviceType != that.serviceType) + return false; + } + + boolean this_present_transactionId = true && this.isSetTransactionId(); + boolean that_present_transactionId = true && that.isSetTransactionId(); + if (this_present_transactionId || that_present_transactionId) { + if (!(this_present_transactionId && that_present_transactionId)) + return false; + if (!this.transactionId.equals(that.transactionId)) + return false; + } + + boolean this_present_spanId = true; + boolean that_present_spanId = true; + if (this_present_spanId || that_present_spanId) { + if (!(this_present_spanId && that_present_spanId)) + return false; + if (this.spanId != that.spanId) + return false; + } + + boolean this_present_endPoint = true && this.isSetEndPoint(); + boolean that_present_endPoint = true && that.isSetEndPoint(); + if (this_present_endPoint || that_present_endPoint) { + if (!(this_present_endPoint && that_present_endPoint)) + return false; + if (!this.endPoint.equals(that.endPoint)) + return false; + } + + boolean this_present_spanEventList = true && this.isSetSpanEventList(); + boolean that_present_spanEventList = true && that.isSetSpanEventList(); + if (this_present_spanEventList || that_present_spanEventList) { + if (!(this_present_spanEventList && that_present_spanEventList)) + return false; + if (!this.spanEventList.equals(that.spanEventList)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TSpanChunk other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApplicationName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetServiceType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetTransactionId()).compareTo(other.isSetTransactionId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetTransactionId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transactionId, other.transactionId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSpanId()).compareTo(other.isSetSpanId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSpanId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanId, other.spanId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEndPoint()).compareTo(other.isSetEndPoint()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEndPoint()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endPoint, other.endPoint); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSpanEventList()).compareTo(other.isSetSpanEventList()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSpanEventList()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanEventList, other.spanEventList); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TSpanChunk("); + boolean first = true; + + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("applicationName:"); + if (this.applicationName == null) { + sb.append("null"); + } else { + sb.append(this.applicationName); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentStartTime:"); + sb.append(this.agentStartTime); + first = false; + if (!first) sb.append(", "); + sb.append("serviceType:"); + sb.append(this.serviceType); + first = false; + if (!first) sb.append(", "); + sb.append("transactionId:"); + if (this.transactionId == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.transactionId, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("spanId:"); + sb.append(this.spanId); + first = false; + if (isSetEndPoint()) { + if (!first) sb.append(", "); + sb.append("endPoint:"); + if (this.endPoint == null) { + sb.append("null"); + } else { + sb.append(this.endPoint); + } + first = false; + } + if (!first) sb.append(", "); + sb.append("spanEventList:"); + if (this.spanEventList == null) { + sb.append("null"); + } else { + sb.append(this.spanEventList); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TSpanChunkStandardSchemeFactory implements SchemeFactory { + public TSpanChunkStandardScheme getScheme() { + return new TSpanChunkStandardScheme(); + } + } + + private static class TSpanChunkStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TSpanChunk struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // APPLICATION_NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // AGENT_START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // SERVICE_TYPE + if (schemeField.type == org.apache.thrift.protocol.TType.I16) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 5: // TRANSACTION_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.transactionId = iprot.readBinary(); + struct.setTransactionIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 8: // SPAN_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 9: // END_POINT + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.endPoint = iprot.readString(); + struct.setEndPointIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // SPAN_EVENT_LIST + if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list24 = iprot.readListBegin(); + struct.spanEventList = new ArrayList(_list24.size); + for (int _i25 = 0; _i25 < _list24.size; ++_i25) + { + TSpanEvent _elem26; + _elem26 = new TSpanEvent(); + _elem26.read(iprot); + struct.spanEventList.add(_elem26); + } + iprot.readListEnd(); + } + struct.setSpanEventListIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TSpanChunk struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + if (struct.applicationName != null) { + oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); + oprot.writeString(struct.applicationName); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); + oprot.writeI64(struct.agentStartTime); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); + oprot.writeI16(struct.serviceType); + oprot.writeFieldEnd(); + if (struct.transactionId != null) { + oprot.writeFieldBegin(TRANSACTION_ID_FIELD_DESC); + oprot.writeBinary(struct.transactionId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(SPAN_ID_FIELD_DESC); + oprot.writeI64(struct.spanId); + oprot.writeFieldEnd(); + if (struct.endPoint != null) { + if (struct.isSetEndPoint()) { + oprot.writeFieldBegin(END_POINT_FIELD_DESC); + oprot.writeString(struct.endPoint); + oprot.writeFieldEnd(); + } + } + if (struct.spanEventList != null) { + oprot.writeFieldBegin(SPAN_EVENT_LIST_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.spanEventList.size())); + for (TSpanEvent _iter27 : struct.spanEventList) + { + _iter27.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TSpanChunkTupleSchemeFactory implements SchemeFactory { + public TSpanChunkTupleScheme getScheme() { + return new TSpanChunkTupleScheme(); + } + } + + private static class TSpanChunkTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetAgentId()) { + optionals.set(0); + } + if (struct.isSetApplicationName()) { + optionals.set(1); + } + if (struct.isSetAgentStartTime()) { + optionals.set(2); + } + if (struct.isSetServiceType()) { + optionals.set(3); + } + if (struct.isSetTransactionId()) { + optionals.set(4); + } + if (struct.isSetSpanId()) { + optionals.set(5); + } + if (struct.isSetEndPoint()) { + optionals.set(6); + } + if (struct.isSetSpanEventList()) { + optionals.set(7); + } + oprot.writeBitSet(optionals, 8); + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetApplicationName()) { + oprot.writeString(struct.applicationName); + } + if (struct.isSetAgentStartTime()) { + oprot.writeI64(struct.agentStartTime); + } + if (struct.isSetServiceType()) { + oprot.writeI16(struct.serviceType); + } + if (struct.isSetTransactionId()) { + oprot.writeBinary(struct.transactionId); + } + if (struct.isSetSpanId()) { + oprot.writeI64(struct.spanId); + } + if (struct.isSetEndPoint()) { + oprot.writeString(struct.endPoint); + } + if (struct.isSetSpanEventList()) { + { + oprot.writeI32(struct.spanEventList.size()); + for (TSpanEvent _iter28 : struct.spanEventList) + { + _iter28.write(oprot); + } + } + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(8); + if (incoming.get(0)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(1)) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } + if (incoming.get(2)) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } + if (incoming.get(3)) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } + if (incoming.get(4)) { + struct.transactionId = iprot.readBinary(); + struct.setTransactionIdIsSet(true); + } + if (incoming.get(5)) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } + if (incoming.get(6)) { + struct.endPoint = iprot.readString(); + struct.setEndPointIsSet(true); + } + if (incoming.get(7)) { + { + org.apache.thrift.protocol.TList _list29 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); + struct.spanEventList = new ArrayList(_list29.size); + for (int _i30 = 0; _i30 < _list29.size; ++_i30) + { + TSpanEvent _elem31; + _elem31 = new TSpanEvent(); + _elem31.read(iprot); + struct.spanEventList.add(_elem31); + } + } + struct.setSpanEventListIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanEvent.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanEvent.java index bf719a869519..82fe63fdd922 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanEvent.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanEvent.java @@ -1,1610 +1,1610 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TSpanEvent implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSpanEvent"); - - private static final org.apache.thrift.protocol.TField SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("spanId", org.apache.thrift.protocol.TType.I64, (short)7); - private static final org.apache.thrift.protocol.TField SEQUENCE_FIELD_DESC = new org.apache.thrift.protocol.TField("sequence", org.apache.thrift.protocol.TType.I16, (short)8); - private static final org.apache.thrift.protocol.TField START_ELAPSED_FIELD_DESC = new org.apache.thrift.protocol.TField("startElapsed", org.apache.thrift.protocol.TType.I32, (short)9); - private static final org.apache.thrift.protocol.TField END_ELAPSED_FIELD_DESC = new org.apache.thrift.protocol.TField("endElapsed", org.apache.thrift.protocol.TType.I32, (short)10); - private static final org.apache.thrift.protocol.TField RPC_FIELD_DESC = new org.apache.thrift.protocol.TField("rpc", org.apache.thrift.protocol.TType.STRING, (short)11); - private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)12); - private static final org.apache.thrift.protocol.TField END_POINT_FIELD_DESC = new org.apache.thrift.protocol.TField("endPoint", org.apache.thrift.protocol.TType.STRING, (short)13); - private static final org.apache.thrift.protocol.TField ANNOTATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("annotations", org.apache.thrift.protocol.TType.LIST, (short)14); - private static final org.apache.thrift.protocol.TField DEPTH_FIELD_DESC = new org.apache.thrift.protocol.TField("depth", org.apache.thrift.protocol.TType.I32, (short)15); - private static final org.apache.thrift.protocol.TField NEXT_SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("nextSpanId", org.apache.thrift.protocol.TType.I64, (short)16); - private static final org.apache.thrift.protocol.TField DESTINATION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("destinationId", org.apache.thrift.protocol.TType.STRING, (short)20); - private static final org.apache.thrift.protocol.TField API_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("apiId", org.apache.thrift.protocol.TType.I32, (short)25); - private static final org.apache.thrift.protocol.TField EXCEPTION_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionInfo", org.apache.thrift.protocol.TType.STRUCT, (short)26); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TSpanEventStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TSpanEventTupleSchemeFactory()); - } - - private long spanId; // optional - private short sequence; // required - private int startElapsed; // required - private int endElapsed; // optional - private String rpc; // optional - private short serviceType; // required - private String endPoint; // optional - private List annotations; // optional - private int depth; // optional - private long nextSpanId; // optional - private String destinationId; // optional - private int apiId; // optional - private TIntStringValue exceptionInfo; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - SPAN_ID((short)7, "spanId"), - SEQUENCE((short)8, "sequence"), - START_ELAPSED((short)9, "startElapsed"), - END_ELAPSED((short)10, "endElapsed"), - RPC((short)11, "rpc"), - SERVICE_TYPE((short)12, "serviceType"), - END_POINT((short)13, "endPoint"), - ANNOTATIONS((short)14, "annotations"), - DEPTH((short)15, "depth"), - NEXT_SPAN_ID((short)16, "nextSpanId"), - DESTINATION_ID((short)20, "destinationId"), - API_ID((short)25, "apiId"), - EXCEPTION_INFO((short)26, "exceptionInfo"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 7: // SPAN_ID - return SPAN_ID; - case 8: // SEQUENCE - return SEQUENCE; - case 9: // START_ELAPSED - return START_ELAPSED; - case 10: // END_ELAPSED - return END_ELAPSED; - case 11: // RPC - return RPC; - case 12: // SERVICE_TYPE - return SERVICE_TYPE; - case 13: // END_POINT - return END_POINT; - case 14: // ANNOTATIONS - return ANNOTATIONS; - case 15: // DEPTH - return DEPTH; - case 16: // NEXT_SPAN_ID - return NEXT_SPAN_ID; - case 20: // DESTINATION_ID - return DESTINATION_ID; - case 25: // API_ID - return API_ID; - case 26: // EXCEPTION_INFO - return EXCEPTION_INFO; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __SPANID_ISSET_ID = 0; - private static final int __SEQUENCE_ISSET_ID = 1; - private static final int __STARTELAPSED_ISSET_ID = 2; - private static final int __ENDELAPSED_ISSET_ID = 3; - private static final int __SERVICETYPE_ISSET_ID = 4; - private static final int __DEPTH_ISSET_ID = 5; - private static final int __NEXTSPANID_ISSET_ID = 6; - private static final int __APIID_ISSET_ID = 7; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.SPAN_ID,_Fields.END_ELAPSED,_Fields.RPC,_Fields.END_POINT,_Fields.ANNOTATIONS,_Fields.DEPTH,_Fields.NEXT_SPAN_ID,_Fields.DESTINATION_ID,_Fields.API_ID,_Fields.EXCEPTION_INFO}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("spanId", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.SEQUENCE, new org.apache.thrift.meta_data.FieldMetaData("sequence", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.START_ELAPSED, new org.apache.thrift.meta_data.FieldMetaData("startElapsed", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.END_ELAPSED, new org.apache.thrift.meta_data.FieldMetaData("endElapsed", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.RPC, new org.apache.thrift.meta_data.FieldMetaData("rpc", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.END_POINT, new org.apache.thrift.meta_data.FieldMetaData("endPoint", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.ANNOTATIONS, new org.apache.thrift.meta_data.FieldMetaData("annotations", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAnnotation.class)))); - tmpMap.put(_Fields.DEPTH, new org.apache.thrift.meta_data.FieldMetaData("depth", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.NEXT_SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("nextSpanId", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.DESTINATION_ID, new org.apache.thrift.meta_data.FieldMetaData("destinationId", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.API_ID, new org.apache.thrift.meta_data.FieldMetaData("apiId", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.EXCEPTION_INFO, new org.apache.thrift.meta_data.FieldMetaData("exceptionInfo", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringValue.class))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpanEvent.class, metaDataMap); - } - - public TSpanEvent() { - this.endElapsed = 0; - - this.depth = -1; - - this.nextSpanId = -1L; - - } - - public TSpanEvent( - short sequence, - int startElapsed, - short serviceType) - { - this(); - this.sequence = sequence; - setSequenceIsSet(true); - this.startElapsed = startElapsed; - setStartElapsedIsSet(true); - this.serviceType = serviceType; - setServiceTypeIsSet(true); - } - - /** - * Performs a deep copy on other. - */ - public TSpanEvent(TSpanEvent other) { - __isset_bitfield = other.__isset_bitfield; - this.spanId = other.spanId; - this.sequence = other.sequence; - this.startElapsed = other.startElapsed; - this.endElapsed = other.endElapsed; - if (other.isSetRpc()) { - this.rpc = other.rpc; - } - this.serviceType = other.serviceType; - if (other.isSetEndPoint()) { - this.endPoint = other.endPoint; - } - if (other.isSetAnnotations()) { - List __this__annotations = new ArrayList(other.annotations.size()); - for (TAnnotation other_element : other.annotations) { - __this__annotations.add(new TAnnotation(other_element)); - } - this.annotations = __this__annotations; - } - this.depth = other.depth; - this.nextSpanId = other.nextSpanId; - if (other.isSetDestinationId()) { - this.destinationId = other.destinationId; - } - this.apiId = other.apiId; - if (other.isSetExceptionInfo()) { - this.exceptionInfo = new TIntStringValue(other.exceptionInfo); - } - } - - public TSpanEvent deepCopy() { - return new TSpanEvent(this); - } - - @Override - public void clear() { - setSpanIdIsSet(false); - this.spanId = 0; - setSequenceIsSet(false); - this.sequence = 0; - setStartElapsedIsSet(false); - this.startElapsed = 0; - this.endElapsed = 0; - - this.rpc = null; - setServiceTypeIsSet(false); - this.serviceType = 0; - this.endPoint = null; - this.annotations = null; - this.depth = -1; - - this.nextSpanId = -1L; - - this.destinationId = null; - setApiIdIsSet(false); - this.apiId = 0; - this.exceptionInfo = null; - } - - public long getSpanId() { - return this.spanId; - } - - public void setSpanId(long spanId) { - this.spanId = spanId; - setSpanIdIsSet(true); - } - - public void unsetSpanId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SPANID_ISSET_ID); - } - - /** Returns true if field spanId is set (has been assigned a value) and false otherwise */ - public boolean isSetSpanId() { - return EncodingUtils.testBit(__isset_bitfield, __SPANID_ISSET_ID); - } - - public void setSpanIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SPANID_ISSET_ID, value); - } - - public short getSequence() { - return this.sequence; - } - - public void setSequence(short sequence) { - this.sequence = sequence; - setSequenceIsSet(true); - } - - public void unsetSequence() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SEQUENCE_ISSET_ID); - } - - /** Returns true if field sequence is set (has been assigned a value) and false otherwise */ - public boolean isSetSequence() { - return EncodingUtils.testBit(__isset_bitfield, __SEQUENCE_ISSET_ID); - } - - public void setSequenceIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SEQUENCE_ISSET_ID, value); - } - - public int getStartElapsed() { - return this.startElapsed; - } - - public void setStartElapsed(int startElapsed) { - this.startElapsed = startElapsed; - setStartElapsedIsSet(true); - } - - public void unsetStartElapsed() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTELAPSED_ISSET_ID); - } - - /** Returns true if field startElapsed is set (has been assigned a value) and false otherwise */ - public boolean isSetStartElapsed() { - return EncodingUtils.testBit(__isset_bitfield, __STARTELAPSED_ISSET_ID); - } - - public void setStartElapsedIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTELAPSED_ISSET_ID, value); - } - - public int getEndElapsed() { - return this.endElapsed; - } - - public void setEndElapsed(int endElapsed) { - this.endElapsed = endElapsed; - setEndElapsedIsSet(true); - } - - public void unsetEndElapsed() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENDELAPSED_ISSET_ID); - } - - /** Returns true if field endElapsed is set (has been assigned a value) and false otherwise */ - public boolean isSetEndElapsed() { - return EncodingUtils.testBit(__isset_bitfield, __ENDELAPSED_ISSET_ID); - } - - public void setEndElapsedIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENDELAPSED_ISSET_ID, value); - } - - public String getRpc() { - return this.rpc; - } - - public void setRpc(String rpc) { - this.rpc = rpc; - } - - public void unsetRpc() { - this.rpc = null; - } - - /** Returns true if field rpc is set (has been assigned a value) and false otherwise */ - public boolean isSetRpc() { - return this.rpc != null; - } - - public void setRpcIsSet(boolean value) { - if (!value) { - this.rpc = null; - } - } - - public short getServiceType() { - return this.serviceType; - } - - public void setServiceType(short serviceType) { - this.serviceType = serviceType; - setServiceTypeIsSet(true); - } - - public void unsetServiceType() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ - public boolean isSetServiceType() { - return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); - } - - public void setServiceTypeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); - } - - public String getEndPoint() { - return this.endPoint; - } - - public void setEndPoint(String endPoint) { - this.endPoint = endPoint; - } - - public void unsetEndPoint() { - this.endPoint = null; - } - - /** Returns true if field endPoint is set (has been assigned a value) and false otherwise */ - public boolean isSetEndPoint() { - return this.endPoint != null; - } - - public void setEndPointIsSet(boolean value) { - if (!value) { - this.endPoint = null; - } - } - - public int getAnnotationsSize() { - return (this.annotations == null) ? 0 : this.annotations.size(); - } - - public java.util.Iterator getAnnotationsIterator() { - return (this.annotations == null) ? null : this.annotations.iterator(); - } - - public void addToAnnotations(TAnnotation elem) { - if (this.annotations == null) { - this.annotations = new ArrayList(); - } - this.annotations.add(elem); - } - - public List getAnnotations() { - return this.annotations; - } - - public void setAnnotations(List annotations) { - this.annotations = annotations; - } - - public void unsetAnnotations() { - this.annotations = null; - } - - /** Returns true if field annotations is set (has been assigned a value) and false otherwise */ - public boolean isSetAnnotations() { - return this.annotations != null; - } - - public void setAnnotationsIsSet(boolean value) { - if (!value) { - this.annotations = null; - } - } - - public int getDepth() { - return this.depth; - } - - public void setDepth(int depth) { - this.depth = depth; - setDepthIsSet(true); - } - - public void unsetDepth() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __DEPTH_ISSET_ID); - } - - /** Returns true if field depth is set (has been assigned a value) and false otherwise */ - public boolean isSetDepth() { - return EncodingUtils.testBit(__isset_bitfield, __DEPTH_ISSET_ID); - } - - public void setDepthIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __DEPTH_ISSET_ID, value); - } - - public long getNextSpanId() { - return this.nextSpanId; - } - - public void setNextSpanId(long nextSpanId) { - this.nextSpanId = nextSpanId; - setNextSpanIdIsSet(true); - } - - public void unsetNextSpanId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NEXTSPANID_ISSET_ID); - } - - /** Returns true if field nextSpanId is set (has been assigned a value) and false otherwise */ - public boolean isSetNextSpanId() { - return EncodingUtils.testBit(__isset_bitfield, __NEXTSPANID_ISSET_ID); - } - - public void setNextSpanIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NEXTSPANID_ISSET_ID, value); - } - - public String getDestinationId() { - return this.destinationId; - } - - public void setDestinationId(String destinationId) { - this.destinationId = destinationId; - } - - public void unsetDestinationId() { - this.destinationId = null; - } - - /** Returns true if field destinationId is set (has been assigned a value) and false otherwise */ - public boolean isSetDestinationId() { - return this.destinationId != null; - } - - public void setDestinationIdIsSet(boolean value) { - if (!value) { - this.destinationId = null; - } - } - - public int getApiId() { - return this.apiId; - } - - public void setApiId(int apiId) { - this.apiId = apiId; - setApiIdIsSet(true); - } - - public void unsetApiId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __APIID_ISSET_ID); - } - - /** Returns true if field apiId is set (has been assigned a value) and false otherwise */ - public boolean isSetApiId() { - return EncodingUtils.testBit(__isset_bitfield, __APIID_ISSET_ID); - } - - public void setApiIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __APIID_ISSET_ID, value); - } - - public TIntStringValue getExceptionInfo() { - return this.exceptionInfo; - } - - public void setExceptionInfo(TIntStringValue exceptionInfo) { - this.exceptionInfo = exceptionInfo; - } - - public void unsetExceptionInfo() { - this.exceptionInfo = null; - } - - /** Returns true if field exceptionInfo is set (has been assigned a value) and false otherwise */ - public boolean isSetExceptionInfo() { - return this.exceptionInfo != null; - } - - public void setExceptionInfoIsSet(boolean value) { - if (!value) { - this.exceptionInfo = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case SPAN_ID: - if (value == null) { - unsetSpanId(); - } else { - setSpanId((Long)value); - } - break; - - case SEQUENCE: - if (value == null) { - unsetSequence(); - } else { - setSequence((Short)value); - } - break; - - case START_ELAPSED: - if (value == null) { - unsetStartElapsed(); - } else { - setStartElapsed((Integer)value); - } - break; - - case END_ELAPSED: - if (value == null) { - unsetEndElapsed(); - } else { - setEndElapsed((Integer)value); - } - break; - - case RPC: - if (value == null) { - unsetRpc(); - } else { - setRpc((String)value); - } - break; - - case SERVICE_TYPE: - if (value == null) { - unsetServiceType(); - } else { - setServiceType((Short)value); - } - break; - - case END_POINT: - if (value == null) { - unsetEndPoint(); - } else { - setEndPoint((String)value); - } - break; - - case ANNOTATIONS: - if (value == null) { - unsetAnnotations(); - } else { - setAnnotations((List)value); - } - break; - - case DEPTH: - if (value == null) { - unsetDepth(); - } else { - setDepth((Integer)value); - } - break; - - case NEXT_SPAN_ID: - if (value == null) { - unsetNextSpanId(); - } else { - setNextSpanId((Long)value); - } - break; - - case DESTINATION_ID: - if (value == null) { - unsetDestinationId(); - } else { - setDestinationId((String)value); - } - break; - - case API_ID: - if (value == null) { - unsetApiId(); - } else { - setApiId((Integer)value); - } - break; - - case EXCEPTION_INFO: - if (value == null) { - unsetExceptionInfo(); - } else { - setExceptionInfo((TIntStringValue)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case SPAN_ID: - return Long.valueOf(getSpanId()); - - case SEQUENCE: - return Short.valueOf(getSequence()); - - case START_ELAPSED: - return Integer.valueOf(getStartElapsed()); - - case END_ELAPSED: - return Integer.valueOf(getEndElapsed()); - - case RPC: - return getRpc(); - - case SERVICE_TYPE: - return Short.valueOf(getServiceType()); - - case END_POINT: - return getEndPoint(); - - case ANNOTATIONS: - return getAnnotations(); - - case DEPTH: - return Integer.valueOf(getDepth()); - - case NEXT_SPAN_ID: - return Long.valueOf(getNextSpanId()); - - case DESTINATION_ID: - return getDestinationId(); - - case API_ID: - return Integer.valueOf(getApiId()); - - case EXCEPTION_INFO: - return getExceptionInfo(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case SPAN_ID: - return isSetSpanId(); - case SEQUENCE: - return isSetSequence(); - case START_ELAPSED: - return isSetStartElapsed(); - case END_ELAPSED: - return isSetEndElapsed(); - case RPC: - return isSetRpc(); - case SERVICE_TYPE: - return isSetServiceType(); - case END_POINT: - return isSetEndPoint(); - case ANNOTATIONS: - return isSetAnnotations(); - case DEPTH: - return isSetDepth(); - case NEXT_SPAN_ID: - return isSetNextSpanId(); - case DESTINATION_ID: - return isSetDestinationId(); - case API_ID: - return isSetApiId(); - case EXCEPTION_INFO: - return isSetExceptionInfo(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TSpanEvent) - return this.equals((TSpanEvent)that); - return false; - } - - public boolean equals(TSpanEvent that) { - if (that == null) - return false; - - boolean this_present_spanId = true && this.isSetSpanId(); - boolean that_present_spanId = true && that.isSetSpanId(); - if (this_present_spanId || that_present_spanId) { - if (!(this_present_spanId && that_present_spanId)) - return false; - if (this.spanId != that.spanId) - return false; - } - - boolean this_present_sequence = true; - boolean that_present_sequence = true; - if (this_present_sequence || that_present_sequence) { - if (!(this_present_sequence && that_present_sequence)) - return false; - if (this.sequence != that.sequence) - return false; - } - - boolean this_present_startElapsed = true; - boolean that_present_startElapsed = true; - if (this_present_startElapsed || that_present_startElapsed) { - if (!(this_present_startElapsed && that_present_startElapsed)) - return false; - if (this.startElapsed != that.startElapsed) - return false; - } - - boolean this_present_endElapsed = true && this.isSetEndElapsed(); - boolean that_present_endElapsed = true && that.isSetEndElapsed(); - if (this_present_endElapsed || that_present_endElapsed) { - if (!(this_present_endElapsed && that_present_endElapsed)) - return false; - if (this.endElapsed != that.endElapsed) - return false; - } - - boolean this_present_rpc = true && this.isSetRpc(); - boolean that_present_rpc = true && that.isSetRpc(); - if (this_present_rpc || that_present_rpc) { - if (!(this_present_rpc && that_present_rpc)) - return false; - if (!this.rpc.equals(that.rpc)) - return false; - } - - boolean this_present_serviceType = true; - boolean that_present_serviceType = true; - if (this_present_serviceType || that_present_serviceType) { - if (!(this_present_serviceType && that_present_serviceType)) - return false; - if (this.serviceType != that.serviceType) - return false; - } - - boolean this_present_endPoint = true && this.isSetEndPoint(); - boolean that_present_endPoint = true && that.isSetEndPoint(); - if (this_present_endPoint || that_present_endPoint) { - if (!(this_present_endPoint && that_present_endPoint)) - return false; - if (!this.endPoint.equals(that.endPoint)) - return false; - } - - boolean this_present_annotations = true && this.isSetAnnotations(); - boolean that_present_annotations = true && that.isSetAnnotations(); - if (this_present_annotations || that_present_annotations) { - if (!(this_present_annotations && that_present_annotations)) - return false; - if (!this.annotations.equals(that.annotations)) - return false; - } - - boolean this_present_depth = true && this.isSetDepth(); - boolean that_present_depth = true && that.isSetDepth(); - if (this_present_depth || that_present_depth) { - if (!(this_present_depth && that_present_depth)) - return false; - if (this.depth != that.depth) - return false; - } - - boolean this_present_nextSpanId = true && this.isSetNextSpanId(); - boolean that_present_nextSpanId = true && that.isSetNextSpanId(); - if (this_present_nextSpanId || that_present_nextSpanId) { - if (!(this_present_nextSpanId && that_present_nextSpanId)) - return false; - if (this.nextSpanId != that.nextSpanId) - return false; - } - - boolean this_present_destinationId = true && this.isSetDestinationId(); - boolean that_present_destinationId = true && that.isSetDestinationId(); - if (this_present_destinationId || that_present_destinationId) { - if (!(this_present_destinationId && that_present_destinationId)) - return false; - if (!this.destinationId.equals(that.destinationId)) - return false; - } - - boolean this_present_apiId = true && this.isSetApiId(); - boolean that_present_apiId = true && that.isSetApiId(); - if (this_present_apiId || that_present_apiId) { - if (!(this_present_apiId && that_present_apiId)) - return false; - if (this.apiId != that.apiId) - return false; - } - - boolean this_present_exceptionInfo = true && this.isSetExceptionInfo(); - boolean that_present_exceptionInfo = true && that.isSetExceptionInfo(); - if (this_present_exceptionInfo || that_present_exceptionInfo) { - if (!(this_present_exceptionInfo && that_present_exceptionInfo)) - return false; - if (!this.exceptionInfo.equals(that.exceptionInfo)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TSpanEvent other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetSpanId()).compareTo(other.isSetSpanId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSpanId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanId, other.spanId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSequence()).compareTo(other.isSetSequence()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSequence()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sequence, other.sequence); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStartElapsed()).compareTo(other.isSetStartElapsed()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStartElapsed()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startElapsed, other.startElapsed); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetEndElapsed()).compareTo(other.isSetEndElapsed()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetEndElapsed()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endElapsed, other.endElapsed); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetRpc()).compareTo(other.isSetRpc()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetRpc()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.rpc, other.rpc); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetServiceType()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetEndPoint()).compareTo(other.isSetEndPoint()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetEndPoint()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endPoint, other.endPoint); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAnnotations()).compareTo(other.isSetAnnotations()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAnnotations()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.annotations, other.annotations); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetDepth()).compareTo(other.isSetDepth()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetDepth()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.depth, other.depth); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetNextSpanId()).compareTo(other.isSetNextSpanId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetNextSpanId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nextSpanId, other.nextSpanId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetDestinationId()).compareTo(other.isSetDestinationId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetDestinationId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.destinationId, other.destinationId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetApiId()).compareTo(other.isSetApiId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetApiId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiId, other.apiId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetExceptionInfo()).compareTo(other.isSetExceptionInfo()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetExceptionInfo()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exceptionInfo, other.exceptionInfo); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TSpanEvent("); - boolean first = true; - - if (isSetSpanId()) { - sb.append("spanId:"); - sb.append(this.spanId); - first = false; - } - if (!first) sb.append(", "); - sb.append("sequence:"); - sb.append(this.sequence); - first = false; - if (!first) sb.append(", "); - sb.append("startElapsed:"); - sb.append(this.startElapsed); - first = false; - if (isSetEndElapsed()) { - if (!first) sb.append(", "); - sb.append("endElapsed:"); - sb.append(this.endElapsed); - first = false; - } - if (isSetRpc()) { - if (!first) sb.append(", "); - sb.append("rpc:"); - if (this.rpc == null) { - sb.append("null"); - } else { - sb.append(this.rpc); - } - first = false; - } - if (!first) sb.append(", "); - sb.append("serviceType:"); - sb.append(this.serviceType); - first = false; - if (isSetEndPoint()) { - if (!first) sb.append(", "); - sb.append("endPoint:"); - if (this.endPoint == null) { - sb.append("null"); - } else { - sb.append(this.endPoint); - } - first = false; - } - if (isSetAnnotations()) { - if (!first) sb.append(", "); - sb.append("annotations:"); - if (this.annotations == null) { - sb.append("null"); - } else { - sb.append(this.annotations); - } - first = false; - } - if (isSetDepth()) { - if (!first) sb.append(", "); - sb.append("depth:"); - sb.append(this.depth); - first = false; - } - if (isSetNextSpanId()) { - if (!first) sb.append(", "); - sb.append("nextSpanId:"); - sb.append(this.nextSpanId); - first = false; - } - if (isSetDestinationId()) { - if (!first) sb.append(", "); - sb.append("destinationId:"); - if (this.destinationId == null) { - sb.append("null"); - } else { - sb.append(this.destinationId); - } - first = false; - } - if (isSetApiId()) { - if (!first) sb.append(", "); - sb.append("apiId:"); - sb.append(this.apiId); - first = false; - } - if (isSetExceptionInfo()) { - if (!first) sb.append(", "); - sb.append("exceptionInfo:"); - if (this.exceptionInfo == null) { - sb.append("null"); - } else { - sb.append(this.exceptionInfo); - } - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - if (exceptionInfo != null) { - exceptionInfo.validate(); - } - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TSpanEventStandardSchemeFactory implements SchemeFactory { - public TSpanEventStandardScheme getScheme() { - return new TSpanEventStandardScheme(); - } - } - - private static class TSpanEventStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TSpanEvent struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 7: // SPAN_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.spanId = iprot.readI64(); - struct.setSpanIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 8: // SEQUENCE - if (schemeField.type == org.apache.thrift.protocol.TType.I16) { - struct.sequence = iprot.readI16(); - struct.setSequenceIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 9: // START_ELAPSED - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.startElapsed = iprot.readI32(); - struct.setStartElapsedIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 10: // END_ELAPSED - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.endElapsed = iprot.readI32(); - struct.setEndElapsedIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 11: // RPC - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.rpc = iprot.readString(); - struct.setRpcIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 12: // SERVICE_TYPE - if (schemeField.type == org.apache.thrift.protocol.TType.I16) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 13: // END_POINT - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.endPoint = iprot.readString(); - struct.setEndPointIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 14: // ANNOTATIONS - if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { - { - org.apache.thrift.protocol.TList _list0 = iprot.readListBegin(); - struct.annotations = new ArrayList(_list0.size); - for (int _i1 = 0; _i1 < _list0.size; ++_i1) - { - TAnnotation _elem2; - _elem2 = new TAnnotation(); - _elem2.read(iprot); - struct.annotations.add(_elem2); - } - iprot.readListEnd(); - } - struct.setAnnotationsIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 15: // DEPTH - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.depth = iprot.readI32(); - struct.setDepthIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 16: // NEXT_SPAN_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.nextSpanId = iprot.readI64(); - struct.setNextSpanIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 20: // DESTINATION_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.destinationId = iprot.readString(); - struct.setDestinationIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 25: // API_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.apiId = iprot.readI32(); - struct.setApiIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 26: // EXCEPTION_INFO - if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { - struct.exceptionInfo = new TIntStringValue(); - struct.exceptionInfo.read(iprot); - struct.setExceptionInfoIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TSpanEvent struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.isSetSpanId()) { - oprot.writeFieldBegin(SPAN_ID_FIELD_DESC); - oprot.writeI64(struct.spanId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(SEQUENCE_FIELD_DESC); - oprot.writeI16(struct.sequence); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(START_ELAPSED_FIELD_DESC); - oprot.writeI32(struct.startElapsed); - oprot.writeFieldEnd(); - if (struct.isSetEndElapsed()) { - oprot.writeFieldBegin(END_ELAPSED_FIELD_DESC); - oprot.writeI32(struct.endElapsed); - oprot.writeFieldEnd(); - } - if (struct.rpc != null) { - if (struct.isSetRpc()) { - oprot.writeFieldBegin(RPC_FIELD_DESC); - oprot.writeString(struct.rpc); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); - oprot.writeI16(struct.serviceType); - oprot.writeFieldEnd(); - if (struct.endPoint != null) { - if (struct.isSetEndPoint()) { - oprot.writeFieldBegin(END_POINT_FIELD_DESC); - oprot.writeString(struct.endPoint); - oprot.writeFieldEnd(); - } - } - if (struct.annotations != null) { - if (struct.isSetAnnotations()) { - oprot.writeFieldBegin(ANNOTATIONS_FIELD_DESC); - { - oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.annotations.size())); - for (TAnnotation _iter3 : struct.annotations) - { - _iter3.write(oprot); - } - oprot.writeListEnd(); - } - oprot.writeFieldEnd(); - } - } - if (struct.isSetDepth()) { - oprot.writeFieldBegin(DEPTH_FIELD_DESC); - oprot.writeI32(struct.depth); - oprot.writeFieldEnd(); - } - if (struct.isSetNextSpanId()) { - oprot.writeFieldBegin(NEXT_SPAN_ID_FIELD_DESC); - oprot.writeI64(struct.nextSpanId); - oprot.writeFieldEnd(); - } - if (struct.destinationId != null) { - if (struct.isSetDestinationId()) { - oprot.writeFieldBegin(DESTINATION_ID_FIELD_DESC); - oprot.writeString(struct.destinationId); - oprot.writeFieldEnd(); - } - } - if (struct.isSetApiId()) { - oprot.writeFieldBegin(API_ID_FIELD_DESC); - oprot.writeI32(struct.apiId); - oprot.writeFieldEnd(); - } - if (struct.exceptionInfo != null) { - if (struct.isSetExceptionInfo()) { - oprot.writeFieldBegin(EXCEPTION_INFO_FIELD_DESC); - struct.exceptionInfo.write(oprot); - oprot.writeFieldEnd(); - } - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TSpanEventTupleSchemeFactory implements SchemeFactory { - public TSpanEventTupleScheme getScheme() { - return new TSpanEventTupleScheme(); - } - } - - private static class TSpanEventTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TSpanEvent struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetSpanId()) { - optionals.set(0); - } - if (struct.isSetSequence()) { - optionals.set(1); - } - if (struct.isSetStartElapsed()) { - optionals.set(2); - } - if (struct.isSetEndElapsed()) { - optionals.set(3); - } - if (struct.isSetRpc()) { - optionals.set(4); - } - if (struct.isSetServiceType()) { - optionals.set(5); - } - if (struct.isSetEndPoint()) { - optionals.set(6); - } - if (struct.isSetAnnotations()) { - optionals.set(7); - } - if (struct.isSetDepth()) { - optionals.set(8); - } - if (struct.isSetNextSpanId()) { - optionals.set(9); - } - if (struct.isSetDestinationId()) { - optionals.set(10); - } - if (struct.isSetApiId()) { - optionals.set(11); - } - if (struct.isSetExceptionInfo()) { - optionals.set(12); - } - oprot.writeBitSet(optionals, 13); - if (struct.isSetSpanId()) { - oprot.writeI64(struct.spanId); - } - if (struct.isSetSequence()) { - oprot.writeI16(struct.sequence); - } - if (struct.isSetStartElapsed()) { - oprot.writeI32(struct.startElapsed); - } - if (struct.isSetEndElapsed()) { - oprot.writeI32(struct.endElapsed); - } - if (struct.isSetRpc()) { - oprot.writeString(struct.rpc); - } - if (struct.isSetServiceType()) { - oprot.writeI16(struct.serviceType); - } - if (struct.isSetEndPoint()) { - oprot.writeString(struct.endPoint); - } - if (struct.isSetAnnotations()) { - { - oprot.writeI32(struct.annotations.size()); - for (TAnnotation _iter4 : struct.annotations) - { - _iter4.write(oprot); - } - } - } - if (struct.isSetDepth()) { - oprot.writeI32(struct.depth); - } - if (struct.isSetNextSpanId()) { - oprot.writeI64(struct.nextSpanId); - } - if (struct.isSetDestinationId()) { - oprot.writeString(struct.destinationId); - } - if (struct.isSetApiId()) { - oprot.writeI32(struct.apiId); - } - if (struct.isSetExceptionInfo()) { - struct.exceptionInfo.write(oprot); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TSpanEvent struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(13); - if (incoming.get(0)) { - struct.spanId = iprot.readI64(); - struct.setSpanIdIsSet(true); - } - if (incoming.get(1)) { - struct.sequence = iprot.readI16(); - struct.setSequenceIsSet(true); - } - if (incoming.get(2)) { - struct.startElapsed = iprot.readI32(); - struct.setStartElapsedIsSet(true); - } - if (incoming.get(3)) { - struct.endElapsed = iprot.readI32(); - struct.setEndElapsedIsSet(true); - } - if (incoming.get(4)) { - struct.rpc = iprot.readString(); - struct.setRpcIsSet(true); - } - if (incoming.get(5)) { - struct.serviceType = iprot.readI16(); - struct.setServiceTypeIsSet(true); - } - if (incoming.get(6)) { - struct.endPoint = iprot.readString(); - struct.setEndPointIsSet(true); - } - if (incoming.get(7)) { - { - org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); - struct.annotations = new ArrayList(_list5.size); - for (int _i6 = 0; _i6 < _list5.size; ++_i6) - { - TAnnotation _elem7; - _elem7 = new TAnnotation(); - _elem7.read(iprot); - struct.annotations.add(_elem7); - } - } - struct.setAnnotationsIsSet(true); - } - if (incoming.get(8)) { - struct.depth = iprot.readI32(); - struct.setDepthIsSet(true); - } - if (incoming.get(9)) { - struct.nextSpanId = iprot.readI64(); - struct.setNextSpanIdIsSet(true); - } - if (incoming.get(10)) { - struct.destinationId = iprot.readString(); - struct.setDestinationIdIsSet(true); - } - if (incoming.get(11)) { - struct.apiId = iprot.readI32(); - struct.setApiIdIsSet(true); - } - if (incoming.get(12)) { - struct.exceptionInfo = new TIntStringValue(); - struct.exceptionInfo.read(iprot); - struct.setExceptionInfoIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TSpanEvent implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSpanEvent"); + + private static final org.apache.thrift.protocol.TField SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("spanId", org.apache.thrift.protocol.TType.I64, (short)7); + private static final org.apache.thrift.protocol.TField SEQUENCE_FIELD_DESC = new org.apache.thrift.protocol.TField("sequence", org.apache.thrift.protocol.TType.I16, (short)8); + private static final org.apache.thrift.protocol.TField START_ELAPSED_FIELD_DESC = new org.apache.thrift.protocol.TField("startElapsed", org.apache.thrift.protocol.TType.I32, (short)9); + private static final org.apache.thrift.protocol.TField END_ELAPSED_FIELD_DESC = new org.apache.thrift.protocol.TField("endElapsed", org.apache.thrift.protocol.TType.I32, (short)10); + private static final org.apache.thrift.protocol.TField RPC_FIELD_DESC = new org.apache.thrift.protocol.TField("rpc", org.apache.thrift.protocol.TType.STRING, (short)11); + private static final org.apache.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceType", org.apache.thrift.protocol.TType.I16, (short)12); + private static final org.apache.thrift.protocol.TField END_POINT_FIELD_DESC = new org.apache.thrift.protocol.TField("endPoint", org.apache.thrift.protocol.TType.STRING, (short)13); + private static final org.apache.thrift.protocol.TField ANNOTATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("annotations", org.apache.thrift.protocol.TType.LIST, (short)14); + private static final org.apache.thrift.protocol.TField DEPTH_FIELD_DESC = new org.apache.thrift.protocol.TField("depth", org.apache.thrift.protocol.TType.I32, (short)15); + private static final org.apache.thrift.protocol.TField NEXT_SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("nextSpanId", org.apache.thrift.protocol.TType.I64, (short)16); + private static final org.apache.thrift.protocol.TField DESTINATION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("destinationId", org.apache.thrift.protocol.TType.STRING, (short)20); + private static final org.apache.thrift.protocol.TField API_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("apiId", org.apache.thrift.protocol.TType.I32, (short)25); + private static final org.apache.thrift.protocol.TField EXCEPTION_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionInfo", org.apache.thrift.protocol.TType.STRUCT, (short)26); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TSpanEventStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TSpanEventTupleSchemeFactory()); + } + + private long spanId; // optional + private short sequence; // required + private int startElapsed; // required + private int endElapsed; // optional + private String rpc; // optional + private short serviceType; // required + private String endPoint; // optional + private List annotations; // optional + private int depth; // optional + private long nextSpanId; // optional + private String destinationId; // optional + private int apiId; // optional + private TIntStringValue exceptionInfo; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + SPAN_ID((short)7, "spanId"), + SEQUENCE((short)8, "sequence"), + START_ELAPSED((short)9, "startElapsed"), + END_ELAPSED((short)10, "endElapsed"), + RPC((short)11, "rpc"), + SERVICE_TYPE((short)12, "serviceType"), + END_POINT((short)13, "endPoint"), + ANNOTATIONS((short)14, "annotations"), + DEPTH((short)15, "depth"), + NEXT_SPAN_ID((short)16, "nextSpanId"), + DESTINATION_ID((short)20, "destinationId"), + API_ID((short)25, "apiId"), + EXCEPTION_INFO((short)26, "exceptionInfo"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 7: // SPAN_ID + return SPAN_ID; + case 8: // SEQUENCE + return SEQUENCE; + case 9: // START_ELAPSED + return START_ELAPSED; + case 10: // END_ELAPSED + return END_ELAPSED; + case 11: // RPC + return RPC; + case 12: // SERVICE_TYPE + return SERVICE_TYPE; + case 13: // END_POINT + return END_POINT; + case 14: // ANNOTATIONS + return ANNOTATIONS; + case 15: // DEPTH + return DEPTH; + case 16: // NEXT_SPAN_ID + return NEXT_SPAN_ID; + case 20: // DESTINATION_ID + return DESTINATION_ID; + case 25: // API_ID + return API_ID; + case 26: // EXCEPTION_INFO + return EXCEPTION_INFO; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __SPANID_ISSET_ID = 0; + private static final int __SEQUENCE_ISSET_ID = 1; + private static final int __STARTELAPSED_ISSET_ID = 2; + private static final int __ENDELAPSED_ISSET_ID = 3; + private static final int __SERVICETYPE_ISSET_ID = 4; + private static final int __DEPTH_ISSET_ID = 5; + private static final int __NEXTSPANID_ISSET_ID = 6; + private static final int __APIID_ISSET_ID = 7; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.SPAN_ID,_Fields.END_ELAPSED,_Fields.RPC,_Fields.END_POINT,_Fields.ANNOTATIONS,_Fields.DEPTH,_Fields.NEXT_SPAN_ID,_Fields.DESTINATION_ID,_Fields.API_ID,_Fields.EXCEPTION_INFO}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("spanId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.SEQUENCE, new org.apache.thrift.meta_data.FieldMetaData("sequence", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.START_ELAPSED, new org.apache.thrift.meta_data.FieldMetaData("startElapsed", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.END_ELAPSED, new org.apache.thrift.meta_data.FieldMetaData("endElapsed", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.RPC, new org.apache.thrift.meta_data.FieldMetaData("rpc", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("serviceType", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.END_POINT, new org.apache.thrift.meta_data.FieldMetaData("endPoint", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.ANNOTATIONS, new org.apache.thrift.meta_data.FieldMetaData("annotations", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAnnotation.class)))); + tmpMap.put(_Fields.DEPTH, new org.apache.thrift.meta_data.FieldMetaData("depth", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.NEXT_SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("nextSpanId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.DESTINATION_ID, new org.apache.thrift.meta_data.FieldMetaData("destinationId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.API_ID, new org.apache.thrift.meta_data.FieldMetaData("apiId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.EXCEPTION_INFO, new org.apache.thrift.meta_data.FieldMetaData("exceptionInfo", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIntStringValue.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpanEvent.class, metaDataMap); + } + + public TSpanEvent() { + this.endElapsed = 0; + + this.depth = -1; + + this.nextSpanId = -1L; + + } + + public TSpanEvent( + short sequence, + int startElapsed, + short serviceType) + { + this(); + this.sequence = sequence; + setSequenceIsSet(true); + this.startElapsed = startElapsed; + setStartElapsedIsSet(true); + this.serviceType = serviceType; + setServiceTypeIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public TSpanEvent(TSpanEvent other) { + __isset_bitfield = other.__isset_bitfield; + this.spanId = other.spanId; + this.sequence = other.sequence; + this.startElapsed = other.startElapsed; + this.endElapsed = other.endElapsed; + if (other.isSetRpc()) { + this.rpc = other.rpc; + } + this.serviceType = other.serviceType; + if (other.isSetEndPoint()) { + this.endPoint = other.endPoint; + } + if (other.isSetAnnotations()) { + List __this__annotations = new ArrayList(other.annotations.size()); + for (TAnnotation other_element : other.annotations) { + __this__annotations.add(new TAnnotation(other_element)); + } + this.annotations = __this__annotations; + } + this.depth = other.depth; + this.nextSpanId = other.nextSpanId; + if (other.isSetDestinationId()) { + this.destinationId = other.destinationId; + } + this.apiId = other.apiId; + if (other.isSetExceptionInfo()) { + this.exceptionInfo = new TIntStringValue(other.exceptionInfo); + } + } + + public TSpanEvent deepCopy() { + return new TSpanEvent(this); + } + + @Override + public void clear() { + setSpanIdIsSet(false); + this.spanId = 0; + setSequenceIsSet(false); + this.sequence = 0; + setStartElapsedIsSet(false); + this.startElapsed = 0; + this.endElapsed = 0; + + this.rpc = null; + setServiceTypeIsSet(false); + this.serviceType = 0; + this.endPoint = null; + this.annotations = null; + this.depth = -1; + + this.nextSpanId = -1L; + + this.destinationId = null; + setApiIdIsSet(false); + this.apiId = 0; + this.exceptionInfo = null; + } + + public long getSpanId() { + return this.spanId; + } + + public void setSpanId(long spanId) { + this.spanId = spanId; + setSpanIdIsSet(true); + } + + public void unsetSpanId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + /** Returns true if field spanId is set (has been assigned a value) and false otherwise */ + public boolean isSetSpanId() { + return EncodingUtils.testBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + public void setSpanIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SPANID_ISSET_ID, value); + } + + public short getSequence() { + return this.sequence; + } + + public void setSequence(short sequence) { + this.sequence = sequence; + setSequenceIsSet(true); + } + + public void unsetSequence() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SEQUENCE_ISSET_ID); + } + + /** Returns true if field sequence is set (has been assigned a value) and false otherwise */ + public boolean isSetSequence() { + return EncodingUtils.testBit(__isset_bitfield, __SEQUENCE_ISSET_ID); + } + + public void setSequenceIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SEQUENCE_ISSET_ID, value); + } + + public int getStartElapsed() { + return this.startElapsed; + } + + public void setStartElapsed(int startElapsed) { + this.startElapsed = startElapsed; + setStartElapsedIsSet(true); + } + + public void unsetStartElapsed() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTELAPSED_ISSET_ID); + } + + /** Returns true if field startElapsed is set (has been assigned a value) and false otherwise */ + public boolean isSetStartElapsed() { + return EncodingUtils.testBit(__isset_bitfield, __STARTELAPSED_ISSET_ID); + } + + public void setStartElapsedIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTELAPSED_ISSET_ID, value); + } + + public int getEndElapsed() { + return this.endElapsed; + } + + public void setEndElapsed(int endElapsed) { + this.endElapsed = endElapsed; + setEndElapsedIsSet(true); + } + + public void unsetEndElapsed() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENDELAPSED_ISSET_ID); + } + + /** Returns true if field endElapsed is set (has been assigned a value) and false otherwise */ + public boolean isSetEndElapsed() { + return EncodingUtils.testBit(__isset_bitfield, __ENDELAPSED_ISSET_ID); + } + + public void setEndElapsedIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENDELAPSED_ISSET_ID, value); + } + + public String getRpc() { + return this.rpc; + } + + public void setRpc(String rpc) { + this.rpc = rpc; + } + + public void unsetRpc() { + this.rpc = null; + } + + /** Returns true if field rpc is set (has been assigned a value) and false otherwise */ + public boolean isSetRpc() { + return this.rpc != null; + } + + public void setRpcIsSet(boolean value) { + if (!value) { + this.rpc = null; + } + } + + public short getServiceType() { + return this.serviceType; + } + + public void setServiceType(short serviceType) { + this.serviceType = serviceType; + setServiceTypeIsSet(true); + } + + public void unsetServiceType() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + /** Returns true if field serviceType is set (has been assigned a value) and false otherwise */ + public boolean isSetServiceType() { + return EncodingUtils.testBit(__isset_bitfield, __SERVICETYPE_ISSET_ID); + } + + public void setServiceTypeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPE_ISSET_ID, value); + } + + public String getEndPoint() { + return this.endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public void unsetEndPoint() { + this.endPoint = null; + } + + /** Returns true if field endPoint is set (has been assigned a value) and false otherwise */ + public boolean isSetEndPoint() { + return this.endPoint != null; + } + + public void setEndPointIsSet(boolean value) { + if (!value) { + this.endPoint = null; + } + } + + public int getAnnotationsSize() { + return (this.annotations == null) ? 0 : this.annotations.size(); + } + + public java.util.Iterator getAnnotationsIterator() { + return (this.annotations == null) ? null : this.annotations.iterator(); + } + + public void addToAnnotations(TAnnotation elem) { + if (this.annotations == null) { + this.annotations = new ArrayList(); + } + this.annotations.add(elem); + } + + public List getAnnotations() { + return this.annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + public void unsetAnnotations() { + this.annotations = null; + } + + /** Returns true if field annotations is set (has been assigned a value) and false otherwise */ + public boolean isSetAnnotations() { + return this.annotations != null; + } + + public void setAnnotationsIsSet(boolean value) { + if (!value) { + this.annotations = null; + } + } + + public int getDepth() { + return this.depth; + } + + public void setDepth(int depth) { + this.depth = depth; + setDepthIsSet(true); + } + + public void unsetDepth() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __DEPTH_ISSET_ID); + } + + /** Returns true if field depth is set (has been assigned a value) and false otherwise */ + public boolean isSetDepth() { + return EncodingUtils.testBit(__isset_bitfield, __DEPTH_ISSET_ID); + } + + public void setDepthIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __DEPTH_ISSET_ID, value); + } + + public long getNextSpanId() { + return this.nextSpanId; + } + + public void setNextSpanId(long nextSpanId) { + this.nextSpanId = nextSpanId; + setNextSpanIdIsSet(true); + } + + public void unsetNextSpanId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NEXTSPANID_ISSET_ID); + } + + /** Returns true if field nextSpanId is set (has been assigned a value) and false otherwise */ + public boolean isSetNextSpanId() { + return EncodingUtils.testBit(__isset_bitfield, __NEXTSPANID_ISSET_ID); + } + + public void setNextSpanIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NEXTSPANID_ISSET_ID, value); + } + + public String getDestinationId() { + return this.destinationId; + } + + public void setDestinationId(String destinationId) { + this.destinationId = destinationId; + } + + public void unsetDestinationId() { + this.destinationId = null; + } + + /** Returns true if field destinationId is set (has been assigned a value) and false otherwise */ + public boolean isSetDestinationId() { + return this.destinationId != null; + } + + public void setDestinationIdIsSet(boolean value) { + if (!value) { + this.destinationId = null; + } + } + + public int getApiId() { + return this.apiId; + } + + public void setApiId(int apiId) { + this.apiId = apiId; + setApiIdIsSet(true); + } + + public void unsetApiId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __APIID_ISSET_ID); + } + + /** Returns true if field apiId is set (has been assigned a value) and false otherwise */ + public boolean isSetApiId() { + return EncodingUtils.testBit(__isset_bitfield, __APIID_ISSET_ID); + } + + public void setApiIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __APIID_ISSET_ID, value); + } + + public TIntStringValue getExceptionInfo() { + return this.exceptionInfo; + } + + public void setExceptionInfo(TIntStringValue exceptionInfo) { + this.exceptionInfo = exceptionInfo; + } + + public void unsetExceptionInfo() { + this.exceptionInfo = null; + } + + /** Returns true if field exceptionInfo is set (has been assigned a value) and false otherwise */ + public boolean isSetExceptionInfo() { + return this.exceptionInfo != null; + } + + public void setExceptionInfoIsSet(boolean value) { + if (!value) { + this.exceptionInfo = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case SPAN_ID: + if (value == null) { + unsetSpanId(); + } else { + setSpanId((Long)value); + } + break; + + case SEQUENCE: + if (value == null) { + unsetSequence(); + } else { + setSequence((Short)value); + } + break; + + case START_ELAPSED: + if (value == null) { + unsetStartElapsed(); + } else { + setStartElapsed((Integer)value); + } + break; + + case END_ELAPSED: + if (value == null) { + unsetEndElapsed(); + } else { + setEndElapsed((Integer)value); + } + break; + + case RPC: + if (value == null) { + unsetRpc(); + } else { + setRpc((String)value); + } + break; + + case SERVICE_TYPE: + if (value == null) { + unsetServiceType(); + } else { + setServiceType((Short)value); + } + break; + + case END_POINT: + if (value == null) { + unsetEndPoint(); + } else { + setEndPoint((String)value); + } + break; + + case ANNOTATIONS: + if (value == null) { + unsetAnnotations(); + } else { + setAnnotations((List)value); + } + break; + + case DEPTH: + if (value == null) { + unsetDepth(); + } else { + setDepth((Integer)value); + } + break; + + case NEXT_SPAN_ID: + if (value == null) { + unsetNextSpanId(); + } else { + setNextSpanId((Long)value); + } + break; + + case DESTINATION_ID: + if (value == null) { + unsetDestinationId(); + } else { + setDestinationId((String)value); + } + break; + + case API_ID: + if (value == null) { + unsetApiId(); + } else { + setApiId((Integer)value); + } + break; + + case EXCEPTION_INFO: + if (value == null) { + unsetExceptionInfo(); + } else { + setExceptionInfo((TIntStringValue)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case SPAN_ID: + return Long.valueOf(getSpanId()); + + case SEQUENCE: + return Short.valueOf(getSequence()); + + case START_ELAPSED: + return Integer.valueOf(getStartElapsed()); + + case END_ELAPSED: + return Integer.valueOf(getEndElapsed()); + + case RPC: + return getRpc(); + + case SERVICE_TYPE: + return Short.valueOf(getServiceType()); + + case END_POINT: + return getEndPoint(); + + case ANNOTATIONS: + return getAnnotations(); + + case DEPTH: + return Integer.valueOf(getDepth()); + + case NEXT_SPAN_ID: + return Long.valueOf(getNextSpanId()); + + case DESTINATION_ID: + return getDestinationId(); + + case API_ID: + return Integer.valueOf(getApiId()); + + case EXCEPTION_INFO: + return getExceptionInfo(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case SPAN_ID: + return isSetSpanId(); + case SEQUENCE: + return isSetSequence(); + case START_ELAPSED: + return isSetStartElapsed(); + case END_ELAPSED: + return isSetEndElapsed(); + case RPC: + return isSetRpc(); + case SERVICE_TYPE: + return isSetServiceType(); + case END_POINT: + return isSetEndPoint(); + case ANNOTATIONS: + return isSetAnnotations(); + case DEPTH: + return isSetDepth(); + case NEXT_SPAN_ID: + return isSetNextSpanId(); + case DESTINATION_ID: + return isSetDestinationId(); + case API_ID: + return isSetApiId(); + case EXCEPTION_INFO: + return isSetExceptionInfo(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TSpanEvent) + return this.equals((TSpanEvent)that); + return false; + } + + public boolean equals(TSpanEvent that) { + if (that == null) + return false; + + boolean this_present_spanId = true && this.isSetSpanId(); + boolean that_present_spanId = true && that.isSetSpanId(); + if (this_present_spanId || that_present_spanId) { + if (!(this_present_spanId && that_present_spanId)) + return false; + if (this.spanId != that.spanId) + return false; + } + + boolean this_present_sequence = true; + boolean that_present_sequence = true; + if (this_present_sequence || that_present_sequence) { + if (!(this_present_sequence && that_present_sequence)) + return false; + if (this.sequence != that.sequence) + return false; + } + + boolean this_present_startElapsed = true; + boolean that_present_startElapsed = true; + if (this_present_startElapsed || that_present_startElapsed) { + if (!(this_present_startElapsed && that_present_startElapsed)) + return false; + if (this.startElapsed != that.startElapsed) + return false; + } + + boolean this_present_endElapsed = true && this.isSetEndElapsed(); + boolean that_present_endElapsed = true && that.isSetEndElapsed(); + if (this_present_endElapsed || that_present_endElapsed) { + if (!(this_present_endElapsed && that_present_endElapsed)) + return false; + if (this.endElapsed != that.endElapsed) + return false; + } + + boolean this_present_rpc = true && this.isSetRpc(); + boolean that_present_rpc = true && that.isSetRpc(); + if (this_present_rpc || that_present_rpc) { + if (!(this_present_rpc && that_present_rpc)) + return false; + if (!this.rpc.equals(that.rpc)) + return false; + } + + boolean this_present_serviceType = true; + boolean that_present_serviceType = true; + if (this_present_serviceType || that_present_serviceType) { + if (!(this_present_serviceType && that_present_serviceType)) + return false; + if (this.serviceType != that.serviceType) + return false; + } + + boolean this_present_endPoint = true && this.isSetEndPoint(); + boolean that_present_endPoint = true && that.isSetEndPoint(); + if (this_present_endPoint || that_present_endPoint) { + if (!(this_present_endPoint && that_present_endPoint)) + return false; + if (!this.endPoint.equals(that.endPoint)) + return false; + } + + boolean this_present_annotations = true && this.isSetAnnotations(); + boolean that_present_annotations = true && that.isSetAnnotations(); + if (this_present_annotations || that_present_annotations) { + if (!(this_present_annotations && that_present_annotations)) + return false; + if (!this.annotations.equals(that.annotations)) + return false; + } + + boolean this_present_depth = true && this.isSetDepth(); + boolean that_present_depth = true && that.isSetDepth(); + if (this_present_depth || that_present_depth) { + if (!(this_present_depth && that_present_depth)) + return false; + if (this.depth != that.depth) + return false; + } + + boolean this_present_nextSpanId = true && this.isSetNextSpanId(); + boolean that_present_nextSpanId = true && that.isSetNextSpanId(); + if (this_present_nextSpanId || that_present_nextSpanId) { + if (!(this_present_nextSpanId && that_present_nextSpanId)) + return false; + if (this.nextSpanId != that.nextSpanId) + return false; + } + + boolean this_present_destinationId = true && this.isSetDestinationId(); + boolean that_present_destinationId = true && that.isSetDestinationId(); + if (this_present_destinationId || that_present_destinationId) { + if (!(this_present_destinationId && that_present_destinationId)) + return false; + if (!this.destinationId.equals(that.destinationId)) + return false; + } + + boolean this_present_apiId = true && this.isSetApiId(); + boolean that_present_apiId = true && that.isSetApiId(); + if (this_present_apiId || that_present_apiId) { + if (!(this_present_apiId && that_present_apiId)) + return false; + if (this.apiId != that.apiId) + return false; + } + + boolean this_present_exceptionInfo = true && this.isSetExceptionInfo(); + boolean that_present_exceptionInfo = true && that.isSetExceptionInfo(); + if (this_present_exceptionInfo || that_present_exceptionInfo) { + if (!(this_present_exceptionInfo && that_present_exceptionInfo)) + return false; + if (!this.exceptionInfo.equals(that.exceptionInfo)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TSpanEvent other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetSpanId()).compareTo(other.isSetSpanId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSpanId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanId, other.spanId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSequence()).compareTo(other.isSetSequence()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSequence()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sequence, other.sequence); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStartElapsed()).compareTo(other.isSetStartElapsed()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStartElapsed()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startElapsed, other.startElapsed); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEndElapsed()).compareTo(other.isSetEndElapsed()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEndElapsed()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endElapsed, other.endElapsed); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRpc()).compareTo(other.isSetRpc()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRpc()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.rpc, other.rpc); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetServiceType()).compareTo(other.isSetServiceType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetServiceType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEndPoint()).compareTo(other.isSetEndPoint()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEndPoint()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endPoint, other.endPoint); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAnnotations()).compareTo(other.isSetAnnotations()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAnnotations()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.annotations, other.annotations); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetDepth()).compareTo(other.isSetDepth()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetDepth()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.depth, other.depth); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetNextSpanId()).compareTo(other.isSetNextSpanId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetNextSpanId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nextSpanId, other.nextSpanId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetDestinationId()).compareTo(other.isSetDestinationId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetDestinationId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.destinationId, other.destinationId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApiId()).compareTo(other.isSetApiId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApiId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.apiId, other.apiId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetExceptionInfo()).compareTo(other.isSetExceptionInfo()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetExceptionInfo()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exceptionInfo, other.exceptionInfo); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TSpanEvent("); + boolean first = true; + + if (isSetSpanId()) { + sb.append("spanId:"); + sb.append(this.spanId); + first = false; + } + if (!first) sb.append(", "); + sb.append("sequence:"); + sb.append(this.sequence); + first = false; + if (!first) sb.append(", "); + sb.append("startElapsed:"); + sb.append(this.startElapsed); + first = false; + if (isSetEndElapsed()) { + if (!first) sb.append(", "); + sb.append("endElapsed:"); + sb.append(this.endElapsed); + first = false; + } + if (isSetRpc()) { + if (!first) sb.append(", "); + sb.append("rpc:"); + if (this.rpc == null) { + sb.append("null"); + } else { + sb.append(this.rpc); + } + first = false; + } + if (!first) sb.append(", "); + sb.append("serviceType:"); + sb.append(this.serviceType); + first = false; + if (isSetEndPoint()) { + if (!first) sb.append(", "); + sb.append("endPoint:"); + if (this.endPoint == null) { + sb.append("null"); + } else { + sb.append(this.endPoint); + } + first = false; + } + if (isSetAnnotations()) { + if (!first) sb.append(", "); + sb.append("annotations:"); + if (this.annotations == null) { + sb.append("null"); + } else { + sb.append(this.annotations); + } + first = false; + } + if (isSetDepth()) { + if (!first) sb.append(", "); + sb.append("depth:"); + sb.append(this.depth); + first = false; + } + if (isSetNextSpanId()) { + if (!first) sb.append(", "); + sb.append("nextSpanId:"); + sb.append(this.nextSpanId); + first = false; + } + if (isSetDestinationId()) { + if (!first) sb.append(", "); + sb.append("destinationId:"); + if (this.destinationId == null) { + sb.append("null"); + } else { + sb.append(this.destinationId); + } + first = false; + } + if (isSetApiId()) { + if (!first) sb.append(", "); + sb.append("apiId:"); + sb.append(this.apiId); + first = false; + } + if (isSetExceptionInfo()) { + if (!first) sb.append(", "); + sb.append("exceptionInfo:"); + if (this.exceptionInfo == null) { + sb.append("null"); + } else { + sb.append(this.exceptionInfo); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + if (exceptionInfo != null) { + exceptionInfo.validate(); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TSpanEventStandardSchemeFactory implements SchemeFactory { + public TSpanEventStandardScheme getScheme() { + return new TSpanEventStandardScheme(); + } + } + + private static class TSpanEventStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TSpanEvent struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 7: // SPAN_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 8: // SEQUENCE + if (schemeField.type == org.apache.thrift.protocol.TType.I16) { + struct.sequence = iprot.readI16(); + struct.setSequenceIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 9: // START_ELAPSED + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.startElapsed = iprot.readI32(); + struct.setStartElapsedIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // END_ELAPSED + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.endElapsed = iprot.readI32(); + struct.setEndElapsedIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 11: // RPC + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.rpc = iprot.readString(); + struct.setRpcIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 12: // SERVICE_TYPE + if (schemeField.type == org.apache.thrift.protocol.TType.I16) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 13: // END_POINT + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.endPoint = iprot.readString(); + struct.setEndPointIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 14: // ANNOTATIONS + if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list0 = iprot.readListBegin(); + struct.annotations = new ArrayList(_list0.size); + for (int _i1 = 0; _i1 < _list0.size; ++_i1) + { + TAnnotation _elem2; + _elem2 = new TAnnotation(); + _elem2.read(iprot); + struct.annotations.add(_elem2); + } + iprot.readListEnd(); + } + struct.setAnnotationsIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 15: // DEPTH + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.depth = iprot.readI32(); + struct.setDepthIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 16: // NEXT_SPAN_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.nextSpanId = iprot.readI64(); + struct.setNextSpanIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 20: // DESTINATION_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.destinationId = iprot.readString(); + struct.setDestinationIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 25: // API_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.apiId = iprot.readI32(); + struct.setApiIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 26: // EXCEPTION_INFO + if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { + struct.exceptionInfo = new TIntStringValue(); + struct.exceptionInfo.read(iprot); + struct.setExceptionInfoIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TSpanEvent struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.isSetSpanId()) { + oprot.writeFieldBegin(SPAN_ID_FIELD_DESC); + oprot.writeI64(struct.spanId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(SEQUENCE_FIELD_DESC); + oprot.writeI16(struct.sequence); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(START_ELAPSED_FIELD_DESC); + oprot.writeI32(struct.startElapsed); + oprot.writeFieldEnd(); + if (struct.isSetEndElapsed()) { + oprot.writeFieldBegin(END_ELAPSED_FIELD_DESC); + oprot.writeI32(struct.endElapsed); + oprot.writeFieldEnd(); + } + if (struct.rpc != null) { + if (struct.isSetRpc()) { + oprot.writeFieldBegin(RPC_FIELD_DESC); + oprot.writeString(struct.rpc); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC); + oprot.writeI16(struct.serviceType); + oprot.writeFieldEnd(); + if (struct.endPoint != null) { + if (struct.isSetEndPoint()) { + oprot.writeFieldBegin(END_POINT_FIELD_DESC); + oprot.writeString(struct.endPoint); + oprot.writeFieldEnd(); + } + } + if (struct.annotations != null) { + if (struct.isSetAnnotations()) { + oprot.writeFieldBegin(ANNOTATIONS_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.annotations.size())); + for (TAnnotation _iter3 : struct.annotations) + { + _iter3.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + } + if (struct.isSetDepth()) { + oprot.writeFieldBegin(DEPTH_FIELD_DESC); + oprot.writeI32(struct.depth); + oprot.writeFieldEnd(); + } + if (struct.isSetNextSpanId()) { + oprot.writeFieldBegin(NEXT_SPAN_ID_FIELD_DESC); + oprot.writeI64(struct.nextSpanId); + oprot.writeFieldEnd(); + } + if (struct.destinationId != null) { + if (struct.isSetDestinationId()) { + oprot.writeFieldBegin(DESTINATION_ID_FIELD_DESC); + oprot.writeString(struct.destinationId); + oprot.writeFieldEnd(); + } + } + if (struct.isSetApiId()) { + oprot.writeFieldBegin(API_ID_FIELD_DESC); + oprot.writeI32(struct.apiId); + oprot.writeFieldEnd(); + } + if (struct.exceptionInfo != null) { + if (struct.isSetExceptionInfo()) { + oprot.writeFieldBegin(EXCEPTION_INFO_FIELD_DESC); + struct.exceptionInfo.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TSpanEventTupleSchemeFactory implements SchemeFactory { + public TSpanEventTupleScheme getScheme() { + return new TSpanEventTupleScheme(); + } + } + + private static class TSpanEventTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TSpanEvent struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetSpanId()) { + optionals.set(0); + } + if (struct.isSetSequence()) { + optionals.set(1); + } + if (struct.isSetStartElapsed()) { + optionals.set(2); + } + if (struct.isSetEndElapsed()) { + optionals.set(3); + } + if (struct.isSetRpc()) { + optionals.set(4); + } + if (struct.isSetServiceType()) { + optionals.set(5); + } + if (struct.isSetEndPoint()) { + optionals.set(6); + } + if (struct.isSetAnnotations()) { + optionals.set(7); + } + if (struct.isSetDepth()) { + optionals.set(8); + } + if (struct.isSetNextSpanId()) { + optionals.set(9); + } + if (struct.isSetDestinationId()) { + optionals.set(10); + } + if (struct.isSetApiId()) { + optionals.set(11); + } + if (struct.isSetExceptionInfo()) { + optionals.set(12); + } + oprot.writeBitSet(optionals, 13); + if (struct.isSetSpanId()) { + oprot.writeI64(struct.spanId); + } + if (struct.isSetSequence()) { + oprot.writeI16(struct.sequence); + } + if (struct.isSetStartElapsed()) { + oprot.writeI32(struct.startElapsed); + } + if (struct.isSetEndElapsed()) { + oprot.writeI32(struct.endElapsed); + } + if (struct.isSetRpc()) { + oprot.writeString(struct.rpc); + } + if (struct.isSetServiceType()) { + oprot.writeI16(struct.serviceType); + } + if (struct.isSetEndPoint()) { + oprot.writeString(struct.endPoint); + } + if (struct.isSetAnnotations()) { + { + oprot.writeI32(struct.annotations.size()); + for (TAnnotation _iter4 : struct.annotations) + { + _iter4.write(oprot); + } + } + } + if (struct.isSetDepth()) { + oprot.writeI32(struct.depth); + } + if (struct.isSetNextSpanId()) { + oprot.writeI64(struct.nextSpanId); + } + if (struct.isSetDestinationId()) { + oprot.writeString(struct.destinationId); + } + if (struct.isSetApiId()) { + oprot.writeI32(struct.apiId); + } + if (struct.isSetExceptionInfo()) { + struct.exceptionInfo.write(oprot); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TSpanEvent struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(13); + if (incoming.get(0)) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } + if (incoming.get(1)) { + struct.sequence = iprot.readI16(); + struct.setSequenceIsSet(true); + } + if (incoming.get(2)) { + struct.startElapsed = iprot.readI32(); + struct.setStartElapsedIsSet(true); + } + if (incoming.get(3)) { + struct.endElapsed = iprot.readI32(); + struct.setEndElapsedIsSet(true); + } + if (incoming.get(4)) { + struct.rpc = iprot.readString(); + struct.setRpcIsSet(true); + } + if (incoming.get(5)) { + struct.serviceType = iprot.readI16(); + struct.setServiceTypeIsSet(true); + } + if (incoming.get(6)) { + struct.endPoint = iprot.readString(); + struct.setEndPointIsSet(true); + } + if (incoming.get(7)) { + { + org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); + struct.annotations = new ArrayList(_list5.size); + for (int _i6 = 0; _i6 < _list5.size; ++_i6) + { + TAnnotation _elem7; + _elem7 = new TAnnotation(); + _elem7.read(iprot); + struct.annotations.add(_elem7); + } + } + struct.setAnnotationsIsSet(true); + } + if (incoming.get(8)) { + struct.depth = iprot.readI32(); + struct.setDepthIsSet(true); + } + if (incoming.get(9)) { + struct.nextSpanId = iprot.readI64(); + struct.setNextSpanIdIsSet(true); + } + if (incoming.get(10)) { + struct.destinationId = iprot.readString(); + struct.setDestinationIdIsSet(true); + } + if (incoming.get(11)) { + struct.apiId = iprot.readI32(); + struct.setApiIdIsSet(true); + } + if (incoming.get(12)) { + struct.exceptionInfo = new TIntStringValue(); + struct.exceptionInfo.read(iprot); + struct.setExceptionInfoIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSqlMetaData.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSqlMetaData.java index 21672542f5a5..953f7b810d70 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSqlMetaData.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSqlMetaData.java @@ -1,674 +1,674 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TSqlMetaData implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSqlMetaData"); - - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)2); - private static final org.apache.thrift.protocol.TField SQL_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("sqlId", org.apache.thrift.protocol.TType.I32, (short)4); - private static final org.apache.thrift.protocol.TField SQL_FIELD_DESC = new org.apache.thrift.protocol.TField("sql", org.apache.thrift.protocol.TType.STRING, (short)5); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TSqlMetaDataStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TSqlMetaDataTupleSchemeFactory()); - } - - private String agentId; // required - private long agentStartTime; // required - private int sqlId; // required - private String sql; // required - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - AGENT_ID((short)1, "agentId"), - AGENT_START_TIME((short)2, "agentStartTime"), - SQL_ID((short)4, "sqlId"), - SQL((short)5, "sql"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // AGENT_ID - return AGENT_ID; - case 2: // AGENT_START_TIME - return AGENT_START_TIME; - case 4: // SQL_ID - return SQL_ID; - case 5: // SQL - return SQL; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __AGENTSTARTTIME_ISSET_ID = 0; - private static final int __SQLID_ISSET_ID = 1; - private byte __isset_bitfield = 0; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.SQL_ID, new org.apache.thrift.meta_data.FieldMetaData("sqlId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.SQL, new org.apache.thrift.meta_data.FieldMetaData("sql", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSqlMetaData.class, metaDataMap); - } - - public TSqlMetaData() { - } - - public TSqlMetaData( - String agentId, - long agentStartTime, - int sqlId, - String sql) - { - this(); - this.agentId = agentId; - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - this.sqlId = sqlId; - setSqlIdIsSet(true); - this.sql = sql; - } - - /** - * Performs a deep copy on other. - */ - public TSqlMetaData(TSqlMetaData other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - this.agentStartTime = other.agentStartTime; - this.sqlId = other.sqlId; - if (other.isSetSql()) { - this.sql = other.sql; - } - } - - public TSqlMetaData deepCopy() { - return new TSqlMetaData(this); - } - - @Override - public void clear() { - this.agentId = null; - setAgentStartTimeIsSet(false); - this.agentStartTime = 0; - setSqlIdIsSet(false); - this.sqlId = 0; - this.sql = null; - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public long getAgentStartTime() { - return this.agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - } - - public void unsetAgentStartTime() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentStartTime() { - return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - public void setAgentStartTimeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); - } - - public int getSqlId() { - return this.sqlId; - } - - public void setSqlId(int sqlId) { - this.sqlId = sqlId; - setSqlIdIsSet(true); - } - - public void unsetSqlId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SQLID_ISSET_ID); - } - - /** Returns true if field sqlId is set (has been assigned a value) and false otherwise */ - public boolean isSetSqlId() { - return EncodingUtils.testBit(__isset_bitfield, __SQLID_ISSET_ID); - } - - public void setSqlIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SQLID_ISSET_ID, value); - } - - public String getSql() { - return this.sql; - } - - public void setSql(String sql) { - this.sql = sql; - } - - public void unsetSql() { - this.sql = null; - } - - /** Returns true if field sql is set (has been assigned a value) and false otherwise */ - public boolean isSetSql() { - return this.sql != null; - } - - public void setSqlIsSet(boolean value) { - if (!value) { - this.sql = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case AGENT_START_TIME: - if (value == null) { - unsetAgentStartTime(); - } else { - setAgentStartTime((Long)value); - } - break; - - case SQL_ID: - if (value == null) { - unsetSqlId(); - } else { - setSqlId((Integer)value); - } - break; - - case SQL: - if (value == null) { - unsetSql(); - } else { - setSql((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case AGENT_ID: - return getAgentId(); - - case AGENT_START_TIME: - return Long.valueOf(getAgentStartTime()); - - case SQL_ID: - return Integer.valueOf(getSqlId()); - - case SQL: - return getSql(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case AGENT_ID: - return isSetAgentId(); - case AGENT_START_TIME: - return isSetAgentStartTime(); - case SQL_ID: - return isSetSqlId(); - case SQL: - return isSetSql(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TSqlMetaData) - return this.equals((TSqlMetaData)that); - return false; - } - - public boolean equals(TSqlMetaData that) { - if (that == null) - return false; - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_agentStartTime = true; - boolean that_present_agentStartTime = true; - if (this_present_agentStartTime || that_present_agentStartTime) { - if (!(this_present_agentStartTime && that_present_agentStartTime)) - return false; - if (this.agentStartTime != that.agentStartTime) - return false; - } - - boolean this_present_sqlId = true; - boolean that_present_sqlId = true; - if (this_present_sqlId || that_present_sqlId) { - if (!(this_present_sqlId && that_present_sqlId)) - return false; - if (this.sqlId != that.sqlId) - return false; - } - - boolean this_present_sql = true && this.isSetSql(); - boolean that_present_sql = true && that.isSetSql(); - if (this_present_sql || that_present_sql) { - if (!(this_present_sql && that_present_sql)) - return false; - if (!this.sql.equals(that.sql)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TSqlMetaData other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentStartTime()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSqlId()).compareTo(other.isSetSqlId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSqlId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sqlId, other.sqlId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetSql()).compareTo(other.isSetSql()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSql()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sql, other.sql); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TSqlMetaData("); - boolean first = true; - - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - if (!first) sb.append(", "); - sb.append("agentStartTime:"); - sb.append(this.agentStartTime); - first = false; - if (!first) sb.append(", "); - sb.append("sqlId:"); - sb.append(this.sqlId); - first = false; - if (!first) sb.append(", "); - sb.append("sql:"); - if (this.sql == null) { - sb.append("null"); - } else { - sb.append(this.sql); - } - first = false; - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TSqlMetaDataStandardSchemeFactory implements SchemeFactory { - public TSqlMetaDataStandardScheme getScheme() { - return new TSqlMetaDataStandardScheme(); - } - } - - private static class TSqlMetaDataStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TSqlMetaData struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // AGENT_START_TIME - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 4: // SQL_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.sqlId = iprot.readI32(); - struct.setSqlIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 5: // SQL - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.sql = iprot.readString(); - struct.setSqlIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TSqlMetaData struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.agentId != null) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); - oprot.writeI64(struct.agentStartTime); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(SQL_ID_FIELD_DESC); - oprot.writeI32(struct.sqlId); - oprot.writeFieldEnd(); - if (struct.sql != null) { - oprot.writeFieldBegin(SQL_FIELD_DESC); - oprot.writeString(struct.sql); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TSqlMetaDataTupleSchemeFactory implements SchemeFactory { - public TSqlMetaDataTupleScheme getScheme() { - return new TSqlMetaDataTupleScheme(); - } - } - - private static class TSqlMetaDataTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TSqlMetaData struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetAgentId()) { - optionals.set(0); - } - if (struct.isSetAgentStartTime()) { - optionals.set(1); - } - if (struct.isSetSqlId()) { - optionals.set(2); - } - if (struct.isSetSql()) { - optionals.set(3); - } - oprot.writeBitSet(optionals, 4); - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetAgentStartTime()) { - oprot.writeI64(struct.agentStartTime); - } - if (struct.isSetSqlId()) { - oprot.writeI32(struct.sqlId); - } - if (struct.isSetSql()) { - oprot.writeString(struct.sql); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TSqlMetaData struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(4); - if (incoming.get(0)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(1)) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } - if (incoming.get(2)) { - struct.sqlId = iprot.readI32(); - struct.setSqlIdIsSet(true); - } - if (incoming.get(3)) { - struct.sql = iprot.readString(); - struct.setSqlIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TSqlMetaData implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSqlMetaData"); + + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)2); + private static final org.apache.thrift.protocol.TField SQL_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("sqlId", org.apache.thrift.protocol.TType.I32, (short)4); + private static final org.apache.thrift.protocol.TField SQL_FIELD_DESC = new org.apache.thrift.protocol.TField("sql", org.apache.thrift.protocol.TType.STRING, (short)5); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TSqlMetaDataStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TSqlMetaDataTupleSchemeFactory()); + } + + private String agentId; // required + private long agentStartTime; // required + private int sqlId; // required + private String sql; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + AGENT_ID((short)1, "agentId"), + AGENT_START_TIME((short)2, "agentStartTime"), + SQL_ID((short)4, "sqlId"), + SQL((short)5, "sql"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // AGENT_ID + return AGENT_ID; + case 2: // AGENT_START_TIME + return AGENT_START_TIME; + case 4: // SQL_ID + return SQL_ID; + case 5: // SQL + return SQL; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __AGENTSTARTTIME_ISSET_ID = 0; + private static final int __SQLID_ISSET_ID = 1; + private byte __isset_bitfield = 0; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.SQL_ID, new org.apache.thrift.meta_data.FieldMetaData("sqlId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.SQL, new org.apache.thrift.meta_data.FieldMetaData("sql", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSqlMetaData.class, metaDataMap); + } + + public TSqlMetaData() { + } + + public TSqlMetaData( + String agentId, + long agentStartTime, + int sqlId, + String sql) + { + this(); + this.agentId = agentId; + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + this.sqlId = sqlId; + setSqlIdIsSet(true); + this.sql = sql; + } + + /** + * Performs a deep copy on other. + */ + public TSqlMetaData(TSqlMetaData other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + this.agentStartTime = other.agentStartTime; + this.sqlId = other.sqlId; + if (other.isSetSql()) { + this.sql = other.sql; + } + } + + public TSqlMetaData deepCopy() { + return new TSqlMetaData(this); + } + + @Override + public void clear() { + this.agentId = null; + setAgentStartTimeIsSet(false); + this.agentStartTime = 0; + setSqlIdIsSet(false); + this.sqlId = 0; + this.sql = null; + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public long getAgentStartTime() { + return this.agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + } + + public void unsetAgentStartTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentStartTime() { + return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + public void setAgentStartTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); + } + + public int getSqlId() { + return this.sqlId; + } + + public void setSqlId(int sqlId) { + this.sqlId = sqlId; + setSqlIdIsSet(true); + } + + public void unsetSqlId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SQLID_ISSET_ID); + } + + /** Returns true if field sqlId is set (has been assigned a value) and false otherwise */ + public boolean isSetSqlId() { + return EncodingUtils.testBit(__isset_bitfield, __SQLID_ISSET_ID); + } + + public void setSqlIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SQLID_ISSET_ID, value); + } + + public String getSql() { + return this.sql; + } + + public void setSql(String sql) { + this.sql = sql; + } + + public void unsetSql() { + this.sql = null; + } + + /** Returns true if field sql is set (has been assigned a value) and false otherwise */ + public boolean isSetSql() { + return this.sql != null; + } + + public void setSqlIsSet(boolean value) { + if (!value) { + this.sql = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case AGENT_START_TIME: + if (value == null) { + unsetAgentStartTime(); + } else { + setAgentStartTime((Long)value); + } + break; + + case SQL_ID: + if (value == null) { + unsetSqlId(); + } else { + setSqlId((Integer)value); + } + break; + + case SQL: + if (value == null) { + unsetSql(); + } else { + setSql((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case AGENT_ID: + return getAgentId(); + + case AGENT_START_TIME: + return Long.valueOf(getAgentStartTime()); + + case SQL_ID: + return Integer.valueOf(getSqlId()); + + case SQL: + return getSql(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case AGENT_ID: + return isSetAgentId(); + case AGENT_START_TIME: + return isSetAgentStartTime(); + case SQL_ID: + return isSetSqlId(); + case SQL: + return isSetSql(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TSqlMetaData) + return this.equals((TSqlMetaData)that); + return false; + } + + public boolean equals(TSqlMetaData that) { + if (that == null) + return false; + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_agentStartTime = true; + boolean that_present_agentStartTime = true; + if (this_present_agentStartTime || that_present_agentStartTime) { + if (!(this_present_agentStartTime && that_present_agentStartTime)) + return false; + if (this.agentStartTime != that.agentStartTime) + return false; + } + + boolean this_present_sqlId = true; + boolean that_present_sqlId = true; + if (this_present_sqlId || that_present_sqlId) { + if (!(this_present_sqlId && that_present_sqlId)) + return false; + if (this.sqlId != that.sqlId) + return false; + } + + boolean this_present_sql = true && this.isSetSql(); + boolean that_present_sql = true && that.isSetSql(); + if (this_present_sql || that_present_sql) { + if (!(this_present_sql && that_present_sql)) + return false; + if (!this.sql.equals(that.sql)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TSqlMetaData other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSqlId()).compareTo(other.isSetSqlId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSqlId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sqlId, other.sqlId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSql()).compareTo(other.isSetSql()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSql()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sql, other.sql); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TSqlMetaData("); + boolean first = true; + + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentStartTime:"); + sb.append(this.agentStartTime); + first = false; + if (!first) sb.append(", "); + sb.append("sqlId:"); + sb.append(this.sqlId); + first = false; + if (!first) sb.append(", "); + sb.append("sql:"); + if (this.sql == null) { + sb.append("null"); + } else { + sb.append(this.sql); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TSqlMetaDataStandardSchemeFactory implements SchemeFactory { + public TSqlMetaDataStandardScheme getScheme() { + return new TSqlMetaDataStandardScheme(); + } + } + + private static class TSqlMetaDataStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TSqlMetaData struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // AGENT_START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // SQL_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.sqlId = iprot.readI32(); + struct.setSqlIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 5: // SQL + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.sql = iprot.readString(); + struct.setSqlIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TSqlMetaData struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); + oprot.writeI64(struct.agentStartTime); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(SQL_ID_FIELD_DESC); + oprot.writeI32(struct.sqlId); + oprot.writeFieldEnd(); + if (struct.sql != null) { + oprot.writeFieldBegin(SQL_FIELD_DESC); + oprot.writeString(struct.sql); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TSqlMetaDataTupleSchemeFactory implements SchemeFactory { + public TSqlMetaDataTupleScheme getScheme() { + return new TSqlMetaDataTupleScheme(); + } + } + + private static class TSqlMetaDataTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TSqlMetaData struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetAgentId()) { + optionals.set(0); + } + if (struct.isSetAgentStartTime()) { + optionals.set(1); + } + if (struct.isSetSqlId()) { + optionals.set(2); + } + if (struct.isSetSql()) { + optionals.set(3); + } + oprot.writeBitSet(optionals, 4); + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetAgentStartTime()) { + oprot.writeI64(struct.agentStartTime); + } + if (struct.isSetSqlId()) { + oprot.writeI32(struct.sqlId); + } + if (struct.isSetSql()) { + oprot.writeString(struct.sql); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TSqlMetaData struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(4); + if (incoming.get(0)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(1)) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } + if (incoming.get(2)) { + struct.sqlId = iprot.readI32(); + struct.setSqlIdIsSet(true); + } + if (incoming.get(3)) { + struct.sql = iprot.readString(); + struct.setSqlIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TStringMetaData.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TStringMetaData.java index d56823373e8b..ee223b4c3777 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TStringMetaData.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TStringMetaData.java @@ -1,674 +1,674 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TStringMetaData implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TStringMetaData"); - - private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)2); - private static final org.apache.thrift.protocol.TField STRING_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("stringId", org.apache.thrift.protocol.TType.I32, (short)4); - private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)5); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TStringMetaDataStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TStringMetaDataTupleSchemeFactory()); - } - - private String agentId; // required - private long agentStartTime; // required - private int stringId; // required - private String stringValue; // required - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - AGENT_ID((short)1, "agentId"), - AGENT_START_TIME((short)2, "agentStartTime"), - STRING_ID((short)4, "stringId"), - STRING_VALUE((short)5, "stringValue"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // AGENT_ID - return AGENT_ID; - case 2: // AGENT_START_TIME - return AGENT_START_TIME; - case 4: // STRING_ID - return STRING_ID; - case 5: // STRING_VALUE - return STRING_VALUE; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __AGENTSTARTTIME_ISSET_ID = 0; - private static final int __STRINGID_ISSET_ID = 1; - private byte __isset_bitfield = 0; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - tmpMap.put(_Fields.STRING_ID, new org.apache.thrift.meta_data.FieldMetaData("stringId", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); - tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TStringMetaData.class, metaDataMap); - } - - public TStringMetaData() { - } - - public TStringMetaData( - String agentId, - long agentStartTime, - int stringId, - String stringValue) - { - this(); - this.agentId = agentId; - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - this.stringId = stringId; - setStringIdIsSet(true); - this.stringValue = stringValue; - } - - /** - * Performs a deep copy on other. - */ - public TStringMetaData(TStringMetaData other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetAgentId()) { - this.agentId = other.agentId; - } - this.agentStartTime = other.agentStartTime; - this.stringId = other.stringId; - if (other.isSetStringValue()) { - this.stringValue = other.stringValue; - } - } - - public TStringMetaData deepCopy() { - return new TStringMetaData(this); - } - - @Override - public void clear() { - this.agentId = null; - setAgentStartTimeIsSet(false); - this.agentStartTime = 0; - setStringIdIsSet(false); - this.stringId = 0; - this.stringValue = null; - } - - public String getAgentId() { - return this.agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public void unsetAgentId() { - this.agentId = null; - } - - /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentId() { - return this.agentId != null; - } - - public void setAgentIdIsSet(boolean value) { - if (!value) { - this.agentId = null; - } - } - - public long getAgentStartTime() { - return this.agentStartTime; - } - - public void setAgentStartTime(long agentStartTime) { - this.agentStartTime = agentStartTime; - setAgentStartTimeIsSet(true); - } - - public void unsetAgentStartTime() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ - public boolean isSetAgentStartTime() { - return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); - } - - public void setAgentStartTimeIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); - } - - public int getStringId() { - return this.stringId; - } - - public void setStringId(int stringId) { - this.stringId = stringId; - setStringIdIsSet(true); - } - - public void unsetStringId() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STRINGID_ISSET_ID); - } - - /** Returns true if field stringId is set (has been assigned a value) and false otherwise */ - public boolean isSetStringId() { - return EncodingUtils.testBit(__isset_bitfield, __STRINGID_ISSET_ID); - } - - public void setStringIdIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STRINGID_ISSET_ID, value); - } - - public String getStringValue() { - return this.stringValue; - } - - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - public void unsetStringValue() { - this.stringValue = null; - } - - /** Returns true if field stringValue is set (has been assigned a value) and false otherwise */ - public boolean isSetStringValue() { - return this.stringValue != null; - } - - public void setStringValueIsSet(boolean value) { - if (!value) { - this.stringValue = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case AGENT_ID: - if (value == null) { - unsetAgentId(); - } else { - setAgentId((String)value); - } - break; - - case AGENT_START_TIME: - if (value == null) { - unsetAgentStartTime(); - } else { - setAgentStartTime((Long)value); - } - break; - - case STRING_ID: - if (value == null) { - unsetStringId(); - } else { - setStringId((Integer)value); - } - break; - - case STRING_VALUE: - if (value == null) { - unsetStringValue(); - } else { - setStringValue((String)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case AGENT_ID: - return getAgentId(); - - case AGENT_START_TIME: - return Long.valueOf(getAgentStartTime()); - - case STRING_ID: - return Integer.valueOf(getStringId()); - - case STRING_VALUE: - return getStringValue(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case AGENT_ID: - return isSetAgentId(); - case AGENT_START_TIME: - return isSetAgentStartTime(); - case STRING_ID: - return isSetStringId(); - case STRING_VALUE: - return isSetStringValue(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TStringMetaData) - return this.equals((TStringMetaData)that); - return false; - } - - public boolean equals(TStringMetaData that) { - if (that == null) - return false; - - boolean this_present_agentId = true && this.isSetAgentId(); - boolean that_present_agentId = true && that.isSetAgentId(); - if (this_present_agentId || that_present_agentId) { - if (!(this_present_agentId && that_present_agentId)) - return false; - if (!this.agentId.equals(that.agentId)) - return false; - } - - boolean this_present_agentStartTime = true; - boolean that_present_agentStartTime = true; - if (this_present_agentStartTime || that_present_agentStartTime) { - if (!(this_present_agentStartTime && that_present_agentStartTime)) - return false; - if (this.agentStartTime != that.agentStartTime) - return false; - } - - boolean this_present_stringId = true; - boolean that_present_stringId = true; - if (this_present_stringId || that_present_stringId) { - if (!(this_present_stringId && that_present_stringId)) - return false; - if (this.stringId != that.stringId) - return false; - } - - boolean this_present_stringValue = true && this.isSetStringValue(); - boolean that_present_stringValue = true && that.isSetStringValue(); - if (this_present_stringValue || that_present_stringValue) { - if (!(this_present_stringValue && that_present_stringValue)) - return false; - if (!this.stringValue.equals(that.stringValue)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TStringMetaData other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetAgentStartTime()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStringId()).compareTo(other.isSetStringId()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStringId()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringId, other.stringId); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetStringValue()).compareTo(other.isSetStringValue()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetStringValue()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue, other.stringValue); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TStringMetaData("); - boolean first = true; - - sb.append("agentId:"); - if (this.agentId == null) { - sb.append("null"); - } else { - sb.append(this.agentId); - } - first = false; - if (!first) sb.append(", "); - sb.append("agentStartTime:"); - sb.append(this.agentStartTime); - first = false; - if (!first) sb.append(", "); - sb.append("stringId:"); - sb.append(this.stringId); - first = false; - if (!first) sb.append(", "); - sb.append("stringValue:"); - if (this.stringValue == null) { - sb.append("null"); - } else { - sb.append(this.stringValue); - } - first = false; - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TStringMetaDataStandardSchemeFactory implements SchemeFactory { - public TStringMetaDataStandardScheme getScheme() { - return new TStringMetaDataStandardScheme(); - } - } - - private static class TStringMetaDataStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TStringMetaData struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // AGENT_ID - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // AGENT_START_TIME - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 4: // STRING_ID - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.stringId = iprot.readI32(); - struct.setStringIdIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 5: // STRING_VALUE - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.stringValue = iprot.readString(); - struct.setStringValueIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TStringMetaData struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.agentId != null) { - oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); - oprot.writeString(struct.agentId); - oprot.writeFieldEnd(); - } - oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); - oprot.writeI64(struct.agentStartTime); - oprot.writeFieldEnd(); - oprot.writeFieldBegin(STRING_ID_FIELD_DESC); - oprot.writeI32(struct.stringId); - oprot.writeFieldEnd(); - if (struct.stringValue != null) { - oprot.writeFieldBegin(STRING_VALUE_FIELD_DESC); - oprot.writeString(struct.stringValue); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TStringMetaDataTupleSchemeFactory implements SchemeFactory { - public TStringMetaDataTupleScheme getScheme() { - return new TStringMetaDataTupleScheme(); - } - } - - private static class TStringMetaDataTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TStringMetaData struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetAgentId()) { - optionals.set(0); - } - if (struct.isSetAgentStartTime()) { - optionals.set(1); - } - if (struct.isSetStringId()) { - optionals.set(2); - } - if (struct.isSetStringValue()) { - optionals.set(3); - } - oprot.writeBitSet(optionals, 4); - if (struct.isSetAgentId()) { - oprot.writeString(struct.agentId); - } - if (struct.isSetAgentStartTime()) { - oprot.writeI64(struct.agentStartTime); - } - if (struct.isSetStringId()) { - oprot.writeI32(struct.stringId); - } - if (struct.isSetStringValue()) { - oprot.writeString(struct.stringValue); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TStringMetaData struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(4); - if (incoming.get(0)) { - struct.agentId = iprot.readString(); - struct.setAgentIdIsSet(true); - } - if (incoming.get(1)) { - struct.agentStartTime = iprot.readI64(); - struct.setAgentStartTimeIsSet(true); - } - if (incoming.get(2)) { - struct.stringId = iprot.readI32(); - struct.setStringIdIsSet(true); - } - if (incoming.get(3)) { - struct.stringValue = iprot.readString(); - struct.setStringValueIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TStringMetaData implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TStringMetaData"); + + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short)2); + private static final org.apache.thrift.protocol.TField STRING_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("stringId", org.apache.thrift.protocol.TType.I32, (short)4); + private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)5); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TStringMetaDataStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TStringMetaDataTupleSchemeFactory()); + } + + private String agentId; // required + private long agentStartTime; // required + private int stringId; // required + private String stringValue; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + AGENT_ID((short)1, "agentId"), + AGENT_START_TIME((short)2, "agentStartTime"), + STRING_ID((short)4, "stringId"), + STRING_VALUE((short)5, "stringValue"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // AGENT_ID + return AGENT_ID; + case 2: // AGENT_START_TIME + return AGENT_START_TIME; + case 4: // STRING_ID + return STRING_ID; + case 5: // STRING_VALUE + return STRING_VALUE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __AGENTSTARTTIME_ISSET_ID = 0; + private static final int __STRINGID_ISSET_ID = 1; + private byte __isset_bitfield = 0; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.STRING_ID, new org.apache.thrift.meta_data.FieldMetaData("stringId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TStringMetaData.class, metaDataMap); + } + + public TStringMetaData() { + } + + public TStringMetaData( + String agentId, + long agentStartTime, + int stringId, + String stringValue) + { + this(); + this.agentId = agentId; + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + this.stringId = stringId; + setStringIdIsSet(true); + this.stringValue = stringValue; + } + + /** + * Performs a deep copy on other. + */ + public TStringMetaData(TStringMetaData other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + this.agentStartTime = other.agentStartTime; + this.stringId = other.stringId; + if (other.isSetStringValue()) { + this.stringValue = other.stringValue; + } + } + + public TStringMetaData deepCopy() { + return new TStringMetaData(this); + } + + @Override + public void clear() { + this.agentId = null; + setAgentStartTimeIsSet(false); + this.agentStartTime = 0; + setStringIdIsSet(false); + this.stringId = 0; + this.stringValue = null; + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public long getAgentStartTime() { + return this.agentStartTime; + } + + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + } + + public void unsetAgentStartTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentStartTime() { + return EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + public void setAgentStartTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); + } + + public int getStringId() { + return this.stringId; + } + + public void setStringId(int stringId) { + this.stringId = stringId; + setStringIdIsSet(true); + } + + public void unsetStringId() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STRINGID_ISSET_ID); + } + + /** Returns true if field stringId is set (has been assigned a value) and false otherwise */ + public boolean isSetStringId() { + return EncodingUtils.testBit(__isset_bitfield, __STRINGID_ISSET_ID); + } + + public void setStringIdIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STRINGID_ISSET_ID, value); + } + + public String getStringValue() { + return this.stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + public void unsetStringValue() { + this.stringValue = null; + } + + /** Returns true if field stringValue is set (has been assigned a value) and false otherwise */ + public boolean isSetStringValue() { + return this.stringValue != null; + } + + public void setStringValueIsSet(boolean value) { + if (!value) { + this.stringValue = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case AGENT_START_TIME: + if (value == null) { + unsetAgentStartTime(); + } else { + setAgentStartTime((Long)value); + } + break; + + case STRING_ID: + if (value == null) { + unsetStringId(); + } else { + setStringId((Integer)value); + } + break; + + case STRING_VALUE: + if (value == null) { + unsetStringValue(); + } else { + setStringValue((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case AGENT_ID: + return getAgentId(); + + case AGENT_START_TIME: + return Long.valueOf(getAgentStartTime()); + + case STRING_ID: + return Integer.valueOf(getStringId()); + + case STRING_VALUE: + return getStringValue(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case AGENT_ID: + return isSetAgentId(); + case AGENT_START_TIME: + return isSetAgentStartTime(); + case STRING_ID: + return isSetStringId(); + case STRING_VALUE: + return isSetStringValue(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TStringMetaData) + return this.equals((TStringMetaData)that); + return false; + } + + public boolean equals(TStringMetaData that) { + if (that == null) + return false; + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_agentStartTime = true; + boolean that_present_agentStartTime = true; + if (this_present_agentStartTime || that_present_agentStartTime) { + if (!(this_present_agentStartTime && that_present_agentStartTime)) + return false; + if (this.agentStartTime != that.agentStartTime) + return false; + } + + boolean this_present_stringId = true; + boolean that_present_stringId = true; + if (this_present_stringId || that_present_stringId) { + if (!(this_present_stringId && that_present_stringId)) + return false; + if (this.stringId != that.stringId) + return false; + } + + boolean this_present_stringValue = true && this.isSetStringValue(); + boolean that_present_stringValue = true && that.isSetStringValue(); + if (this_present_stringValue || that_present_stringValue) { + if (!(this_present_stringValue && that_present_stringValue)) + return false; + if (!this.stringValue.equals(that.stringValue)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TStringMetaData other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStringId()).compareTo(other.isSetStringId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStringId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringId, other.stringId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStringValue()).compareTo(other.isSetStringValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStringValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue, other.stringValue); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TStringMetaData("); + boolean first = true; + + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentStartTime:"); + sb.append(this.agentStartTime); + first = false; + if (!first) sb.append(", "); + sb.append("stringId:"); + sb.append(this.stringId); + first = false; + if (!first) sb.append(", "); + sb.append("stringValue:"); + if (this.stringValue == null) { + sb.append("null"); + } else { + sb.append(this.stringValue); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TStringMetaDataStandardSchemeFactory implements SchemeFactory { + public TStringMetaDataStandardScheme getScheme() { + return new TStringMetaDataStandardScheme(); + } + } + + private static class TStringMetaDataStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TStringMetaData struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // AGENT_START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // STRING_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.stringId = iprot.readI32(); + struct.setStringIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 5: // STRING_VALUE + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.stringValue = iprot.readString(); + struct.setStringValueIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TStringMetaData struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); + oprot.writeI64(struct.agentStartTime); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(STRING_ID_FIELD_DESC); + oprot.writeI32(struct.stringId); + oprot.writeFieldEnd(); + if (struct.stringValue != null) { + oprot.writeFieldBegin(STRING_VALUE_FIELD_DESC); + oprot.writeString(struct.stringValue); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TStringMetaDataTupleSchemeFactory implements SchemeFactory { + public TStringMetaDataTupleScheme getScheme() { + return new TStringMetaDataTupleScheme(); + } + } + + private static class TStringMetaDataTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TStringMetaData struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetAgentId()) { + optionals.set(0); + } + if (struct.isSetAgentStartTime()) { + optionals.set(1); + } + if (struct.isSetStringId()) { + optionals.set(2); + } + if (struct.isSetStringValue()) { + optionals.set(3); + } + oprot.writeBitSet(optionals, 4); + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetAgentStartTime()) { + oprot.writeI64(struct.agentStartTime); + } + if (struct.isSetStringId()) { + oprot.writeI32(struct.stringId); + } + if (struct.isSetStringValue()) { + oprot.writeString(struct.stringValue); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TStringMetaData struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(4); + if (incoming.get(0)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(1)) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } + if (incoming.get(2)) { + struct.stringId = iprot.readI32(); + struct.setStringIdIsSet(true); + } + if (incoming.get(3)) { + struct.stringValue = iprot.readString(); + struct.setStringValueIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandEcho.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandEcho.java new file mode 100644 index 000000000000..406c516ce9c1 --- /dev/null +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandEcho.java @@ -0,0 +1,385 @@ +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto.command; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TCommandEcho implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TCommandEcho"); + + private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("message", org.apache.thrift.protocol.TType.STRING, (short)1); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TCommandEchoStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TCommandEchoTupleSchemeFactory()); + } + + private String message; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + MESSAGE((short)1, "message"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // MESSAGE + return MESSAGE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("message", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TCommandEcho.class, metaDataMap); + } + + public TCommandEcho() { + } + + public TCommandEcho( + String message) + { + this(); + this.message = message; + } + + /** + * Performs a deep copy on other. + */ + public TCommandEcho(TCommandEcho other) { + if (other.isSetMessage()) { + this.message = other.message; + } + } + + public TCommandEcho deepCopy() { + return new TCommandEcho(this); + } + + @Override + public void clear() { + this.message = null; + } + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + + public void unsetMessage() { + this.message = null; + } + + /** Returns true if field message is set (has been assigned a value) and false otherwise */ + public boolean isSetMessage() { + return this.message != null; + } + + public void setMessageIsSet(boolean value) { + if (!value) { + this.message = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case MESSAGE: + if (value == null) { + unsetMessage(); + } else { + setMessage((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case MESSAGE: + return getMessage(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case MESSAGE: + return isSetMessage(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TCommandEcho) + return this.equals((TCommandEcho)that); + return false; + } + + public boolean equals(TCommandEcho that) { + if (that == null) + return false; + + boolean this_present_message = true && this.isSetMessage(); + boolean that_present_message = true && that.isSetMessage(); + if (this_present_message || that_present_message) { + if (!(this_present_message && that_present_message)) + return false; + if (!this.message.equals(that.message)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TCommandEcho other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetMessage()).compareTo(other.isSetMessage()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetMessage()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, other.message); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TCommandEcho("); + boolean first = true; + + sb.append("message:"); + if (this.message == null) { + sb.append("null"); + } else { + sb.append(this.message); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TCommandEchoStandardSchemeFactory implements SchemeFactory { + public TCommandEchoStandardScheme getScheme() { + return new TCommandEchoStandardScheme(); + } + } + + private static class TCommandEchoStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TCommandEcho struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // MESSAGE + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.message = iprot.readString(); + struct.setMessageIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TCommandEcho struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.message != null) { + oprot.writeFieldBegin(MESSAGE_FIELD_DESC); + oprot.writeString(struct.message); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TCommandEchoTupleSchemeFactory implements SchemeFactory { + public TCommandEchoTupleScheme getScheme() { + return new TCommandEchoTupleScheme(); + } + } + + private static class TCommandEchoTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TCommandEcho struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetMessage()) { + optionals.set(0); + } + oprot.writeBitSet(optionals, 1); + if (struct.isSetMessage()) { + oprot.writeString(struct.message); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TCommandEcho struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(1); + if (incoming.get(0)) { + struct.message = iprot.readString(); + struct.setMessageIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandThreadDump.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandThreadDump.java index 42ff435b2da2..bbd346ca6ffc 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandThreadDump.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandThreadDump.java @@ -1,600 +1,600 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto.command; - -import org.apache.thrift.scheme.IScheme; -import org.apache.thrift.scheme.SchemeFactory; -import org.apache.thrift.scheme.StandardScheme; - -import org.apache.thrift.scheme.TupleScheme; -import org.apache.thrift.protocol.TTupleProtocol; -import org.apache.thrift.protocol.TProtocolException; -import org.apache.thrift.EncodingUtils; -import org.apache.thrift.TException; -import org.apache.thrift.async.AsyncMethodCallback; -import org.apache.thrift.server.AbstractNonblockingServer.*; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.EnumMap; -import java.util.Set; -import java.util.HashSet; -import java.util.EnumSet; -import java.util.Collections; -import java.util.BitSet; -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TCommandThreadDump implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TCommandThreadDump"); - - private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)1); - private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)2); - private static final org.apache.thrift.protocol.TField PENDING_TIME_MILLIS_FIELD_DESC = new org.apache.thrift.protocol.TField("pendingTimeMillis", org.apache.thrift.protocol.TType.I64, (short)3); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new TCommandThreadDumpStandardSchemeFactory()); - schemes.put(TupleScheme.class, new TCommandThreadDumpTupleSchemeFactory()); - } - - private TThreadDumpType type; // required - private String name; // optional - private long pendingTimeMillis; // optional - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - /** - * - * @see TThreadDumpType - */ - TYPE((short)1, "type"), - NAME((short)2, "name"), - PENDING_TIME_MILLIS((short)3, "pendingTimeMillis"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // TYPE - return TYPE; - case 2: // NAME - return NAME; - case 3: // PENDING_TIME_MILLIS - return PENDING_TIME_MILLIS; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - private static final int __PENDINGTIMEMILLIS_ISSET_ID = 0; - private byte __isset_bitfield = 0; - private _Fields optionals[] = {_Fields.NAME,_Fields.PENDING_TIME_MILLIS}; - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TThreadDumpType.class))); - tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); - tmpMap.put(_Fields.PENDING_TIME_MILLIS, new org.apache.thrift.meta_data.FieldMetaData("pendingTimeMillis", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TCommandThreadDump.class, metaDataMap); - } - - public TCommandThreadDump() { - this.type = com.nhn.pinpoint.thrift.dto.command.TThreadDumpType.TARGET; - - } - - public TCommandThreadDump( - TThreadDumpType type) - { - this(); - this.type = type; - } - - /** - * Performs a deep copy on other. - */ - public TCommandThreadDump(TCommandThreadDump other) { - __isset_bitfield = other.__isset_bitfield; - if (other.isSetType()) { - this.type = other.type; - } - if (other.isSetName()) { - this.name = other.name; - } - this.pendingTimeMillis = other.pendingTimeMillis; - } - - public TCommandThreadDump deepCopy() { - return new TCommandThreadDump(this); - } - - @Override - public void clear() { - this.type = com.nhn.pinpoint.thrift.dto.command.TThreadDumpType.TARGET; - - this.name = null; - setPendingTimeMillisIsSet(false); - this.pendingTimeMillis = 0; - } - - /** - * - * @see TThreadDumpType - */ - public TThreadDumpType getType() { - return this.type; - } - - /** - * - * @see TThreadDumpType - */ - public void setType(TThreadDumpType type) { - this.type = type; - } - - public void unsetType() { - this.type = null; - } - - /** Returns true if field type is set (has been assigned a value) and false otherwise */ - public boolean isSetType() { - return this.type != null; - } - - public void setTypeIsSet(boolean value) { - if (!value) { - this.type = null; - } - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public void unsetName() { - this.name = null; - } - - /** Returns true if field name is set (has been assigned a value) and false otherwise */ - public boolean isSetName() { - return this.name != null; - } - - public void setNameIsSet(boolean value) { - if (!value) { - this.name = null; - } - } - - public long getPendingTimeMillis() { - return this.pendingTimeMillis; - } - - public void setPendingTimeMillis(long pendingTimeMillis) { - this.pendingTimeMillis = pendingTimeMillis; - setPendingTimeMillisIsSet(true); - } - - public void unsetPendingTimeMillis() { - __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PENDINGTIMEMILLIS_ISSET_ID); - } - - /** Returns true if field pendingTimeMillis is set (has been assigned a value) and false otherwise */ - public boolean isSetPendingTimeMillis() { - return EncodingUtils.testBit(__isset_bitfield, __PENDINGTIMEMILLIS_ISSET_ID); - } - - public void setPendingTimeMillisIsSet(boolean value) { - __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PENDINGTIMEMILLIS_ISSET_ID, value); - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case TYPE: - if (value == null) { - unsetType(); - } else { - setType((TThreadDumpType)value); - } - break; - - case NAME: - if (value == null) { - unsetName(); - } else { - setName((String)value); - } - break; - - case PENDING_TIME_MILLIS: - if (value == null) { - unsetPendingTimeMillis(); - } else { - setPendingTimeMillis((Long)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case TYPE: - return getType(); - - case NAME: - return getName(); - - case PENDING_TIME_MILLIS: - return Long.valueOf(getPendingTimeMillis()); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case TYPE: - return isSetType(); - case NAME: - return isSetName(); - case PENDING_TIME_MILLIS: - return isSetPendingTimeMillis(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof TCommandThreadDump) - return this.equals((TCommandThreadDump)that); - return false; - } - - public boolean equals(TCommandThreadDump that) { - if (that == null) - return false; - - boolean this_present_type = true && this.isSetType(); - boolean that_present_type = true && that.isSetType(); - if (this_present_type || that_present_type) { - if (!(this_present_type && that_present_type)) - return false; - if (!this.type.equals(that.type)) - return false; - } - - boolean this_present_name = true && this.isSetName(); - boolean that_present_name = true && that.isSetName(); - if (this_present_name || that_present_name) { - if (!(this_present_name && that_present_name)) - return false; - if (!this.name.equals(that.name)) - return false; - } - - boolean this_present_pendingTimeMillis = true && this.isSetPendingTimeMillis(); - boolean that_present_pendingTimeMillis = true && that.isSetPendingTimeMillis(); - if (this_present_pendingTimeMillis || that_present_pendingTimeMillis) { - if (!(this_present_pendingTimeMillis && that_present_pendingTimeMillis)) - return false; - if (this.pendingTimeMillis != that.pendingTimeMillis) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public int compareTo(TCommandThreadDump other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - - lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetType()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetName()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetPendingTimeMillis()).compareTo(other.isSetPendingTimeMillis()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetPendingTimeMillis()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pendingTimeMillis, other.pendingTimeMillis); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TCommandThreadDump("); - boolean first = true; - - sb.append("type:"); - if (this.type == null) { - sb.append("null"); - } else { - sb.append(this.type); - } - first = false; - if (isSetName()) { - if (!first) sb.append(", "); - sb.append("name:"); - if (this.name == null) { - sb.append("null"); - } else { - sb.append(this.name); - } - first = false; - } - if (isSetPendingTimeMillis()) { - if (!first) sb.append(", "); - sb.append("pendingTimeMillis:"); - sb.append(this.pendingTimeMillis); - first = false; - } - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - // check for sub-struct validity - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bitfield = 0; - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class TCommandThreadDumpStandardSchemeFactory implements SchemeFactory { - public TCommandThreadDumpStandardScheme getScheme() { - return new TCommandThreadDumpStandardScheme(); - } - } - - private static class TCommandThreadDumpStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, TCommandThreadDump struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // TYPE - if (schemeField.type == org.apache.thrift.protocol.TType.I32) { - struct.type = TThreadDumpType.findByValue(iprot.readI32()); - struct.setTypeIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // NAME - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.name = iprot.readString(); - struct.setNameIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // PENDING_TIME_MILLIS - if (schemeField.type == org.apache.thrift.protocol.TType.I64) { - struct.pendingTimeMillis = iprot.readI64(); - struct.setPendingTimeMillisIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, TCommandThreadDump struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.type != null) { - oprot.writeFieldBegin(TYPE_FIELD_DESC); - oprot.writeI32(struct.type.getValue()); - oprot.writeFieldEnd(); - } - if (struct.name != null) { - if (struct.isSetName()) { - oprot.writeFieldBegin(NAME_FIELD_DESC); - oprot.writeString(struct.name); - oprot.writeFieldEnd(); - } - } - if (struct.isSetPendingTimeMillis()) { - oprot.writeFieldBegin(PENDING_TIME_MILLIS_FIELD_DESC); - oprot.writeI64(struct.pendingTimeMillis); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class TCommandThreadDumpTupleSchemeFactory implements SchemeFactory { - public TCommandThreadDumpTupleScheme getScheme() { - return new TCommandThreadDumpTupleScheme(); - } - } - - private static class TCommandThreadDumpTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, TCommandThreadDump struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetType()) { - optionals.set(0); - } - if (struct.isSetName()) { - optionals.set(1); - } - if (struct.isSetPendingTimeMillis()) { - optionals.set(2); - } - oprot.writeBitSet(optionals, 3); - if (struct.isSetType()) { - oprot.writeI32(struct.type.getValue()); - } - if (struct.isSetName()) { - oprot.writeString(struct.name); - } - if (struct.isSetPendingTimeMillis()) { - oprot.writeI64(struct.pendingTimeMillis); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, TCommandThreadDump struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(3); - if (incoming.get(0)) { - struct.type = TThreadDumpType.findByValue(iprot.readI32()); - struct.setTypeIsSet(true); - } - if (incoming.get(1)) { - struct.name = iprot.readString(); - struct.setNameIsSet(true); - } - if (incoming.get(2)) { - struct.pendingTimeMillis = iprot.readI64(); - struct.setPendingTimeMillisIsSet(true); - } - } - } - -} - +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto.command; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TCommandThreadDump implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TCommandThreadDump"); + + private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField PENDING_TIME_MILLIS_FIELD_DESC = new org.apache.thrift.protocol.TField("pendingTimeMillis", org.apache.thrift.protocol.TType.I64, (short)3); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TCommandThreadDumpStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TCommandThreadDumpTupleSchemeFactory()); + } + + private TThreadDumpType type; // required + private String name; // optional + private long pendingTimeMillis; // optional + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + /** + * + * @see TThreadDumpType + */ + TYPE((short)1, "type"), + NAME((short)2, "name"), + PENDING_TIME_MILLIS((short)3, "pendingTimeMillis"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // TYPE + return TYPE; + case 2: // NAME + return NAME; + case 3: // PENDING_TIME_MILLIS + return PENDING_TIME_MILLIS; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __PENDINGTIMEMILLIS_ISSET_ID = 0; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.NAME,_Fields.PENDING_TIME_MILLIS}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TThreadDumpType.class))); + tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.PENDING_TIME_MILLIS, new org.apache.thrift.meta_data.FieldMetaData("pendingTimeMillis", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TCommandThreadDump.class, metaDataMap); + } + + public TCommandThreadDump() { + this.type = com.nhn.pinpoint.thrift.dto.command.TThreadDumpType.TARGET; + + } + + public TCommandThreadDump( + TThreadDumpType type) + { + this(); + this.type = type; + } + + /** + * Performs a deep copy on other. + */ + public TCommandThreadDump(TCommandThreadDump other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetType()) { + this.type = other.type; + } + if (other.isSetName()) { + this.name = other.name; + } + this.pendingTimeMillis = other.pendingTimeMillis; + } + + public TCommandThreadDump deepCopy() { + return new TCommandThreadDump(this); + } + + @Override + public void clear() { + this.type = com.nhn.pinpoint.thrift.dto.command.TThreadDumpType.TARGET; + + this.name = null; + setPendingTimeMillisIsSet(false); + this.pendingTimeMillis = 0; + } + + /** + * + * @see TThreadDumpType + */ + public TThreadDumpType getType() { + return this.type; + } + + /** + * + * @see TThreadDumpType + */ + public void setType(TThreadDumpType type) { + this.type = type; + } + + public void unsetType() { + this.type = null; + } + + /** Returns true if field type is set (has been assigned a value) and false otherwise */ + public boolean isSetType() { + return this.type != null; + } + + public void setTypeIsSet(boolean value) { + if (!value) { + this.type = null; + } + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public void unsetName() { + this.name = null; + } + + /** Returns true if field name is set (has been assigned a value) and false otherwise */ + public boolean isSetName() { + return this.name != null; + } + + public void setNameIsSet(boolean value) { + if (!value) { + this.name = null; + } + } + + public long getPendingTimeMillis() { + return this.pendingTimeMillis; + } + + public void setPendingTimeMillis(long pendingTimeMillis) { + this.pendingTimeMillis = pendingTimeMillis; + setPendingTimeMillisIsSet(true); + } + + public void unsetPendingTimeMillis() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PENDINGTIMEMILLIS_ISSET_ID); + } + + /** Returns true if field pendingTimeMillis is set (has been assigned a value) and false otherwise */ + public boolean isSetPendingTimeMillis() { + return EncodingUtils.testBit(__isset_bitfield, __PENDINGTIMEMILLIS_ISSET_ID); + } + + public void setPendingTimeMillisIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PENDINGTIMEMILLIS_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case TYPE: + if (value == null) { + unsetType(); + } else { + setType((TThreadDumpType)value); + } + break; + + case NAME: + if (value == null) { + unsetName(); + } else { + setName((String)value); + } + break; + + case PENDING_TIME_MILLIS: + if (value == null) { + unsetPendingTimeMillis(); + } else { + setPendingTimeMillis((Long)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case TYPE: + return getType(); + + case NAME: + return getName(); + + case PENDING_TIME_MILLIS: + return Long.valueOf(getPendingTimeMillis()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case TYPE: + return isSetType(); + case NAME: + return isSetName(); + case PENDING_TIME_MILLIS: + return isSetPendingTimeMillis(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TCommandThreadDump) + return this.equals((TCommandThreadDump)that); + return false; + } + + public boolean equals(TCommandThreadDump that) { + if (that == null) + return false; + + boolean this_present_type = true && this.isSetType(); + boolean that_present_type = true && that.isSetType(); + if (this_present_type || that_present_type) { + if (!(this_present_type && that_present_type)) + return false; + if (!this.type.equals(that.type)) + return false; + } + + boolean this_present_name = true && this.isSetName(); + boolean that_present_name = true && that.isSetName(); + if (this_present_name || that_present_name) { + if (!(this_present_name && that_present_name)) + return false; + if (!this.name.equals(that.name)) + return false; + } + + boolean this_present_pendingTimeMillis = true && this.isSetPendingTimeMillis(); + boolean that_present_pendingTimeMillis = true && that.isSetPendingTimeMillis(); + if (this_present_pendingTimeMillis || that_present_pendingTimeMillis) { + if (!(this_present_pendingTimeMillis && that_present_pendingTimeMillis)) + return false; + if (this.pendingTimeMillis != that.pendingTimeMillis) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TCommandThreadDump other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPendingTimeMillis()).compareTo(other.isSetPendingTimeMillis()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPendingTimeMillis()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pendingTimeMillis, other.pendingTimeMillis); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TCommandThreadDump("); + boolean first = true; + + sb.append("type:"); + if (this.type == null) { + sb.append("null"); + } else { + sb.append(this.type); + } + first = false; + if (isSetName()) { + if (!first) sb.append(", "); + sb.append("name:"); + if (this.name == null) { + sb.append("null"); + } else { + sb.append(this.name); + } + first = false; + } + if (isSetPendingTimeMillis()) { + if (!first) sb.append(", "); + sb.append("pendingTimeMillis:"); + sb.append(this.pendingTimeMillis); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TCommandThreadDumpStandardSchemeFactory implements SchemeFactory { + public TCommandThreadDumpStandardScheme getScheme() { + return new TCommandThreadDumpStandardScheme(); + } + } + + private static class TCommandThreadDumpStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TCommandThreadDump struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // TYPE + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.type = TThreadDumpType.findByValue(iprot.readI32()); + struct.setTypeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.name = iprot.readString(); + struct.setNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // PENDING_TIME_MILLIS + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.pendingTimeMillis = iprot.readI64(); + struct.setPendingTimeMillisIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TCommandThreadDump struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.type != null) { + oprot.writeFieldBegin(TYPE_FIELD_DESC); + oprot.writeI32(struct.type.getValue()); + oprot.writeFieldEnd(); + } + if (struct.name != null) { + if (struct.isSetName()) { + oprot.writeFieldBegin(NAME_FIELD_DESC); + oprot.writeString(struct.name); + oprot.writeFieldEnd(); + } + } + if (struct.isSetPendingTimeMillis()) { + oprot.writeFieldBegin(PENDING_TIME_MILLIS_FIELD_DESC); + oprot.writeI64(struct.pendingTimeMillis); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TCommandThreadDumpTupleSchemeFactory implements SchemeFactory { + public TCommandThreadDumpTupleScheme getScheme() { + return new TCommandThreadDumpTupleScheme(); + } + } + + private static class TCommandThreadDumpTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TCommandThreadDump struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetType()) { + optionals.set(0); + } + if (struct.isSetName()) { + optionals.set(1); + } + if (struct.isSetPendingTimeMillis()) { + optionals.set(2); + } + oprot.writeBitSet(optionals, 3); + if (struct.isSetType()) { + oprot.writeI32(struct.type.getValue()); + } + if (struct.isSetName()) { + oprot.writeString(struct.name); + } + if (struct.isSetPendingTimeMillis()) { + oprot.writeI64(struct.pendingTimeMillis); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TCommandThreadDump struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(3); + if (incoming.get(0)) { + struct.type = TThreadDumpType.findByValue(iprot.readI32()); + struct.setTypeIsSet(true); + } + if (incoming.get(1)) { + struct.name = iprot.readString(); + struct.setNameIsSet(true); + } + if (incoming.get(2)) { + struct.pendingTimeMillis = iprot.readI64(); + struct.setPendingTimeMillisIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandTransfer.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandTransfer.java new file mode 100644 index 000000000000..6221e9c06630 --- /dev/null +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TCommandTransfer.java @@ -0,0 +1,692 @@ +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto.command; + +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.SchemeFactory; +import org.apache.thrift.scheme.StandardScheme; + +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.protocol.TTupleProtocol; +import org.apache.thrift.protocol.TProtocolException; +import org.apache.thrift.EncodingUtils; +import org.apache.thrift.TException; +import org.apache.thrift.async.AsyncMethodCallback; +import org.apache.thrift.server.AbstractNonblockingServer.*; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TCommandTransfer implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TCommandTransfer"); + + private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("startTime", org.apache.thrift.protocol.TType.I64, (short)3); + private static final org.apache.thrift.protocol.TField PAYLOAD_FIELD_DESC = new org.apache.thrift.protocol.TField("payload", org.apache.thrift.protocol.TType.STRING, (short)4); + + private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); + static { + schemes.put(StandardScheme.class, new TCommandTransferStandardSchemeFactory()); + schemes.put(TupleScheme.class, new TCommandTransferTupleSchemeFactory()); + } + + private String applicationName; // required + private String agentId; // required + private long startTime; // optional + private ByteBuffer payload; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + APPLICATION_NAME((short)1, "applicationName"), + AGENT_ID((short)2, "agentId"), + START_TIME((short)3, "startTime"), + PAYLOAD((short)4, "payload"); + + private static final Map byName = new HashMap(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // APPLICATION_NAME + return APPLICATION_NAME; + case 2: // AGENT_ID + return AGENT_ID; + case 3: // START_TIME + return START_TIME; + case 4: // PAYLOAD + return PAYLOAD; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __STARTTIME_ISSET_ID = 0; + private byte __isset_bitfield = 0; + private _Fields optionals[] = {_Fields.START_TIME}; + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.START_TIME, new org.apache.thrift.meta_data.FieldMetaData("startTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.PAYLOAD, new org.apache.thrift.meta_data.FieldMetaData("payload", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TCommandTransfer.class, metaDataMap); + } + + public TCommandTransfer() { + } + + public TCommandTransfer( + String applicationName, + String agentId, + ByteBuffer payload) + { + this(); + this.applicationName = applicationName; + this.agentId = agentId; + this.payload = payload; + } + + /** + * Performs a deep copy on other. + */ + public TCommandTransfer(TCommandTransfer other) { + __isset_bitfield = other.__isset_bitfield; + if (other.isSetApplicationName()) { + this.applicationName = other.applicationName; + } + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + this.startTime = other.startTime; + if (other.isSetPayload()) { + this.payload = org.apache.thrift.TBaseHelper.copyBinary(other.payload); +; + } + } + + public TCommandTransfer deepCopy() { + return new TCommandTransfer(this); + } + + @Override + public void clear() { + this.applicationName = null; + this.agentId = null; + setStartTimeIsSet(false); + this.startTime = 0; + this.payload = null; + } + + public String getApplicationName() { + return this.applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public void unsetApplicationName() { + this.applicationName = null; + } + + /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ + public boolean isSetApplicationName() { + return this.applicationName != null; + } + + public void setApplicationNameIsSet(boolean value) { + if (!value) { + this.applicationName = null; + } + } + + public String getAgentId() { + return this.agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + public long getStartTime() { + return this.startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + setStartTimeIsSet(true); + } + + public void unsetStartTime() { + __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTTIME_ISSET_ID); + } + + /** Returns true if field startTime is set (has been assigned a value) and false otherwise */ + public boolean isSetStartTime() { + return EncodingUtils.testBit(__isset_bitfield, __STARTTIME_ISSET_ID); + } + + public void setStartTimeIsSet(boolean value) { + __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTTIME_ISSET_ID, value); + } + + public byte[] getPayload() { + setPayload(org.apache.thrift.TBaseHelper.rightSize(payload)); + return payload == null ? null : payload.array(); + } + + public ByteBuffer bufferForPayload() { + return payload; + } + + public void setPayload(byte[] payload) { + setPayload(payload == null ? (ByteBuffer)null : ByteBuffer.wrap(payload)); + } + + public void setPayload(ByteBuffer payload) { + this.payload = payload; + } + + public void unsetPayload() { + this.payload = null; + } + + /** Returns true if field payload is set (has been assigned a value) and false otherwise */ + public boolean isSetPayload() { + return this.payload != null; + } + + public void setPayloadIsSet(boolean value) { + if (!value) { + this.payload = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case APPLICATION_NAME: + if (value == null) { + unsetApplicationName(); + } else { + setApplicationName((String)value); + } + break; + + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String)value); + } + break; + + case START_TIME: + if (value == null) { + unsetStartTime(); + } else { + setStartTime((Long)value); + } + break; + + case PAYLOAD: + if (value == null) { + unsetPayload(); + } else { + setPayload((ByteBuffer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case APPLICATION_NAME: + return getApplicationName(); + + case AGENT_ID: + return getAgentId(); + + case START_TIME: + return Long.valueOf(getStartTime()); + + case PAYLOAD: + return getPayload(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case APPLICATION_NAME: + return isSetApplicationName(); + case AGENT_ID: + return isSetAgentId(); + case START_TIME: + return isSetStartTime(); + case PAYLOAD: + return isSetPayload(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TCommandTransfer) + return this.equals((TCommandTransfer)that); + return false; + } + + public boolean equals(TCommandTransfer that) { + if (that == null) + return false; + + boolean this_present_applicationName = true && this.isSetApplicationName(); + boolean that_present_applicationName = true && that.isSetApplicationName(); + if (this_present_applicationName || that_present_applicationName) { + if (!(this_present_applicationName && that_present_applicationName)) + return false; + if (!this.applicationName.equals(that.applicationName)) + return false; + } + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_startTime = true && this.isSetStartTime(); + boolean that_present_startTime = true && that.isSetStartTime(); + if (this_present_startTime || that_present_startTime) { + if (!(this_present_startTime && that_present_startTime)) + return false; + if (this.startTime != that.startTime) + return false; + } + + boolean this_present_payload = true && this.isSetPayload(); + boolean that_present_payload = true && that.isSetPayload(); + if (this_present_payload || that_present_payload) { + if (!(this_present_payload && that_present_payload)) + return false; + if (!this.payload.equals(that.payload)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int compareTo(TCommandTransfer other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApplicationName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStartTime()).compareTo(other.isSetStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startTime, other.startTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPayload()).compareTo(other.isSetPayload()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPayload()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.payload, other.payload); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + schemes.get(iprot.getScheme()).getScheme().read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + schemes.get(oprot.getScheme()).getScheme().write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TCommandTransfer("); + boolean first = true; + + sb.append("applicationName:"); + if (this.applicationName == null) { + sb.append("null"); + } else { + sb.append(this.applicationName); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (isSetStartTime()) { + if (!first) sb.append(", "); + sb.append("startTime:"); + sb.append(this.startTime); + first = false; + } + if (!first) sb.append(", "); + sb.append("payload:"); + if (this.payload == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.payload, sb); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TCommandTransferStandardSchemeFactory implements SchemeFactory { + public TCommandTransferStandardScheme getScheme() { + return new TCommandTransferStandardScheme(); + } + } + + private static class TCommandTransferStandardScheme extends StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TCommandTransfer struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) + { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // APPLICATION_NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.startTime = iprot.readI64(); + struct.setStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // PAYLOAD + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.payload = iprot.readBinary(); + struct.setPayloadIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TCommandTransfer struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.applicationName != null) { + oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); + oprot.writeString(struct.applicationName); + oprot.writeFieldEnd(); + } + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + if (struct.isSetStartTime()) { + oprot.writeFieldBegin(START_TIME_FIELD_DESC); + oprot.writeI64(struct.startTime); + oprot.writeFieldEnd(); + } + if (struct.payload != null) { + oprot.writeFieldBegin(PAYLOAD_FIELD_DESC); + oprot.writeBinary(struct.payload); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TCommandTransferTupleSchemeFactory implements SchemeFactory { + public TCommandTransferTupleScheme getScheme() { + return new TCommandTransferTupleScheme(); + } + } + + private static class TCommandTransferTupleScheme extends TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TCommandTransfer struct) throws org.apache.thrift.TException { + TTupleProtocol oprot = (TTupleProtocol) prot; + BitSet optionals = new BitSet(); + if (struct.isSetApplicationName()) { + optionals.set(0); + } + if (struct.isSetAgentId()) { + optionals.set(1); + } + if (struct.isSetStartTime()) { + optionals.set(2); + } + if (struct.isSetPayload()) { + optionals.set(3); + } + oprot.writeBitSet(optionals, 4); + if (struct.isSetApplicationName()) { + oprot.writeString(struct.applicationName); + } + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetStartTime()) { + oprot.writeI64(struct.startTime); + } + if (struct.isSetPayload()) { + oprot.writeBinary(struct.payload); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TCommandTransfer struct) throws org.apache.thrift.TException { + TTupleProtocol iprot = (TTupleProtocol) prot; + BitSet incoming = iprot.readBitSet(4); + if (incoming.get(0)) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } + if (incoming.get(1)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(2)) { + struct.startTime = iprot.readI64(); + struct.setStartTimeIsSet(true); + } + if (incoming.get(3)) { + struct.payload = iprot.readBinary(); + struct.setPayloadIsSet(true); + } + } + } + +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TThreadDumpType.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TThreadDumpType.java index c112cb6fea7e..08130d22d8a6 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TThreadDumpType.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/command/TThreadDumpType.java @@ -1,45 +1,45 @@ -/** - * Autogenerated by Thrift Compiler (0.9.1) - * - * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING - * @generated - */ -package com.nhn.pinpoint.thrift.dto.command; - - -import java.util.Map; -import java.util.HashMap; -import org.apache.thrift.TEnum; - -public enum TThreadDumpType implements org.apache.thrift.TEnum { - TARGET(0), - PENDING(1); - - private final int value; - - private TThreadDumpType(int value) { - this.value = value; - } - - /** - * Get the integer value of this enum value, as defined in the Thrift IDL. - */ - public int getValue() { - return value; - } - - /** - * Find a the enum type by its integer value, as defined in the Thrift IDL. - * @return null if the value is not found. - */ - public static TThreadDumpType findByValue(int value) { - switch (value) { - case 0: - return TARGET; - case 1: - return PENDING; - default: - return null; - } - } -} +/** + * Autogenerated by Thrift Compiler (0.9.1) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ +package com.nhn.pinpoint.thrift.dto.command; + + +import java.util.Map; +import java.util.HashMap; +import org.apache.thrift.TEnum; + +public enum TThreadDumpType implements org.apache.thrift.TEnum { + TARGET(0), + PENDING(1); + + private final int value; + + private TThreadDumpType(int value) { + this.value = value; + } + + /** + * Get the integer value of this enum value, as defined in the Thrift IDL. + */ + public int getValue() { + return value; + } + + /** + * Find a the enum type by its integer value, as defined in the Thrift IDL. + * @return null if the value is not found. + */ + public static TThreadDumpType findByValue(int value) { + switch (value) { + case 0: + return TARGET; + case 1: + return PENDING; + default: + return null; + } + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/BytesUtils.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/BytesUtils.java index a88d59e70185..bc294c7ad773 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/BytesUtils.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/BytesUtils.java @@ -1,14 +1,14 @@ -package com.nhn.pinpoint.thrift.io; - -/** - * @author emeroad - */ -class BytesUtils { - public static byte writeShort1(final short value) { - return (byte) (value >> 8); - } - - public static byte writeShort2(final short value) { - return (byte) (value); - } -} +package com.nhn.pinpoint.thrift.io; + +/** + * @author emeroad + */ +class BytesUtils { + public static byte writeShort1(final short value) { + return (byte) (value >> 8); + } + + public static byte writeShort2(final short value) { + return (byte) (value); + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DeserializerFactory.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DeserializerFactory.java index 60af1a098163..db1ac8035733 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DeserializerFactory.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DeserializerFactory.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.thrift.io; - -/** - * @author emeroad - */ -public interface DeserializerFactory { - HeaderTBaseDeserializer createDeserializer(); -} +package com.nhn.pinpoint.thrift.io; + +/** + * @author emeroad + */ +public interface DeserializerFactory { + HeaderTBaseDeserializer createDeserializer(); +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/Header.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/Header.java index f880c94abdab..24a4d116a11d 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/Header.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/Header.java @@ -1,58 +1,58 @@ -package com.nhn.pinpoint.thrift.io; - -/** - * @author emeroad - */ -public class Header { - - public static final byte SIGNATURE = (byte) 0xef; - - public static final int HEADER_SIZE = 4; - - private byte signature = SIGNATURE; - private byte version = 0x10; - private short type = 0; - - public Header() { - } - - public Header(byte signature, byte version, short type) { - this.signature = signature; - this.version = version; - this.type = type; - } - - public byte getSignature() { - return signature; - } - - public void setSignature(byte signature) { - this.signature = signature; - } - - public byte getVersion() { - return version; - } - - public void setVersion(byte version) { - this.version = version; - } - - public short getType() { - return type; - } - - public void setType(short type) { - this.type = type; - } - - @Override - public String toString() { - return "Header{" + - "signature=" + signature + - ", version=" + version + - ", type=" + type + - '}'; - } -} - +package com.nhn.pinpoint.thrift.io; + +/** + * @author emeroad + */ +public class Header { + + public static final byte SIGNATURE = (byte) 0xef; + + public static final int HEADER_SIZE = 4; + + private byte signature = SIGNATURE; + private byte version = 0x10; + private short type = 0; + + public Header() { + } + + public Header(byte signature, byte version, short type) { + this.signature = signature; + this.version = version; + this.type = type; + } + + public byte getSignature() { + return signature; + } + + public void setSignature(byte signature) { + this.signature = signature; + } + + public byte getVersion() { + return version; + } + + public void setVersion(byte version) { + this.version = version; + } + + public short getType() { + return type; + } + + public void setType(short type) { + this.type = type; + } + + @Override + public String toString() { + return "Header{" + + "signature=" + signature + + ", version=" + version + + ", type=" + type + + '}'; + } +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializer.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializer.java index 0e3ab9bf1a4a..c5fccd3a725c 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializer.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializer.java @@ -1,78 +1,78 @@ -package com.nhn.pinpoint.thrift.io; - -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TProtocol; -import org.apache.thrift.protocol.TProtocolFactory; -import org.apache.thrift.transport.TMemoryInputTransport; - -/** - * copy->TBaseDeserializer - */ -public class HeaderTBaseDeserializer { - - private final TProtocol protocol; - private final TMemoryInputTransport trans; - private final TBaseLocator locator; - - /** - * Create a new TDeserializer. It will use the TProtocol specified by the - * factory that is passed in. - * - * @param protocolFactory Factory to create a protocol - */ - HeaderTBaseDeserializer(TProtocolFactory protocolFactory, TBaseLocator locator) { - this.trans = new TMemoryInputTransport(); - this.protocol = protocolFactory.getProtocol(trans); - this.locator = locator; - } - - /** - * Deserialize the Thrift object from a byte array. - * - * @param bytes The array to read from - */ - public TBase deserialize(byte[] bytes) throws TException { - try { - trans.reset(bytes); - Header header = readHeader(); - final int validate = validate(header); - if (validate == HeaderUtils.OK) { - TBase base = locator.tBaseLookup(header.getType()); - base.read(protocol); - return base; - } - if (validate == HeaderUtils.PASS_L4) { - return new L4Packet(header); - } - throw new IllegalStateException("invalid validate " + validate); - } finally { - trans.clear(); - protocol.reset(); - } - } - - private int validate(Header header) throws TException { - final byte signature = header.getSignature(); - final int result = HeaderUtils.validateSignature(signature); - if (result == HeaderUtils.FAIL) { - throw new TException("Invalid Signature:" + header); - } - return result; - } - - private Header readHeader() throws TException { - final byte signature = protocol.readByte(); - final byte version = protocol.readByte(); - // 프로토콜 변경에 관계 없이 고정 사이즈의 데이터로 인코딩 하도록 변경. - final byte type1 = protocol.readByte(); - final byte type2 = protocol.readByte(); - final short type = bytesToShort(type1, type2); - return new Header(signature, version, type); - } - - private short bytesToShort(final byte byte1, final byte byte2) { - return (short) (((byte1 & 0xff) << 8) | ((byte2 & 0xff))); - } - -} +package com.nhn.pinpoint.thrift.io; + +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.protocol.TProtocolFactory; +import org.apache.thrift.transport.TMemoryInputTransport; + +/** + * copy->TBaseDeserializer + */ +public class HeaderTBaseDeserializer { + + private final TProtocol protocol; + private final TMemoryInputTransport trans; + private final TBaseLocator locator; + + /** + * Create a new TDeserializer. It will use the TProtocol specified by the + * factory that is passed in. + * + * @param protocolFactory Factory to create a protocol + */ + HeaderTBaseDeserializer(TProtocolFactory protocolFactory, TBaseLocator locator) { + this.trans = new TMemoryInputTransport(); + this.protocol = protocolFactory.getProtocol(trans); + this.locator = locator; + } + + /** + * Deserialize the Thrift object from a byte array. + * + * @param bytes The array to read from + */ + public TBase deserialize(byte[] bytes) throws TException { + try { + trans.reset(bytes); + Header header = readHeader(); + final int validate = validate(header); + if (validate == HeaderUtils.OK) { + TBase base = locator.tBaseLookup(header.getType()); + base.read(protocol); + return base; + } + if (validate == HeaderUtils.PASS_L4) { + return new L4Packet(header); + } + throw new IllegalStateException("invalid validate " + validate); + } finally { + trans.clear(); + protocol.reset(); + } + } + + private int validate(Header header) throws TException { + final byte signature = header.getSignature(); + final int result = HeaderUtils.validateSignature(signature); + if (result == HeaderUtils.FAIL) { + throw new TException("Invalid Signature:" + header); + } + return result; + } + + private Header readHeader() throws TException { + final byte signature = protocol.readByte(); + final byte version = protocol.readByte(); + // 프로토콜 변경에 관계 없이 고정 사이즈의 데이터로 인코딩 하도록 변경. + final byte type1 = protocol.readByte(); + final byte type2 = protocol.readByte(); + final short type = bytesToShort(type1, type2); + return new Header(signature, version, type); + } + + private short bytesToShort(final byte byte1, final byte byte2) { + return (short) (((byte1 & 0xff) << 8) | ((byte2 & 0xff))); + } + +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactory.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactory.java index beaf55e4746e..3aac1c2a05e2 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactory.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactory.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.thrift.io; - -import java.io.ByteArrayOutputStream; - -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.protocol.TProtocolFactory; - -/** - * @author koo.taejin - */ -public final class HeaderTBaseDeserializerFactory implements DeserializerFactory { - - private static final TBaseLocator DEFAULT_TBASE_LOCATOR = new DefaultTBaseLocator(); - - private static final TProtocolFactory DEFAULT_PROTOCOL_FACTORY = new TCompactProtocol.Factory(); - - public static final HeaderTBaseDeserializerFactory DEFAULT_FACTORY = new HeaderTBaseDeserializerFactory(); - - private final TProtocolFactory protocolFactory; - private TBaseLocator locator; - - public HeaderTBaseDeserializerFactory() { - this(DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); - } - - public TBaseLocator getLocator() { - return locator; - } - - public TProtocolFactory getProtocolFactory() { - return protocolFactory; - } - - public HeaderTBaseDeserializerFactory(TProtocolFactory protocolFactory, TBaseLocator locator) { - if (protocolFactory == null) { - throw new NullPointerException("protocolFactory must not be null"); - } - if (locator == null) { - throw new NullPointerException("locator must not be null"); - } - this.protocolFactory = protocolFactory; - this.locator = locator; - } - - - @Override - public HeaderTBaseDeserializer createDeserializer() { - return new HeaderTBaseDeserializer(protocolFactory, locator); - } - -} +package com.nhn.pinpoint.thrift.io; + +import java.io.ByteArrayOutputStream; + +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.protocol.TProtocolFactory; + +/** + * @author koo.taejin + */ +public final class HeaderTBaseDeserializerFactory implements DeserializerFactory { + + private static final TBaseLocator DEFAULT_TBASE_LOCATOR = new DefaultTBaseLocator(); + + private static final TProtocolFactory DEFAULT_PROTOCOL_FACTORY = new TCompactProtocol.Factory(); + + public static final HeaderTBaseDeserializerFactory DEFAULT_FACTORY = new HeaderTBaseDeserializerFactory(); + + private final TProtocolFactory protocolFactory; + private TBaseLocator locator; + + public HeaderTBaseDeserializerFactory() { + this(DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); + } + + public TBaseLocator getLocator() { + return locator; + } + + public TProtocolFactory getProtocolFactory() { + return protocolFactory; + } + + public HeaderTBaseDeserializerFactory(TProtocolFactory protocolFactory, TBaseLocator locator) { + if (protocolFactory == null) { + throw new NullPointerException("protocolFactory must not be null"); + } + if (locator == null) { + throw new NullPointerException("locator must not be null"); + } + this.protocolFactory = protocolFactory; + this.locator = locator; + } + + + @Override + public HeaderTBaseDeserializer createDeserializer() { + return new HeaderTBaseDeserializer(protocolFactory, locator); + } + +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializer.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializer.java index 8216eca56a19..024098eb6cb1 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializer.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializer.java @@ -1,91 +1,91 @@ -package com.nhn.pinpoint.thrift.io; - - -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; - -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TProtocol; -import org.apache.thrift.protocol.TProtocolFactory; -import org.apache.thrift.transport.TIOStreamTransport; - -/** - * Generic utility for easily serializing objects into a byte array or Java - * String. - * copy->HeaderTBaseSerializer - */ -public class HeaderTBaseSerializer { - - private final ByteArrayOutputStream baos; - private final TProtocol protocol; - private final TBaseLocator locator; - - /** - * Create a new HeaderTBaseSerializer. - */ - HeaderTBaseSerializer(ByteArrayOutputStream bos, TProtocolFactory protocolFactory, TBaseLocator locator) { - this.baos = bos; - TIOStreamTransport transport = new TIOStreamTransport(bos); - this.protocol = protocolFactory.getProtocol(transport); - this.locator = locator; - } - - /** - * Serialize the Thrift object into a byte array. The process is simple, - * just clear the byte array output, write the object into it, and grab the - * raw bytes. - * - * @param base The object to serialize - * @return Serialized object in byte[] format - */ - public byte[] serialize(TBase base) throws TException { - final Header header = locator.headerLookup(base); - baos.reset(); - writeHeader(header); - base.write(protocol); - return baos.toByteArray(); - } - - public int getInterBufferSize() { - return baos.size(); - } - - private void writeHeader(Header header) throws TException { - protocol.writeByte(header.getSignature()); - protocol.writeByte(header.getVersion()); - // 프로토콜 변경에 관계 없이 고정 사이즈의 데이터로 인코딩 하도록 변경. - short type = header.getType(); - protocol.writeByte(BytesUtils.writeShort1(type)); - protocol.writeByte(BytesUtils.writeShort2(type)); - } - - /** - * Serialize the Thrift object into a Java string, using the default JVM - * charset encoding. - * - * @param base The object to serialize - * @return Serialized object as a String - */ - public String toString(TBase base) throws TException { - return new String(serialize(base)); - } - - /** - * Serialize the Thrift object into a Java string, using a specified - * character set for encoding. - * - * @param base The object to serialize - * @param charset Valid JVM charset - * @return Serialized object as a String - */ - public String toString(TBase base, String charset) throws TException { - try { - return new String(serialize(base), charset); - } catch (UnsupportedEncodingException uex) { - throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); - } - } - - -} +package com.nhn.pinpoint.thrift.io; + + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; + +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.protocol.TProtocolFactory; +import org.apache.thrift.transport.TIOStreamTransport; + +/** + * Generic utility for easily serializing objects into a byte array or Java + * String. + * copy->HeaderTBaseSerializer + */ +public class HeaderTBaseSerializer { + + private final ByteArrayOutputStream baos; + private final TProtocol protocol; + private final TBaseLocator locator; + + /** + * Create a new HeaderTBaseSerializer. + */ + HeaderTBaseSerializer(ByteArrayOutputStream bos, TProtocolFactory protocolFactory, TBaseLocator locator) { + this.baos = bos; + TIOStreamTransport transport = new TIOStreamTransport(bos); + this.protocol = protocolFactory.getProtocol(transport); + this.locator = locator; + } + + /** + * Serialize the Thrift object into a byte array. The process is simple, + * just clear the byte array output, write the object into it, and grab the + * raw bytes. + * + * @param base The object to serialize + * @return Serialized object in byte[] format + */ + public byte[] serialize(TBase base) throws TException { + final Header header = locator.headerLookup(base); + baos.reset(); + writeHeader(header); + base.write(protocol); + return baos.toByteArray(); + } + + public int getInterBufferSize() { + return baos.size(); + } + + private void writeHeader(Header header) throws TException { + protocol.writeByte(header.getSignature()); + protocol.writeByte(header.getVersion()); + // 프로토콜 변경에 관계 없이 고정 사이즈의 데이터로 인코딩 하도록 변경. + short type = header.getType(); + protocol.writeByte(BytesUtils.writeShort1(type)); + protocol.writeByte(BytesUtils.writeShort2(type)); + } + + /** + * Serialize the Thrift object into a Java string, using the default JVM + * charset encoding. + * + * @param base The object to serialize + * @return Serialized object as a String + */ + public String toString(TBase base) throws TException { + return new String(serialize(base)); + } + + /** + * Serialize the Thrift object into a Java string, using a specified + * character set for encoding. + * + * @param base The object to serialize + * @param charset Valid JVM charset + * @return Serialized object as a String + */ + public String toString(TBase base, String charset) throws TException { + try { + return new String(serialize(base), charset); + } catch (UnsupportedEncodingException uex) { + throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); + } + } + + +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerFactory.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerFactory.java index 7476445d0c79..bf9b3594654b 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerFactory.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerFactory.java @@ -1,77 +1,77 @@ -package com.nhn.pinpoint.thrift.io; - -import org.apache.thrift.protocol.TCompactProtocol; -import org.apache.thrift.protocol.TProtocolFactory; - -import java.io.ByteArrayOutputStream; - -/** - * @author koo.taejin - */ -public final class HeaderTBaseSerializerFactory implements SerializerFactory { - - private static final TBaseLocator DEFAULT_TBASE_LOCATOR = new DefaultTBaseLocator(); - - private static final TProtocolFactory DEFAULT_PROTOCOL_FACTORY = new TCompactProtocol.Factory(); - - private static final boolean DEFAULT_SAFE_GURANTEED = true; - - public static final int DEFAULT_STREAM_SIZE = 1024 * 8; - - public static final int DEFAULT_UDP_STREAM_MAX_SIZE = 1024 * 64; - - public static final HeaderTBaseSerializerFactory DEFAULT_FACTORY = new HeaderTBaseSerializerFactory(); - - private final boolean safetyGuranteed; - private final int outputStreamSize; - private final TProtocolFactory protocolFactory; - private final TBaseLocator locator; - - public HeaderTBaseSerializerFactory() { - this(DEFAULT_SAFE_GURANTEED, DEFAULT_STREAM_SIZE, DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); - } - - public HeaderTBaseSerializerFactory(boolean safetyGuranteed) { - this(safetyGuranteed, DEFAULT_STREAM_SIZE, DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); - } - - public HeaderTBaseSerializerFactory(boolean safetyGuranteed, int outputStreamSize) { - this(safetyGuranteed, outputStreamSize, DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); - } - - public HeaderTBaseSerializerFactory(boolean safetyGuranteed, int outputStreamSize, TProtocolFactory protocolFactory, TBaseLocator locator) { - this.safetyGuranteed = safetyGuranteed; - this.outputStreamSize = outputStreamSize; - this.protocolFactory = protocolFactory; - this.locator = locator; - } - - public boolean isSafetyGuranteed() { - return safetyGuranteed; - } - - public int getOutputStreamSize() { - return outputStreamSize; - } - - public TProtocolFactory getProtocolFactory() { - return protocolFactory; - } - - public TBaseLocator getLocator() { - return locator; - } - - @Override - public HeaderTBaseSerializer createSerializer() { - ByteArrayOutputStream baos = null; - if (safetyGuranteed) { - baos = new ByteArrayOutputStream(outputStreamSize); - } else { - baos = new UnsafeByteArrayOutputStream(outputStreamSize); - } - - return new HeaderTBaseSerializer(baos, protocolFactory, locator); - } - -} +package com.nhn.pinpoint.thrift.io; + +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.protocol.TProtocolFactory; + +import java.io.ByteArrayOutputStream; + +/** + * @author koo.taejin + */ +public final class HeaderTBaseSerializerFactory implements SerializerFactory { + + private static final TBaseLocator DEFAULT_TBASE_LOCATOR = new DefaultTBaseLocator(); + + private static final TProtocolFactory DEFAULT_PROTOCOL_FACTORY = new TCompactProtocol.Factory(); + + private static final boolean DEFAULT_SAFE_GURANTEED = true; + + public static final int DEFAULT_STREAM_SIZE = 1024 * 8; + + public static final int DEFAULT_UDP_STREAM_MAX_SIZE = 1024 * 64; + + public static final HeaderTBaseSerializerFactory DEFAULT_FACTORY = new HeaderTBaseSerializerFactory(); + + private final boolean safetyGuranteed; + private final int outputStreamSize; + private final TProtocolFactory protocolFactory; + private final TBaseLocator locator; + + public HeaderTBaseSerializerFactory() { + this(DEFAULT_SAFE_GURANTEED, DEFAULT_STREAM_SIZE, DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); + } + + public HeaderTBaseSerializerFactory(boolean safetyGuranteed) { + this(safetyGuranteed, DEFAULT_STREAM_SIZE, DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); + } + + public HeaderTBaseSerializerFactory(boolean safetyGuranteed, int outputStreamSize) { + this(safetyGuranteed, outputStreamSize, DEFAULT_PROTOCOL_FACTORY, DEFAULT_TBASE_LOCATOR); + } + + public HeaderTBaseSerializerFactory(boolean safetyGuranteed, int outputStreamSize, TProtocolFactory protocolFactory, TBaseLocator locator) { + this.safetyGuranteed = safetyGuranteed; + this.outputStreamSize = outputStreamSize; + this.protocolFactory = protocolFactory; + this.locator = locator; + } + + public boolean isSafetyGuranteed() { + return safetyGuranteed; + } + + public int getOutputStreamSize() { + return outputStreamSize; + } + + public TProtocolFactory getProtocolFactory() { + return protocolFactory; + } + + public TBaseLocator getLocator() { + return locator; + } + + @Override + public HeaderTBaseSerializer createSerializer() { + ByteArrayOutputStream baos = null; + if (safetyGuranteed) { + baos = new ByteArrayOutputStream(outputStreamSize); + } else { + baos = new UnsafeByteArrayOutputStream(outputStreamSize); + } + + return new HeaderTBaseSerializer(baos, protocolFactory, locator); + } + +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderUtils.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderUtils.java index 63528fe6ed43..3dc2411e415c 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderUtils.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/HeaderUtils.java @@ -1,20 +1,20 @@ -package com.nhn.pinpoint.thrift.io; - -/** - * @author emeroad - */ -final class HeaderUtils { - public static final int OK = Header.SIGNATURE; - // TODO L4 상수화 시켜 놓았는데. 변경이 가능하도록 해야 될듯 하다. - public static final int PASS_L4 = 85; // Udp - public static final int FAIL = 0; - - public static int validateSignature(byte signature) { - if (Header.SIGNATURE == signature) { - return OK; - } else if (PASS_L4 == signature) { - return PASS_L4; - } - return FAIL; - } -} +package com.nhn.pinpoint.thrift.io; + +/** + * @author emeroad + */ +final class HeaderUtils { + public static final int OK = Header.SIGNATURE; + // TODO L4 상수화 시켜 놓았는데. 변경이 가능하도록 해야 될듯 하다. + public static final int PASS_L4 = 85; // Udp + public static final int FAIL = 0; + + public static int validateSignature(byte signature) { + if (Header.SIGNATURE == signature) { + return OK; + } else if (PASS_L4 == signature) { + return PASS_L4; + } + return FAIL; + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/L4Packet.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/L4Packet.java index d68e34f4c803..4d1626281763 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/L4Packet.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/L4Packet.java @@ -1,63 +1,63 @@ -package com.nhn.pinpoint.thrift.io; - -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.apache.thrift.TFieldIdEnum; -import org.apache.thrift.protocol.TProtocol; - -/** - * @author emeroad - */ -public class L4Packet implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - - private final Header header; - - public L4Packet(Header header) { - this.header = header; - } - - public Header getHeader() { - return header; - } - - @Override - public void read(TProtocol tProtocol) throws TException { - } - - @Override - public void write(TProtocol tProtocol) throws TException { - } - - @Override - public TFieldIdEnum fieldForId(int i) { - return null; - } - - @Override - public boolean isSet(TFieldIdEnum tFieldIdEnum) { - return false; - } - - @Override - public Object getFieldValue(TFieldIdEnum tFieldIdEnum) { - return null; - } - - @Override - public void setFieldValue(TFieldIdEnum tFieldIdEnum, Object o) { - } - - @Override - public TBase deepCopy() { - return null; - } - - @Override - public void clear() { - } - - @Override - public int compareTo(L4Packet o) { - return 0; - } -} +package com.nhn.pinpoint.thrift.io; + +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.apache.thrift.TFieldIdEnum; +import org.apache.thrift.protocol.TProtocol; + +/** + * @author emeroad + */ +public class L4Packet implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + + private final Header header; + + public L4Packet(Header header) { + this.header = header; + } + + public Header getHeader() { + return header; + } + + @Override + public void read(TProtocol tProtocol) throws TException { + } + + @Override + public void write(TProtocol tProtocol) throws TException { + } + + @Override + public TFieldIdEnum fieldForId(int i) { + return null; + } + + @Override + public boolean isSet(TFieldIdEnum tFieldIdEnum) { + return false; + } + + @Override + public Object getFieldValue(TFieldIdEnum tFieldIdEnum) { + return null; + } + + @Override + public void setFieldValue(TFieldIdEnum tFieldIdEnum, Object o) { + } + + @Override + public TBase deepCopy() { + return null; + } + + @Override + public void clear() { + } + + @Override + public int compareTo(L4Packet o) { + return 0; + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/NetworkAvailabilityCheckPacket.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/NetworkAvailabilityCheckPacket.java index d3c5e73f1c39..c46c1cc60010 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/NetworkAvailabilityCheckPacket.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/NetworkAvailabilityCheckPacket.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.thrift.io; - -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.apache.thrift.TFieldIdEnum; -import org.apache.thrift.protocol.TProtocol; - -/** - * @author netspider - */ -public class NetworkAvailabilityCheckPacket implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { - - private static final long serialVersionUID = -1170704876834222604L; - - public transient static final byte[] DATA_OK = "OK".getBytes(); - - @Override - public void read(TProtocol tProtocol) throws TException { - } - - @Override - public void write(TProtocol tProtocol) throws TException { - } - - @Override - public TFieldIdEnum fieldForId(int i) { - return null; - } - - @Override - public boolean isSet(TFieldIdEnum tFieldIdEnum) { - return false; - } - - @Override - public Object getFieldValue(TFieldIdEnum tFieldIdEnum) { - return null; - } - - @Override - public void setFieldValue(TFieldIdEnum tFieldIdEnum, Object o) { - } - - @Override - public TBase deepCopy() { - return null; - } - - @Override - public void clear() { - } - - @Override - public int compareTo(NetworkAvailabilityCheckPacket o) { - return 0; - } -} +package com.nhn.pinpoint.thrift.io; + +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.apache.thrift.TFieldIdEnum; +import org.apache.thrift.protocol.TProtocol; + +/** + * @author netspider + */ +public class NetworkAvailabilityCheckPacket implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + + private static final long serialVersionUID = -1170704876834222604L; + + public transient static final byte[] DATA_OK = "OK".getBytes(); + + @Override + public void read(TProtocol tProtocol) throws TException { + } + + @Override + public void write(TProtocol tProtocol) throws TException { + } + + @Override + public TFieldIdEnum fieldForId(int i) { + return null; + } + + @Override + public boolean isSet(TFieldIdEnum tFieldIdEnum) { + return false; + } + + @Override + public Object getFieldValue(TFieldIdEnum tFieldIdEnum) { + return null; + } + + @Override + public void setFieldValue(TFieldIdEnum tFieldIdEnum, Object o) { + } + + @Override + public TBase deepCopy() { + return null; + } + + @Override + public void clear() { + } + + @Override + public int compareTo(NetworkAvailabilityCheckPacket o) { + return 0; + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/PacketUtils.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/PacketUtils.java index 2488ebc9463d..9f96b2eac334 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/PacketUtils.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/PacketUtils.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.thrift.io; - -import java.net.DatagramPacket; -import java.util.Arrays; - -/** - * @author emeroad - */ -public class PacketUtils { - - public static byte[] sliceData(DatagramPacket packet, int startOffset) { - if (packet == null) { - throw new NullPointerException("packet must not be null"); - } - int packetLength = packet.getLength(); - int packetOffset = packet.getOffset(); - byte[] source = packet.getData(); - return Arrays.copyOfRange(source, packetOffset + startOffset, packetLength); - } - - public static byte[] sliceData(byte[] packet, int startOffset, int length) { - if (packet == null) { - throw new NullPointerException("packet must not be null"); - } - return Arrays.copyOfRange(packet, startOffset, length); - } -} +package com.nhn.pinpoint.thrift.io; + +import java.net.DatagramPacket; +import java.util.Arrays; + +/** + * @author emeroad + */ +public class PacketUtils { + + public static byte[] sliceData(DatagramPacket packet, int startOffset) { + if (packet == null) { + throw new NullPointerException("packet must not be null"); + } + int packetLength = packet.getLength(); + int packetOffset = packet.getOffset(); + byte[] source = packet.getData(); + return Arrays.copyOfRange(source, packetOffset + startOffset, packetLength); + } + + public static byte[] sliceData(byte[] packet, int startOffset, int length) { + if (packet == null) { + throw new NullPointerException("packet must not be null"); + } + return Arrays.copyOfRange(packet, startOffset, length); + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/SerializerFactory.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/SerializerFactory.java index 45c3a1884ffa..d9c53da13a8f 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/SerializerFactory.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/SerializerFactory.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.thrift.io; - -/** - * @author emeroad - */ -public interface SerializerFactory { - HeaderTBaseSerializer createSerializer(); -} +package com.nhn.pinpoint.thrift.io; + +/** + * @author emeroad + */ +public interface SerializerFactory { + HeaderTBaseSerializer createSerializer(); +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandType.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandType.java index f55dc651319d..cc8fb950bae0 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandType.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandType.java @@ -3,7 +3,9 @@ import org.apache.thrift.TBase; import com.nhn.pinpoint.thrift.dto.TResult; +import com.nhn.pinpoint.thrift.dto.command.TCommandEcho; import com.nhn.pinpoint.thrift.dto.command.TCommandThreadDump; +import com.nhn.pinpoint.thrift.dto.command.TCommandTransfer; /** * @author koo.taejin @@ -19,6 +21,18 @@ public TBase newObject() { return new TResult(); } }, + TRANSFER((short) 700, TCommandTransfer.class) { + @Override + public TBase newObject() { + return new TCommandTransfer(); + } + }, + ECHO((short) 710, TCommandEcho.class) { + @Override + public TBase newObject() { + return new TCommandEcho(); + } + }, THREAD_DUMP((short) 720, TCommandThreadDump.class) { @Override public TBase newObject() { diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandTypeVersion.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandTypeVersion.java index 3ab1f481ee94..628986ed48c6 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandTypeVersion.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/TCommandTypeVersion.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import org.apache.thrift.TBase; + /** * @author koo.taejin */ @@ -10,6 +12,9 @@ public enum TCommandTypeVersion { // Agent 버젼과 맞추면 좋을듯 일단은 Agent 버전과 맞춰놓음 V_1_0_2_SNAPSHOT("1.0.2-SNAPSHOT", TCommandType.RESULT, TCommandType.THREAD_DUMP), + V_1_0_2("1.0.2", V_1_0_2_SNAPSHOT), + V_1_0_3_SNAPSHOT("1.0.3-SNAPSHOT", V_1_0_2, TCommandType.ECHO, TCommandType.TRANSFER), + UNKNOWN("UNKNOWN"); private final String versionName; @@ -38,6 +43,24 @@ private TCommandTypeVersion(String versionName, TCommandType... supportCommandAr public List getSupportCommandList() { return supportCommandList; } + + public boolean isSupportCommand(TBase command) { + if (command == null) { + return false; + } + + for (TCommandType eachCommand : supportCommandList) { + if (eachCommand == null) { + continue; + } + + if (eachCommand.getClazz() == command.getClass()) { + return true; + } + } + + return false; + } public String getVersionName() { return versionName; diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseDeserializerFactory.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseDeserializerFactory.java index 7e8b1151541a..97d566e524c1 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseDeserializerFactory.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseDeserializerFactory.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.thrift.io; - -/** - * @author emeroad - */ -public class ThreadLocalHeaderTBaseDeserializerFactory implements DeserializerFactory { - - private final ThreadLocal cache = new ThreadLocal() { - @Override - protected HeaderTBaseDeserializer initialValue() { - return factory.createDeserializer(); - } - }; - - private final DeserializerFactory factory; - - public ThreadLocalHeaderTBaseDeserializerFactory(DeserializerFactory factory) { - if (factory == null) { - throw new NullPointerException("factory must not be null"); - } - this.factory = factory; - } - - @Override - public HeaderTBaseDeserializer createDeserializer() { - return cache.get(); - } -} +package com.nhn.pinpoint.thrift.io; + +/** + * @author emeroad + */ +public class ThreadLocalHeaderTBaseDeserializerFactory implements DeserializerFactory { + + private final ThreadLocal cache = new ThreadLocal() { + @Override + protected HeaderTBaseDeserializer initialValue() { + return factory.createDeserializer(); + } + }; + + private final DeserializerFactory factory; + + public ThreadLocalHeaderTBaseDeserializerFactory(DeserializerFactory factory) { + if (factory == null) { + throw new NullPointerException("factory must not be null"); + } + this.factory = factory; + } + + @Override + public HeaderTBaseDeserializer createDeserializer() { + return cache.get(); + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseSerializerFactory.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseSerializerFactory.java index 0788b491be85..ce3ccc30d7e5 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseSerializerFactory.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/ThreadLocalHeaderTBaseSerializerFactory.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.thrift.io; - -/** - * @author emeroad - */ -public class ThreadLocalHeaderTBaseSerializerFactory implements SerializerFactory { - - private final ThreadLocal cache = new ThreadLocal() { - @Override - protected HeaderTBaseSerializer initialValue() { - return factory.createSerializer(); - } - }; - - private final SerializerFactory factory; - - public ThreadLocalHeaderTBaseSerializerFactory(SerializerFactory factory) { - if (factory == null) { - throw new NullPointerException("factory must not be null"); - } - this.factory = factory; - } - - - @Override - public HeaderTBaseSerializer createSerializer() { - return cache.get(); - } -} +package com.nhn.pinpoint.thrift.io; + +/** + * @author emeroad + */ +public class ThreadLocalHeaderTBaseSerializerFactory implements SerializerFactory { + + private final ThreadLocal cache = new ThreadLocal() { + @Override + protected HeaderTBaseSerializer initialValue() { + return factory.createSerializer(); + } + }; + + private final SerializerFactory factory; + + public ThreadLocalHeaderTBaseSerializerFactory(SerializerFactory factory) { + if (factory == null) { + throw new NullPointerException("factory must not be null"); + } + this.factory = factory; + } + + + @Override + public HeaderTBaseSerializer createSerializer() { + return cache.get(); + } +} diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/UnsafeByteArrayOutputStream.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/UnsafeByteArrayOutputStream.java index 3c611a857ccf..76cf7f2195df 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/UnsafeByteArrayOutputStream.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/UnsafeByteArrayOutputStream.java @@ -1,182 +1,182 @@ -package com.nhn.pinpoint.thrift.io; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; - -/** - * @author emeroad - */ -public class UnsafeByteArrayOutputStream extends ByteArrayOutputStream { - - /** - * The buffer where data is stored. - */ - protected byte buf[]; - - /** - * The number of valid bytes in the buffer. - */ - protected int count; - - /** - * Creates a new byte array output stream. The buffer capacity is - * initially 32 bytes, though its size increases if necessary. - */ - public UnsafeByteArrayOutputStream() { - this(32); - } - - /** - * Creates a new byte array output stream, with a buffer capacity of - * the specified size, in bytes. - * - * @param size the initial size. - * @throws IllegalArgumentException if size is negative. - */ - public UnsafeByteArrayOutputStream(int size) { - if (size < 0) { - throw new IllegalArgumentException("Negative initial size: " - + size); - } - buf = new byte[size]; - } - - /** - * Writes the specified byte to this byte array output stream. - * - * @param b the byte to be written. - */ - public void write(int b) { - int newcount = count + 1; - if (newcount > buf.length) { - buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); - } - buf[count] = (byte) b; - count = newcount; - } - - /** - * Writes len bytes from the specified byte array - * starting at offset off to this byte array output stream. - * - * @param b the data. - * @param off the start offset in the data. - * @param len the number of bytes to write. - */ - public void write(byte b[], int off, int len) { - if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) > b.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; - } - int newcount = count + len; - if (newcount > buf.length) { - buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); - } - System.arraycopy(b, off, buf, count, len); - count = newcount; - } - - /** - * Writes the complete contents of this byte array output stream to - * the specified output stream argument, as if by calling the output - * stream's write method using out.write(buf, 0, count). - * - * @param out the output stream to which to write the data. - * @throws java.io.IOException if an I/O error occurs. - */ - public void writeTo(OutputStream out) throws IOException { - out.write(buf, 0, count); - } - - /** - * Resets the count field of this byte array output - * stream to zero, so that all currently accumulated output in the - * output stream is discarded. The output stream can be used again, - * reusing the already allocated buffer space. - * - * @see java.io.ByteArrayInputStream#count - */ - public void reset() { - count = 0; - } - - /** - * Creates a newly allocated byte array. Its size is the current - * size of this output stream and the valid contents of the buffer - * have been copied into it. - * - * @return the current contents of this output stream, as a byte array. - * @see java.io.ByteArrayOutputStream#size() - */ - public byte toByteArray()[] { - return buf; - } - - /** - * Returns the current size of the buffer. - * - * @return the value of the count field, which is the number - * of valid bytes in this output stream. - * @see java.io.ByteArrayOutputStream#count - */ - public int size() { - return count; - } - - /** - * Converts the buffer's contents into a string decoding bytes using the - * platform's default character set. The length of the new String - * is a function of the character set, and hence may not be equal to the - * size of the buffer. - *

- *

This method always replaces malformed-input and unmappable-character - * sequences with the default replacement string for the platform's - * default character set. The {@linkplain java.nio.charset.CharsetDecoder} - * class should be used when more control over the decoding process is - * required. - * - * @return String decoded from the buffer's contents. - * @since JDK1.1 - */ - public String toString() { - return new String(buf, 0, count); - } - - /** - * Converts the buffer's contents into a string by decoding the bytes using - * the specified {@link java.nio.charset.Charset charsetName}. The length of - * the new String is a function of the charset, and hence may not be - * equal to the length of the byte array. - *

- *

This method always replaces malformed-input and unmappable-character - * sequences with this charset's default replacement string. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. - * - * @param charsetName the name of a supported - * {@linkplain java.nio.charset.Charset charset} - * @return String decoded from the buffer's contents. - * @throws java.io.UnsupportedEncodingException - * If the named charset is not supported - * @since JDK1.1 - */ - public String toString(String charsetName) - throws UnsupportedEncodingException { - return new String(buf, 0, count, charsetName); - } - - - /** - * Closing a ByteArrayOutputStream has no effect. The methods in - * this class can be called after the stream has been closed without - * generating an IOException. - *

- */ - public void close() throws IOException { - } -} +package com.nhn.pinpoint.thrift.io; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +/** + * @author emeroad + */ +public class UnsafeByteArrayOutputStream extends ByteArrayOutputStream { + + /** + * The buffer where data is stored. + */ + protected byte buf[]; + + /** + * The number of valid bytes in the buffer. + */ + protected int count; + + /** + * Creates a new byte array output stream. The buffer capacity is + * initially 32 bytes, though its size increases if necessary. + */ + public UnsafeByteArrayOutputStream() { + this(32); + } + + /** + * Creates a new byte array output stream, with a buffer capacity of + * the specified size, in bytes. + * + * @param size the initial size. + * @throws IllegalArgumentException if size is negative. + */ + public UnsafeByteArrayOutputStream(int size) { + if (size < 0) { + throw new IllegalArgumentException("Negative initial size: " + + size); + } + buf = new byte[size]; + } + + /** + * Writes the specified byte to this byte array output stream. + * + * @param b the byte to be written. + */ + public void write(int b) { + int newcount = count + 1; + if (newcount > buf.length) { + buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); + } + buf[count] = (byte) b; + count = newcount; + } + + /** + * Writes len bytes from the specified byte array + * starting at offset off to this byte array output stream. + * + * @param b the data. + * @param off the start offset in the data. + * @param len the number of bytes to write. + */ + public void write(byte b[], int off, int len) { + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) > b.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + int newcount = count + len; + if (newcount > buf.length) { + buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); + } + System.arraycopy(b, off, buf, count, len); + count = newcount; + } + + /** + * Writes the complete contents of this byte array output stream to + * the specified output stream argument, as if by calling the output + * stream's write method using out.write(buf, 0, count). + * + * @param out the output stream to which to write the data. + * @throws java.io.IOException if an I/O error occurs. + */ + public void writeTo(OutputStream out) throws IOException { + out.write(buf, 0, count); + } + + /** + * Resets the count field of this byte array output + * stream to zero, so that all currently accumulated output in the + * output stream is discarded. The output stream can be used again, + * reusing the already allocated buffer space. + * + * @see java.io.ByteArrayInputStream#count + */ + public void reset() { + count = 0; + } + + /** + * Creates a newly allocated byte array. Its size is the current + * size of this output stream and the valid contents of the buffer + * have been copied into it. + * + * @return the current contents of this output stream, as a byte array. + * @see java.io.ByteArrayOutputStream#size() + */ + public byte toByteArray()[] { + return buf; + } + + /** + * Returns the current size of the buffer. + * + * @return the value of the count field, which is the number + * of valid bytes in this output stream. + * @see java.io.ByteArrayOutputStream#count + */ + public int size() { + return count; + } + + /** + * Converts the buffer's contents into a string decoding bytes using the + * platform's default character set. The length of the new String + * is a function of the character set, and hence may not be equal to the + * size of the buffer. + *

+ *

This method always replaces malformed-input and unmappable-character + * sequences with the default replacement string for the platform's + * default character set. The {@linkplain java.nio.charset.CharsetDecoder} + * class should be used when more control over the decoding process is + * required. + * + * @return String decoded from the buffer's contents. + * @since JDK1.1 + */ + public String toString() { + return new String(buf, 0, count); + } + + /** + * Converts the buffer's contents into a string by decoding the bytes using + * the specified {@link java.nio.charset.Charset charsetName}. The length of + * the new String is a function of the charset, and hence may not be + * equal to the length of the byte array. + *

+ *

This method always replaces malformed-input and unmappable-character + * sequences with this charset's default replacement string. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param charsetName the name of a supported + * {@linkplain java.nio.charset.Charset charset} + * @return String decoded from the buffer's contents. + * @throws java.io.UnsupportedEncodingException + * If the named charset is not supported + * @since JDK1.1 + */ + public String toString(String charsetName) + throws UnsupportedEncodingException { + return new String(buf, 0, count, charsetName); + } + + + /** + * Closing a ByteArrayOutputStream has no effect. The methods in + * this class can be called after the stream has been closed without + * generating an IOException. + *

+ */ + public void close() throws IOException { + } +} diff --git a/thrift/src/main/thrift/Command.thrift b/thrift/src/main/thrift/Command.thrift index 86c4f2b243a6..f1ecd4ba4d6f 100644 --- a/thrift/src/main/thrift/Command.thrift +++ b/thrift/src/main/thrift/Command.thrift @@ -1,11 +1,20 @@ -namespace java com.nhn.pinpoint.thrift.dto.command - -enum TThreadDumpType { - TARGET, - PENDING -} -struct TCommandThreadDump { - 1: TThreadDumpType type = TThreadDumpType.TARGET - 2: optional string name - 3: optional i64 pendingTimeMillis -} +namespace java com.nhn.pinpoint.thrift.dto.command + +enum TThreadDumpType { + TARGET, + PENDING +} +struct TCommandThreadDump { + 1: TThreadDumpType type = TThreadDumpType.TARGET + 2: optional string name + 3: optional i64 pendingTimeMillis +} +struct TCommandEcho { + 1: string message +} +struct TCommandTransfer { + 1: string applicationName + 2: string agentId + 3: optional i64 startTime + 4: binary payload +} diff --git a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactoryTest.java b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactoryTest.java index 69889fa0f9d0..fc255ae85d34 100644 --- a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactoryTest.java +++ b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseDeserializerFactoryTest.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.thrift.io; - -import junit.framework.Assert; - -import org.junit.Test; - -public class HeaderTBaseDeserializerFactoryTest { - - @Test - public void optionTest1() { - - HeaderTBaseSerializerFactory factory = new HeaderTBaseSerializerFactory(); - Assert.assertTrue(factory.isSafetyGuranteed()); - } - - @Test - public void optionTest2() { - HeaderTBaseSerializerFactory factory = new HeaderTBaseSerializerFactory(true, 1); - Assert.assertTrue(factory.isSafetyGuranteed()); - } - - @Test - public void optionTest() { - HeaderTBaseSerializerFactory factory = new HeaderTBaseSerializerFactory(false, 1); - Assert.assertFalse(factory.isSafetyGuranteed()); - } - - -} +package com.nhn.pinpoint.thrift.io; + +import junit.framework.Assert; + +import org.junit.Test; + +public class HeaderTBaseDeserializerFactoryTest { + + @Test + public void optionTest1() { + + HeaderTBaseSerializerFactory factory = new HeaderTBaseSerializerFactory(); + Assert.assertTrue(factory.isSafetyGuranteed()); + } + + @Test + public void optionTest2() { + HeaderTBaseSerializerFactory factory = new HeaderTBaseSerializerFactory(true, 1); + Assert.assertTrue(factory.isSafetyGuranteed()); + } + + @Test + public void optionTest() { + HeaderTBaseSerializerFactory factory = new HeaderTBaseSerializerFactory(false, 1); + Assert.assertFalse(factory.isSafetyGuranteed()); + } + + +} diff --git a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerTest.java b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerTest.java index f0f035dc0911..17a98a4c0d0c 100644 --- a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerTest.java +++ b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTBaseSerializerTest.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.thrift.io; - -import com.nhn.pinpoint.thrift.dto.TAgentInfo; - -import org.apache.thrift.TException; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; - -/** - * @author emeroad - */ -public class HeaderTBaseSerializerTest { - private final Logger logger = LoggerFactory.getLogger(HeaderTBaseSerializerTest.class.getName()); - - - @Test - public void testSerialize1() throws Exception { - HeaderTBaseSerializer serializer = new HeaderTBaseSerializerFactory(false).createSerializer(); - HeaderTBaseDeserializer deserializer = new HeaderTBaseDeserializerFactory().createDeserializer(); - - test(serializer, deserializer); - } - - @Test - public void testSerialize2() throws Exception { - HeaderTBaseSerializer serializer = new HeaderTBaseSerializerFactory().createSerializer(); - HeaderTBaseDeserializer deserializer = new HeaderTBaseDeserializerFactory().createDeserializer(); - - test(serializer, deserializer); - } - - private void test(HeaderTBaseSerializer serializer, HeaderTBaseDeserializer deserializer) throws TException { - - Header header = new Header(); - // 10 을 JVMInfoThriftDTO type - header.setType((short) 10); - - TAgentInfo tAgentInfo = new TAgentInfo(); - tAgentInfo.setAgentId("agentId"); - tAgentInfo.setHostname("host"); - tAgentInfo.setApplicationName("applicationName"); - - byte[] serialize = serializer.serialize(tAgentInfo); - dump(serialize); - - TAgentInfo deserialize = (TAgentInfo) deserializer.deserialize(serialize); - logger.debug("deserializer:{}", deserialize.getClass()); - - Assert.assertEquals(deserialize, tAgentInfo); - } - - public void dump(byte[] data) { - String s = Arrays.toString(data); - logger.debug("size:{} data:{}", data.length, s); - } -} +package com.nhn.pinpoint.thrift.io; + +import com.nhn.pinpoint.thrift.dto.TAgentInfo; + +import org.apache.thrift.TException; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +/** + * @author emeroad + */ +public class HeaderTBaseSerializerTest { + private final Logger logger = LoggerFactory.getLogger(HeaderTBaseSerializerTest.class.getName()); + + + @Test + public void testSerialize1() throws Exception { + HeaderTBaseSerializer serializer = new HeaderTBaseSerializerFactory(false).createSerializer(); + HeaderTBaseDeserializer deserializer = new HeaderTBaseDeserializerFactory().createDeserializer(); + + test(serializer, deserializer); + } + + @Test + public void testSerialize2() throws Exception { + HeaderTBaseSerializer serializer = new HeaderTBaseSerializerFactory().createSerializer(); + HeaderTBaseDeserializer deserializer = new HeaderTBaseDeserializerFactory().createDeserializer(); + + test(serializer, deserializer); + } + + private void test(HeaderTBaseSerializer serializer, HeaderTBaseDeserializer deserializer) throws TException { + + Header header = new Header(); + // 10 을 JVMInfoThriftDTO type + header.setType((short) 10); + + TAgentInfo tAgentInfo = new TAgentInfo(); + tAgentInfo.setAgentId("agentId"); + tAgentInfo.setHostname("host"); + tAgentInfo.setApplicationName("applicationName"); + + byte[] serialize = serializer.serialize(tAgentInfo); + dump(serialize); + + TAgentInfo deserialize = (TAgentInfo) deserializer.deserialize(serialize); + logger.debug("deserializer:{}", deserialize.getClass()); + + Assert.assertEquals(deserialize, tAgentInfo); + } + + public void dump(byte[] data) { + String s = Arrays.toString(data); + logger.debug("size:{} data:{}", data.length, s); + } +} diff --git a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTest.java b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTest.java index 5be67ce01a9c..e3748dec0bcb 100644 --- a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTest.java +++ b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderTest.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.thrift.io; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class HeaderTest { - - private final Logger logger = LoggerFactory.getLogger(Header.class.getName()); - - @Test - public void testGetSignature() throws Exception { - Header header = new Header(); - byte signature = header.getSignature(); - short type = header.getType(); - byte version = header.getVersion(); - } -} +package com.nhn.pinpoint.thrift.io; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class HeaderTest { + + private final Logger logger = LoggerFactory.getLogger(Header.class.getName()); + + @Test + public void testGetSignature() throws Exception { + Header header = new Header(); + byte signature = header.getSignature(); + short type = header.getType(); + byte version = header.getVersion(); + } +} diff --git a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderUtilsTest.java b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderUtilsTest.java index a5be1209e8f2..ff49bd204320 100644 --- a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderUtilsTest.java +++ b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/HeaderUtilsTest.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.thrift.io; - -import org.apache.thrift.TException; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class HeaderUtilsTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - @Test - public void validateSignature() throws TException { - Header header = new Header(); - Assert.assertTrue(HeaderUtils.validateSignature(header.getSignature()) == HeaderUtils.OK); - - - Header error = new Header((byte) 0x11, (byte) 0x20, (short) 1); - Assert.assertTrue(HeaderUtils.validateSignature(error.getSignature()) != HeaderUtils.OK); - - - logger.info(header.toString()); - } - -} +package com.nhn.pinpoint.thrift.io; + +import org.apache.thrift.TException; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class HeaderUtilsTest { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Test + public void validateSignature() throws TException { + Header header = new Header(); + Assert.assertTrue(HeaderUtils.validateSignature(header.getSignature()) == HeaderUtils.OK); + + + Header error = new Header((byte) 0x11, (byte) 0x20, (short) 1); + Assert.assertTrue(HeaderUtils.validateSignature(error.getSignature()) != HeaderUtils.OK); + + + logger.info(header.toString()); + } + +} diff --git a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/PacketUtilsTest.java b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/PacketUtilsTest.java index a9b9267eddf6..b97a7f8bca90 100644 --- a/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/PacketUtilsTest.java +++ b/thrift/src/test/java/com/navercorp/pinpoint/thrift/io/PacketUtilsTest.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.thrift.io; - - -import org.junit.Assert; -import org.junit.Test; - -import java.net.DatagramPacket; -import java.util.Arrays; - -/** - * @author emeroad - */ -public class PacketUtilsTest { - @Test - public void testSliceData1() throws Exception { - DatagramPacket packet = createPacket(10); - packet.setLength(5); - - - byte[] bytes1 = PacketUtils.sliceData(packet, 0); - Assert.assertEquals(bytes1.length, 5); - } - - @Test - public void testSliceData2() throws Exception { - DatagramPacket packet = createPacket(10); - Arrays.fill(packet.getData(), 1, 8, (byte)'a'); - - byte[] bytes1 = PacketUtils.sliceData(packet, 0); - Assert.assertArrayEquals(bytes1, packet.getData()); - } - - - @Test - public void testSliceData3() throws Exception { - DatagramPacket packet = createPacket(10); - Arrays.fill(packet.getData(), 1, 8, (byte)'a'); - packet.setLength(4); - - byte[] bytes1 = PacketUtils.sliceData(packet, 0); - Assert.assertArrayEquals(bytes1, Arrays.copyOf(packet.getData(), 4)); - } - - private DatagramPacket createPacket(int size) { - byte[] bytes = new byte[size]; - return new DatagramPacket(bytes, 0, bytes.length); - } -} +package com.nhn.pinpoint.thrift.io; + + +import org.junit.Assert; +import org.junit.Test; + +import java.net.DatagramPacket; +import java.util.Arrays; + +/** + * @author emeroad + */ +public class PacketUtilsTest { + @Test + public void testSliceData1() throws Exception { + DatagramPacket packet = createPacket(10); + packet.setLength(5); + + + byte[] bytes1 = PacketUtils.sliceData(packet, 0); + Assert.assertEquals(bytes1.length, 5); + } + + @Test + public void testSliceData2() throws Exception { + DatagramPacket packet = createPacket(10); + Arrays.fill(packet.getData(), 1, 8, (byte)'a'); + + byte[] bytes1 = PacketUtils.sliceData(packet, 0); + Assert.assertArrayEquals(bytes1, packet.getData()); + } + + + @Test + public void testSliceData3() throws Exception { + DatagramPacket packet = createPacket(10); + Arrays.fill(packet.getData(), 1, 8, (byte)'a'); + packet.setLength(4); + + byte[] bytes1 = PacketUtils.sliceData(packet, 0); + Assert.assertArrayEquals(bytes1, Arrays.copyOf(packet.getData(), 4)); + } + + private DatagramPacket createPacket(int size) { + byte[] bytes = new byte[size]; + return new DatagramPacket(bytes, 0, bytes.length); + } +} diff --git a/web/findbugs-exclude.xml b/web/findbugs-exclude.xml index a4b4e8251d57..0193409a64e7 100644 --- a/web/findbugs-exclude.xml +++ b/web/findbugs-exclude.xml @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/web/src/.bowerrc b/web/src/.bowerrc index d528c255cca3..e2b3bc79dad1 100644 --- a/web/src/.bowerrc +++ b/web/src/.bowerrc @@ -1,3 +1,3 @@ -{ - "directory": "main/webapp/components" -} +{ + "directory": "main/webapp/components" +} diff --git a/web/src/karma.conf.js b/web/src/karma.conf.js index 4afda8620f4d..693449c66e19 100644 --- a/web/src/karma.conf.js +++ b/web/src/karma.conf.js @@ -1,56 +1,56 @@ -// Karma configuration - -// base path, that will be used to resolve files and exclude -basePath = ''; - -// list of files / patterns to load in the browser -files = [ - JASMINE, - JASMINE_ADAPTER, - 'main/webapp/components/angular/angular.js', - 'main/webapp/components/angular-mocks/angular-mocks.js', - 'main/webapp/components/angular-resource/angular-resource.js', - 'main/webapp/scripts/*.js', - 'main/webapp/scripts/**/*.js', - 'test/webapp/**/*.js' -]; - -// list of files to exclude -exclude = []; - -// test results reporter to use -// possible values: dots || progress || growl -reporters = ['progress']; - -// web server port -port = 8080; - -// cli runner port -runnerPort = 9100; - -// enable / disable colors in the output (reporters and logs) -colors = true; - -// level of logging -// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG -logLevel = LOG_INFO; - -// enable / disable watching file and executing tests whenever any file changes -autoWatch = true; - -// Start these browsers, currently available: -// - Chrome -// - ChromeCanary -// - Firefox -// - Opera -// - Safari (only Mac) -// - PhantomJS -// - IE (only Windows) -browsers = ['Chrome']; - -// If browser does not capture in given timeout [ms], kill it -captureTimeout = 5000; - -// Continuous Integration mode -// if true, it capture browsers, run tests and exit -singleRun = false; +// Karma configuration + +// base path, that will be used to resolve files and exclude +basePath = ''; + +// list of files / patterns to load in the browser +files = [ + JASMINE, + JASMINE_ADAPTER, + 'main/webapp/components/angular/angular.js', + 'main/webapp/components/angular-mocks/angular-mocks.js', + 'main/webapp/components/angular-resource/angular-resource.js', + 'main/webapp/scripts/*.js', + 'main/webapp/scripts/**/*.js', + 'test/webapp/**/*.js' +]; + +// list of files to exclude +exclude = []; + +// test results reporter to use +// possible values: dots || progress || growl +reporters = ['progress']; + +// web server port +port = 8080; + +// cli runner port +runnerPort = 9100; + +// enable / disable colors in the output (reporters and logs) +colors = true; + +// level of logging +// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG +logLevel = LOG_INFO; + +// enable / disable watching file and executing tests whenever any file changes +autoWatch = true; + +// Start these browsers, currently available: +// - Chrome +// - ChromeCanary +// - Firefox +// - Opera +// - Safari (only Mac) +// - PhantomJS +// - IE (only Windows) +browsers = ['Chrome']; + +// If browser does not capture in given timeout [ms], kill it +captureTimeout = 5000; + +// Continuous Integration mode +// if true, it capture browsers, run tests and exit +singleRun = false; diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmEvent.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmEvent.java index 188de3ab7034..3603f76ee760 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmEvent.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmEvent.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.web.alarm; - -import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; - -/** - * - * @author koo.taejin - */ -public interface AlarmEvent { - - // 머가 더 들어가야 할까 - - long getEventStartTimeMillis(); - - MapStatisticsCallerDao getMapStatisticsCallerDao(); - -} +package com.nhn.pinpoint.web.alarm; + +import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; + +/** + * + * @author koo.taejin + */ +public interface AlarmEvent { + + // 머가 더 들어가야 할까 + + long getEventStartTimeMillis(); + + MapStatisticsCallerDao getMapStatisticsCallerDao(); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJob.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJob.java index a1bfe8b5d92d..38a6238499d5 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJob.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJob.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.web.alarm; - - -public interface AlarmJob { - - boolean execute(AlarmEvent event); - -} +package com.nhn.pinpoint.web.alarm; + + +public interface AlarmJob { + + boolean execute(AlarmEvent event); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJobsRepository.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJobsRepository.java index 09842992df87..b502ac6fc80a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJobsRepository.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmJobsRepository.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.web.alarm; - -import java.util.List; - -import com.nhn.pinpoint.web.vo.Application; - -public interface AlarmJobsRepository { - - int getTotalJobCount(); - - List getAlarmJob(Application application); - - List getRegistedApplicationList(); - -} +package com.nhn.pinpoint.web.alarm; + +import java.util.List; + +import com.nhn.pinpoint.web.vo.Application; + +public interface AlarmJobsRepository { + + int getTotalJobCount(); + + List getAlarmJob(Application application); + + List getRegistedApplicationList(); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmMailTemplate.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmMailTemplate.java index 4ebb7b8ffac5..c6f58c0b8729 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmMailTemplate.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/AlarmMailTemplate.java @@ -1,56 +1,56 @@ -package com.nhn.pinpoint.web.alarm; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; -import com.nhn.pinpoint.web.alarm.resource.MailResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; -import com.nhn.pinpoint.web.vo.Application; - -public class AlarmMailTemplate { - - private static final String LINE_FEED = "
"; - private static final String LINK_FORMAT = "%s"; - - private final Application application; - private final MailResource mailResource; - private final AlarmEvent alarmEvent; - - public AlarmMailTemplate(Application application, MailResource mailResource, AlarmEvent alarmEvent) { - this.application = application; - this.mailResource = mailResource; - this.alarmEvent = alarmEvent; - } - - public String createSubject() { - return String.format(mailResource.getSubject(), application.getName()); - } - - public String createBody(List alarmCheckFilterList) { - StringBuilder body = new StringBuilder(); - body.append(application); - body.append(" Alarm."); - body.append(LINE_FEED); - - body.append("

    "); - for (AlarmCheckFilter alarmCheckFilter : alarmCheckFilterList) { - AlarmRuleResource rule = alarmCheckFilter.getRule(); - - body.append("
  • "); - - body.append(String.format("%s
    ", rule.getMainCategory().getName() + " (" + rule.getSubCategory().getName() + ")")); - body.append(">= ").append(rule.getThresholdRule()).append(" ").append(rule.getSubCategory().getUnit()).append(" (").append(TimeUnit.MILLISECONDS.toMinutes(rule.getContinuosTime())).append(" min)
    "); - String url = mailResource.getPinpointUrl() + "/#/main/" + application.getName() + "@" + application.getCode() + "/" + TimeUnit.MILLISECONDS.toMinutes(rule.getContinuosTime()) + "/" + alarmEvent.getEventStartTimeMillis(); - body.append(String.format(LINK_FORMAT, url, url)); -// contents.append("
    "); - - body.append("
  • "); - } - body.append("
"); - - return body.toString(); - } - - -} +package com.nhn.pinpoint.web.alarm; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; +import com.nhn.pinpoint.web.alarm.resource.MailResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; +import com.nhn.pinpoint.web.vo.Application; + +public class AlarmMailTemplate { + + private static final String LINE_FEED = "
"; + private static final String LINK_FORMAT = "%s"; + + private final Application application; + private final MailResource mailResource; + private final AlarmEvent alarmEvent; + + public AlarmMailTemplate(Application application, MailResource mailResource, AlarmEvent alarmEvent) { + this.application = application; + this.mailResource = mailResource; + this.alarmEvent = alarmEvent; + } + + public String createSubject() { + return String.format(mailResource.getSubject(), application.getName()); + } + + public String createBody(List alarmCheckFilterList) { + StringBuilder body = new StringBuilder(); + body.append(application); + body.append(" Alarm."); + body.append(LINE_FEED); + + body.append("
    "); + for (AlarmCheckFilter alarmCheckFilter : alarmCheckFilterList) { + AlarmRuleResource rule = alarmCheckFilter.getRule(); + + body.append("
  • "); + + body.append(String.format("%s
    ", rule.getMainCategory().getName() + " (" + rule.getSubCategory().getName() + ")")); + body.append(">= ").append(rule.getThresholdRule()).append(" ").append(rule.getSubCategory().getUnit()).append(" (").append(TimeUnit.MILLISECONDS.toMinutes(rule.getContinuosTime())).append(" min)
    "); + String url = mailResource.getPinpointUrl() + "/#/main/" + application.getName() + "@" + application.getCode() + "/" + TimeUnit.MILLISECONDS.toMinutes(rule.getContinuosTime()) + "/" + alarmEvent.getEventStartTimeMillis(); + body.append(String.format(LINK_FORMAT, url, url)); +// contents.append("
    "); + + body.append("
  • "); + } + body.append("
"); + + return body.toString(); + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmEvent.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmEvent.java index bacf87cab01d..cabc8c3f8567 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmEvent.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmEvent.java @@ -1,27 +1,27 @@ -package com.nhn.pinpoint.web.alarm; - -import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; - -public class DefaultAlarmEvent implements AlarmEvent { - - private final long startEventTimeMillis; - private MapStatisticsCallerDao mapStatisticsCallerDao; - - public DefaultAlarmEvent(long startEventTimeMillis) { - this.startEventTimeMillis = startEventTimeMillis; - } - - @Override - public long getEventStartTimeMillis() { - return startEventTimeMillis; - } - - public MapStatisticsCallerDao getMapStatisticsCallerDao() { - return mapStatisticsCallerDao; - } - - public void setMapStatisticsCallerDao(MapStatisticsCallerDao mapStatisticsCallerDao) { - this.mapStatisticsCallerDao = mapStatisticsCallerDao; - } - -} +package com.nhn.pinpoint.web.alarm; + +import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; + +public class DefaultAlarmEvent implements AlarmEvent { + + private final long startEventTimeMillis; + private MapStatisticsCallerDao mapStatisticsCallerDao; + + public DefaultAlarmEvent(long startEventTimeMillis) { + this.startEventTimeMillis = startEventTimeMillis; + } + + @Override + public long getEventStartTimeMillis() { + return startEventTimeMillis; + } + + public MapStatisticsCallerDao getMapStatisticsCallerDao() { + return mapStatisticsCallerDao; + } + + public void setMapStatisticsCallerDao(MapStatisticsCallerDao mapStatisticsCallerDao) { + this.mapStatisticsCallerDao = mapStatisticsCallerDao; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJob.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJob.java index 0d5f97b52d5c..c6c71c95be80 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJob.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJob.java @@ -1,70 +1,70 @@ -package com.nhn.pinpoint.web.alarm; - -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; -import com.nhn.pinpoint.web.alarm.filter.AlarmFilter; -import com.nhn.pinpoint.web.alarm.filter.AlarmSendFilter; -import com.nhn.pinpoint.web.vo.Application; - -/** - * - * @author koo.taejin - */ -public class DefaultAlarmJob implements AlarmJob { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - - public DefaultAlarmJob(Application application) { - this.application = application; - } - - private final List checkFilterList = new ArrayList(); - private final List sendFilterList = new ArrayList(); - - @Override - public boolean execute(AlarmEvent event) { - logger.debug("{} {} execute. CheckFilterList={}, SendFilterList={}", application, this.getClass().getSimpleName(), checkFilterList, sendFilterList); - - for (AlarmCheckFilter checkFilter : this.checkFilterList) { - boolean isSatisfy = checkFilter.check(event); - logger.debug("{} filter Satisfy({})", checkFilter.getClass().getSimpleName(), isSatisfy); - if (!isSatisfy) { - return false; - } - } - - for (AlarmSendFilter sendFilter : this.sendFilterList) { - sendFilter.send(this.checkFilterList, event); - } - - return true; - } - - public void addFilter(List filterList) { - for (AlarmFilter filter : filterList) { - addFilter(filter); - } - } - - public boolean addFilter(AlarmFilter filter) { - if (filter instanceof AlarmSendFilter) { - sendFilterList.add((AlarmSendFilter) filter); - return true; - } - - if (filter instanceof AlarmCheckFilter) { - checkFilterList.add((AlarmCheckFilter) filter); - return true; - } - - return false; - } - -} +package com.nhn.pinpoint.web.alarm; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; +import com.nhn.pinpoint.web.alarm.filter.AlarmFilter; +import com.nhn.pinpoint.web.alarm.filter.AlarmSendFilter; +import com.nhn.pinpoint.web.vo.Application; + +/** + * + * @author koo.taejin + */ +public class DefaultAlarmJob implements AlarmJob { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + + public DefaultAlarmJob(Application application) { + this.application = application; + } + + private final List checkFilterList = new ArrayList(); + private final List sendFilterList = new ArrayList(); + + @Override + public boolean execute(AlarmEvent event) { + logger.debug("{} {} execute. CheckFilterList={}, SendFilterList={}", application, this.getClass().getSimpleName(), checkFilterList, sendFilterList); + + for (AlarmCheckFilter checkFilter : this.checkFilterList) { + boolean isSatisfy = checkFilter.check(event); + logger.debug("{} filter Satisfy({})", checkFilter.getClass().getSimpleName(), isSatisfy); + if (!isSatisfy) { + return false; + } + } + + for (AlarmSendFilter sendFilter : this.sendFilterList) { + sendFilter.send(this.checkFilterList, event); + } + + return true; + } + + public void addFilter(List filterList) { + for (AlarmFilter filter : filterList) { + addFilter(filter); + } + } + + public boolean addFilter(AlarmFilter filter) { + if (filter instanceof AlarmSendFilter) { + sendFilterList.add((AlarmSendFilter) filter); + return true; + } + + if (filter instanceof AlarmCheckFilter) { + checkFilterList.add((AlarmCheckFilter) filter); + return true; + } + + return false; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJobsRepository.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJobsRepository.java index 671f1193f87b..117572174a1c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJobsRepository.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/DefaultAlarmJobsRepository.java @@ -1,68 +1,68 @@ -package com.nhn.pinpoint.web.alarm; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.MapUtils; - -import com.nhn.pinpoint.web.vo.Application; - -public class DefaultAlarmJobsRepository implements AlarmJobsRepository { - - private final Map> repository = new HashMap>(); - - public DefaultAlarmJobsRepository() { - } - - @Override - public int getTotalJobCount() { - int totalCount = 0; - - Collection> values = repository.values(); - for (List value : values) { - totalCount += value.size(); - } - - return totalCount; - } - - public List addAlarmJob(Application application, AlarmJob job) { - List registedJobs = (List) MapUtils.getObject(repository, application, new ArrayList()); - registedJobs.add(job); - - repository.put(application, registedJobs); - - return registedJobs; - } - - public List getAlarmJob(Application application) { - List alarmJobList = repository.get(application); - - if (alarmJobList == null || alarmJobList.size() == 0) { - return Collections.emptyList(); - } - - List shallowCopyResult = new ArrayList(); - shallowCopyResult.addAll(alarmJobList); - return shallowCopyResult; - } - - public List getRegistedApplicationList() { - Set keyList = repository.keySet(); - - if (CollectionUtils.isEmpty(keyList)) { - return Collections.emptyList(); - } - - List shallowCopyResult = new ArrayList(); - shallowCopyResult.addAll(keyList); - return shallowCopyResult; - } - -} +package com.nhn.pinpoint.web.alarm; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; + +import com.nhn.pinpoint.web.vo.Application; + +public class DefaultAlarmJobsRepository implements AlarmJobsRepository { + + private final Map> repository = new HashMap>(); + + public DefaultAlarmJobsRepository() { + } + + @Override + public int getTotalJobCount() { + int totalCount = 0; + + Collection> values = repository.values(); + for (List value : values) { + totalCount += value.size(); + } + + return totalCount; + } + + public List addAlarmJob(Application application, AlarmJob job) { + List registedJobs = (List) MapUtils.getObject(repository, application, new ArrayList()); + registedJobs.add(job); + + repository.put(application, registedJobs); + + return registedJobs; + } + + public List getAlarmJob(Application application) { + List alarmJobList = repository.get(application); + + if (alarmJobList == null || alarmJobList.size() == 0) { + return Collections.emptyList(); + } + + List shallowCopyResult = new ArrayList(); + shallowCopyResult.addAll(alarmJobList); + return shallowCopyResult; + } + + public List getRegistedApplicationList() { + Set keyList = repository.keySet(); + + if (CollectionUtils.isEmpty(keyList)) { + return Collections.emptyList(); + } + + List shallowCopyResult = new ArrayList(); + shallowCopyResult.addAll(keyList); + return shallowCopyResult; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/MainCategory.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/MainCategory.java index 8a4736de191a..dc26faee5f54 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/MainCategory.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/MainCategory.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.web.alarm; - - -public enum MainCategory { - - // 받은 요청, 보낸 요청 등으로 나누면 될듯 - REQUEST_SENDED("REQUEST_SENDED", 1), - REQUEST_RECEIVED("REQUEST_RECEIVED", 2) - ; - - private final String name; - private final int code; - - private MainCategory(String name, int code) { - this.name = name; - this.code = code; - } - - public String getName() { - return name; - } - - public int getCode() { - return code; - } - - public static MainCategory getValue(String value) { - MainCategory[] categories = MainCategory.values(); - for (MainCategory category : categories) { - if (category.getName().equalsIgnoreCase(value)) { - return category; - } - } - - return null; - } - - public static MainCategory getValue(int code) { - for (MainCategory eachCategory : MainCategory.values()) { - if (eachCategory.getCode() == code) { - return eachCategory; - } - } - - return null; - } - -} +package com.nhn.pinpoint.web.alarm; + + +public enum MainCategory { + + // 받은 요청, 보낸 요청 등으로 나누면 될듯 + REQUEST_SENDED("REQUEST_SENDED", 1), + REQUEST_RECEIVED("REQUEST_RECEIVED", 2) + ; + + private final String name; + private final int code; + + private MainCategory(String name, int code) { + this.name = name; + this.code = code; + } + + public String getName() { + return name; + } + + public int getCode() { + return code; + } + + public static MainCategory getValue(String value) { + MainCategory[] categories = MainCategory.values(); + for (MainCategory category : categories) { + if (category.getName().equalsIgnoreCase(value)) { + return category; + } + } + + return null; + } + + public static MainCategory getValue(int code) { + for (MainCategory eachCategory : MainCategory.values()) { + if (eachCategory.getCode() == code) { + return eachCategory; + } + } + + return null; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/SubCategory.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/SubCategory.java index cd7528e6c8f2..44b79272adaf 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/SubCategory.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/SubCategory.java @@ -1,150 +1,150 @@ -package com.nhn.pinpoint.web.alarm; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; -import com.nhn.pinpoint.web.alarm.filter.AlarmFilter; -import com.nhn.pinpoint.web.alarm.filter.FailureCountFilter; -import com.nhn.pinpoint.web.alarm.filter.FailureRatesFilter; -import com.nhn.pinpoint.web.alarm.filter.SlowCountFilter; -import com.nhn.pinpoint.web.alarm.filter.SlowRatesFilter; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; -import com.nhn.pinpoint.web.vo.Application; - -/** - * - * @author koo.taejin - */ -public enum SubCategory { - - // 이후에 Filter가 늘어나게 되면 Decorator패턴으로 변경하는 것도 좋은 방법일듯함 - // 보낸 요청 받은 요청 - FAIL_RATE("FAIL_RATE", 1, "%", MainCategory.REQUEST_SENDED) { - @Override - public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { - AlarmCheckFilter filter = null; - if (MainCategory.REQUEST_SENDED == parent) { - filter = new FailureRatesFilter(application); - } - - if (filter != null) { - filter.initialize(rule); - } - - return filter; - } - }, - FAIL_COUNT("FAIL_COUNT", 2, " ", MainCategory.REQUEST_SENDED) { - @Override - public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { - AlarmCheckFilter filter = null; - if (MainCategory.REQUEST_SENDED == parent) { - filter = new FailureCountFilter(application); - } - - if (filter != null) { - filter.initialize(rule); - } - - return filter; - } - }, - SLOW_RATE("SLOW_RATE", 3, "%", MainCategory.REQUEST_SENDED) { - @Override - public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { - AlarmCheckFilter filter = null; - if (MainCategory.REQUEST_SENDED == parent) { - filter = new SlowRatesFilter(application); - } - - if (filter != null) { - filter.initialize(rule); - } - - return filter; - } - }, - SLOW_COUNT("SLOW_COUNT", 4, " ", MainCategory.REQUEST_SENDED) { - @Override - public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { - AlarmCheckFilter filter = null; - if (MainCategory.REQUEST_SENDED == parent) { - filter = new SlowCountFilter(application); - } - - if (filter != null) { - filter.initialize(rule); - } - - return filter; - } - }; - - private final String name; - private final int code; - private final List parentSupportCategoryList; - private final String unit; - - private SubCategory(String name, int code, String unit, MainCategory firstParentSupportCategory, MainCategory... otherParentSupportCategories) { - this.name = name; - this.code = code; - this.unit = unit; - - parentSupportCategoryList = new ArrayList(); - - parentSupportCategoryList.add(firstParentSupportCategory); - - Collections.addAll(parentSupportCategoryList, otherParentSupportCategories); - } - - public String getName() { - return name; - } - - public int getCode() { - return code; - } - - public String getUnit() { - return unit; - } - - private List getParentSupportCategoryList() { - return parentSupportCategoryList; - } - - AlarmFilter createAlarmFilter(Application application, AlarmRuleResource rule) throws Exception { - List parentSupportCategoryList = getParentSupportCategoryList(); - if (parentSupportCategoryList.size() == 1) { - return createAlarmFilter(application, parentSupportCategoryList.get(0), rule); - } else { - throw new Exception("Ambiguous ParentCategory Exception"); - } - } - - public abstract AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule); - - public static SubCategory getValue(String value) { - SubCategory[] categories = SubCategory.values(); - for (SubCategory category : categories) { - if (category.getName().equalsIgnoreCase(value)) { - return category; - } - } - - return null; - } - - public static SubCategory getValue(int code) { - for (SubCategory eachCategory : SubCategory.values()) { - if (eachCategory.getCode() == code) { - return eachCategory; - } - } - - return null; - } - -} +package com.nhn.pinpoint.web.alarm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; +import com.nhn.pinpoint.web.alarm.filter.AlarmFilter; +import com.nhn.pinpoint.web.alarm.filter.FailureCountFilter; +import com.nhn.pinpoint.web.alarm.filter.FailureRatesFilter; +import com.nhn.pinpoint.web.alarm.filter.SlowCountFilter; +import com.nhn.pinpoint.web.alarm.filter.SlowRatesFilter; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; +import com.nhn.pinpoint.web.vo.Application; + +/** + * + * @author koo.taejin + */ +public enum SubCategory { + + // 이후에 Filter가 늘어나게 되면 Decorator패턴으로 변경하는 것도 좋은 방법일듯함 + // 보낸 요청 받은 요청 + FAIL_RATE("FAIL_RATE", 1, "%", MainCategory.REQUEST_SENDED) { + @Override + public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { + AlarmCheckFilter filter = null; + if (MainCategory.REQUEST_SENDED == parent) { + filter = new FailureRatesFilter(application); + } + + if (filter != null) { + filter.initialize(rule); + } + + return filter; + } + }, + FAIL_COUNT("FAIL_COUNT", 2, " ", MainCategory.REQUEST_SENDED) { + @Override + public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { + AlarmCheckFilter filter = null; + if (MainCategory.REQUEST_SENDED == parent) { + filter = new FailureCountFilter(application); + } + + if (filter != null) { + filter.initialize(rule); + } + + return filter; + } + }, + SLOW_RATE("SLOW_RATE", 3, "%", MainCategory.REQUEST_SENDED) { + @Override + public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { + AlarmCheckFilter filter = null; + if (MainCategory.REQUEST_SENDED == parent) { + filter = new SlowRatesFilter(application); + } + + if (filter != null) { + filter.initialize(rule); + } + + return filter; + } + }, + SLOW_COUNT("SLOW_COUNT", 4, " ", MainCategory.REQUEST_SENDED) { + @Override + public AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule) { + AlarmCheckFilter filter = null; + if (MainCategory.REQUEST_SENDED == parent) { + filter = new SlowCountFilter(application); + } + + if (filter != null) { + filter.initialize(rule); + } + + return filter; + } + }; + + private final String name; + private final int code; + private final List parentSupportCategoryList; + private final String unit; + + private SubCategory(String name, int code, String unit, MainCategory firstParentSupportCategory, MainCategory... otherParentSupportCategories) { + this.name = name; + this.code = code; + this.unit = unit; + + parentSupportCategoryList = new ArrayList(); + + parentSupportCategoryList.add(firstParentSupportCategory); + + Collections.addAll(parentSupportCategoryList, otherParentSupportCategories); + } + + public String getName() { + return name; + } + + public int getCode() { + return code; + } + + public String getUnit() { + return unit; + } + + private List getParentSupportCategoryList() { + return parentSupportCategoryList; + } + + AlarmFilter createAlarmFilter(Application application, AlarmRuleResource rule) throws Exception { + List parentSupportCategoryList = getParentSupportCategoryList(); + if (parentSupportCategoryList.size() == 1) { + return createAlarmFilter(application, parentSupportCategoryList.get(0), rule); + } else { + throw new Exception("Ambiguous ParentCategory Exception"); + } + } + + public abstract AlarmCheckFilter createAlarmFilter(Application application, MainCategory parent, AlarmRuleResource rule); + + public static SubCategory getValue(String value) { + SubCategory[] categories = SubCategory.values(); + for (SubCategory category : categories) { + if (category.getName().equalsIgnoreCase(value)) { + return category; + } + } + + return null; + } + + public static SubCategory getValue(int code) { + for (SubCategory eachCategory : SubCategory.values()) { + if (eachCategory.getCode() == code) { + return eachCategory; + } + } + + return null; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckCountFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckCountFilter.java index 9d434748768e..7c028eab05ff 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckCountFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckCountFilter.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.web.alarm.filter; - -public abstract class AlarmCheckCountFilter extends AlarmCheckFilter { - - protected boolean check(long count) { - int threshold = getRule().getThresholdRule(); - - if (count >= threshold) { - return true; - } else { - return false; - } - } - -} +package com.nhn.pinpoint.web.alarm.filter; + +public abstract class AlarmCheckCountFilter extends AlarmCheckFilter { + + protected boolean check(long count) { + int threshold = getRule().getThresholdRule(); + + if (count >= threshold) { + return true; + } else { + return false; + } + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckFilter.java index 565b1b78c4ed..a9b821196bac 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckFilter.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; - -/** - * - * @author koo.taejin - */ -public abstract class AlarmCheckFilter implements AlarmFilter { - - private AlarmRuleResource rule; - - abstract public boolean check(AlarmEvent event); - - public void initialize(AlarmRuleResource rule) { - this.rule = rule; - } - - public AlarmRuleResource getRule() { - return rule; - } - -} +package com.nhn.pinpoint.web.alarm.filter; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; + +/** + * + * @author koo.taejin + */ +public abstract class AlarmCheckFilter implements AlarmFilter { + + private AlarmRuleResource rule; + + abstract public boolean check(AlarmEvent event); + + public void initialize(AlarmRuleResource rule) { + this.rule = rule; + } + + public AlarmRuleResource getRule() { + return rule; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckRatesFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckRatesFilter.java index 1dc943cb5a17..94e23762670f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckRatesFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmCheckRatesFilter.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.web.alarm.filter; - - -public abstract class AlarmCheckRatesFilter extends AlarmCheckFilter { - - protected boolean check(long count, long totalCount) { - int rates = getRates(count, totalCount); - - int threshold = getRule().getThresholdRule(); - - if (rates >= threshold) { - return true; - } else { - return false; - } - } - - private int getRates(long count, long totalCount) { - int percent = 0; - if (count == 0 || totalCount == 0) { - return percent; - } else { - percent = Math.round((count * 100) / totalCount); - } - - return percent; - } - -} +package com.nhn.pinpoint.web.alarm.filter; + + +public abstract class AlarmCheckRatesFilter extends AlarmCheckFilter { + + protected boolean check(long count, long totalCount) { + int rates = getRates(count, totalCount); + + int threshold = getRule().getThresholdRule(); + + if (rates >= threshold) { + return true; + } else { + return false; + } + } + + private int getRates(long count, long totalCount) { + int percent = 0; + if (count == 0 || totalCount == 0) { + return percent; + } else { + percent = Math.round((count * 100) / totalCount); + } + + return percent; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmFilter.java index be5fdd26cfa9..26ce17c5f88b 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmFilter.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.web.alarm.filter; - - -/** - * - * @author koo.taejin - */ -public interface AlarmFilter { - -} +package com.nhn.pinpoint.web.alarm.filter; + + +/** + * + * @author koo.taejin + */ +public interface AlarmFilter { + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmMailSendFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmMailSendFilter.java index c9a14855d606..c2eb5e911f31 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmMailSendFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmMailSendFilter.java @@ -1,98 +1,98 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import java.nio.charset.Charset; -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.alarm.AlarmMailTemplate; -import com.nhn.pinpoint.web.alarm.resource.MailResource; -import com.nhn.pinpoint.web.vo.Application; -import com.nhncorp.lucy.net.call.Fault; -import com.nhncorp.lucy.net.call.Reply; -import com.nhncorp.lucy.net.call.ReturnValue; -import com.nhncorp.lucy.net.invoker.InvocationFuture; -import com.nhncorp.lucy.npc.connector.NpcConnectionFactory; -import com.nhncorp.lucy.npc.connector.NpcHessianConnector; - -/** - * - * @author koo.taejin - */ -public class AlarmMailSendFilter extends AlarmSendFilter { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private static final String ADDR_SEPARATOR = ";"; - - private final Application application; - private final MailResource mailResource; - private final List receiverList; - - public AlarmMailSendFilter(Application application, MailResource mailResource, List receiverList) { - this.application = application; - this.mailResource = mailResource; - this.receiverList = receiverList; - } - - @Override - public boolean send(List alarmCheckFilterList, AlarmEvent event) { - NpcConnectionFactory factory = new NpcConnectionFactory(); - factory.setBoxDirectoryServiceHostName(mailResource.getUrl()); - factory.setCharset(Charset.forName("UTF-8")); - factory.setLightWeight(true); - - NpcHessianConnector connector = null; - try { - connector = factory.create(); - - AlarmMailTemplate mailTemplate = new AlarmMailTemplate(application, mailResource, event); - - Object[] params = createSendMailParams(alarmCheckFilterList, mailTemplate); - - InvocationFuture future = connector.invoke(null, "send", params); - future.await(); - Reply reply = (Reply) future.getReturnValue(); - if (reply instanceof ReturnValue) { - Object result = ((ReturnValue) reply).get(); - logger.debug("MessageId:{}", result); - return true; - } else if (reply instanceof Fault) { - String code = ((Fault) reply).getCode(); - String message = ((Fault) reply).getMessage(); - logger.warn("Unexpected result:code={}, message={}", code, message); - } else { - logger.warn("Unexpected clazz({}).", reply.getClass()); - } - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } finally { - if (connector != null) { - connector.dispose(); - } - } - - // TODO Auto-generated method stub - return false; - } - - private Object[] createSendMailParams(List alarmCheckFilterList, AlarmMailTemplate mailTemplate) { - return new Object[] { - mailResource.getServiceId(), - mailResource.getOption(), - mailResource.getSenderEmailAddress(), /* 보낸이 */ - "", /* 답장 받을 주소 */ - joinAddresses(receiverList), /* 받는이 */ - mailTemplate.createSubject(), - mailTemplate.createBody(alarmCheckFilterList) - }; - } - - private String joinAddresses(List addresses) { - return StringUtils.join(addresses, ADDR_SEPARATOR); - } - -} +package com.nhn.pinpoint.web.alarm.filter; + +import java.nio.charset.Charset; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.alarm.AlarmMailTemplate; +import com.nhn.pinpoint.web.alarm.resource.MailResource; +import com.nhn.pinpoint.web.vo.Application; +import com.nhncorp.lucy.net.call.Fault; +import com.nhncorp.lucy.net.call.Reply; +import com.nhncorp.lucy.net.call.ReturnValue; +import com.nhncorp.lucy.net.invoker.InvocationFuture; +import com.nhncorp.lucy.npc.connector.NpcConnectionFactory; +import com.nhncorp.lucy.npc.connector.NpcHessianConnector; + +/** + * + * @author koo.taejin + */ +public class AlarmMailSendFilter extends AlarmSendFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final String ADDR_SEPARATOR = ";"; + + private final Application application; + private final MailResource mailResource; + private final List receiverList; + + public AlarmMailSendFilter(Application application, MailResource mailResource, List receiverList) { + this.application = application; + this.mailResource = mailResource; + this.receiverList = receiverList; + } + + @Override + public boolean send(List alarmCheckFilterList, AlarmEvent event) { + NpcConnectionFactory factory = new NpcConnectionFactory(); + factory.setBoxDirectoryServiceHostName(mailResource.getUrl()); + factory.setCharset(Charset.forName("UTF-8")); + factory.setLightWeight(true); + + NpcHessianConnector connector = null; + try { + connector = factory.create(); + + AlarmMailTemplate mailTemplate = new AlarmMailTemplate(application, mailResource, event); + + Object[] params = createSendMailParams(alarmCheckFilterList, mailTemplate); + + InvocationFuture future = connector.invoke(null, "send", params); + future.await(); + Reply reply = (Reply) future.getReturnValue(); + if (reply instanceof ReturnValue) { + Object result = ((ReturnValue) reply).get(); + logger.debug("MessageId:{}", result); + return true; + } else if (reply instanceof Fault) { + String code = ((Fault) reply).getCode(); + String message = ((Fault) reply).getMessage(); + logger.warn("Unexpected result:code={}, message={}", code, message); + } else { + logger.warn("Unexpected clazz({}).", reply.getClass()); + } + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } finally { + if (connector != null) { + connector.dispose(); + } + } + + // TODO Auto-generated method stub + return false; + } + + private Object[] createSendMailParams(List alarmCheckFilterList, AlarmMailTemplate mailTemplate) { + return new Object[] { + mailResource.getServiceId(), + mailResource.getOption(), + mailResource.getSenderEmailAddress(), /* 보낸이 */ + "", /* 답장 받을 주소 */ + joinAddresses(receiverList), /* 받는이 */ + mailTemplate.createSubject(), + mailTemplate.createBody(alarmCheckFilterList) + }; + } + + private String joinAddresses(List addresses) { + return StringUtils.join(addresses, ADDR_SEPARATOR); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSendFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSendFilter.java index a739d1478627..5b397d910689 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSendFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSendFilter.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import java.util.List; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; - -/** - * - * @author koo.taejin - */ -public abstract class AlarmSendFilter implements AlarmFilter { - - abstract public boolean send(List checkFilterList, AlarmEvent event); - -} +package com.nhn.pinpoint.web.alarm.filter; + +import java.util.List; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; + +/** + * + * @author koo.taejin + */ +public abstract class AlarmSendFilter implements AlarmFilter { + + abstract public boolean send(List checkFilterList, AlarmEvent event); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSmsSendFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSmsSendFilter.java index c2cac9a82443..9cbd4e4d3416 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSmsSendFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/AlarmSmsSendFilter.java @@ -1,79 +1,79 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.alarm.resource.SmsResource; -import com.nhn.pinpoint.web.vo.Application; - -/** - * - * @author koo.taejin - */ -public class AlarmSmsSendFilter extends AlarmSendFilter { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private static final String QUOTATATION = "\""; - - private final Application application; - private final SmsResource smsResource; - private final List receiverList; - - public AlarmSmsSendFilter(Application application, SmsResource smsResource, List receiverList) { - this.application = application; - this.smsResource = smsResource; - this.receiverList = receiverList; - } - - @Override - public boolean send(List alarmCheckFilterList, AlarmEvent event) { - DefaultHttpClient client = new DefaultHttpClient(); - - List nvps = new ArrayList(); - nvps.add(new BasicNameValuePair("serviceId", smsResource.getServiceId())); - nvps.add(new BasicNameValuePair("sendMdn", QUOTATATION + smsResource.getSenderPhoneNumber() + QUOTATATION)); - nvps.add(new BasicNameValuePair("receiveMdnList", convertToReceiverFormat(receiverList))); - nvps.add(new BasicNameValuePair("content", QUOTATATION + null + QUOTATATION)); - - HttpGet get = new HttpGet(smsResource.getUrl() + "?" + URLEncodedUtils.format(nvps, "UTF-8")); - - logger.debug("{}", get.getURI()); - - try { - HttpResponse response = client.execute(get); - if (response != null) { - HttpEntity entity = response.getEntity(); - // 이작업 자체가 닫는거랑 같음 - logger.debug("result={}", EntityUtils.toString(entity)); - } - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } finally { - // 이건 일단 이렇게 하고 나중에 성능을 위해서 바꾸장 - client.getConnectionManager().shutdown(); - } - return false; - } - - private String convertToReceiverFormat(List receivers) { - List result = new ArrayList(); - for (String receiver : receivers) { - result.add(QUOTATATION + receiver + QUOTATATION); - } - return result.toString(); - } - -} +package com.nhn.pinpoint.web.alarm.filter; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.alarm.resource.SmsResource; +import com.nhn.pinpoint.web.vo.Application; + +/** + * + * @author koo.taejin + */ +public class AlarmSmsSendFilter extends AlarmSendFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final String QUOTATATION = "\""; + + private final Application application; + private final SmsResource smsResource; + private final List receiverList; + + public AlarmSmsSendFilter(Application application, SmsResource smsResource, List receiverList) { + this.application = application; + this.smsResource = smsResource; + this.receiverList = receiverList; + } + + @Override + public boolean send(List alarmCheckFilterList, AlarmEvent event) { + DefaultHttpClient client = new DefaultHttpClient(); + + List nvps = new ArrayList(); + nvps.add(new BasicNameValuePair("serviceId", smsResource.getServiceId())); + nvps.add(new BasicNameValuePair("sendMdn", QUOTATATION + smsResource.getSenderPhoneNumber() + QUOTATATION)); + nvps.add(new BasicNameValuePair("receiveMdnList", convertToReceiverFormat(receiverList))); + nvps.add(new BasicNameValuePair("content", QUOTATATION + null + QUOTATATION)); + + HttpGet get = new HttpGet(smsResource.getUrl() + "?" + URLEncodedUtils.format(nvps, "UTF-8")); + + logger.debug("{}", get.getURI()); + + try { + HttpResponse response = client.execute(get); + if (response != null) { + HttpEntity entity = response.getEntity(); + // 이작업 자체가 닫는거랑 같음 + logger.debug("result={}", EntityUtils.toString(entity)); + } + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } finally { + // 이건 일단 이렇게 하고 나중에 성능을 위해서 바꾸장 + client.getConnectionManager().shutdown(); + } + return false; + } + + private String convertToReceiverFormat(List receivers) { + List result = new ArrayList(); + for (String receiver : receivers) { + result.add(QUOTATATION + receiver + QUOTATATION); + } + return result.toString(); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureCountFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureCountFilter.java index bb0eebc50179..2a1f515e78c1 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureCountFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureCountFilter.java @@ -1,87 +1,87 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import java.util.Collection; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; -import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; - -/** - * - * @author koo.taejin - */ -public class FailureCountFilter extends AlarmCheckCountFilter { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - - public FailureCountFilter(Application application) { - this.application = application; - } - - @Override - public boolean check(AlarmEvent event) { - logger.debug("{} check.", this.getClass().getSimpleName()); - - MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); - if (dao == null) { - logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); - return false; - } - - long startEventTimeMillis = event.getEventStartTimeMillis(); - - // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 - // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? - // 일단은 아주 단순하게 - int continuationTime = getRule().getContinuosTime(); - Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); - - LinkDataMap linkDataMap = dao.selectCaller(application, range); - for (LinkData linkData : linkDataMap.getLinkDataList()) { - Application toApplication = linkData.getToApplication(); -// if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { -// logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); -// continue; -// } - - AgentHistogramList sourceList = linkData.getSourceList(); - Collection agentHistogramList = sourceList.getAgentHistogramList(); - - boolean isSatisFied = checkCounts(toApplication, agentHistogramList); - if (isSatisFied) { - return true; - } - } - - return false; - } - - private boolean checkCounts(Application toApplication, Collection agentHistogramList) { - long totalCount = 0; - long successCount = 0; - long errorCount = 0; - - for (AgentHistogram agent : agentHistogramList) { - for (TimeHistogram time : agent.getTimeHistogram()) { - totalCount += time.getTotalCount(); - successCount += time.getSuccessCount(); - errorCount = time.getErrorCount(); - } - } - logger.info("{} -> {} {}/{}(error={})", application.getName(), toApplication.getName(), successCount, totalCount, errorCount); - - return check(errorCount); - } - -} +package com.nhn.pinpoint.web.alarm.filter; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; +import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; + +/** + * + * @author koo.taejin + */ +public class FailureCountFilter extends AlarmCheckCountFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + + public FailureCountFilter(Application application) { + this.application = application; + } + + @Override + public boolean check(AlarmEvent event) { + logger.debug("{} check.", this.getClass().getSimpleName()); + + MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); + if (dao == null) { + logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); + return false; + } + + long startEventTimeMillis = event.getEventStartTimeMillis(); + + // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 + // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? + // 일단은 아주 단순하게 + int continuationTime = getRule().getContinuosTime(); + Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); + + LinkDataMap linkDataMap = dao.selectCaller(application, range); + for (LinkData linkData : linkDataMap.getLinkDataList()) { + Application toApplication = linkData.getToApplication(); +// if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { +// logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); +// continue; +// } + + AgentHistogramList sourceList = linkData.getSourceList(); + Collection agentHistogramList = sourceList.getAgentHistogramList(); + + boolean isSatisFied = checkCounts(toApplication, agentHistogramList); + if (isSatisFied) { + return true; + } + } + + return false; + } + + private boolean checkCounts(Application toApplication, Collection agentHistogramList) { + long totalCount = 0; + long successCount = 0; + long errorCount = 0; + + for (AgentHistogram agent : agentHistogramList) { + for (TimeHistogram time : agent.getTimeHistogram()) { + totalCount += time.getTotalCount(); + successCount += time.getSuccessCount(); + errorCount = time.getErrorCount(); + } + } + logger.info("{} -> {} {}/{}(error={})", application.getName(), toApplication.getName(), successCount, totalCount, errorCount); + + return check(errorCount); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureRatesFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureRatesFilter.java index 51ffe8f9696c..f933bde3a16e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureRatesFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/FailureRatesFilter.java @@ -1,88 +1,88 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import java.util.Collection; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; -import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; - -/** - * - * @author koo.taejin - */ -public class FailureRatesFilter extends AlarmCheckRatesFilter { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - - public FailureRatesFilter(Application application) { - this.application = application; - } - - @Override - public boolean check(AlarmEvent event) { - logger.debug("{} check.", this.getClass().getSimpleName()); - - MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); - if (dao == null) { - logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); - return false; - } - - long startEventTimeMillis = event.getEventStartTimeMillis(); - - // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 - // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? - // 일단은 아주 단순하게 - int continuationTime = getRule().getContinuosTime(); - Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); - - LinkDataMap linkDataMap = dao.selectCaller(application, range); - for (LinkData linkData : linkDataMap.getLinkDataList()) { - Application toApplication = linkData.getToApplication(); -// if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { -// logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); -// continue; -// } - - AgentHistogramList sourceList = linkData.getSourceList(); - Collection agentHistogramList = sourceList.getAgentHistogramList(); - - boolean isSatisFied = checkRates(toApplication, agentHistogramList); - if (isSatisFied) { - return true; - } - } - - return false; - } - - private boolean checkRates(Application toApplication, Collection agentHistogramList) { - long totalCount = 0; - long successCount = 0; - long slowCount = 0; - long errorCount = 0; - - for (AgentHistogram agent : agentHistogramList) { - for (TimeHistogram time : agent.getTimeHistogram()) { - totalCount += time.getTotalCount(); - successCount += time.getSuccessCount(); - slowCount += time.getSlowCount(); - errorCount = time.getErrorCount(); - } - } - logger.info("{} -> {} {}/{}(slow={}, error={})", application.getName(), toApplication.getName(), successCount, totalCount, slowCount, errorCount); - - return check(errorCount, totalCount); - } -} +package com.nhn.pinpoint.web.alarm.filter; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; +import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; + +/** + * + * @author koo.taejin + */ +public class FailureRatesFilter extends AlarmCheckRatesFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + + public FailureRatesFilter(Application application) { + this.application = application; + } + + @Override + public boolean check(AlarmEvent event) { + logger.debug("{} check.", this.getClass().getSimpleName()); + + MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); + if (dao == null) { + logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); + return false; + } + + long startEventTimeMillis = event.getEventStartTimeMillis(); + + // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 + // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? + // 일단은 아주 단순하게 + int continuationTime = getRule().getContinuosTime(); + Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); + + LinkDataMap linkDataMap = dao.selectCaller(application, range); + for (LinkData linkData : linkDataMap.getLinkDataList()) { + Application toApplication = linkData.getToApplication(); +// if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { +// logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); +// continue; +// } + + AgentHistogramList sourceList = linkData.getSourceList(); + Collection agentHistogramList = sourceList.getAgentHistogramList(); + + boolean isSatisFied = checkRates(toApplication, agentHistogramList); + if (isSatisFied) { + return true; + } + } + + return false; + } + + private boolean checkRates(Application toApplication, Collection agentHistogramList) { + long totalCount = 0; + long successCount = 0; + long slowCount = 0; + long errorCount = 0; + + for (AgentHistogram agent : agentHistogramList) { + for (TimeHistogram time : agent.getTimeHistogram()) { + totalCount += time.getTotalCount(); + successCount += time.getSuccessCount(); + slowCount += time.getSlowCount(); + errorCount = time.getErrorCount(); + } + } + logger.info("{} -> {} {}/{}(slow={}, error={})", application.getName(), toApplication.getName(), successCount, totalCount, slowCount, errorCount); + + return check(errorCount, totalCount); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowCountFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowCountFilter.java index b5e8c018cc04..3872f4df26e8 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowCountFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowCountFilter.java @@ -1,82 +1,82 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import java.util.Collection; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; -import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; - -public class SlowCountFilter extends AlarmCheckCountFilter { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - - public SlowCountFilter(Application application) { - this.application = application; - } - - @Override - public boolean check(AlarmEvent event) { - logger.debug("{} check.", this.getClass().getSimpleName()); - - MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); - if (dao == null) { - logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); - return false; - } - - long startEventTimeMillis = event.getEventStartTimeMillis(); - - // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 - // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? - // 일단은 아주 단순하게 - int continuationTime = getRule().getContinuosTime(); - Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); - - LinkDataMap linkDataMap = dao.selectCaller(application, range); - for (LinkData linkData : linkDataMap.getLinkDataList()) { - Application toApplication = linkData.getToApplication(); - if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { - logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); - continue; - } - - AgentHistogramList sourceList = linkData.getSourceList(); - Collection agentHistogramList = sourceList.getAgentHistogramList(); - - boolean isSatisFied = checkCounts(toApplication, agentHistogramList, event); - if (isSatisFied) { - return true; - } - } - - return false; - } - - private boolean checkCounts(Application toApplication, Collection agentHistogramList, AlarmEvent event) { - long totalCount = 0; - long successCount = 0; - long slowCount = 0; - - for (AgentHistogram agent : agentHistogramList) { - for (TimeHistogram time : agent.getTimeHistogram()) { - totalCount += time.getTotalCount(); - slowCount += time.getSlowCount(); - } - } - logger.info("{} -> {} {}/{}(slow={})", application.getName(), toApplication.getName(), successCount, totalCount, slowCount); - - return check(slowCount); - } - -} +package com.nhn.pinpoint.web.alarm.filter; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; +import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; + +public class SlowCountFilter extends AlarmCheckCountFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + + public SlowCountFilter(Application application) { + this.application = application; + } + + @Override + public boolean check(AlarmEvent event) { + logger.debug("{} check.", this.getClass().getSimpleName()); + + MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); + if (dao == null) { + logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); + return false; + } + + long startEventTimeMillis = event.getEventStartTimeMillis(); + + // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 + // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? + // 일단은 아주 단순하게 + int continuationTime = getRule().getContinuosTime(); + Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); + + LinkDataMap linkDataMap = dao.selectCaller(application, range); + for (LinkData linkData : linkDataMap.getLinkDataList()) { + Application toApplication = linkData.getToApplication(); + if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { + logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); + continue; + } + + AgentHistogramList sourceList = linkData.getSourceList(); + Collection agentHistogramList = sourceList.getAgentHistogramList(); + + boolean isSatisFied = checkCounts(toApplication, agentHistogramList, event); + if (isSatisFied) { + return true; + } + } + + return false; + } + + private boolean checkCounts(Application toApplication, Collection agentHistogramList, AlarmEvent event) { + long totalCount = 0; + long successCount = 0; + long slowCount = 0; + + for (AgentHistogram agent : agentHistogramList) { + for (TimeHistogram time : agent.getTimeHistogram()) { + totalCount += time.getTotalCount(); + slowCount += time.getSlowCount(); + } + } + logger.info("{} -> {} {}/{}(slow={})", application.getName(), toApplication.getName(), successCount, totalCount, slowCount); + + return check(slowCount); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowRatesFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowRatesFilter.java index e81436ab624f..39648d9ac3b8 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowRatesFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/filter/SlowRatesFilter.java @@ -1,85 +1,85 @@ -package com.nhn.pinpoint.web.alarm.filter; - -import java.util.Collection; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; -import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; - -/** - * - * @author koo.taejin - */ -public class SlowRatesFilter extends AlarmCheckRatesFilter { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - - public SlowRatesFilter(Application application) { - this.application = application; - } - - @Override - public boolean check(AlarmEvent event) { - logger.debug("{} check.", this.getClass().getSimpleName()); - - MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); - if (dao == null) { - logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); - return false; - } - - long startEventTimeMillis = event.getEventStartTimeMillis(); - - // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 - // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? - // 일단은 아주 단순하게 - int continuationTime = getRule().getContinuosTime(); - Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); - - LinkDataMap linkDataMap = dao.selectCaller(application, range); - for (LinkData linkData : linkDataMap.getLinkDataList()) { - Application toApplication = linkData.getToApplication(); - if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { - logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); - continue; - } - - AgentHistogramList sourceList = linkData.getSourceList(); - Collection agentHistogramList = sourceList.getAgentHistogramList(); - - boolean isSatisFied = checkRates(toApplication, agentHistogramList); - if (isSatisFied) { - return true; - } - } - - return false; - } - - private boolean checkRates(Application toApplication, Collection agentHistogramList) { - long totalCount = 0; - long successCount = 0; - long slowCount = 0; - - for (AgentHistogram agent : agentHistogramList) { - for (TimeHistogram time : agent.getTimeHistogram()) { - totalCount += time.getTotalCount(); - slowCount += time.getSlowCount(); - } - } - logger.info("{} -> {} {}/{}(slow={})", application.getName(), toApplication.getName(), successCount, totalCount, slowCount); - - return check(slowCount, totalCount); - } +package com.nhn.pinpoint.web.alarm.filter; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkData; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; +import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; + +/** + * + * @author koo.taejin + */ +public class SlowRatesFilter extends AlarmCheckRatesFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + + public SlowRatesFilter(Application application) { + this.application = application; + } + + @Override + public boolean check(AlarmEvent event) { + logger.debug("{} check.", this.getClass().getSimpleName()); + + MapStatisticsCallerDao dao = event.getMapStatisticsCallerDao(); + if (dao == null) { + logger.warn("{} object is null.", MapStatisticsCallerDao.class.getSimpleName()); + return false; + } + + long startEventTimeMillis = event.getEventStartTimeMillis(); + + // 이것도 CheckTImeMillis의 시간이 길면 나누어야 함 + // 추가적으로 시간이 범위에 있는 만큼 다 안들어 오면 ?? + // 일단은 아주 단순하게 + int continuationTime = getRule().getContinuosTime(); + Range range = Range.createUncheckedRange(startEventTimeMillis - continuationTime, startEventTimeMillis); + + LinkDataMap linkDataMap = dao.selectCaller(application, range); + for (LinkData linkData : linkDataMap.getLinkDataList()) { + Application toApplication = linkData.getToApplication(); + if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) { + logger.debug("Application({}) is invalid serviceType. this is skip.", toApplication.getName()); + continue; + } + + AgentHistogramList sourceList = linkData.getSourceList(); + Collection agentHistogramList = sourceList.getAgentHistogramList(); + + boolean isSatisFied = checkRates(toApplication, agentHistogramList); + if (isSatisFied) { + return true; + } + } + + return false; + } + + private boolean checkRates(Application toApplication, Collection agentHistogramList) { + long totalCount = 0; + long successCount = 0; + long slowCount = 0; + + for (AgentHistogram agent : agentHistogramList) { + for (TimeHistogram time : agent.getTimeHistogram()) { + totalCount += time.getTotalCount(); + slowCount += time.getSlowCount(); + } + } + logger.info("{} -> {} {}/{}(slow={})", application.getName(), toApplication.getName(), successCount, totalCount, slowCount); + + return check(slowCount, totalCount); + } } \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResource.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResource.java index 4e255b32557d..aafdb73a295e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResource.java @@ -1,17 +1,17 @@ -package com.nhn.pinpoint.web.alarm.resource; - -public interface MailResource { - - String getPinpointUrl(); - - String getUrl(); - - String getServiceId(); - - String getSenderEmailAddress(); - - String getOption(); - - String getSubject(); - -} +package com.nhn.pinpoint.web.alarm.resource; + +public interface MailResource { + + String getPinpointUrl(); + + String getUrl(); + + String getServiceId(); + + String getSenderEmailAddress(); + + String getOption(); + + String getSubject(); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResourceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResourceImpl.java index c65b79dfc763..df983e2ccbe1 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResourceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/MailResourceImpl.java @@ -1,80 +1,80 @@ -package com.nhn.pinpoint.web.alarm.resource; - -import org.springframework.beans.factory.annotation.Value; - -/** - * - * @author koo.taejin - */ -public class MailResourceImpl implements MailResource { - - @Value("#{dataProps['pinpoint.url']}") - private String pinpointUrl; - @Value("#{dataProps['alarm.mail.url']}") - private String url; - @Value("#{dataProps['alarm.mail.serviceId']}") - private String serviceId; - @Value("#{dataProps['alarm.mail.sender.emailAddress']}") - private String senderEmailAddress; - @Value("#{dataProps['alarm.mail.option']}") - private String option; - @Value("#{dataProps['alarm.mail.subject']}") - private String subject; - - - - @Override - public String getPinpointUrl() { - return pinpointUrl; - } - public void setPinpointUrl(String pinpointUrl) { - this.pinpointUrl = pinpointUrl; - } - - @Override - public String getUrl() { - return url; - } - public void setUrl(String url) { - this.url = url; - } - - @Override - public String getServiceId() { - return serviceId; - } - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - @Override - public String getSenderEmailAddress() { - return senderEmailAddress; - } - public void setSenderEmailAddress(String senderEmailAddress) { - this.senderEmailAddress = senderEmailAddress; - } - - @Override - public String getOption() { - return option; - } - public void setOption(String option) { - this.option = option; - } - - @Override - public String getSubject() { - return subject; - } - public void setSubject(String subject) { - this.subject = subject; - } - - @Override - public String toString() { - return "MailResourceImpl [pinpointUrl=" + pinpointUrl + ", url=" + url + ", serviceId=" + serviceId + ", senderEmailAddress=" + senderEmailAddress - + ", option=" + option + ", subject=" + subject + "]"; - } - -} +package com.nhn.pinpoint.web.alarm.resource; + +import org.springframework.beans.factory.annotation.Value; + +/** + * + * @author koo.taejin + */ +public class MailResourceImpl implements MailResource { + + @Value("#{dataProps['pinpoint.url']}") + private String pinpointUrl; + @Value("#{dataProps['alarm.mail.url']}") + private String url; + @Value("#{dataProps['alarm.mail.serviceId']}") + private String serviceId; + @Value("#{dataProps['alarm.mail.sender.emailAddress']}") + private String senderEmailAddress; + @Value("#{dataProps['alarm.mail.option']}") + private String option; + @Value("#{dataProps['alarm.mail.subject']}") + private String subject; + + + + @Override + public String getPinpointUrl() { + return pinpointUrl; + } + public void setPinpointUrl(String pinpointUrl) { + this.pinpointUrl = pinpointUrl; + } + + @Override + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + + @Override + public String getServiceId() { + return serviceId; + } + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + @Override + public String getSenderEmailAddress() { + return senderEmailAddress; + } + public void setSenderEmailAddress(String senderEmailAddress) { + this.senderEmailAddress = senderEmailAddress; + } + + @Override + public String getOption() { + return option; + } + public void setOption(String option) { + this.option = option; + } + + @Override + public String getSubject() { + return subject; + } + public void setSubject(String subject) { + this.subject = subject; + } + + @Override + public String toString() { + return "MailResourceImpl [pinpointUrl=" + pinpointUrl + ", url=" + url + ", serviceId=" + serviceId + ", senderEmailAddress=" + senderEmailAddress + + ", option=" + option + ", subject=" + subject + "]"; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResource.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResource.java index 645e01a21d20..472e2969abef 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResource.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.web.alarm.resource; - -public interface SmsResource { - - String getPinpointUrl(); - - String getUrl(); - - String getServiceId(); - - String getSenderPhoneNumber(); - -} +package com.nhn.pinpoint.web.alarm.resource; + +public interface SmsResource { + + String getPinpointUrl(); + + String getUrl(); + + String getServiceId(); + + String getSenderPhoneNumber(); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResourceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResourceImpl.java index 8bc9dbaa8b04..1202550827b2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResourceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/resource/SmsResourceImpl.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.web.alarm.resource; - -import org.springframework.beans.factory.annotation.Value; - -/** - * - * @author koo.taejin - */ -public class SmsResourceImpl implements SmsResource { - - @Value("#{dataProps['pinpoint.url']}") - private String pinpointUrl; - @Value("#{dataProps['alarm.sms.url']}") - private String url; - @Value("#{dataProps['alarm.sms.serviceId']}") - private String serviceId; - @Value("#{dataProps['alarm.sms.sender.phoneNumber']}") - private String senderPhoneNumber; - - @Override - public String getPinpointUrl() { - return pinpointUrl; - } - public void setPinpointUrl(String pinpointUrl) { - this.pinpointUrl = pinpointUrl; - } - - @Override - public String getUrl() { - return url; - } - public void setUrl(String url) { - this.url = url; - } - - @Override - public String getServiceId() { - return serviceId; - } - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - @Override - public String getSenderPhoneNumber() { - return senderPhoneNumber; - } - public void setSenderPhoneNumber(String senderPhoneNumber) { - this.senderPhoneNumber = senderPhoneNumber; - } - - @Override - public String toString() { - return "SmsResourceImpl [pinpointUrl=" + pinpointUrl + ", url=" + url + ", serviceId=" + serviceId + ", senderPhoneNumber=" + senderPhoneNumber + "]"; - } - -} +package com.nhn.pinpoint.web.alarm.resource; + +import org.springframework.beans.factory.annotation.Value; + +/** + * + * @author koo.taejin + */ +public class SmsResourceImpl implements SmsResource { + + @Value("#{dataProps['pinpoint.url']}") + private String pinpointUrl; + @Value("#{dataProps['alarm.sms.url']}") + private String url; + @Value("#{dataProps['alarm.sms.serviceId']}") + private String serviceId; + @Value("#{dataProps['alarm.sms.sender.phoneNumber']}") + private String senderPhoneNumber; + + @Override + public String getPinpointUrl() { + return pinpointUrl; + } + public void setPinpointUrl(String pinpointUrl) { + this.pinpointUrl = pinpointUrl; + } + + @Override + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + + @Override + public String getServiceId() { + return serviceId; + } + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + @Override + public String getSenderPhoneNumber() { + return senderPhoneNumber; + } + public void setSenderPhoneNumber(String senderPhoneNumber) { + this.senderPhoneNumber = senderPhoneNumber; + } + + @Override + public String toString() { + return "SmsResourceImpl [pinpointUrl=" + pinpointUrl + ", url=" + url + ", serviceId=" + serviceId + ", senderPhoneNumber=" + senderPhoneNumber + "]"; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactGroupResource.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactGroupResource.java index eb44692be4b7..94427d4de49a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactGroupResource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactGroupResource.java @@ -1,97 +1,97 @@ -package com.nhn.pinpoint.web.alarm.vo; - - -import java.util.Date; -import java.util.List; - -import org.apache.ibatis.type.Alias; - -@Alias("alarmContactGroup") -public class AlarmContactGroupResource { - - private Integer id; - - private String alarmContactGroupName; - private String alarmContactGroupDescrption; - - private Date registerTime; - private String registerEmployeeNumber; - - private Date modifyTime; - private String modifyEmployeeNumber; - - private List alarmContactList; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getAlarmContactGroupName() { - return alarmContactGroupName; - } - - public void setAlarmContactGroupName(String alarmContactGroupName) { - this.alarmContactGroupName = alarmContactGroupName; - } - - public String getAlarmContactGroupDescrption() { - return alarmContactGroupDescrption; - } - - public void setAlarmContactGroupDescrption(String alarmContactGroupDescrption) { - this.alarmContactGroupDescrption = alarmContactGroupDescrption; - } - - public List getAlarmContactList() { - return alarmContactList; - } - - public void setAlarmContactList(List alarmContactList) { - this.alarmContactList = alarmContactList; - } - - - public Date getRegisterTime() { - return registerTime; - } - - public void setRegisterTime(Date registerTime) { - this.registerTime = registerTime; - } - - public String getRegisterEmployeeNumber() { - return registerEmployeeNumber; - } - - public void setRegisterEmployeeNumber(String registerEmployeeNumber) { - this.registerEmployeeNumber = registerEmployeeNumber; - } - - public Date getModifyTime() { - return modifyTime; - } - - public void setModifyTime(Date modifyTime) { - this.modifyTime = modifyTime; - } - - public String getModifyEmployeeNumber() { - return modifyEmployeeNumber; - } - - public void setModifyEmployeeNumber(String modifyEmployeeNumber) { - this.modifyEmployeeNumber = modifyEmployeeNumber; - } - - @Override - public String toString() { - return "AlarmContactGroupResource [id=" + id + ", alarmContactGroupName=" + alarmContactGroupName + ", alarmContactGroupDescrption=" - + alarmContactGroupDescrption + ", registerTime=" + registerTime + ", registerEmployeeNumber=" + registerEmployeeNumber + ", modifyTime=" - + modifyTime + ", modifyEmployeeNumber=" + modifyEmployeeNumber + ", alarmContactList=" + alarmContactList + "]"; - } - -} +package com.nhn.pinpoint.web.alarm.vo; + + +import java.util.Date; +import java.util.List; + +import org.apache.ibatis.type.Alias; + +@Alias("alarmContactGroup") +public class AlarmContactGroupResource { + + private Integer id; + + private String alarmContactGroupName; + private String alarmContactGroupDescrption; + + private Date registerTime; + private String registerEmployeeNumber; + + private Date modifyTime; + private String modifyEmployeeNumber; + + private List alarmContactList; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getAlarmContactGroupName() { + return alarmContactGroupName; + } + + public void setAlarmContactGroupName(String alarmContactGroupName) { + this.alarmContactGroupName = alarmContactGroupName; + } + + public String getAlarmContactGroupDescrption() { + return alarmContactGroupDescrption; + } + + public void setAlarmContactGroupDescrption(String alarmContactGroupDescrption) { + this.alarmContactGroupDescrption = alarmContactGroupDescrption; + } + + public List getAlarmContactList() { + return alarmContactList; + } + + public void setAlarmContactList(List alarmContactList) { + this.alarmContactList = alarmContactList; + } + + + public Date getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(Date registerTime) { + this.registerTime = registerTime; + } + + public String getRegisterEmployeeNumber() { + return registerEmployeeNumber; + } + + public void setRegisterEmployeeNumber(String registerEmployeeNumber) { + this.registerEmployeeNumber = registerEmployeeNumber; + } + + public Date getModifyTime() { + return modifyTime; + } + + public void setModifyTime(Date modifyTime) { + this.modifyTime = modifyTime; + } + + public String getModifyEmployeeNumber() { + return modifyEmployeeNumber; + } + + public void setModifyEmployeeNumber(String modifyEmployeeNumber) { + this.modifyEmployeeNumber = modifyEmployeeNumber; + } + + @Override + public String toString() { + return "AlarmContactGroupResource [id=" + id + ", alarmContactGroupName=" + alarmContactGroupName + ", alarmContactGroupDescrption=" + + alarmContactGroupDescrption + ", registerTime=" + registerTime + ", registerEmployeeNumber=" + registerEmployeeNumber + ", modifyTime=" + + modifyTime + ", modifyEmployeeNumber=" + modifyEmployeeNumber + ", alarmContactList=" + alarmContactList + "]"; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactResource.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactResource.java index e127f85216b5..d89bafeaa591 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactResource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmContactResource.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.web.alarm.vo; - -import org.apache.ibatis.type.Alias; - -@Alias("alarmContact") -public class AlarmContactResource { - - private Integer id; - private Integer alarmContactGroupId; - private String phoneNum; - private String emailAddress; - - public Integer getId() { - return id; - } - public void setId(Integer id) { - this.id = id; - } - public Integer getAlarmContactGroupId() { - return alarmContactGroupId; - } - public void setAlarmContactGroupId(Integer alarmContactGroupId) { - this.alarmContactGroupId = alarmContactGroupId; - } - public String getPhoneNum() { - return phoneNum; - } - public void setPhoneNum(String phoneNum) { - this.phoneNum = phoneNum; - } - public String getEmailAddress() { - return emailAddress; - } - public void setEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; - } - - @Override - public String toString() { - return "AlarmContactResource [id=" + id + ", alarmContactGroupId=" + alarmContactGroupId + ", phoneNum=" + phoneNum + ", emailAddress=" + emailAddress - + "]"; - } - -} +package com.nhn.pinpoint.web.alarm.vo; + +import org.apache.ibatis.type.Alias; + +@Alias("alarmContact") +public class AlarmContactResource { + + private Integer id; + private Integer alarmContactGroupId; + private String phoneNum; + private String emailAddress; + + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public Integer getAlarmContactGroupId() { + return alarmContactGroupId; + } + public void setAlarmContactGroupId(Integer alarmContactGroupId) { + this.alarmContactGroupId = alarmContactGroupId; + } + public String getPhoneNum() { + return phoneNum; + } + public void setPhoneNum(String phoneNum) { + this.phoneNum = phoneNum; + } + public String getEmailAddress() { + return emailAddress; + } + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + + @Override + public String toString() { + return "AlarmContactResource [id=" + id + ", alarmContactGroupId=" + alarmContactGroupId + ", phoneNum=" + phoneNum + ", emailAddress=" + emailAddress + + "]"; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmResource.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmResource.java index b93462126c62..bf90ded3e476 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmResource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmResource.java @@ -1,70 +1,70 @@ -package com.nhn.pinpoint.web.alarm.vo; - -import org.apache.ibatis.type.Alias; - -@Alias("alarm") -public class AlarmResource { - - private Integer id; - - private String agentId; - - private String alarmGroupName; - private String alarmGroupDescrption; - - private AlarmRuleGroupResource alarmRuleGroup; - private AlarmContactGroupResource alarmContactGroup; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getAgentId() { - return agentId; - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public String getAlarmGroupName() { - return alarmGroupName; - } - public void setAlarmGroupName(String alarmGroupName) { - this.alarmGroupName = alarmGroupName; - } - - public String getAlarmGroupDescrption() { - return alarmGroupDescrption; - } - public void setAlarmGroupDescrption(String alarmGroupDescrption) { - this.alarmGroupDescrption = alarmGroupDescrption; - } - - public AlarmRuleGroupResource getAlarmRuleGroup() { - return alarmRuleGroup; - } - - public void setAlarmRuleGroup(AlarmRuleGroupResource alarmRuleGroup) { - this.alarmRuleGroup = alarmRuleGroup; - } - - public AlarmContactGroupResource getAlarmContactGroup() { - return alarmContactGroup; - } - - public void setAlarmContactGroup(AlarmContactGroupResource alarmContactGroup) { - this.alarmContactGroup = alarmContactGroup; - } - - @Override - public String toString() { - return "AlarmResource [id=" + id + ", agentId=" + agentId + ", alarmGroupName=" + alarmGroupName + ", alarmGroupDescrption=" + alarmGroupDescrption - + ", alarmRuleGroup=" + alarmRuleGroup + ", alarmContactGroup=" + alarmContactGroup + "]"; - } - -} +package com.nhn.pinpoint.web.alarm.vo; + +import org.apache.ibatis.type.Alias; + +@Alias("alarm") +public class AlarmResource { + + private Integer id; + + private String agentId; + + private String alarmGroupName; + private String alarmGroupDescrption; + + private AlarmRuleGroupResource alarmRuleGroup; + private AlarmContactGroupResource alarmContactGroup; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public String getAlarmGroupName() { + return alarmGroupName; + } + public void setAlarmGroupName(String alarmGroupName) { + this.alarmGroupName = alarmGroupName; + } + + public String getAlarmGroupDescrption() { + return alarmGroupDescrption; + } + public void setAlarmGroupDescrption(String alarmGroupDescrption) { + this.alarmGroupDescrption = alarmGroupDescrption; + } + + public AlarmRuleGroupResource getAlarmRuleGroup() { + return alarmRuleGroup; + } + + public void setAlarmRuleGroup(AlarmRuleGroupResource alarmRuleGroup) { + this.alarmRuleGroup = alarmRuleGroup; + } + + public AlarmContactGroupResource getAlarmContactGroup() { + return alarmContactGroup; + } + + public void setAlarmContactGroup(AlarmContactGroupResource alarmContactGroup) { + this.alarmContactGroup = alarmContactGroup; + } + + @Override + public String toString() { + return "AlarmResource [id=" + id + ", agentId=" + agentId + ", alarmGroupName=" + alarmGroupName + ", alarmGroupDescrption=" + alarmGroupDescrption + + ", alarmRuleGroup=" + alarmRuleGroup + ", alarmContactGroup=" + alarmContactGroup + "]"; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleGroupResource.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleGroupResource.java index 93091c6e2240..60d65d0dc7c2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleGroupResource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleGroupResource.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.web.alarm.vo; - -import java.util.List; - -import org.apache.ibatis.type.Alias; - -@Alias("alarmRuleGroup") -public class AlarmRuleGroupResource { - - private Integer id; - - private String alarmRuleGroupName; - private String alarmRuleGroupDescrption; - - private List alarmRuleList; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getAlarmRuleGroupName() { - return alarmRuleGroupName; - } - - public void setAlarmRuleGroupName(String alarmRuleGroupName) { - this.alarmRuleGroupName = alarmRuleGroupName; - } - - public String getAlarmRuleGroupDescrption() { - return alarmRuleGroupDescrption; - } - - public void setAlarmRuleGroupDescrption(String alarmRuleGroupDescrption) { - this.alarmRuleGroupDescrption = alarmRuleGroupDescrption; - } - - public List getAlarmRuleList() { - return alarmRuleList; - } - - public void setAlarmRuleList(List alarmRuleList) { - this.alarmRuleList = alarmRuleList; - } - - @Override - public String toString() { - return "AlarmRuleGroupResource [id=" + id + ", alarmRuleGroupName=" + alarmRuleGroupName + ", alarmRuleGroupDescrption=" - + alarmRuleGroupDescrption + ", alarmRuleList=" + alarmRuleList + "]"; - } - -} +package com.nhn.pinpoint.web.alarm.vo; + +import java.util.List; + +import org.apache.ibatis.type.Alias; + +@Alias("alarmRuleGroup") +public class AlarmRuleGroupResource { + + private Integer id; + + private String alarmRuleGroupName; + private String alarmRuleGroupDescrption; + + private List alarmRuleList; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getAlarmRuleGroupName() { + return alarmRuleGroupName; + } + + public void setAlarmRuleGroupName(String alarmRuleGroupName) { + this.alarmRuleGroupName = alarmRuleGroupName; + } + + public String getAlarmRuleGroupDescrption() { + return alarmRuleGroupDescrption; + } + + public void setAlarmRuleGroupDescrption(String alarmRuleGroupDescrption) { + this.alarmRuleGroupDescrption = alarmRuleGroupDescrption; + } + + public List getAlarmRuleList() { + return alarmRuleList; + } + + public void setAlarmRuleList(List alarmRuleList) { + this.alarmRuleList = alarmRuleList; + } + + @Override + public String toString() { + return "AlarmRuleGroupResource [id=" + id + ", alarmRuleGroupName=" + alarmRuleGroupName + ", alarmRuleGroupDescrption=" + + alarmRuleGroupDescrption + ", alarmRuleList=" + alarmRuleList + "]"; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleResource.java b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleResource.java index 3a323426a325..afbf17df60f1 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleResource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/alarm/vo/AlarmRuleResource.java @@ -1,147 +1,147 @@ -package com.nhn.pinpoint.web.alarm.vo; - -import org.apache.ibatis.type.Alias; - -import com.nhn.pinpoint.web.alarm.MainCategory; -import com.nhn.pinpoint.web.alarm.SubCategory; - -/** - * - * @author koo.taejin - */ -@Alias("alarmRule") -public class AlarmRuleResource { - - private Integer id; - private Integer alarmRuleGroupId; - private Integer alarmRuleSubCategoryId; - private Integer thresholdRule; - private boolean compareRule; - private Integer continuosTime; - private String alarmRuleName; - private String alarmRuleDescrption; - -// private MainCategory mainCategory; -// private SubCategory subCategory; - - private String mainCategory; - private String subCategory; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Integer getAlarmRuleGroupId() { - return alarmRuleGroupId; - } - - public void setAlarmRuleGroupId(Integer alarmRuleGroupId) { - this.alarmRuleGroupId = alarmRuleGroupId; - } - - public Integer getAlarmRuleSubCategoryId() { - return alarmRuleSubCategoryId; - } - - public void setAlarmRuleSubCategoryId(Integer alarmRuleSubCategoryId) { - this.alarmRuleSubCategoryId = alarmRuleSubCategoryId; - } - - public Integer getThresholdRule() { - return thresholdRule; - } - - public void setThresholdRule(Integer thresholdRule) { - this.thresholdRule = thresholdRule; - } - - public boolean isCompareRule() { - return compareRule; - } - - public void setCompareRule(boolean compareRule) { - this.compareRule = compareRule; - } - - public Integer getContinuosTime() { - return continuosTime; - } - - public void setContinuosTime(Integer continuosTime) { - this.continuosTime = continuosTime; - } - - public String getAlarmRuleName() { - return alarmRuleName; - } - - public void setAlarmRuleName(String alarmRuleName) { - this.alarmRuleName = alarmRuleName; - } - - public String getAlarmRuleDescrption() { - return alarmRuleDescrption; - } - - public void setAlarmRuleDescrption(String alarmRuleDescrption) { - this.alarmRuleDescrption = alarmRuleDescrption; - } - - - public MainCategory getMainCategory() { - return MainCategory.getValue(mainCategory); - } - - public void setMainCategory(String mainCategory) { - this.mainCategory = mainCategory; - } - - public SubCategory getSubCategory() { - return SubCategory.getValue(subCategory); - } - - public void setSubCategory(String subCategory) { - this.subCategory = subCategory; - } - - public String ruleToString() { - StringBuilder rule = new StringBuilder(); - - rule.append(getMainCategory().getName() + " "); - rule.append(getSubCategory().getName() + " "); - rule.append(">=" + thresholdRule + getSubCategory().getUnit() + " "); - rule.append("(" + getContinuosTime() + "ms)"); - - return rule.toString(); - } - - @Override - public String toString() { - return "AlarmRuleResource [id=" + id + ", alarmRuleGroupId=" + alarmRuleGroupId + ", alarmRuleSubCategoryId=" + alarmRuleSubCategoryId - + ", thresholdRule=" + thresholdRule + ", compareRule=" + compareRule + ", continuosTime=" + continuosTime + ", alarmRuleName=" + alarmRuleName - + ", alarmRuleDescrption=" + alarmRuleDescrption + ", mainCategory=" + mainCategory + ", subCategory=" + subCategory + "]"; - } - - -// public String getMainCategory() { -// return mainCategory; -// } -// -// public void setMainCategory(String mainCategory) { -// this.mainCategory = mainCategory; -// } -// -// public String getSubCategory() { -// return subCategory; -// } -// -// public void setSubCategory(String subCategory) { -// this.subCategory = subCategory; -// } - - -} +package com.nhn.pinpoint.web.alarm.vo; + +import org.apache.ibatis.type.Alias; + +import com.nhn.pinpoint.web.alarm.MainCategory; +import com.nhn.pinpoint.web.alarm.SubCategory; + +/** + * + * @author koo.taejin + */ +@Alias("alarmRule") +public class AlarmRuleResource { + + private Integer id; + private Integer alarmRuleGroupId; + private Integer alarmRuleSubCategoryId; + private Integer thresholdRule; + private boolean compareRule; + private Integer continuosTime; + private String alarmRuleName; + private String alarmRuleDescrption; + +// private MainCategory mainCategory; +// private SubCategory subCategory; + + private String mainCategory; + private String subCategory; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getAlarmRuleGroupId() { + return alarmRuleGroupId; + } + + public void setAlarmRuleGroupId(Integer alarmRuleGroupId) { + this.alarmRuleGroupId = alarmRuleGroupId; + } + + public Integer getAlarmRuleSubCategoryId() { + return alarmRuleSubCategoryId; + } + + public void setAlarmRuleSubCategoryId(Integer alarmRuleSubCategoryId) { + this.alarmRuleSubCategoryId = alarmRuleSubCategoryId; + } + + public Integer getThresholdRule() { + return thresholdRule; + } + + public void setThresholdRule(Integer thresholdRule) { + this.thresholdRule = thresholdRule; + } + + public boolean isCompareRule() { + return compareRule; + } + + public void setCompareRule(boolean compareRule) { + this.compareRule = compareRule; + } + + public Integer getContinuosTime() { + return continuosTime; + } + + public void setContinuosTime(Integer continuosTime) { + this.continuosTime = continuosTime; + } + + public String getAlarmRuleName() { + return alarmRuleName; + } + + public void setAlarmRuleName(String alarmRuleName) { + this.alarmRuleName = alarmRuleName; + } + + public String getAlarmRuleDescrption() { + return alarmRuleDescrption; + } + + public void setAlarmRuleDescrption(String alarmRuleDescrption) { + this.alarmRuleDescrption = alarmRuleDescrption; + } + + + public MainCategory getMainCategory() { + return MainCategory.getValue(mainCategory); + } + + public void setMainCategory(String mainCategory) { + this.mainCategory = mainCategory; + } + + public SubCategory getSubCategory() { + return SubCategory.getValue(subCategory); + } + + public void setSubCategory(String subCategory) { + this.subCategory = subCategory; + } + + public String ruleToString() { + StringBuilder rule = new StringBuilder(); + + rule.append(getMainCategory().getName() + " "); + rule.append(getSubCategory().getName() + " "); + rule.append(">=" + thresholdRule + getSubCategory().getUnit() + " "); + rule.append("(" + getContinuosTime() + "ms)"); + + return rule.toString(); + } + + @Override + public String toString() { + return "AlarmRuleResource [id=" + id + ", alarmRuleGroupId=" + alarmRuleGroupId + ", alarmRuleSubCategoryId=" + alarmRuleSubCategoryId + + ", thresholdRule=" + thresholdRule + ", compareRule=" + compareRule + ", continuosTime=" + continuosTime + ", alarmRuleName=" + alarmRuleName + + ", alarmRuleDescrption=" + alarmRuleDescrption + ", mainCategory=" + mainCategory + ", subCategory=" + subCategory + "]"; + } + + +// public String getMainCategory() { +// return mainCategory; +// } +// +// public void setMainCategory(String mainCategory) { +// this.mainCategory = mainCategory; +// } +// +// public String getSubCategory() { +// return subCategory; +// } +// +// public void setSubCategory(String subCategory) { +// this.subCategory = subCategory; +// } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ApplicationMapBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ApplicationMapBuilder.java index a1d312daaadf..f8420695f2f7 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ApplicationMapBuilder.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ApplicationMapBuilder.java @@ -1,404 +1,404 @@ -package com.nhn.pinpoint.web.applicationmap; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.web.applicationmap.histogram.*; -import com.nhn.pinpoint.web.applicationmap.rawdata.*; -import com.nhn.pinpoint.web.dao.MapResponseDao; -import com.nhn.pinpoint.web.service.AgentInfoService; -import com.nhn.pinpoint.web.vo.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class ApplicationMapBuilder { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Range range; - - public ApplicationMapBuilder(Range range) { - if (range == null) { - throw new NullPointerException("range must not be null"); - } - - this.range = range; - } - - public ApplicationMap build(LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService, NodeHistogramDataSource nodeHistogramDataSource) { - if (linkDataDuplexMap == null) { - throw new NullPointerException("linkDataMap must not be null"); - } - if (agentInfoService == null) { - throw new NullPointerException("agentInfoService must not be null"); - } - - NodeList nodeList = buildNode(linkDataDuplexMap); - LinkList linkList = buildLink(nodeList, linkDataDuplexMap); - - - appendNodeResponseTime(nodeList, linkList, nodeHistogramDataSource); - // agentInfo를 넣는다. - appendAgentInfo(nodeList, linkDataDuplexMap, agentInfoService); - - final ApplicationMap map = new ApplicationMap(range, nodeList, linkList); - return map; - } - - - public ApplicationMap build(LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService, final MapResponseDao mapResponseDao) { - NodeHistogramDataSource responseSource = new NodeHistogramDataSource() { - @Override - public NodeHistogram createNodeHistogram(Application application) { - final List responseHistogram = mapResponseDao.selectResponseTime(application, range); - final NodeHistogram nodeHistogram = new NodeHistogram(application, range, responseHistogram); - return nodeHistogram; - } - }; - return this.build(linkDataDuplexMap, agentInfoService, responseSource); - } - - public ApplicationMap build(LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService, final ResponseHistogramBuilder mapHistogramSummary) { - NodeHistogramDataSource responseSource = new NodeHistogramDataSource() { - @Override - public NodeHistogram createNodeHistogram(Application application) { - List responseHistogram = mapHistogramSummary.getResponseTimeList(application); - final NodeHistogram nodeHistogram = new NodeHistogram(application, range, responseHistogram); - return nodeHistogram; - } - }; - return this.build(linkDataDuplexMap, agentInfoService, responseSource); - } - - public interface NodeHistogramDataSource { - NodeHistogram createNodeHistogram(Application application); - } - - - private NodeList buildNode(LinkDataDuplexMap linkDataDuplexMap) { - NodeList nodeList = new NodeList(); - createNode(nodeList, linkDataDuplexMap.getSourceLinkDataMap()); - logger.debug("node size:{}", nodeList.size()); - createNode(nodeList, linkDataDuplexMap.getTargetLinkDataMap()); - logger.debug("node size:{}", nodeList.size()); - - logger.debug("allNode:{}", nodeList.getNodeList()); - return nodeList; - } - - private void createNode(NodeList nodeList, LinkDataMap linkDataMap) { - - for (LinkData linkData : linkDataMap.getLinkDataList()) { - final Application fromApplication = linkData.getFromApplication(); - // FROM -> TO에서 FROM이 CLIENT가 아니면 FROM은 node - // rpc가 나올수가 없음. 이미 unknown으로 치환을 하기 때문에. 만약 rpc가 나온다면 이상한 케이스임 - if (!fromApplication.getServiceType().isRpcClient()) { - final boolean success = addNode(nodeList, fromApplication); - if (success) { - logger.debug("createSourceNode:{}", fromApplication); - } - } else { - logger.warn("found rpc fromNode linkData:{}", linkData); - } - - - final Application toApplication = linkData.getToApplication(); - // FROM -> TO에서 TO가 CLIENT가 아니면 TO는 node - if (!toApplication.getServiceType().isRpcClient()) { - final boolean success = addNode(nodeList, toApplication); - if (success) { - logger.debug("createTargetNode:{}", toApplication); - } - } else { - logger.warn("found rpc toNode:{}", linkData); - } - } - - } - - private boolean addNode(NodeList nodeList, Application application) { - if (nodeList.containsNode(application)) { - return false; - } - - Node fromNode = new Node(application); - return nodeList.addNode(fromNode); - } - - private LinkList buildLink(NodeList nodeList, LinkDataDuplexMap linkDataDuplexMap) { - // 변경하면 안됨. - LinkList linkList = new LinkList(); - createSourceLink(nodeList, linkList, linkDataDuplexMap.getSourceLinkDataMap()); - logger.debug("link size:{}", linkList.size()); - createTargetLink(nodeList, linkList, linkDataDuplexMap.getTargetLinkDataMap()); - logger.debug("link size:{}", linkList.size()); - - for (Link link : linkList.getLinkList()) { - appendLinkHistogram(link, linkDataDuplexMap); - } - return linkList; - } - - private void appendLinkHistogram(Link link, LinkDataDuplexMap linkDataDuplexMap) { - logger.debug("appendLinkHistogram link:{}", link); - - LinkKey key = link.getLinkKey(); - LinkData sourceLinkData = linkDataDuplexMap.getSourceLinkData(key); - if (sourceLinkData != null) { - link.addSource(sourceLinkData.getLinkCallDataMap()); - } - LinkData targetLinkData = linkDataDuplexMap.getTargetLinkData(key); - if (targetLinkData != null) { - link.addTarget(targetLinkData.getLinkCallDataMap()); - } - } - - private void createSourceLink(NodeList nodeList, LinkList linkList, LinkDataMap linkDataMap) { - - for (LinkData linkData : linkDataMap.getLinkDataList()) { - final Application fromApplicationId = linkData.getFromApplication(); - Node fromNode = nodeList.findNode(fromApplicationId); - - final Application toApplicationId = linkData.getToApplication(); - Node toNode = nodeList.findNode(toApplicationId); - - // rpc client가 빠진경우임. - if (toNode == null) { - logger.warn("toNode rcp client not found:{}", toApplicationId); - continue; - } - - // RPC client인 경우 dest application이 이미 있으면 삭제, 없으면 unknown cloud로 변경 - // 여기서 RPC가 나올일이 없지 않나하는데. 먼저 앞단에서 Unknown노드로 변경시킴. - if (toNode.getServiceType().isRpcClient()) { - if (!nodeList.containsNode(toNode.getApplication())) { - final Link link = addLink(linkList, fromNode, toNode, CreateType.Source); - if (link != null) { - logger.debug("createRpcSourceLink:{}", link); - } - } - } else { - final Link link = addLink(linkList, fromNode, toNode, CreateType.Source); - if (link != null) { - logger.debug("createSourceLink:{}", link); - } - } - } - } - - private Link addLink(LinkList linkList, Node fromNode, Node toNode, CreateType createType) { - final Link link = new Link(createType, fromNode, toNode, range); - if (linkList.addLink(link)) { - return link; - } else { - return null; - } - } - - - private void createTargetLink(NodeList nodeList, LinkList linkList, LinkDataMap linkDataMap) { - - for (LinkData linkData : linkDataMap.getLinkDataList()) { - final Application fromApplicationId = linkData.getFromApplication(); - Node fromNode = nodeList.findNode(fromApplicationId); - // TODO - final Application toApplicationId = linkData.getToApplication(); - Node toNode = nodeList.findNode(toApplicationId); - - // rpc client가 빠진경우임. - if (fromNode == null) { - logger.warn("fromNode rcp client not found:{}", toApplicationId); - continue; - } - - // RPC client인 경우 dest application이 이미 있으면 삭제, 없으면 unknown cloud로 변경. - if (toNode.getServiceType().isRpcClient()) { - // to 노드가 존재하는지 검사? - if (!nodeList.containsNode(toNode.getApplication())) { - final Link link = addLink(linkList, fromNode, toNode, CreateType.Target); - if(link != null) { - logger.debug("createRpcTargetLink:{}", link); - } - } - } else { - final Link link = addLink(linkList, fromNode, toNode, CreateType.Target); - if(link != null) { - logger.debug("createTargetLink:{}", link); - } - } - } - } - - public void appendNodeResponseTime(NodeList nodeList, LinkList linkList, NodeHistogramDataSource nodeHistogramDataSource) { - if (nodeHistogramDataSource == null) { - throw new NullPointerException("nodeHistogramDataSource must not be null"); - } - - final Collection nodes = nodeList.getNodeList(); - for (Node node : nodes) { - final ServiceType nodeType = node.getServiceType(); - if (nodeType.isWas()) { - // was일 경우 자신의 response 히스토그램을 조회하여 채운다. - final Application wasNode = node.getApplication(); - final NodeHistogram nodeHistogram = nodeHistogramDataSource.createNodeHistogram(wasNode); - node.setNodeHistogram(nodeHistogram); - - } else if(nodeType.isTerminal() || nodeType.isUnknown()) { - final NodeHistogram nodeHistogram = createTerminalNodeHistogram(node, linkList); - node.setNodeHistogram(nodeHistogram); - } else if (nodeType.isUser()) { - // User노드인 경우 source 링크를 찾아 histogram을 생성한다. - Application userNode = node.getApplication(); - - final NodeHistogram nodeHistogram = new NodeHistogram(userNode, range); - final List fromLink = linkList.findFromLink(userNode); - if (fromLink.size() > 1) { - logger.warn("Invalid from UserNode:{}", linkList); - throw new IllegalArgumentException("Invalid from UserNode.size() :" + fromLink.size()); - } else if (fromLink.size() == 0) { - logger.warn("from UserNode not found:{}", userNode); - continue; - } - final Link sourceLink = fromLink.get(0); - nodeHistogram.setApplicationHistogram(sourceLink.getHistogram()); - - ApplicationTimeHistogram histogramData = sourceLink.getTargetApplicationTimeSeriesHistogramData(); - nodeHistogram.setApplicationTimeHistogram(histogramData); - - node.setNodeHistogram(nodeHistogram); - } else { - // 그냥 데미 데이터 - NodeHistogram dummy = new NodeHistogram(node.getApplication(), range); - node.setNodeHistogram(dummy); - } - - } - - } - - private NodeHistogram createTerminalNodeHistogram(Node node, LinkList linkList) { - // 터미널 노드인경우, 자신을 가리키는 link값을 합하여 histogram을 생성한다. - final Application nodeApplication = node.getApplication(); - final NodeHistogram nodeHistogram = new NodeHistogram(nodeApplication, range); - - // appclicationHistogram 생성. - final List toLinkList = linkList.findToLink(nodeApplication); - final Histogram applicationHistogram = new Histogram(node.getServiceType()); - for (Link link : toLinkList) { - applicationHistogram.add(link.getHistogram()); - } - nodeHistogram.setApplicationHistogram(applicationHistogram); - - // applicationTimeHistogram 생성. - LinkCallDataMap linkCallDataMap = new LinkCallDataMap(); - for (Link link : toLinkList) { - LinkCallDataMap sourceLinkCallDataMap = link.getSourceLinkCallDataMap(); - linkCallDataMap.addLinkDataMap(sourceLinkCallDataMap); - } - ApplicationTimeHistogramBuilder builder = new ApplicationTimeHistogramBuilder(nodeApplication, range); - ApplicationTimeHistogram applicationTimeHistogram = builder.build(linkCallDataMap.getLinkDataList()); - nodeHistogram.setApplicationTimeHistogram(applicationTimeHistogram); - - // terminal일 경우 node의 AgentLevel histogram을 추가로 생성한다. - if (nodeApplication.getServiceType().isTerminal()) { - final Map agentHistogramMap = new HashMap(); - - for (Link link : toLinkList) { - LinkCallDataMap sourceLinkCallDataMap = link.getSourceLinkCallDataMap(); - AgentHistogramList targetList = sourceLinkCallDataMap.getTargetList(); - for (AgentHistogram histogram : targetList.getAgentHistogramList()) { - Histogram find = agentHistogramMap.get(histogram.getId()); - if (find == null) { - find = new Histogram(histogram.getServiceType()); - agentHistogramMap.put(histogram.getId(), find); - } - find.add(histogram.getHistogram()); - } - nodeHistogram.setAgentHistogramMap(agentHistogramMap); - } - } - - LinkCallDataMap mergeSource = new LinkCallDataMap(); - for (Link link : toLinkList) { - LinkCallDataMap sourceLinkCallDataMap = link.getSourceLinkCallDataMap(); - mergeSource.addLinkDataMap(sourceLinkCallDataMap); - } - - AgentTimeHistogramBuilder agentTimeBuilder = new AgentTimeHistogramBuilder(nodeApplication, range); - AgentTimeHistogram agentTimeHistogram = agentTimeBuilder.buildTarget(mergeSource); - nodeHistogram.setAgentTimeHistogram(agentTimeHistogram); - - return nodeHistogram; - } - - public void appendAgentInfo(NodeList nodeList, LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService) { - for (Node node : nodeList.getNodeList()) { - appendServerInfo(node, linkDataDuplexMap, agentInfoService); - } - - } - - private void appendServerInfo(Node node, LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService) { - final ServiceType nodeServiceType = node.getServiceType(); - if (nodeServiceType.isUnknown()) { - // unknown노드는 무엇이 설치되어있는지 알수가 없음. - return; - } - - if (nodeServiceType.isTerminal()) { - // terminal노드에 설치되어 있는 정보를 유추한다. - ServerBuilder builder = new ServerBuilder(); - for (LinkData linkData : linkDataDuplexMap.getSourceLinkDataList()) { - Application toApplication = linkData.getToApplication(); - if (node.getApplication().equals(toApplication)) { - builder.addCallHistogramList(linkData.getTargetList()); - } - } - ServerInstanceList serverInstanceList = builder.build(); - node.setServerInstanceList(serverInstanceList); - } else if (nodeServiceType.isWas()) { - Set agentList = agentInfoService.selectAgent(node.getApplication().getName(), range); - if (agentList.isEmpty()) { - return; - } - logger.debug("add agentInfo. {}, {}", node.getApplication(), agentList); - ServerBuilder builder = new ServerBuilder(); - agentList = filterAgentInfoByResponseData(agentList, node); - builder.addAgentInfo(agentList); - ServerInstanceList serverInstanceList = builder.build(); - - // destination이 WAS이고 agent가 설치되어있으면 agentSet이 존재한다. - node.setServerInstanceList(serverInstanceList); - } else { - // 기타 해당 되지 않는 상황일 경우 empty 정보를 넣는다. - node.setServerInstanceList(new ServerInstanceList()); - } - - } - - /** - * 실제 응답속도 정보가 있는 데이터를 기반으로 AgentInfo를 필터링 친다. - * 정공이라고 말할 수 있는 코드는 아님. - * 나중에 실제 서버가 살아 있는 정보를 기반으로 이를 유추할수 있게 해야한다. - */ - private Set filterAgentInfoByResponseData(Set agentList, Node node) { - Set filteredAgentInfo = new HashSet(); - - NodeHistogram nodeHistogram = node.getNodeHistogram(); - Map agentHistogramMap = nodeHistogram.getAgentHistogramMap(); - for (AgentInfoBo agentInfoBo : agentList) { - String agentId = agentInfoBo.getAgentId(); - if (agentHistogramMap.containsKey(agentId)) { - filteredAgentInfo.add(agentInfoBo); - } - } - - return filteredAgentInfo; - } - - -} +package com.nhn.pinpoint.web.applicationmap; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.web.applicationmap.histogram.*; +import com.nhn.pinpoint.web.applicationmap.rawdata.*; +import com.nhn.pinpoint.web.dao.MapResponseDao; +import com.nhn.pinpoint.web.service.AgentInfoService; +import com.nhn.pinpoint.web.vo.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class ApplicationMapBuilder { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Range range; + + public ApplicationMapBuilder(Range range) { + if (range == null) { + throw new NullPointerException("range must not be null"); + } + + this.range = range; + } + + public ApplicationMap build(LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService, NodeHistogramDataSource nodeHistogramDataSource) { + if (linkDataDuplexMap == null) { + throw new NullPointerException("linkDataMap must not be null"); + } + if (agentInfoService == null) { + throw new NullPointerException("agentInfoService must not be null"); + } + + NodeList nodeList = buildNode(linkDataDuplexMap); + LinkList linkList = buildLink(nodeList, linkDataDuplexMap); + + + appendNodeResponseTime(nodeList, linkList, nodeHistogramDataSource); + // agentInfo를 넣는다. + appendAgentInfo(nodeList, linkDataDuplexMap, agentInfoService); + + final ApplicationMap map = new ApplicationMap(range, nodeList, linkList); + return map; + } + + + public ApplicationMap build(LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService, final MapResponseDao mapResponseDao) { + NodeHistogramDataSource responseSource = new NodeHistogramDataSource() { + @Override + public NodeHistogram createNodeHistogram(Application application) { + final List responseHistogram = mapResponseDao.selectResponseTime(application, range); + final NodeHistogram nodeHistogram = new NodeHistogram(application, range, responseHistogram); + return nodeHistogram; + } + }; + return this.build(linkDataDuplexMap, agentInfoService, responseSource); + } + + public ApplicationMap build(LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService, final ResponseHistogramBuilder mapHistogramSummary) { + NodeHistogramDataSource responseSource = new NodeHistogramDataSource() { + @Override + public NodeHistogram createNodeHistogram(Application application) { + List responseHistogram = mapHistogramSummary.getResponseTimeList(application); + final NodeHistogram nodeHistogram = new NodeHistogram(application, range, responseHistogram); + return nodeHistogram; + } + }; + return this.build(linkDataDuplexMap, agentInfoService, responseSource); + } + + public interface NodeHistogramDataSource { + NodeHistogram createNodeHistogram(Application application); + } + + + private NodeList buildNode(LinkDataDuplexMap linkDataDuplexMap) { + NodeList nodeList = new NodeList(); + createNode(nodeList, linkDataDuplexMap.getSourceLinkDataMap()); + logger.debug("node size:{}", nodeList.size()); + createNode(nodeList, linkDataDuplexMap.getTargetLinkDataMap()); + logger.debug("node size:{}", nodeList.size()); + + logger.debug("allNode:{}", nodeList.getNodeList()); + return nodeList; + } + + private void createNode(NodeList nodeList, LinkDataMap linkDataMap) { + + for (LinkData linkData : linkDataMap.getLinkDataList()) { + final Application fromApplication = linkData.getFromApplication(); + // FROM -> TO에서 FROM이 CLIENT가 아니면 FROM은 node + // rpc가 나올수가 없음. 이미 unknown으로 치환을 하기 때문에. 만약 rpc가 나온다면 이상한 케이스임 + if (!fromApplication.getServiceType().isRpcClient()) { + final boolean success = addNode(nodeList, fromApplication); + if (success) { + logger.debug("createSourceNode:{}", fromApplication); + } + } else { + logger.warn("found rpc fromNode linkData:{}", linkData); + } + + + final Application toApplication = linkData.getToApplication(); + // FROM -> TO에서 TO가 CLIENT가 아니면 TO는 node + if (!toApplication.getServiceType().isRpcClient()) { + final boolean success = addNode(nodeList, toApplication); + if (success) { + logger.debug("createTargetNode:{}", toApplication); + } + } else { + logger.warn("found rpc toNode:{}", linkData); + } + } + + } + + private boolean addNode(NodeList nodeList, Application application) { + if (nodeList.containsNode(application)) { + return false; + } + + Node fromNode = new Node(application); + return nodeList.addNode(fromNode); + } + + private LinkList buildLink(NodeList nodeList, LinkDataDuplexMap linkDataDuplexMap) { + // 변경하면 안됨. + LinkList linkList = new LinkList(); + createSourceLink(nodeList, linkList, linkDataDuplexMap.getSourceLinkDataMap()); + logger.debug("link size:{}", linkList.size()); + createTargetLink(nodeList, linkList, linkDataDuplexMap.getTargetLinkDataMap()); + logger.debug("link size:{}", linkList.size()); + + for (Link link : linkList.getLinkList()) { + appendLinkHistogram(link, linkDataDuplexMap); + } + return linkList; + } + + private void appendLinkHistogram(Link link, LinkDataDuplexMap linkDataDuplexMap) { + logger.debug("appendLinkHistogram link:{}", link); + + LinkKey key = link.getLinkKey(); + LinkData sourceLinkData = linkDataDuplexMap.getSourceLinkData(key); + if (sourceLinkData != null) { + link.addSource(sourceLinkData.getLinkCallDataMap()); + } + LinkData targetLinkData = linkDataDuplexMap.getTargetLinkData(key); + if (targetLinkData != null) { + link.addTarget(targetLinkData.getLinkCallDataMap()); + } + } + + private void createSourceLink(NodeList nodeList, LinkList linkList, LinkDataMap linkDataMap) { + + for (LinkData linkData : linkDataMap.getLinkDataList()) { + final Application fromApplicationId = linkData.getFromApplication(); + Node fromNode = nodeList.findNode(fromApplicationId); + + final Application toApplicationId = linkData.getToApplication(); + Node toNode = nodeList.findNode(toApplicationId); + + // rpc client가 빠진경우임. + if (toNode == null) { + logger.warn("toNode rcp client not found:{}", toApplicationId); + continue; + } + + // RPC client인 경우 dest application이 이미 있으면 삭제, 없으면 unknown cloud로 변경 + // 여기서 RPC가 나올일이 없지 않나하는데. 먼저 앞단에서 Unknown노드로 변경시킴. + if (toNode.getServiceType().isRpcClient()) { + if (!nodeList.containsNode(toNode.getApplication())) { + final Link link = addLink(linkList, fromNode, toNode, CreateType.Source); + if (link != null) { + logger.debug("createRpcSourceLink:{}", link); + } + } + } else { + final Link link = addLink(linkList, fromNode, toNode, CreateType.Source); + if (link != null) { + logger.debug("createSourceLink:{}", link); + } + } + } + } + + private Link addLink(LinkList linkList, Node fromNode, Node toNode, CreateType createType) { + final Link link = new Link(createType, fromNode, toNode, range); + if (linkList.addLink(link)) { + return link; + } else { + return null; + } + } + + + private void createTargetLink(NodeList nodeList, LinkList linkList, LinkDataMap linkDataMap) { + + for (LinkData linkData : linkDataMap.getLinkDataList()) { + final Application fromApplicationId = linkData.getFromApplication(); + Node fromNode = nodeList.findNode(fromApplicationId); + // TODO + final Application toApplicationId = linkData.getToApplication(); + Node toNode = nodeList.findNode(toApplicationId); + + // rpc client가 빠진경우임. + if (fromNode == null) { + logger.warn("fromNode rcp client not found:{}", toApplicationId); + continue; + } + + // RPC client인 경우 dest application이 이미 있으면 삭제, 없으면 unknown cloud로 변경. + if (toNode.getServiceType().isRpcClient()) { + // to 노드가 존재하는지 검사? + if (!nodeList.containsNode(toNode.getApplication())) { + final Link link = addLink(linkList, fromNode, toNode, CreateType.Target); + if(link != null) { + logger.debug("createRpcTargetLink:{}", link); + } + } + } else { + final Link link = addLink(linkList, fromNode, toNode, CreateType.Target); + if(link != null) { + logger.debug("createTargetLink:{}", link); + } + } + } + } + + public void appendNodeResponseTime(NodeList nodeList, LinkList linkList, NodeHistogramDataSource nodeHistogramDataSource) { + if (nodeHistogramDataSource == null) { + throw new NullPointerException("nodeHistogramDataSource must not be null"); + } + + final Collection nodes = nodeList.getNodeList(); + for (Node node : nodes) { + final ServiceType nodeType = node.getServiceType(); + if (nodeType.isWas()) { + // was일 경우 자신의 response 히스토그램을 조회하여 채운다. + final Application wasNode = node.getApplication(); + final NodeHistogram nodeHistogram = nodeHistogramDataSource.createNodeHistogram(wasNode); + node.setNodeHistogram(nodeHistogram); + + } else if(nodeType.isTerminal() || nodeType.isUnknown()) { + final NodeHistogram nodeHistogram = createTerminalNodeHistogram(node, linkList); + node.setNodeHistogram(nodeHistogram); + } else if (nodeType.isUser()) { + // User노드인 경우 source 링크를 찾아 histogram을 생성한다. + Application userNode = node.getApplication(); + + final NodeHistogram nodeHistogram = new NodeHistogram(userNode, range); + final List fromLink = linkList.findFromLink(userNode); + if (fromLink.size() > 1) { + logger.warn("Invalid from UserNode:{}", linkList); + throw new IllegalArgumentException("Invalid from UserNode.size() :" + fromLink.size()); + } else if (fromLink.size() == 0) { + logger.warn("from UserNode not found:{}", userNode); + continue; + } + final Link sourceLink = fromLink.get(0); + nodeHistogram.setApplicationHistogram(sourceLink.getHistogram()); + + ApplicationTimeHistogram histogramData = sourceLink.getTargetApplicationTimeSeriesHistogramData(); + nodeHistogram.setApplicationTimeHistogram(histogramData); + + node.setNodeHistogram(nodeHistogram); + } else { + // 그냥 데미 데이터 + NodeHistogram dummy = new NodeHistogram(node.getApplication(), range); + node.setNodeHistogram(dummy); + } + + } + + } + + private NodeHistogram createTerminalNodeHistogram(Node node, LinkList linkList) { + // 터미널 노드인경우, 자신을 가리키는 link값을 합하여 histogram을 생성한다. + final Application nodeApplication = node.getApplication(); + final NodeHistogram nodeHistogram = new NodeHistogram(nodeApplication, range); + + // appclicationHistogram 생성. + final List toLinkList = linkList.findToLink(nodeApplication); + final Histogram applicationHistogram = new Histogram(node.getServiceType()); + for (Link link : toLinkList) { + applicationHistogram.add(link.getHistogram()); + } + nodeHistogram.setApplicationHistogram(applicationHistogram); + + // applicationTimeHistogram 생성. + LinkCallDataMap linkCallDataMap = new LinkCallDataMap(); + for (Link link : toLinkList) { + LinkCallDataMap sourceLinkCallDataMap = link.getSourceLinkCallDataMap(); + linkCallDataMap.addLinkDataMap(sourceLinkCallDataMap); + } + ApplicationTimeHistogramBuilder builder = new ApplicationTimeHistogramBuilder(nodeApplication, range); + ApplicationTimeHistogram applicationTimeHistogram = builder.build(linkCallDataMap.getLinkDataList()); + nodeHistogram.setApplicationTimeHistogram(applicationTimeHistogram); + + // terminal일 경우 node의 AgentLevel histogram을 추가로 생성한다. + if (nodeApplication.getServiceType().isTerminal()) { + final Map agentHistogramMap = new HashMap(); + + for (Link link : toLinkList) { + LinkCallDataMap sourceLinkCallDataMap = link.getSourceLinkCallDataMap(); + AgentHistogramList targetList = sourceLinkCallDataMap.getTargetList(); + for (AgentHistogram histogram : targetList.getAgentHistogramList()) { + Histogram find = agentHistogramMap.get(histogram.getId()); + if (find == null) { + find = new Histogram(histogram.getServiceType()); + agentHistogramMap.put(histogram.getId(), find); + } + find.add(histogram.getHistogram()); + } + nodeHistogram.setAgentHistogramMap(agentHistogramMap); + } + } + + LinkCallDataMap mergeSource = new LinkCallDataMap(); + for (Link link : toLinkList) { + LinkCallDataMap sourceLinkCallDataMap = link.getSourceLinkCallDataMap(); + mergeSource.addLinkDataMap(sourceLinkCallDataMap); + } + + AgentTimeHistogramBuilder agentTimeBuilder = new AgentTimeHistogramBuilder(nodeApplication, range); + AgentTimeHistogram agentTimeHistogram = agentTimeBuilder.buildTarget(mergeSource); + nodeHistogram.setAgentTimeHistogram(agentTimeHistogram); + + return nodeHistogram; + } + + public void appendAgentInfo(NodeList nodeList, LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService) { + for (Node node : nodeList.getNodeList()) { + appendServerInfo(node, linkDataDuplexMap, agentInfoService); + } + + } + + private void appendServerInfo(Node node, LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService) { + final ServiceType nodeServiceType = node.getServiceType(); + if (nodeServiceType.isUnknown()) { + // unknown노드는 무엇이 설치되어있는지 알수가 없음. + return; + } + + if (nodeServiceType.isTerminal()) { + // terminal노드에 설치되어 있는 정보를 유추한다. + ServerBuilder builder = new ServerBuilder(); + for (LinkData linkData : linkDataDuplexMap.getSourceLinkDataList()) { + Application toApplication = linkData.getToApplication(); + if (node.getApplication().equals(toApplication)) { + builder.addCallHistogramList(linkData.getTargetList()); + } + } + ServerInstanceList serverInstanceList = builder.build(); + node.setServerInstanceList(serverInstanceList); + } else if (nodeServiceType.isWas()) { + Set agentList = agentInfoService.selectAgent(node.getApplication().getName(), range); + if (agentList.isEmpty()) { + return; + } + logger.debug("add agentInfo. {}, {}", node.getApplication(), agentList); + ServerBuilder builder = new ServerBuilder(); + agentList = filterAgentInfoByResponseData(agentList, node); + builder.addAgentInfo(agentList); + ServerInstanceList serverInstanceList = builder.build(); + + // destination이 WAS이고 agent가 설치되어있으면 agentSet이 존재한다. + node.setServerInstanceList(serverInstanceList); + } else { + // 기타 해당 되지 않는 상황일 경우 empty 정보를 넣는다. + node.setServerInstanceList(new ServerInstanceList()); + } + + } + + /** + * 실제 응답속도 정보가 있는 데이터를 기반으로 AgentInfo를 필터링 친다. + * 정공이라고 말할 수 있는 코드는 아님. + * 나중에 실제 서버가 살아 있는 정보를 기반으로 이를 유추할수 있게 해야한다. + */ + private Set filterAgentInfoByResponseData(Set agentList, Node node) { + Set filteredAgentInfo = new HashSet(); + + NodeHistogram nodeHistogram = node.getNodeHistogram(); + Map agentHistogramMap = nodeHistogram.getAgentHistogramMap(); + for (AgentInfoBo agentInfoBo : agentList) { + String agentId = agentInfoBo.getAgentId(); + if (agentHistogramMap.containsKey(agentId)) { + filteredAgentInfo.add(agentInfoBo); + } + } + + return filteredAgentInfo; + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/CreateType.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/CreateType.java index 350804763cf7..0b767902e33e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/CreateType.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/CreateType.java @@ -1,9 +1,9 @@ -package com.nhn.pinpoint.web.applicationmap; - -/** - * 호출한 정보에 의해서 생성된거면 Source, 호출당한 정보에 의해서 생성되면 Target - * @author emeroad - */ -public enum CreateType { - Source, Target -} +package com.nhn.pinpoint.web.applicationmap; + +/** + * 호출한 정보에 의해서 생성된거면 Source, 호출당한 정보에 의해서 생성되면 Target + * @author emeroad + */ +public enum CreateType { + Source, Target +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/FilterMapWrap.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/FilterMapWrap.java index d6f2cfe9fb99..2d708d928657 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/FilterMapWrap.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/FilterMapWrap.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.web.applicationmap; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.nhn.pinpoint.web.view.FilterMapWrapSerializer; -import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; - -import java.util.List; - -/** - * @author emeroad - */ -@JsonSerialize(using = FilterMapWrapSerializer.class) -public class FilterMapWrap { - private final ApplicationMap applicationMap; - private Long lastFetchedTimestamp; - - public FilterMapWrap(ApplicationMap applicationMap) { - this.applicationMap = applicationMap; - } - - - public void setLastFetchedTimestamp(Long lastFetchedTimestamp) { - this.lastFetchedTimestamp = lastFetchedTimestamp; - } - - public ApplicationMap getApplicationMap() { - return applicationMap; - } - - public Long getLastFetchedTimestamp() { - return lastFetchedTimestamp; - } - - public List getApplicationScatterScanResult() { - return this.applicationMap.getApplicationScatterScanResultList(); - } -} +package com.nhn.pinpoint.web.applicationmap; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.nhn.pinpoint.web.view.FilterMapWrapSerializer; +import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; + +import java.util.List; + +/** + * @author emeroad + */ +@JsonSerialize(using = FilterMapWrapSerializer.class) +public class FilterMapWrap { + private final ApplicationMap applicationMap; + private Long lastFetchedTimestamp; + + public FilterMapWrap(ApplicationMap applicationMap) { + this.applicationMap = applicationMap; + } + + + public void setLastFetchedTimestamp(Long lastFetchedTimestamp) { + this.lastFetchedTimestamp = lastFetchedTimestamp; + } + + public ApplicationMap getApplicationMap() { + return applicationMap; + } + + public Long getLastFetchedTimestamp() { + return lastFetchedTimestamp; + } + + public List getApplicationScatterScanResult() { + return this.applicationMap.getApplicationScatterScanResultList(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkList.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkList.java index 6b8e3e7a8202..841c790a2d8b 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkList.java @@ -1,94 +1,94 @@ -package com.nhn.pinpoint.web.applicationmap; - -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.LinkKey; - -import java.util.*; - -/** - * @author emeroad - */ -public class LinkList { - - private final Map linkMap = new HashMap(); - - public Collection getLinkList() { - return this.linkMap.values(); - } - - public void addLinkList(LinkList linkList) { - if (linkList == null) { - throw new NullPointerException("linkList must not be null"); - } - - for (Link link : linkList.getLinkList()) { - addLink(link); - } - } - - /** - * toApplication을 가리키는(호출당하는) 모든 link를 찾음. - * @param toApplication - * @return - */ - public List findToLink(Application toApplication) { - if (toApplication == null) { - throw new NullPointerException("toApplication must not be null"); - } - - List findList = new ArrayList(); - for (Link link : linkMap.values()) { - Node toNode = link.getTo(); - // destnation이 자신을 가리키는 모든 Link를 찾음. - if (toNode.getApplication().equals(toApplication)) { - findList.add(link); - } - } - return findList; - } - - /** - * fromApplication 에서 나가는(호출하는) link를 모두 찾음. - * @param fromApplication - * @return - */ - public List findFromLink(Application fromApplication) { - if (fromApplication == null) { - throw new NullPointerException("toApplication must not be null"); - } - - List findList = new ArrayList(); - for (Link link : linkMap.values()) { - Node fromNode = link.getFrom(); - - if (fromNode.getApplication().equals(fromApplication)) { - findList.add(link); - } - } - return findList; - } - - public boolean addLink(Link link) { - if (link == null) { - throw new NullPointerException("link must not be null"); - } - - final LinkKey linkId = link.getLinkKey(); - final Link find = this.linkMap.get(linkId); - if (find != null) { - return false; - } - return this.linkMap.put(linkId, link) == null; - } - - public boolean containsNode(Link link) { - if (link == null) { - throw new NullPointerException("linkKey must not be null"); - } - return linkMap.containsKey(link.getLinkKey()); - } - - public int size() { - return this.linkMap.size(); - } -} +package com.nhn.pinpoint.web.applicationmap; + +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.LinkKey; + +import java.util.*; + +/** + * @author emeroad + */ +public class LinkList { + + private final Map linkMap = new HashMap(); + + public Collection getLinkList() { + return this.linkMap.values(); + } + + public void addLinkList(LinkList linkList) { + if (linkList == null) { + throw new NullPointerException("linkList must not be null"); + } + + for (Link link : linkList.getLinkList()) { + addLink(link); + } + } + + /** + * toApplication을 가리키는(호출당하는) 모든 link를 찾음. + * @param toApplication + * @return + */ + public List findToLink(Application toApplication) { + if (toApplication == null) { + throw new NullPointerException("toApplication must not be null"); + } + + List findList = new ArrayList(); + for (Link link : linkMap.values()) { + Node toNode = link.getTo(); + // destnation이 자신을 가리키는 모든 Link를 찾음. + if (toNode.getApplication().equals(toApplication)) { + findList.add(link); + } + } + return findList; + } + + /** + * fromApplication 에서 나가는(호출하는) link를 모두 찾음. + * @param fromApplication + * @return + */ + public List findFromLink(Application fromApplication) { + if (fromApplication == null) { + throw new NullPointerException("toApplication must not be null"); + } + + List findList = new ArrayList(); + for (Link link : linkMap.values()) { + Node fromNode = link.getFrom(); + + if (fromNode.getApplication().equals(fromApplication)) { + findList.add(link); + } + } + return findList; + } + + public boolean addLink(Link link) { + if (link == null) { + throw new NullPointerException("link must not be null"); + } + + final LinkKey linkId = link.getLinkKey(); + final Link find = this.linkMap.get(linkId); + if (find != null) { + return false; + } + return this.linkMap.put(linkId, link) == null; + } + + public boolean containsNode(Link link) { + if (link == null) { + throw new NullPointerException("linkKey must not be null"); + } + return linkMap.containsKey(link.getLinkKey()); + } + + public int size() { + return this.linkMap.size(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkStateResolver.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkStateResolver.java index 35ed13e669d0..faf5c607cc50 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkStateResolver.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/LinkStateResolver.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.web.applicationmap; - -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; - -/** - * @author emeroad - */ -public class LinkStateResolver { - public static final LinkStateResolver DEFAULT_LINK_STATE_RESOLVER = new LinkStateResolver(); - public static final String BAD = "bad"; - - public String resolve(Link link) { - if (link == null) { - throw new NullPointerException("link must not be null"); - } - // Histogram이 중복으로 생성되고 있어 그냥 인자로 받음 수정 요망. - final long error = getErrorRate(link.getHistogram()); - if (error * 100 > 10) { - return BAD; - } - return "default"; - - } - - public boolean isAlert(Link link) { - String resolve = resolve(link); - if (BAD.equals(resolve)) { - return true; - } - return false; - } - - private long getErrorRate(Histogram histogram) { - if (histogram == null) { - throw new NullPointerException("histogram must not be null"); - } - final long totalCount = histogram.getTotalCount(); - if (totalCount == 0) { - return 0; - } - return histogram.getErrorCount() / totalCount; - } -} +package com.nhn.pinpoint.web.applicationmap; + +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; + +/** + * @author emeroad + */ +public class LinkStateResolver { + public static final LinkStateResolver DEFAULT_LINK_STATE_RESOLVER = new LinkStateResolver(); + public static final String BAD = "bad"; + + public String resolve(Link link) { + if (link == null) { + throw new NullPointerException("link must not be null"); + } + // Histogram이 중복으로 생성되고 있어 그냥 인자로 받음 수정 요망. + final long error = getErrorRate(link.getHistogram()); + if (error * 100 > 10) { + return BAD; + } + return "default"; + + } + + public boolean isAlert(Link link) { + String resolve = resolve(link); + if (BAD.equals(resolve)) { + return true; + } + return false; + } + + private long getErrorRate(Histogram histogram) { + if (histogram == null) { + throw new NullPointerException("histogram must not be null"); + } + final long totalCount = histogram.getTotalCount(); + if (totalCount == 0) { + return 0; + } + return histogram.getErrorCount() / totalCount; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/MapWrap.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/MapWrap.java index ece9e569a2be..001812c28226 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/MapWrap.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/MapWrap.java @@ -1,22 +1,22 @@ -package com.nhn.pinpoint.web.applicationmap; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -/** - * @author emeroad - */ -@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) -public class MapWrap { - private final ApplicationMap applicationMap; - - public MapWrap(ApplicationMap applicationMap) { - this.applicationMap = applicationMap; - } - - @JsonProperty("applicationMapData") - public ApplicationMap getApplicationMap() { - return applicationMap; - } - -} +package com.nhn.pinpoint.web.applicationmap; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * @author emeroad + */ +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) +public class MapWrap { + private final ApplicationMap applicationMap; + + public MapWrap(ApplicationMap applicationMap) { + this.applicationMap = applicationMap; + } + + @JsonProperty("applicationMapData") + public ApplicationMap getApplicationMap() { + return applicationMap; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/NodeList.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/NodeList.java index 0c3f46cb4fc8..9823e5563f9c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/NodeList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/NodeList.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.web.applicationmap; - -import com.nhn.pinpoint.web.vo.Application; - -import java.util.*; - -/** - * @author emeroad - */ -public class NodeList { - - private final Map nodeMap = new HashMap(); - - public Collection getNodeList() { - return this.nodeMap.values(); - } - - public Node findNode(Application application) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - return this.nodeMap.get(application); - } - - public boolean addNode(Node node) { - if (node == null) { - throw new NullPointerException("node must not be null"); - } - final Application nodeId = node.getApplication(); - Node findNode = findNode(nodeId); - if (findNode != null) { - return false; - } - return nodeMap.put(nodeId, node) == null; - } - - - public void addNodeList(NodeList nodeList) { - if (nodeList == null) { - throw new NullPointerException("nodeList must not be null"); - } - for (Node node : nodeList.getNodeList()) { - addNode(node); - } - } - - public boolean containsNode(Application application) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - return nodeMap.containsKey(application); - } - - public int size() { - return this.nodeMap.size(); - } -} +package com.nhn.pinpoint.web.applicationmap; + +import com.nhn.pinpoint.web.vo.Application; + +import java.util.*; + +/** + * @author emeroad + */ +public class NodeList { + + private final Map nodeMap = new HashMap(); + + public Collection getNodeList() { + return this.nodeMap.values(); + } + + public Node findNode(Application application) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + return this.nodeMap.get(application); + } + + public boolean addNode(Node node) { + if (node == null) { + throw new NullPointerException("node must not be null"); + } + final Application nodeId = node.getApplication(); + Node findNode = findNode(nodeId); + if (findNode != null) { + return false; + } + return nodeMap.put(nodeId, node) == null; + } + + + public void addNodeList(NodeList nodeList) { + if (nodeList == null) { + throw new NullPointerException("nodeList must not be null"); + } + for (Node node : nodeList.getNodeList()) { + addNode(node); + } + } + + public boolean containsNode(Application application) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + return nodeMap.containsKey(application); + } + + public int size() { + return this.nodeMap.size(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerBuilder.java index d0d20a12ac56..8652b6117311 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerBuilder.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerBuilder.java @@ -1,103 +1,103 @@ -package com.nhn.pinpoint.web.applicationmap; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class ServerBuilder { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final AgentHistogramList agentHistogramList; - private final Set agentSet; - - public ServerBuilder() { - this.agentHistogramList = new AgentHistogramList(); - this.agentSet = new HashSet(); - } - - public void addCallHistogramList(AgentHistogramList agentHistogramList) { - if (agentHistogramList == null) { - return; - } - this.agentHistogramList.addAgentHistogram(agentHistogramList); - } - - public void addAgentInfo(Set agentInfoBo) { - if (agentInfoBo == null) { - return; - } - this.agentSet.addAll(agentInfoBo); - } - - public void addServerInstance(ServerBuilder copy) { - if (copy == null) { - throw new NullPointerException("copy must not be null"); - } - addCallHistogramList(copy.agentHistogramList); - addAgentInfo(copy.agentSet); - } - - - - private String getHostName(String instanceName) { - final int pos = instanceName.indexOf(':'); - if (pos > 0) { - return instanceName.substring(0, pos); - } else { - return instanceName; - } - } - - /** - * 어플리케이션에 속한 물리서버와 서버 인스턴스 정보를 채운다. - * - * @param hostHistogram - */ - public ServerInstanceList buildLogicalServer(final AgentHistogramList hostHistogram) { - ServerInstanceList serverInstanceList = new ServerInstanceList(); - for (AgentHistogram agentHistogram : hostHistogram.getAgentHistogramList()) { - final String instanceName = agentHistogram.getId(); - final String hostName = getHostName(agentHistogram.getId()); - final ServiceType serviceType = agentHistogram.getServiceType(); - - final ServerInstance serverInstance = new ServerInstance(hostName, instanceName, serviceType); - serverInstanceList.addServerInstance(serverInstance); - } - return serverInstanceList; - } - - public ServerInstanceList buildPhysicalServer(final Set agentSet) { - final ServerInstanceList serverInstanceList = new ServerInstanceList(); - for (AgentInfoBo agent : agentSet) { - final ServerInstance serverInstance = new ServerInstance(agent); - serverInstanceList.addServerInstance(serverInstance); - - } - return serverInstanceList; - } - - - - public ServerInstanceList build() { - if (!agentSet.isEmpty()) { - // agent이름이 존재할 경우. 실제 리얼 서버가 존재할 경우 - this.logger.debug("buildPhysicalServer:{}", agentSet); - return buildPhysicalServer(agentSet); - } else { - // 논리 이름으로 구성. - this.logger.debug("buildLogicalServer"); - return buildLogicalServer(agentHistogramList); - } - } - - -} +package com.nhn.pinpoint.web.applicationmap; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class ServerBuilder { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final AgentHistogramList agentHistogramList; + private final Set agentSet; + + public ServerBuilder() { + this.agentHistogramList = new AgentHistogramList(); + this.agentSet = new HashSet(); + } + + public void addCallHistogramList(AgentHistogramList agentHistogramList) { + if (agentHistogramList == null) { + return; + } + this.agentHistogramList.addAgentHistogram(agentHistogramList); + } + + public void addAgentInfo(Set agentInfoBo) { + if (agentInfoBo == null) { + return; + } + this.agentSet.addAll(agentInfoBo); + } + + public void addServerInstance(ServerBuilder copy) { + if (copy == null) { + throw new NullPointerException("copy must not be null"); + } + addCallHistogramList(copy.agentHistogramList); + addAgentInfo(copy.agentSet); + } + + + + private String getHostName(String instanceName) { + final int pos = instanceName.indexOf(':'); + if (pos > 0) { + return instanceName.substring(0, pos); + } else { + return instanceName; + } + } + + /** + * 어플리케이션에 속한 물리서버와 서버 인스턴스 정보를 채운다. + * + * @param hostHistogram + */ + public ServerInstanceList buildLogicalServer(final AgentHistogramList hostHistogram) { + ServerInstanceList serverInstanceList = new ServerInstanceList(); + for (AgentHistogram agentHistogram : hostHistogram.getAgentHistogramList()) { + final String instanceName = agentHistogram.getId(); + final String hostName = getHostName(agentHistogram.getId()); + final ServiceType serviceType = agentHistogram.getServiceType(); + + final ServerInstance serverInstance = new ServerInstance(hostName, instanceName, serviceType); + serverInstanceList.addServerInstance(serverInstance); + } + return serverInstanceList; + } + + public ServerInstanceList buildPhysicalServer(final Set agentSet) { + final ServerInstanceList serverInstanceList = new ServerInstanceList(); + for (AgentInfoBo agent : agentSet) { + final ServerInstance serverInstance = new ServerInstance(agent); + serverInstanceList.addServerInstance(serverInstance); + + } + return serverInstanceList; + } + + + + public ServerInstanceList build() { + if (!agentSet.isEmpty()) { + // agent이름이 존재할 경우. 실제 리얼 서버가 존재할 경우 + this.logger.debug("buildPhysicalServer:{}", agentSet); + return buildPhysicalServer(agentSet); + } else { + // 논리 이름으로 구성. + this.logger.debug("buildLogicalServer"); + return buildLogicalServer(agentHistogramList); + } + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerInstanceList.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerInstanceList.java index 751c62da1f52..79db3f48caa3 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerInstanceList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerInstanceList.java @@ -1,65 +1,65 @@ -package com.nhn.pinpoint.web.applicationmap; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.nhn.pinpoint.web.view.ServerInstanceListSerializer; - -/** - * @author emeroad - * @author netspider - */ -@JsonSerialize(using = ServerInstanceListSerializer.class) -public class ServerInstanceList { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Map> serverInstanceList = new TreeMap>(); - - public ServerInstanceList() { - } - - public Map> getServerInstanceList() { - // list의 소트가 안되 있는 문제가 있음. - return serverInstanceList; - } - - public int getInstanceCount() { - int count = 0; - for (List entry : serverInstanceList.values()) { - count += entry.size(); - } - return count; - } - - private void addServerInstance(List nodeList, ServerInstance serverInstance) { - for (ServerInstance node : nodeList) { - boolean equalsNode = node.equals(serverInstance); - if (equalsNode) { - return; - } - } - nodeList.add(serverInstance); - } - - private List getServerInstanceList(String hostName) { - List find = serverInstanceList.get(hostName); - if (find == null) { - find = new ArrayList(); - serverInstanceList.put(hostName, find); - } - return find; - } - - void addServerInstance(ServerInstance serverInstance) { - List find = getServerInstanceList(serverInstance.getHostName()); - addServerInstance(find, serverInstance); - } -} +package com.nhn.pinpoint.web.applicationmap; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.nhn.pinpoint.web.view.ServerInstanceListSerializer; + +/** + * @author emeroad + * @author netspider + */ +@JsonSerialize(using = ServerInstanceListSerializer.class) +public class ServerInstanceList { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Map> serverInstanceList = new TreeMap>(); + + public ServerInstanceList() { + } + + public Map> getServerInstanceList() { + // list의 소트가 안되 있는 문제가 있음. + return serverInstanceList; + } + + public int getInstanceCount() { + int count = 0; + for (List entry : serverInstanceList.values()) { + count += entry.size(); + } + return count; + } + + private void addServerInstance(List nodeList, ServerInstance serverInstance) { + for (ServerInstance node : nodeList) { + boolean equalsNode = node.equals(serverInstance); + if (equalsNode) { + return; + } + } + nodeList.add(serverInstance); + } + + private List getServerInstanceList(String hostName) { + List find = serverInstanceList.get(hostName); + if (find == null) { + find = new ArrayList(); + serverInstanceList.put(hostName, find); + } + return find; + } + + void addServerInstance(ServerInstance serverInstance) { + List find = getServerInstanceList(serverInstance.getHostName()); + addServerInstance(find, serverInstance); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerType.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerType.java index f670b8b5e5e7..a02a4beb1da1 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerType.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/ServerType.java @@ -1,8 +1,8 @@ -package com.nhn.pinpoint.web.applicationmap; - -/** - * @author emeroad - */ -public enum ServerType { - Logical, Physical -} +package com.nhn.pinpoint.web.applicationmap; + +/** + * @author emeroad + */ +public enum ServerType { + Logical, Physical +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java index bf8d0e879804..5d3b48d18aed 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java @@ -1,117 +1,117 @@ -package com.nhn.pinpoint.web.applicationmap.histogram; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.SlotType; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import com.nhn.pinpoint.web.util.TimeWindow; -import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; -import com.nhn.pinpoint.web.view.AgentResponseTimeViewModel; -import com.nhn.pinpoint.web.view.ResponseTimeViewModel; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * 리팩토링하면서 AgentHistogramList에 기능이 거의 위임되었음. - * viewCreate정도로 기능이 한정되서 추후 삭제하거나. 이름을 변경해야 될듯하다. - * @author emeroad - */ -public class AgentTimeHistogram { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - private final Range range; - private final TimeWindow window; - - private final AgentHistogramList agentHistogramList; - - public AgentTimeHistogram(Application application, Range range) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - this.application = application; - this.range = range; - this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); - this.agentHistogramList = new AgentHistogramList(); - } - - public AgentTimeHistogram(Application application, Range range, AgentHistogramList agentHistogramList) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - if (agentHistogramList == null) { - throw new NullPointerException("agentHistogramList must not be null"); - } - this.application = application; - this.range = range; - this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); - this.agentHistogramList = agentHistogramList; - } - - - public List createViewModel() { - final List result = new ArrayList(); - for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { - Application agentId = agentHistogram.getAgentId(); - List timeList = sortTimeHistogram(agentHistogram.getTimeHistogram()); - AgentResponseTimeViewModel model = createAgentResponseTimeViewModel(agentId, timeList); - result.add(model); - } - Collections.sort(result, new Comparator() { - @Override - public int compare(AgentResponseTimeViewModel o1, AgentResponseTimeViewModel o2) { - return o1.getAgentName().compareTo(o2.getAgentName()); - } - }); - return result; - } - - private List sortTimeHistogram(Collection timeMap) { - List timeList = new ArrayList(timeMap); - Collections.sort(timeList, TimeHistogram.TIME_STAMP_ASC_COMPARATOR); - return timeList; - } - - - private AgentResponseTimeViewModel createAgentResponseTimeViewModel(Application agentName, List timeHistogramList) { - List responseTimeViewModel = createResponseTimeViewModel(timeHistogramList); - AgentResponseTimeViewModel agentResponseTimeViewModel = new AgentResponseTimeViewModel(agentName, responseTimeViewModel); - return agentResponseTimeViewModel; - } - - public List createResponseTimeViewModel(List timeHistogramList) { - final List value = new ArrayList(5); - ServiceType serviceType = application.getServiceType(); - HistogramSchema schema = serviceType.getHistogramSchema(); - value.add(new ResponseTimeViewModel(schema.getFastSlot().getSlotName(), getColumnValue(SlotType.FAST, timeHistogramList))); - value.add(new ResponseTimeViewModel(schema.getNormalSlot().getSlotName(), getColumnValue(SlotType.NORMAL, timeHistogramList))); - value.add(new ResponseTimeViewModel(schema.getSlowSlot().getSlotName(), getColumnValue(SlotType.SLOW, timeHistogramList))); - value.add(new ResponseTimeViewModel(schema.getVerySlowSlot().getSlotName(), getColumnValue(SlotType.VERY_SLOW, timeHistogramList))); - value.add(new ResponseTimeViewModel(schema.getErrorSlot().getSlotName(), getColumnValue(SlotType.ERROR, timeHistogramList))); - return value; - } - - public List getColumnValue(SlotType slotType, List timeHistogramList) { - List result = new ArrayList(timeHistogramList.size()); - for (TimeHistogram timeHistogram : timeHistogramList) { - result.add(new ResponseTimeViewModel.TimeCount(timeHistogram.getTimeStamp(), getCount(timeHistogram, slotType))); - } - return result; - } - - public long getCount(TimeHistogram timeHistogram, SlotType slotType) { - return timeHistogram.getCount(slotType); - } -} +package com.nhn.pinpoint.web.applicationmap.histogram; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.SlotType; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.nhn.pinpoint.web.util.TimeWindow; +import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; +import com.nhn.pinpoint.web.view.AgentResponseTimeViewModel; +import com.nhn.pinpoint.web.view.ResponseTimeViewModel; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * 리팩토링하면서 AgentHistogramList에 기능이 거의 위임되었음. + * viewCreate정도로 기능이 한정되서 추후 삭제하거나. 이름을 변경해야 될듯하다. + * @author emeroad + */ +public class AgentTimeHistogram { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + private final Range range; + private final TimeWindow window; + + private final AgentHistogramList agentHistogramList; + + public AgentTimeHistogram(Application application, Range range) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + this.application = application; + this.range = range; + this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); + this.agentHistogramList = new AgentHistogramList(); + } + + public AgentTimeHistogram(Application application, Range range, AgentHistogramList agentHistogramList) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + if (agentHistogramList == null) { + throw new NullPointerException("agentHistogramList must not be null"); + } + this.application = application; + this.range = range; + this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); + this.agentHistogramList = agentHistogramList; + } + + + public List createViewModel() { + final List result = new ArrayList(); + for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { + Application agentId = agentHistogram.getAgentId(); + List timeList = sortTimeHistogram(agentHistogram.getTimeHistogram()); + AgentResponseTimeViewModel model = createAgentResponseTimeViewModel(agentId, timeList); + result.add(model); + } + Collections.sort(result, new Comparator() { + @Override + public int compare(AgentResponseTimeViewModel o1, AgentResponseTimeViewModel o2) { + return o1.getAgentName().compareTo(o2.getAgentName()); + } + }); + return result; + } + + private List sortTimeHistogram(Collection timeMap) { + List timeList = new ArrayList(timeMap); + Collections.sort(timeList, TimeHistogram.TIME_STAMP_ASC_COMPARATOR); + return timeList; + } + + + private AgentResponseTimeViewModel createAgentResponseTimeViewModel(Application agentName, List timeHistogramList) { + List responseTimeViewModel = createResponseTimeViewModel(timeHistogramList); + AgentResponseTimeViewModel agentResponseTimeViewModel = new AgentResponseTimeViewModel(agentName, responseTimeViewModel); + return agentResponseTimeViewModel; + } + + public List createResponseTimeViewModel(List timeHistogramList) { + final List value = new ArrayList(5); + ServiceType serviceType = application.getServiceType(); + HistogramSchema schema = serviceType.getHistogramSchema(); + value.add(new ResponseTimeViewModel(schema.getFastSlot().getSlotName(), getColumnValue(SlotType.FAST, timeHistogramList))); + value.add(new ResponseTimeViewModel(schema.getNormalSlot().getSlotName(), getColumnValue(SlotType.NORMAL, timeHistogramList))); + value.add(new ResponseTimeViewModel(schema.getSlowSlot().getSlotName(), getColumnValue(SlotType.SLOW, timeHistogramList))); + value.add(new ResponseTimeViewModel(schema.getVerySlowSlot().getSlotName(), getColumnValue(SlotType.VERY_SLOW, timeHistogramList))); + value.add(new ResponseTimeViewModel(schema.getErrorSlot().getSlotName(), getColumnValue(SlotType.ERROR, timeHistogramList))); + return value; + } + + public List getColumnValue(SlotType slotType, List timeHistogramList) { + List result = new ArrayList(timeHistogramList.size()); + for (TimeHistogram timeHistogram : timeHistogramList) { + result.add(new ResponseTimeViewModel.TimeCount(timeHistogram.getTimeStamp(), getCount(timeHistogram, slotType))); + } + return result; + } + + public long getCount(TimeHistogram timeHistogram, SlotType slotType) { + return timeHistogram.getCount(slotType); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java index d722e065bbf2..dea821632083 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java @@ -1,104 +1,104 @@ -package com.nhn.pinpoint.web.applicationmap.histogram; - -import com.nhn.pinpoint.common.SlotType; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkCallDataMap; -import com.nhn.pinpoint.web.util.TimeWindow; -import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; -import com.nhn.pinpoint.web.vo.ResponseTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class AgentTimeHistogramBuilder { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - private final Range range; - private final TimeWindow window; - - public AgentTimeHistogramBuilder(Application application, Range range) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - this.application = application; - this.range = range; - this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); - } - - - public AgentTimeHistogram build(List responseHistogramList) { - AgentHistogramList agentHistogramList = new AgentHistogramList(application, responseHistogramList); - return build(agentHistogramList); - } - - public AgentTimeHistogram buildSource(LinkCallDataMap linkCallDataMap) { - if (linkCallDataMap == null) { - throw new NullPointerException("linkCallDataMap must not be null"); - } - return build(linkCallDataMap.getSourceList()); - } - - public AgentTimeHistogram buildTarget(LinkCallDataMap linkCallDataMap) { - if (linkCallDataMap == null) { - throw new NullPointerException("linkCallDataMap must not be null"); - } - return build(linkCallDataMap.getTargetList()); - } - - - private AgentTimeHistogram build(AgentHistogramList agentHistogramList) { - AgentHistogramList histogramList = interpolation(agentHistogramList, window); - AgentTimeHistogram agentTimeHistogram = new AgentTimeHistogram(application, range, histogramList); - return agentTimeHistogram; - } - - - private AgentHistogramList interpolation(AgentHistogramList agentHistogramList, TimeWindow window) { - if (agentHistogramList.size() == 0) { - return new AgentHistogramList(); - } - - // window 공간생성. AgentHistogramList 사용이전에는 그냥 생짜 자료구조를 사용함. - // list로 할수도 있으나, filter일 경우 range를 초과하는 경우가 발생할 가능성이 있어 map으로 생성한다. - // 좀더 나은 방인이 있으면 변경하는게 좋을듯. - final AgentHistogramList resultAgentHistogramList = new AgentHistogramList(); - for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { - List timeHistogramList = new ArrayList(); - for (Long time : window) { - timeHistogramList.add(new TimeHistogram(application.getServiceType(), time)); - } - resultAgentHistogramList.addTimeHistogram(agentHistogram.getAgentId(), timeHistogramList); - } - - for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { - for (TimeHistogram timeHistogram : agentHistogram.getTimeHistogram()) { - final Long time = window.refineTimestamp(timeHistogram.getTimeStamp()); - Application agentId = agentHistogram.getAgentId(); - TimeHistogram windowHistogram = new TimeHistogram(timeHistogram.getHistogramSchema(), time); - windowHistogram.add(timeHistogram); - resultAgentHistogramList.addTimeHistogram(agentId, windowHistogram); - } - } - - return resultAgentHistogramList; - } - - - public long getCount(TimeHistogram timeHistogram, SlotType slotType) { - return timeHistogram.getCount(slotType); - } - - -} +package com.nhn.pinpoint.web.applicationmap.histogram; + +import com.nhn.pinpoint.common.SlotType; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkCallDataMap; +import com.nhn.pinpoint.web.util.TimeWindow; +import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; +import com.nhn.pinpoint.web.vo.ResponseTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class AgentTimeHistogramBuilder { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + private final Range range; + private final TimeWindow window; + + public AgentTimeHistogramBuilder(Application application, Range range) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + this.application = application; + this.range = range; + this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); + } + + + public AgentTimeHistogram build(List responseHistogramList) { + AgentHistogramList agentHistogramList = new AgentHistogramList(application, responseHistogramList); + return build(agentHistogramList); + } + + public AgentTimeHistogram buildSource(LinkCallDataMap linkCallDataMap) { + if (linkCallDataMap == null) { + throw new NullPointerException("linkCallDataMap must not be null"); + } + return build(linkCallDataMap.getSourceList()); + } + + public AgentTimeHistogram buildTarget(LinkCallDataMap linkCallDataMap) { + if (linkCallDataMap == null) { + throw new NullPointerException("linkCallDataMap must not be null"); + } + return build(linkCallDataMap.getTargetList()); + } + + + private AgentTimeHistogram build(AgentHistogramList agentHistogramList) { + AgentHistogramList histogramList = interpolation(agentHistogramList, window); + AgentTimeHistogram agentTimeHistogram = new AgentTimeHistogram(application, range, histogramList); + return agentTimeHistogram; + } + + + private AgentHistogramList interpolation(AgentHistogramList agentHistogramList, TimeWindow window) { + if (agentHistogramList.size() == 0) { + return new AgentHistogramList(); + } + + // window 공간생성. AgentHistogramList 사용이전에는 그냥 생짜 자료구조를 사용함. + // list로 할수도 있으나, filter일 경우 range를 초과하는 경우가 발생할 가능성이 있어 map으로 생성한다. + // 좀더 나은 방인이 있으면 변경하는게 좋을듯. + final AgentHistogramList resultAgentHistogramList = new AgentHistogramList(); + for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { + List timeHistogramList = new ArrayList(); + for (Long time : window) { + timeHistogramList.add(new TimeHistogram(application.getServiceType(), time)); + } + resultAgentHistogramList.addTimeHistogram(agentHistogram.getAgentId(), timeHistogramList); + } + + for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { + for (TimeHistogram timeHistogram : agentHistogram.getTimeHistogram()) { + final Long time = window.refineTimestamp(timeHistogram.getTimeStamp()); + Application agentId = agentHistogram.getAgentId(); + TimeHistogram windowHistogram = new TimeHistogram(timeHistogram.getHistogramSchema(), time); + windowHistogram.add(timeHistogram); + resultAgentHistogramList.addTimeHistogram(agentId, windowHistogram); + } + } + + return resultAgentHistogramList; + } + + + public long getCount(TimeHistogram timeHistogram, SlotType slotType) { + return timeHistogram.getCount(slotType); + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogram.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogram.java index a5ada71694ce..47938ba69640 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogram.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogram.java @@ -1,75 +1,75 @@ -package com.nhn.pinpoint.web.applicationmap.histogram; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.SlotType; -import com.nhn.pinpoint.web.view.ResponseTimeViewModel; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class ApplicationTimeHistogram { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - private final Range range; - - private List histogramList; - - public ApplicationTimeHistogram(Application application, Range range) { - this(application, range, Collections.emptyList()); - } - - public ApplicationTimeHistogram(Application application, Range range, List histogramList) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - if (histogramList == null) { - throw new NullPointerException("histogramList must not be null"); - } - this.application = application; - this.range = range; - this.histogramList = histogramList; - } - - public List createViewModel() { - final List value = new ArrayList(5); - ServiceType serviceType = application.getServiceType(); - HistogramSchema schema = serviceType.getHistogramSchema(); - value.add(new ResponseTimeViewModel(schema.getFastSlot().getSlotName(), getColumnValue(SlotType.FAST))); - value.add(new ResponseTimeViewModel(schema.getNormalSlot().getSlotName(), getColumnValue(SlotType.NORMAL))); - value.add(new ResponseTimeViewModel(schema.getSlowSlot().getSlotName(), getColumnValue(SlotType.SLOW))); - value.add(new ResponseTimeViewModel(schema.getVerySlowSlot().getSlotName(), getColumnValue(SlotType.VERY_SLOW))); - value.add(new ResponseTimeViewModel(schema.getErrorSlot().getSlotName(), getColumnValue(SlotType.ERROR))); - return value; - - } - - public List getColumnValue(SlotType slotType) { - List result = new ArrayList(histogramList.size()); - for (TimeHistogram timeHistogram : histogramList) { - final long timeStamp = timeHistogram.getTimeStamp(); - - ResponseTimeViewModel.TimeCount TimeCount = new ResponseTimeViewModel.TimeCount(timeStamp, getCount(timeHistogram, slotType)); - result.add(TimeCount); - } - return result; - } - - - public long getCount(TimeHistogram timeHistogram, SlotType slotType) { - return timeHistogram.getCount(slotType); - } - - -} +package com.nhn.pinpoint.web.applicationmap.histogram; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.SlotType; +import com.nhn.pinpoint.web.view.ResponseTimeViewModel; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class ApplicationTimeHistogram { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + private final Range range; + + private List histogramList; + + public ApplicationTimeHistogram(Application application, Range range) { + this(application, range, Collections.emptyList()); + } + + public ApplicationTimeHistogram(Application application, Range range, List histogramList) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + if (histogramList == null) { + throw new NullPointerException("histogramList must not be null"); + } + this.application = application; + this.range = range; + this.histogramList = histogramList; + } + + public List createViewModel() { + final List value = new ArrayList(5); + ServiceType serviceType = application.getServiceType(); + HistogramSchema schema = serviceType.getHistogramSchema(); + value.add(new ResponseTimeViewModel(schema.getFastSlot().getSlotName(), getColumnValue(SlotType.FAST))); + value.add(new ResponseTimeViewModel(schema.getNormalSlot().getSlotName(), getColumnValue(SlotType.NORMAL))); + value.add(new ResponseTimeViewModel(schema.getSlowSlot().getSlotName(), getColumnValue(SlotType.SLOW))); + value.add(new ResponseTimeViewModel(schema.getVerySlowSlot().getSlotName(), getColumnValue(SlotType.VERY_SLOW))); + value.add(new ResponseTimeViewModel(schema.getErrorSlot().getSlotName(), getColumnValue(SlotType.ERROR))); + return value; + + } + + public List getColumnValue(SlotType slotType) { + List result = new ArrayList(histogramList.size()); + for (TimeHistogram timeHistogram : histogramList) { + final long timeStamp = timeHistogram.getTimeStamp(); + + ResponseTimeViewModel.TimeCount TimeCount = new ResponseTimeViewModel.TimeCount(timeStamp, getCount(timeHistogram, slotType)); + result.add(TimeCount); + } + return result; + } + + + public long getCount(TimeHistogram timeHistogram, SlotType slotType) { + return timeHistogram.getCount(slotType); + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogramBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogramBuilder.java index ae452ec629f7..8ef4b8e0385d 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogramBuilder.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApplicationTimeHistogramBuilder.java @@ -1,120 +1,120 @@ -package com.nhn.pinpoint.web.applicationmap.histogram; - -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkCallData; -import com.nhn.pinpoint.web.util.TimeWindow; -import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.Range; -import com.nhn.pinpoint.web.vo.ResponseTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class ApplicationTimeHistogramBuilder { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - private final Range range; - private final TimeWindow window; - - - - public ApplicationTimeHistogramBuilder(Application application, Range range) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - this.application = application; - this.range = range; - this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); - } - - public ApplicationTimeHistogram build(List responseHistogramList) { - if (responseHistogramList == null) { - throw new NullPointerException("responseHistogramList must not be null"); - } - - Map applicationLevelHistogram = new HashMap(); - - for (ResponseTime responseTime : responseHistogramList) { - final Long timeStamp = responseTime.getTimeStamp(); - TimeHistogram timeHistogram = applicationLevelHistogram.get(timeStamp); - if (timeHistogram == null) { - timeHistogram = new TimeHistogram(application.getServiceType(), timeStamp); - applicationLevelHistogram.put(timeStamp, timeHistogram); - } - // 개별 agent 레벨 데이터를 합친다. - Histogram applicationResponseHistogram = responseTime.getApplicationResponseHistogram(); - timeHistogram.add(applicationResponseHistogram); - } - - -// Collections.sort(histogramList, TimeHistogram.TIME_STAMP_ASC_COMPARATOR); - List histogramList = interpolation(applicationLevelHistogram.values()); - if (logger.isTraceEnabled()) { - for (TimeHistogram histogram : histogramList) { - logger.trace("applicationLevel histogram:{}", histogram); - } - } - ApplicationTimeHistogram applicationTimeHistogram = new ApplicationTimeHistogram(application, range, histogramList); - return applicationTimeHistogram; - } - - public ApplicationTimeHistogram build(Collection linkCallDataMapList) { - Map applicationLevelHistogram = new HashMap(); - for (LinkCallData linkCallData : linkCallDataMapList) { - for (TimeHistogram timeHistogram : linkCallData.getTimeHistogram()) { - Long timeStamp = timeHistogram.getTimeStamp(); - TimeHistogram histogram = applicationLevelHistogram.get(timeStamp); - if (histogram == null) { - histogram = new TimeHistogram(timeHistogram.getHistogramSchema(), timeStamp); - applicationLevelHistogram.put(timeStamp, histogram); - } - histogram.add(timeHistogram); - } - } - - List histogramList = interpolation(applicationLevelHistogram.values()); - if (logger.isTraceEnabled()) { - for (TimeHistogram histogram : histogramList) { - logger.trace("applicationLevel histogram:{}", histogram); - } - } - ApplicationTimeHistogram applicationTimeHistogram = new ApplicationTimeHistogram(application, range, histogramList); - return applicationTimeHistogram; - - } - - private List interpolation(Collection histogramList) { - // span에 대한 개별 조회시 window time만 가지고 보간하는것에 한계가 있을수 있음. - // - Map resultMap = new HashMap(); - for (Long time : window) { - resultMap.put(time, new TimeHistogram(application.getServiceType(), time)); - } - - - for (TimeHistogram timeHistogram : histogramList) { - long time = window.refineTimestamp(timeHistogram.getTimeStamp()); - - TimeHistogram windowHistogram = resultMap.get(time); - if (windowHistogram == null) { - windowHistogram = new TimeHistogram(application.getServiceType(), time); - resultMap.put(time, windowHistogram); - } - windowHistogram.add(timeHistogram); - } - - - List resultList = new ArrayList(resultMap.values()); - Collections.sort(resultList, TimeHistogram.TIME_STAMP_ASC_COMPARATOR); - return resultList; - } - -} +package com.nhn.pinpoint.web.applicationmap.histogram; + +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkCallData; +import com.nhn.pinpoint.web.util.TimeWindow; +import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.Range; +import com.nhn.pinpoint.web.vo.ResponseTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class ApplicationTimeHistogramBuilder { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + private final Range range; + private final TimeWindow window; + + + + public ApplicationTimeHistogramBuilder(Application application, Range range) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + this.application = application; + this.range = range; + this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); + } + + public ApplicationTimeHistogram build(List responseHistogramList) { + if (responseHistogramList == null) { + throw new NullPointerException("responseHistogramList must not be null"); + } + + Map applicationLevelHistogram = new HashMap(); + + for (ResponseTime responseTime : responseHistogramList) { + final Long timeStamp = responseTime.getTimeStamp(); + TimeHistogram timeHistogram = applicationLevelHistogram.get(timeStamp); + if (timeHistogram == null) { + timeHistogram = new TimeHistogram(application.getServiceType(), timeStamp); + applicationLevelHistogram.put(timeStamp, timeHistogram); + } + // 개별 agent 레벨 데이터를 합친다. + Histogram applicationResponseHistogram = responseTime.getApplicationResponseHistogram(); + timeHistogram.add(applicationResponseHistogram); + } + + +// Collections.sort(histogramList, TimeHistogram.TIME_STAMP_ASC_COMPARATOR); + List histogramList = interpolation(applicationLevelHistogram.values()); + if (logger.isTraceEnabled()) { + for (TimeHistogram histogram : histogramList) { + logger.trace("applicationLevel histogram:{}", histogram); + } + } + ApplicationTimeHistogram applicationTimeHistogram = new ApplicationTimeHistogram(application, range, histogramList); + return applicationTimeHistogram; + } + + public ApplicationTimeHistogram build(Collection linkCallDataMapList) { + Map applicationLevelHistogram = new HashMap(); + for (LinkCallData linkCallData : linkCallDataMapList) { + for (TimeHistogram timeHistogram : linkCallData.getTimeHistogram()) { + Long timeStamp = timeHistogram.getTimeStamp(); + TimeHistogram histogram = applicationLevelHistogram.get(timeStamp); + if (histogram == null) { + histogram = new TimeHistogram(timeHistogram.getHistogramSchema(), timeStamp); + applicationLevelHistogram.put(timeStamp, histogram); + } + histogram.add(timeHistogram); + } + } + + List histogramList = interpolation(applicationLevelHistogram.values()); + if (logger.isTraceEnabled()) { + for (TimeHistogram histogram : histogramList) { + logger.trace("applicationLevel histogram:{}", histogram); + } + } + ApplicationTimeHistogram applicationTimeHistogram = new ApplicationTimeHistogram(application, range, histogramList); + return applicationTimeHistogram; + + } + + private List interpolation(Collection histogramList) { + // span에 대한 개별 조회시 window time만 가지고 보간하는것에 한계가 있을수 있음. + // + Map resultMap = new HashMap(); + for (Long time : window) { + resultMap.put(time, new TimeHistogram(application.getServiceType(), time)); + } + + + for (TimeHistogram timeHistogram : histogramList) { + long time = window.refineTimestamp(timeHistogram.getTimeStamp()); + + TimeHistogram windowHistogram = resultMap.get(time); + if (windowHistogram == null) { + windowHistogram = new TimeHistogram(application.getServiceType(), time); + resultMap.put(time, windowHistogram); + } + windowHistogram.add(timeHistogram); + } + + + List resultList = new ArrayList(resultMap.values()); + Collections.sort(resultList, TimeHistogram.TIME_STAMP_ASC_COMPARATOR); + return resultList; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/NodeHistogram.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/NodeHistogram.java index c2a88257957e..46855b9699fe 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/NodeHistogram.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/NodeHistogram.java @@ -1,156 +1,156 @@ -package com.nhn.pinpoint.web.applicationmap.histogram; - -import com.nhn.pinpoint.web.view.AgentResponseTimeViewModelList; -import com.nhn.pinpoint.web.view.ResponseTimeViewModel; -import com.nhn.pinpoint.web.vo.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -import java.util.*; - -/** - * applicationHistogram - * agentHistogram - * applicationTimeHistogram - * agentTimeHistogram - * 의 집합 - * @author emeroad - */ -public class NodeHistogram { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application application; - - private final Range range; - - // ApplicationLevelHistogram - private Histogram applicationHistogram; - - // key는 agentId이다. - private Map agentHistogramMap; - - private ApplicationTimeHistogram applicationTimeHistogram; - - private AgentTimeHistogram agentTimeHistogram; - - - public NodeHistogram(Application application, Range range) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - this.application = application; - this.range = range; - - this.applicationHistogram = new Histogram(this.application.getServiceType()); - this.agentHistogramMap = new HashMap(); - - this.applicationTimeHistogram = new ApplicationTimeHistogram(this.application, this.range); - this.agentTimeHistogram = new AgentTimeHistogram(this.application, this.range); - } - - public NodeHistogram(Application application, Range range, List responseHistogramList) { - if (application == null) { - throw new NullPointerException("application must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - if (responseHistogramList == null) { - throw new NullPointerException("responseHistogramList must not be null"); - } - this.application = application; - this.range = range; - - this.agentTimeHistogram = createAgentLevelTimeSeriesResponseTime(responseHistogramList); - this.applicationTimeHistogram = createApplicationLevelTimeSeriesResponseTime(responseHistogramList); - - this.agentHistogramMap = createAgentLevelResponseTime(responseHistogramList); - this.applicationHistogram = createApplicationLevelResponseTime(responseHistogramList); - - } - - - public Histogram getApplicationHistogram() { - return applicationHistogram; - } - - public void setApplicationTimeHistogram(ApplicationTimeHistogram applicationTimeHistogram) { - this.applicationTimeHistogram = applicationTimeHistogram; - } - - public void setApplicationHistogram(Histogram applicationHistogram) { - if (applicationHistogram == null) { - throw new NullPointerException("applicationHistogram must not be null"); - } - this.applicationHistogram = applicationHistogram; - } - - public void setAgentHistogramMap(Map agentHistogramMap) { - this.agentHistogramMap = agentHistogramMap; - } - - public Map getAgentHistogramMap() { - return agentHistogramMap; - } - - public List getApplicationTimeHistogram() { - return applicationTimeHistogram.createViewModel(); - } - - - public AgentResponseTimeViewModelList getAgentTimeHistogram() { - return new AgentResponseTimeViewModelList(agentTimeHistogram.createViewModel()); - } - - public void setAgentTimeHistogram(AgentTimeHistogram agentTimeHistogram) { - this.agentTimeHistogram = agentTimeHistogram; - } - - private ApplicationTimeHistogram createApplicationLevelTimeSeriesResponseTime(List responseHistogramList) { - ApplicationTimeHistogramBuilder builder = new ApplicationTimeHistogramBuilder(application, range); - return builder.build(responseHistogramList); - } - - - private AgentTimeHistogram createAgentLevelTimeSeriesResponseTime(List responseHistogramList) { - AgentTimeHistogramBuilder builder = new AgentTimeHistogramBuilder(application, range); - AgentTimeHistogram histogram = builder.build(responseHistogramList); - return histogram; - } - - - private Map createAgentLevelResponseTime(List responseHistogramList) { - Map agentHistogramMap = new HashMap(); - for (ResponseTime responseTime : responseHistogramList) { - for (Map.Entry entry : responseTime.getAgentHistogram()) { - addAgentLevelHistogram(agentHistogramMap, entry.getKey(), entry.getValue()); - } - } - return agentHistogramMap; - } - - private void addAgentLevelHistogram(Map agentHistogramMap, String agentId, TimeHistogram histogram) { - Histogram agentHistogram = agentHistogramMap.get(agentId); - if (agentHistogram == null) { - agentHistogram = new Histogram(application.getServiceType()); - agentHistogramMap.put(agentId, agentHistogram); - } - agentHistogram.add(histogram); - } - - private Histogram createApplicationLevelResponseTime(List responseHistogram) { - final Histogram applicationHistogram = new Histogram(this.application.getServiceType()); - for (ResponseTime responseTime : responseHistogram) { - final Collection histogramList = responseTime.getAgentResponseHistogramList(); - for (Histogram histogram : histogramList) { - applicationHistogram.add(histogram); - } - } - return applicationHistogram; - } -} +package com.nhn.pinpoint.web.applicationmap.histogram; + +import com.nhn.pinpoint.web.view.AgentResponseTimeViewModelList; +import com.nhn.pinpoint.web.view.ResponseTimeViewModel; +import com.nhn.pinpoint.web.vo.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import java.util.*; + +/** + * applicationHistogram + * agentHistogram + * applicationTimeHistogram + * agentTimeHistogram + * 의 집합 + * @author emeroad + */ +public class NodeHistogram { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application application; + + private final Range range; + + // ApplicationLevelHistogram + private Histogram applicationHistogram; + + // key는 agentId이다. + private Map agentHistogramMap; + + private ApplicationTimeHistogram applicationTimeHistogram; + + private AgentTimeHistogram agentTimeHistogram; + + + public NodeHistogram(Application application, Range range) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + this.application = application; + this.range = range; + + this.applicationHistogram = new Histogram(this.application.getServiceType()); + this.agentHistogramMap = new HashMap(); + + this.applicationTimeHistogram = new ApplicationTimeHistogram(this.application, this.range); + this.agentTimeHistogram = new AgentTimeHistogram(this.application, this.range); + } + + public NodeHistogram(Application application, Range range, List responseHistogramList) { + if (application == null) { + throw new NullPointerException("application must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + if (responseHistogramList == null) { + throw new NullPointerException("responseHistogramList must not be null"); + } + this.application = application; + this.range = range; + + this.agentTimeHistogram = createAgentLevelTimeSeriesResponseTime(responseHistogramList); + this.applicationTimeHistogram = createApplicationLevelTimeSeriesResponseTime(responseHistogramList); + + this.agentHistogramMap = createAgentLevelResponseTime(responseHistogramList); + this.applicationHistogram = createApplicationLevelResponseTime(responseHistogramList); + + } + + + public Histogram getApplicationHistogram() { + return applicationHistogram; + } + + public void setApplicationTimeHistogram(ApplicationTimeHistogram applicationTimeHistogram) { + this.applicationTimeHistogram = applicationTimeHistogram; + } + + public void setApplicationHistogram(Histogram applicationHistogram) { + if (applicationHistogram == null) { + throw new NullPointerException("applicationHistogram must not be null"); + } + this.applicationHistogram = applicationHistogram; + } + + public void setAgentHistogramMap(Map agentHistogramMap) { + this.agentHistogramMap = agentHistogramMap; + } + + public Map getAgentHistogramMap() { + return agentHistogramMap; + } + + public List getApplicationTimeHistogram() { + return applicationTimeHistogram.createViewModel(); + } + + + public AgentResponseTimeViewModelList getAgentTimeHistogram() { + return new AgentResponseTimeViewModelList(agentTimeHistogram.createViewModel()); + } + + public void setAgentTimeHistogram(AgentTimeHistogram agentTimeHistogram) { + this.agentTimeHistogram = agentTimeHistogram; + } + + private ApplicationTimeHistogram createApplicationLevelTimeSeriesResponseTime(List responseHistogramList) { + ApplicationTimeHistogramBuilder builder = new ApplicationTimeHistogramBuilder(application, range); + return builder.build(responseHistogramList); + } + + + private AgentTimeHistogram createAgentLevelTimeSeriesResponseTime(List responseHistogramList) { + AgentTimeHistogramBuilder builder = new AgentTimeHistogramBuilder(application, range); + AgentTimeHistogram histogram = builder.build(responseHistogramList); + return histogram; + } + + + private Map createAgentLevelResponseTime(List responseHistogramList) { + Map agentHistogramMap = new HashMap(); + for (ResponseTime responseTime : responseHistogramList) { + for (Map.Entry entry : responseTime.getAgentHistogram()) { + addAgentLevelHistogram(agentHistogramMap, entry.getKey(), entry.getValue()); + } + } + return agentHistogramMap; + } + + private void addAgentLevelHistogram(Map agentHistogramMap, String agentId, TimeHistogram histogram) { + Histogram agentHistogram = agentHistogramMap.get(agentId); + if (agentHistogram == null) { + agentHistogram = new Histogram(application.getServiceType()); + agentHistogramMap.put(agentId, agentHistogram); + } + agentHistogram.add(histogram); + } + + private Histogram createApplicationLevelResponseTime(List responseHistogram) { + final Histogram applicationHistogram = new Histogram(this.application.getServiceType()); + for (ResponseTime responseTime : responseHistogram) { + final Collection histogramList = responseTime.getAgentResponseHistogramList(); + for (Histogram histogram : histogramList) { + applicationHistogram.add(histogram); + } + } + return applicationHistogram; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/TimeHistogram.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/TimeHistogram.java index 2a4999acaa65..8f50eb9a6593 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/TimeHistogram.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/TimeHistogram.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.web.applicationmap.histogram; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.ServiceType; - -import java.util.Comparator; - -/** - * @author emeroad - */ -public class TimeHistogram extends Histogram { - - public static final Comparator TIME_STAMP_ASC_COMPARATOR = new TimeStampAscComparator(); - - private final long timeStamp; - - public TimeHistogram(ServiceType serviceType, long timeStamp) { - super(serviceType); - this.timeStamp = timeStamp; - } - - public TimeHistogram(HistogramSchema schema, long timeStamp) { - super(schema); - this.timeStamp = timeStamp; - } - - public long getTimeStamp() { - return timeStamp; - } - - - private static class TimeStampAscComparator implements Comparator { - @Override - public int compare(TimeHistogram thisVal, TimeHistogram anotherVal) { - long thisLong = thisVal.getTimeStamp(); - long anotherLong = anotherVal.getTimeStamp(); - return (thisLong TIME_STAMP_ASC_COMPARATOR = new TimeStampAscComparator(); + + private final long timeStamp; + + public TimeHistogram(ServiceType serviceType, long timeStamp) { + super(serviceType); + this.timeStamp = timeStamp; + } + + public TimeHistogram(HistogramSchema schema, long timeStamp) { + super(schema); + this.timeStamp = timeStamp; + } + + public long getTimeStamp() { + return timeStamp; + } + + + private static class TimeStampAscComparator implements Comparator { + @Override + public int compare(TimeHistogram thisVal, TimeHistogram anotherVal) { + long thisLong = thisVal.getTimeStamp(); + long anotherLong = anotherVal.getTimeStamp(); + return (thisLong serverMatcherList = new ArrayList(); - private ServerMatcher defaultMatcher = new DefaultNSightMatcher(); - - public MatcherGroup() { - setAddDefaultMatcher(); - } - - public void setDefaultMatcher(ServerMatcher defaultMatcher) { - if (defaultMatcher == null) { - throw new NullPointerException("defaultMatcher must not be null"); - } - this.defaultMatcher = defaultMatcher; - } - - public void addServerMatcher(ServerMatcher serverMatcher) { - if (serverMatcher == null) { - throw new NullPointerException("serverMatcher must not be null"); - } - serverMatcherList.add(serverMatcher); - } - - public void setAddDefaultMatcher() { - // 시간되면 spring에서 찾아 오게 하던지?? - // 그냥 빨랑 할려고 코드로 함. - serverMatcherList.add(new NSightMatcher()); - serverMatcherList.add(new JapanNSightMatcher()); - } - - public ServerMatcher match(String serverName) { - if (serverName == null) { - throw new NullPointerException("serverName must not be null"); - } - - for (ServerMatcher serverMatcher : serverMatcherList) { - if(serverMatcher.isMatched(serverName)) { - return serverMatcher; - } - } - return defaultMatcher; - } - -} +package com.nhn.pinpoint.web.applicationmap.link; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +public class MatcherGroup { + + private final List serverMatcherList = new ArrayList(); + private ServerMatcher defaultMatcher = new DefaultNSightMatcher(); + + public MatcherGroup() { + setAddDefaultMatcher(); + } + + public void setDefaultMatcher(ServerMatcher defaultMatcher) { + if (defaultMatcher == null) { + throw new NullPointerException("defaultMatcher must not be null"); + } + this.defaultMatcher = defaultMatcher; + } + + public void addServerMatcher(ServerMatcher serverMatcher) { + if (serverMatcher == null) { + throw new NullPointerException("serverMatcher must not be null"); + } + serverMatcherList.add(serverMatcher); + } + + public void setAddDefaultMatcher() { + // 시간되면 spring에서 찾아 오게 하던지?? + // 그냥 빨랑 할려고 코드로 함. + serverMatcherList.add(new NSightMatcher()); + serverMatcherList.add(new JapanNSightMatcher()); + } + + public ServerMatcher match(String serverName) { + if (serverName == null) { + throw new NullPointerException("serverName must not be null"); + } + + for (ServerMatcher serverMatcher : serverMatcherList) { + if(serverMatcher.isMatched(serverName)) { + return serverMatcher; + } + } + return defaultMatcher; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/NSightMatcher.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/NSightMatcher.java index f03affe3d4b6..d6da0a269b90 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/NSightMatcher.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/NSightMatcher.java @@ -1,35 +1,35 @@ -package com.nhn.pinpoint.web.applicationmap.link; - -/** - * @author emeroad - */ -public class NSightMatcher implements ServerMatcher { - - public static final String POST_FIX = ".nhnsystem.com"; - - public static final String URL = "http://nsight.nhncorp.com/dashboard_server/"; - - @Override - public boolean isMatched(String serverName) { - if (serverName == null) { - return false; - } - return serverName.endsWith(POST_FIX); - } - - @Override - public String getLinkName() { - return "NSight"; - } - - @Override - public String getLink(String serverName) { - - final int index = serverName.lastIndexOf(POST_FIX); - if (index == -1) { - throw new IllegalArgumentException("invalid serverName:" + serverName); - } - String hostName = serverName.substring(0, index); - return URL + hostName; - } -} +package com.nhn.pinpoint.web.applicationmap.link; + +/** + * @author emeroad + */ +public class NSightMatcher implements ServerMatcher { + + public static final String POST_FIX = ".nhnsystem.com"; + + public static final String URL = "http://nsight.nhncorp.com/dashboard_server/"; + + @Override + public boolean isMatched(String serverName) { + if (serverName == null) { + return false; + } + return serverName.endsWith(POST_FIX); + } + + @Override + public String getLinkName() { + return "NSight"; + } + + @Override + public String getLink(String serverName) { + + final int index = serverName.lastIndexOf(POST_FIX); + if (index == -1) { + throw new IllegalArgumentException("invalid serverName:" + serverName); + } + String hostName = serverName.substring(0, index); + return URL + hostName; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/ServerMatcher.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/ServerMatcher.java index df3d5b813ac1..087ad1958e72 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/ServerMatcher.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/link/ServerMatcher.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.web.applicationmap.link; - -/** - * @author emeroad - */ -public interface ServerMatcher { - boolean isMatched(String serverName); - - String getLinkName(); - - String getLink(String serverName); -} +package com.nhn.pinpoint.web.applicationmap.link; + +/** + * @author emeroad + */ +public interface ServerMatcher { + boolean isMatched(String serverName); + + String getLinkName(); + + String getLink(String serverName); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/AgentHistogramList.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/AgentHistogramList.java index 4e529c46ec8a..19bd2a678203 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/AgentHistogramList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/AgentHistogramList.java @@ -1,131 +1,131 @@ -package com.nhn.pinpoint.web.applicationmap.rawdata; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.ResponseTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class AgentHistogramList { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - // agent별 Time 시리즈 데이터를 가지고 있음. - private final Map agentHistogramMap = new HashMap(); - - public AgentHistogramList() { - } - - public AgentHistogramList(Application application, List responseHistogramList) { - if (responseHistogramList == null) { - throw new NullPointerException("responseHistogramList must not be null"); - } - - for (ResponseTime responseTime : responseHistogramList) { - for (Map.Entry agentEntry : responseTime.getAgentHistogram()) { - TimeHistogram timeHistogram = agentEntry.getValue(); - this.addAgentHistogram(agentEntry.getKey(), application.getServiceType(), timeHistogram); - } - } - } - - - public void addTimeHistogram(Application agentId, Collection histogramList) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - if (histogramList == null) { - throw new NullPointerException("histogramList must not be null"); - } - AgentHistogram agentHistogram = getAgentHistogram(agentId); - agentHistogram.addTimeHistogram(histogramList); - } - - public void addTimeHistogram(Application agentId, TimeHistogram timeHistogram) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - if (timeHistogram == null) { - throw new NullPointerException("timeHistogram must not be null"); - } - AgentHistogram agentHistogram = getAgentHistogram(agentId); - agentHistogram.addTimeHistogram(timeHistogram); - } - - public void addAgentHistogram(String agentName, ServiceType serviceType, Collection histogramList) { - Application agentId = new Application(agentName, serviceType); - addTimeHistogram(agentId, histogramList); - } - - public void addAgentHistogram(String agentName, ServiceType serviceType, TimeHistogram timeHistogram) { - Application agentId = new Application(agentName, serviceType); - addTimeHistogram(agentId, timeHistogram); - } - - - - private AgentHistogram getAgentHistogram(Application agentId) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - - AgentHistogram agentHistogram = agentHistogramMap.get(agentId); - if (agentHistogram == null) { - agentHistogram = new AgentHistogram(agentId); - agentHistogramMap.put(agentId, agentHistogram); - } - return agentHistogram; - } - - public Histogram mergeHistogram(ServiceType serviceType) { - final Histogram histogram = new Histogram(serviceType); - for (AgentHistogram agentHistogram : getAgentHistogramList()) { - histogram.add(agentHistogram.getHistogram()); - } - return histogram; - } - - - - public void addAgentHistogram(AgentHistogram agentHistogram) { - if (agentHistogram == null) { - throw new NullPointerException("agentHistogram must not be null"); - } - final String hostName = agentHistogram.getId(); - ServiceType serviceType = agentHistogram.getServiceType(); - - Application agentId = new Application(hostName, serviceType); - AgentHistogram findAgentHistogram = getAgentHistogram(agentId); - findAgentHistogram.addTimeHistogram(agentHistogram.getTimeHistogram()); - } - - public void addAgentHistogram(AgentHistogramList addAgentHistogramList) { - if (addAgentHistogramList == null) { - throw new NullPointerException("agentHistogram must not be null"); - } - for (AgentHistogram agentHistogram : addAgentHistogramList.agentHistogramMap.values()) { - addAgentHistogram(agentHistogram); - } - } - - public Collection getAgentHistogramList() { - return agentHistogramMap.values(); - } - - @Override - public String toString() { - return "AgentHistogramList{" - + agentHistogramMap + - '}'; - } - - public int size() { - return this.agentHistogramMap.size(); - } -} +package com.nhn.pinpoint.web.applicationmap.rawdata; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.ResponseTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class AgentHistogramList { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + // agent별 Time 시리즈 데이터를 가지고 있음. + private final Map agentHistogramMap = new HashMap(); + + public AgentHistogramList() { + } + + public AgentHistogramList(Application application, List responseHistogramList) { + if (responseHistogramList == null) { + throw new NullPointerException("responseHistogramList must not be null"); + } + + for (ResponseTime responseTime : responseHistogramList) { + for (Map.Entry agentEntry : responseTime.getAgentHistogram()) { + TimeHistogram timeHistogram = agentEntry.getValue(); + this.addAgentHistogram(agentEntry.getKey(), application.getServiceType(), timeHistogram); + } + } + } + + + public void addTimeHistogram(Application agentId, Collection histogramList) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + if (histogramList == null) { + throw new NullPointerException("histogramList must not be null"); + } + AgentHistogram agentHistogram = getAgentHistogram(agentId); + agentHistogram.addTimeHistogram(histogramList); + } + + public void addTimeHistogram(Application agentId, TimeHistogram timeHistogram) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + if (timeHistogram == null) { + throw new NullPointerException("timeHistogram must not be null"); + } + AgentHistogram agentHistogram = getAgentHistogram(agentId); + agentHistogram.addTimeHistogram(timeHistogram); + } + + public void addAgentHistogram(String agentName, ServiceType serviceType, Collection histogramList) { + Application agentId = new Application(agentName, serviceType); + addTimeHistogram(agentId, histogramList); + } + + public void addAgentHistogram(String agentName, ServiceType serviceType, TimeHistogram timeHistogram) { + Application agentId = new Application(agentName, serviceType); + addTimeHistogram(agentId, timeHistogram); + } + + + + private AgentHistogram getAgentHistogram(Application agentId) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + + AgentHistogram agentHistogram = agentHistogramMap.get(agentId); + if (agentHistogram == null) { + agentHistogram = new AgentHistogram(agentId); + agentHistogramMap.put(agentId, agentHistogram); + } + return agentHistogram; + } + + public Histogram mergeHistogram(ServiceType serviceType) { + final Histogram histogram = new Histogram(serviceType); + for (AgentHistogram agentHistogram : getAgentHistogramList()) { + histogram.add(agentHistogram.getHistogram()); + } + return histogram; + } + + + + public void addAgentHistogram(AgentHistogram agentHistogram) { + if (agentHistogram == null) { + throw new NullPointerException("agentHistogram must not be null"); + } + final String hostName = agentHistogram.getId(); + ServiceType serviceType = agentHistogram.getServiceType(); + + Application agentId = new Application(hostName, serviceType); + AgentHistogram findAgentHistogram = getAgentHistogram(agentId); + findAgentHistogram.addTimeHistogram(agentHistogram.getTimeHistogram()); + } + + public void addAgentHistogram(AgentHistogramList addAgentHistogramList) { + if (addAgentHistogramList == null) { + throw new NullPointerException("agentHistogram must not be null"); + } + for (AgentHistogram agentHistogram : addAgentHistogramList.agentHistogramMap.values()) { + addAgentHistogram(agentHistogram); + } + } + + public Collection getAgentHistogramList() { + return agentHistogramMap.values(); + } + + @Override + public String toString() { + return "AgentHistogramList{" + + agentHistogramMap + + '}'; + } + + public int size() { + return this.agentHistogramMap.size(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkCallDataMap.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkCallDataMap.java index e302fd152c7b..d5794d859f5d 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkCallDataMap.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkCallDataMap.java @@ -1,107 +1,107 @@ -package com.nhn.pinpoint.web.applicationmap.rawdata; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.vo.LinkKey; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * @author emeroad - */ -public class LinkCallDataMap { - -// private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Map linkDataMap = new HashMap(); - - public LinkCallDataMap() { - } - - public LinkCallDataMap(LinkCallDataMap copyLinkCallDataMap) { - if (copyLinkCallDataMap == null) { - throw new NullPointerException("copyLinkCallDataMap must not be null"); - } - addLinkDataMap(copyLinkCallDataMap); - } - - public void addCallData(String sourceAgentId, short sourceServiceType, String targetId, short targetServiceType, long timestamp, short slot, long count) { - addCallData(sourceAgentId, ServiceType.findServiceType(sourceServiceType), targetId, ServiceType.findServiceType(targetServiceType), timestamp, slot, count); - } - - public void addCallData(String sourceAgentId, short sourceServiceType, String targetId, short targetServiceType, Collection timeHistogramList) { - LinkKey linkKey = createLinkKey(sourceAgentId, ServiceType.findServiceType(sourceServiceType), targetId, ServiceType.findServiceType(targetServiceType)); - LinkCallData linkCallData = getLinkCallData(linkKey); - linkCallData.addCallData(timeHistogramList); - } - - public void addCallData(String sourceAgentId, ServiceType sourceServiceType, String targetId, ServiceType targetServiceType, long timestamp, short slot, long count) { - LinkKey linkKey = createLinkKey(sourceAgentId, sourceServiceType, targetId, targetServiceType); - LinkCallData linkCallData = getLinkCallData(linkKey); - linkCallData.addCallData(timestamp, slot, count); - } - - private LinkKey createLinkKey(String sourceAgentId, ServiceType sourceServiceType, String targetId, ServiceType targetServiceType) { - return new LinkKey(sourceAgentId, sourceServiceType, targetId, targetServiceType); - } - - public void addLinkDataMap(LinkCallDataMap target) { - if (target == null) { - throw new NullPointerException("target must not be null"); - } - for (Map.Entry copyEntry : target.linkDataMap.entrySet()) { - final LinkKey key = copyEntry.getKey(); - final LinkCallData copyLinkCallData = copyEntry.getValue(); - LinkCallData linkCallData = getLinkCallData(key); - linkCallData.addRawCallData(copyLinkCallData); - } - - } - - private LinkCallData getLinkCallData(LinkKey key) { - final Map rawCallDataMap = this.linkDataMap; - LinkCallData linkCallData = rawCallDataMap.get(key); - if (linkCallData == null) { - linkCallData = new LinkCallData(key); - rawCallDataMap.put(key, linkCallData); - } - return linkCallData; - } - - public Collection getLinkDataList() { - return linkDataMap.values(); - } - - public AgentHistogramList getTargetList() { - AgentHistogramList targetList = new AgentHistogramList(); - for (Map.Entry linkKeyRawCallDataEntry : linkDataMap.entrySet()) { - final LinkKey key = linkKeyRawCallDataEntry.getKey(); - final LinkCallData linkCallData = linkKeyRawCallDataEntry.getValue(); - targetList.addAgentHistogram(key.getToApplication(), key.getToServiceType(), linkCallData.getTimeHistogram()); - } - return targetList; - } - - - public AgentHistogramList getSourceList() { - AgentHistogramList sourceList = new AgentHistogramList(); - for (Map.Entry linkKeyRawCallDataEntry : linkDataMap.entrySet()) { - final LinkKey key = linkKeyRawCallDataEntry.getKey(); - final LinkCallData linkCallData = linkKeyRawCallDataEntry.getValue(); - // to의 ServiceType이 들어가야 한다. - // 여기서 source란 source의 입장에서 target 호출시의 데이터를 의미하는 것이기 때문에. ServiceType자체는 To의 ServiceType이 들어가야한다. - sourceList.addAgentHistogram(key.getFromApplication(), key.getToServiceType(), linkCallData.getTimeHistogram()); - } - return sourceList; - } - - @Override - public String toString() { - return "LinkCallDataMap{" - + linkDataMap + - '}'; - } -} +package com.nhn.pinpoint.web.applicationmap.rawdata; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.vo.LinkKey; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * @author emeroad + */ +public class LinkCallDataMap { + +// private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Map linkDataMap = new HashMap(); + + public LinkCallDataMap() { + } + + public LinkCallDataMap(LinkCallDataMap copyLinkCallDataMap) { + if (copyLinkCallDataMap == null) { + throw new NullPointerException("copyLinkCallDataMap must not be null"); + } + addLinkDataMap(copyLinkCallDataMap); + } + + public void addCallData(String sourceAgentId, short sourceServiceType, String targetId, short targetServiceType, long timestamp, short slot, long count) { + addCallData(sourceAgentId, ServiceType.findServiceType(sourceServiceType), targetId, ServiceType.findServiceType(targetServiceType), timestamp, slot, count); + } + + public void addCallData(String sourceAgentId, short sourceServiceType, String targetId, short targetServiceType, Collection timeHistogramList) { + LinkKey linkKey = createLinkKey(sourceAgentId, ServiceType.findServiceType(sourceServiceType), targetId, ServiceType.findServiceType(targetServiceType)); + LinkCallData linkCallData = getLinkCallData(linkKey); + linkCallData.addCallData(timeHistogramList); + } + + public void addCallData(String sourceAgentId, ServiceType sourceServiceType, String targetId, ServiceType targetServiceType, long timestamp, short slot, long count) { + LinkKey linkKey = createLinkKey(sourceAgentId, sourceServiceType, targetId, targetServiceType); + LinkCallData linkCallData = getLinkCallData(linkKey); + linkCallData.addCallData(timestamp, slot, count); + } + + private LinkKey createLinkKey(String sourceAgentId, ServiceType sourceServiceType, String targetId, ServiceType targetServiceType) { + return new LinkKey(sourceAgentId, sourceServiceType, targetId, targetServiceType); + } + + public void addLinkDataMap(LinkCallDataMap target) { + if (target == null) { + throw new NullPointerException("target must not be null"); + } + for (Map.Entry copyEntry : target.linkDataMap.entrySet()) { + final LinkKey key = copyEntry.getKey(); + final LinkCallData copyLinkCallData = copyEntry.getValue(); + LinkCallData linkCallData = getLinkCallData(key); + linkCallData.addRawCallData(copyLinkCallData); + } + + } + + private LinkCallData getLinkCallData(LinkKey key) { + final Map rawCallDataMap = this.linkDataMap; + LinkCallData linkCallData = rawCallDataMap.get(key); + if (linkCallData == null) { + linkCallData = new LinkCallData(key); + rawCallDataMap.put(key, linkCallData); + } + return linkCallData; + } + + public Collection getLinkDataList() { + return linkDataMap.values(); + } + + public AgentHistogramList getTargetList() { + AgentHistogramList targetList = new AgentHistogramList(); + for (Map.Entry linkKeyRawCallDataEntry : linkDataMap.entrySet()) { + final LinkKey key = linkKeyRawCallDataEntry.getKey(); + final LinkCallData linkCallData = linkKeyRawCallDataEntry.getValue(); + targetList.addAgentHistogram(key.getToApplication(), key.getToServiceType(), linkCallData.getTimeHistogram()); + } + return targetList; + } + + + public AgentHistogramList getSourceList() { + AgentHistogramList sourceList = new AgentHistogramList(); + for (Map.Entry linkKeyRawCallDataEntry : linkDataMap.entrySet()) { + final LinkKey key = linkKeyRawCallDataEntry.getKey(); + final LinkCallData linkCallData = linkKeyRawCallDataEntry.getValue(); + // to의 ServiceType이 들어가야 한다. + // 여기서 source란 source의 입장에서 target 호출시의 데이터를 의미하는 것이기 때문에. ServiceType자체는 To의 ServiceType이 들어가야한다. + sourceList.addAgentHistogram(key.getFromApplication(), key.getToServiceType(), linkCallData.getTimeHistogram()); + } + return sourceList; + } + + @Override + public String toString() { + return "LinkCallDataMap{" + + linkDataMap + + '}'; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkDataDuplexMap.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkDataDuplexMap.java index 30adfe764606..214389cbd276 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkDataDuplexMap.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/rawdata/LinkDataDuplexMap.java @@ -1,96 +1,96 @@ -package com.nhn.pinpoint.web.applicationmap.rawdata; - -import com.nhn.pinpoint.web.vo.LinkKey; - -import java.util.Collection; - -/** - * @author emeroad - */ -public class LinkDataDuplexMap { - - private final LinkDataMap sourceLinkDataMap; - - private final LinkDataMap targetLinkDataMap; - - public LinkDataDuplexMap() { - this.sourceLinkDataMap = new LinkDataMap(); - this.targetLinkDataMap = new LinkDataMap(); - } - - - public LinkDataMap getSourceLinkDataMap() { - return sourceLinkDataMap; - } - - public Collection getSourceLinkDataList() { - return sourceLinkDataMap.getLinkDataList(); - } - - public LinkDataMap getTargetLinkDataMap() { - return targetLinkDataMap; - } - - public Collection getTargetLinkDataList() { - return targetLinkDataMap.getLinkDataList(); - } - - - public void addLinkDataDuplexMap(LinkDataDuplexMap linkDataDuplexMap) { - if (linkDataDuplexMap == null) { - throw new NullPointerException("linkDataDuplexMap must not be null"); - } - for (LinkData copyLinkData : linkDataDuplexMap.sourceLinkDataMap.getLinkDataList()) { - addSourceLinkData(copyLinkData); - } - for (LinkData copyLinkData : linkDataDuplexMap.targetLinkDataMap.getLinkDataList()) { - addTargetLinkData(copyLinkData); - } - } - - public void addSourceLinkData(LinkData copyLinkData) { - if (copyLinkData == null) { - throw new NullPointerException("copyLinkData must not be null"); - } - sourceLinkDataMap.addLinkData(copyLinkData); - } - - - public void addTargetLinkData(LinkData copyLinkData) { - if (copyLinkData == null) { - throw new NullPointerException("copyLinkData must not be null"); - } - targetLinkDataMap.addLinkData(copyLinkData); - } - - - public int size() { - return sourceLinkDataMap.size() + targetLinkDataMap.size(); - } - - - public LinkData getSourceLinkData(LinkKey findLinkKey) { - if (findLinkKey == null) { - throw new NullPointerException("findLinkKey must not be null"); - } - - return sourceLinkDataMap.getLinkData(findLinkKey); - } - - public LinkData getTargetLinkData(LinkKey findLinkKey) { - if (findLinkKey == null) { - throw new NullPointerException("findLinkKey must not be null"); - } - - return targetLinkDataMap.getLinkData(findLinkKey); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("LinkDataDuplexMap{"); - sb.append("sourceLinkDataMap=").append(sourceLinkDataMap); - sb.append(", targetLinkDataMap=").append(targetLinkDataMap); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.web.applicationmap.rawdata; + +import com.nhn.pinpoint.web.vo.LinkKey; + +import java.util.Collection; + +/** + * @author emeroad + */ +public class LinkDataDuplexMap { + + private final LinkDataMap sourceLinkDataMap; + + private final LinkDataMap targetLinkDataMap; + + public LinkDataDuplexMap() { + this.sourceLinkDataMap = new LinkDataMap(); + this.targetLinkDataMap = new LinkDataMap(); + } + + + public LinkDataMap getSourceLinkDataMap() { + return sourceLinkDataMap; + } + + public Collection getSourceLinkDataList() { + return sourceLinkDataMap.getLinkDataList(); + } + + public LinkDataMap getTargetLinkDataMap() { + return targetLinkDataMap; + } + + public Collection getTargetLinkDataList() { + return targetLinkDataMap.getLinkDataList(); + } + + + public void addLinkDataDuplexMap(LinkDataDuplexMap linkDataDuplexMap) { + if (linkDataDuplexMap == null) { + throw new NullPointerException("linkDataDuplexMap must not be null"); + } + for (LinkData copyLinkData : linkDataDuplexMap.sourceLinkDataMap.getLinkDataList()) { + addSourceLinkData(copyLinkData); + } + for (LinkData copyLinkData : linkDataDuplexMap.targetLinkDataMap.getLinkDataList()) { + addTargetLinkData(copyLinkData); + } + } + + public void addSourceLinkData(LinkData copyLinkData) { + if (copyLinkData == null) { + throw new NullPointerException("copyLinkData must not be null"); + } + sourceLinkDataMap.addLinkData(copyLinkData); + } + + + public void addTargetLinkData(LinkData copyLinkData) { + if (copyLinkData == null) { + throw new NullPointerException("copyLinkData must not be null"); + } + targetLinkDataMap.addLinkData(copyLinkData); + } + + + public int size() { + return sourceLinkDataMap.size() + targetLinkDataMap.size(); + } + + + public LinkData getSourceLinkData(LinkKey findLinkKey) { + if (findLinkKey == null) { + throw new NullPointerException("findLinkKey must not be null"); + } + + return sourceLinkDataMap.getLinkData(findLinkKey); + } + + public LinkData getTargetLinkData(LinkKey findLinkKey) { + if (findLinkKey == null) { + throw new NullPointerException("findLinkKey must not be null"); + } + + return targetLinkDataMap.getLinkData(findLinkKey); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("LinkDataDuplexMap{"); + sb.append("sourceLinkDataMap=").append(sourceLinkDataMap); + sb.append(", targetLinkDataMap=").append(targetLinkDataMap); + sb.append('}'); + return sb.toString(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java index 59e3bb8d6305..af4492dadf19 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java @@ -1,82 +1,82 @@ -package com.nhn.pinpoint.web.calltree.span; - -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; - -/** - * @author emeroad - */ -public class SpanAlign { - private int depth; - private SpanBo spanBo; - private SpanEventBo spanEventBo; - private boolean span = true; - private boolean hasChild = false; - - public SpanAlign(int depth, SpanBo spanBo) { - if (spanBo == null) { - throw new NullPointerException("spanBo must not be null"); - } - this.depth = depth; - this.spanBo = spanBo; - this.span = true; - } - - public SpanAlign(int depth, SpanBo spanBo, SpanEventBo spanEventBo) { - if (spanBo == null) { - throw new NullPointerException("spanBo must not be null"); - } - if (spanEventBo == null) { - throw new NullPointerException("spanEventBo must not be null"); - } - this.depth = depth; - this.spanBo = spanBo; - this.spanEventBo = spanEventBo; - this.span = false; - } - - public void setSpan(boolean span) { - this.span = span; - } - - public boolean isSpan() { - return span; - } - - public int getDepth() { - return depth; - } - - public SpanBo getSpanBo() { - return spanBo; - } - - public SpanEventBo getSpanEventBo() { - return spanEventBo; - } - - public boolean isHasChild() { - return hasChild; - } - - public void setHasChild(boolean hasChild) { - this.hasChild = hasChild; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("SpanAlign{"); - sb.append("depth=").append(depth); - if (span) { - sb.append(", spanBo=").append(spanBo); - sb.append(", spanEventBo=").append(spanEventBo); - } else { - sb.append(", spanEventBo=").append(spanEventBo); - sb.append(", spanBo=").append(spanBo); - } - sb.append(", span=").append(span); - sb.append(", hasChild=").append(hasChild); - sb.append('}'); - return sb.toString(); - } -} +package com.nhn.pinpoint.web.calltree.span; + +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; + +/** + * @author emeroad + */ +public class SpanAlign { + private int depth; + private SpanBo spanBo; + private SpanEventBo spanEventBo; + private boolean span = true; + private boolean hasChild = false; + + public SpanAlign(int depth, SpanBo spanBo) { + if (spanBo == null) { + throw new NullPointerException("spanBo must not be null"); + } + this.depth = depth; + this.spanBo = spanBo; + this.span = true; + } + + public SpanAlign(int depth, SpanBo spanBo, SpanEventBo spanEventBo) { + if (spanBo == null) { + throw new NullPointerException("spanBo must not be null"); + } + if (spanEventBo == null) { + throw new NullPointerException("spanEventBo must not be null"); + } + this.depth = depth; + this.spanBo = spanBo; + this.spanEventBo = spanEventBo; + this.span = false; + } + + public void setSpan(boolean span) { + this.span = span; + } + + public boolean isSpan() { + return span; + } + + public int getDepth() { + return depth; + } + + public SpanBo getSpanBo() { + return spanBo; + } + + public SpanEventBo getSpanEventBo() { + return spanEventBo; + } + + public boolean isHasChild() { + return hasChild; + } + + public void setHasChild(boolean hasChild) { + this.hasChild = hasChild; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("SpanAlign{"); + sb.append("depth=").append(depth); + if (span) { + sb.append(", spanBo=").append(spanBo); + sb.append(", spanEventBo=").append(spanEventBo); + } else { + sb.append(", spanEventBo=").append(spanEventBo); + sb.append(", spanBo=").append(spanBo); + } + sb.append(", span=").append(span); + sb.append(", hasChild=").append(hasChild); + sb.append('}'); + return sb.toString(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanIdMatcher.java b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanIdMatcher.java index 5fddde71cc62..61dde152bc20 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanIdMatcher.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanIdMatcher.java @@ -1,127 +1,127 @@ -package com.nhn.pinpoint.web.calltree.span; - -import com.nhn.pinpoint.common.bo.SpanBo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * @author emeroad - */ -public class SpanIdMatcher { - private List nextSpanBoList; - - private static final long MAX_EXCLUDE_WEIGHT = 1000 * 5; - - public SpanIdMatcher(List nextSpanBoList) { - if (nextSpanBoList == null) { - throw new NullPointerException("nextSpanBoList must not be null"); - } - this.nextSpanBoList = nextSpanBoList; - } - - public SpanBo approximateMatch(long spanEventBoStartTime) { - // 매칭 알고리즘이 있어야 함. - List weightSpanList = computeWeight(spanEventBoStartTime); - if (weightSpanList.size() == 0) { - return null; - } - Collections.sort(weightSpanList, new Comparator() { - @Override - public int compare(WeightSpanBo wSpan1, WeightSpanBo wSpan2) { - final long spanWeight1 = wSpan1.getWeight(); - final long spanWeight2 = wSpan2.getWeight(); - if (spanWeight1 < spanWeight2) { - return -1; - } else { - if (spanWeight1 == spanWeight2) { - return 0; - } else { - return 1; - } - } - } - }); - - SpanBo minWeight = getMinWeight(weightSpanList); - if (minWeight != null) { - nextSpanBoList.remove(minWeight); - } - return minWeight; - } - - private SpanBo getMinWeight(List weightSpanList) { - long min = Long.MAX_VALUE; - final List minValue = new ArrayList(); - for (WeightSpanBo weightSpanBo : weightSpanList) { - long weight = weightSpanBo.getWeight(); - if (weight <= min) { - minValue.add(weightSpanBo.getSpanBo()); - min = weight; - } - } - - if (minValue.size() == 1) { - return minValue.get(0); - } - // 2개 이상일 경우일단 그냥 앞선 데이터를 던짐. - // 뭔가 로그 필요. - return minValue.get(0); - } - - private List computeWeight(long spanEventBoStartTime) { - List weightSpanList = new ArrayList(); - for (SpanBo next : nextSpanBoList) { - long startTime = next.getStartTime(); - long distance = startTime - spanEventBoStartTime; - long weightDistance = getWeightDistance(distance); - if (weightDistance > MAX_EXCLUDE_WEIGHT) { - // MAX WEIGHT보다 가중치가 높을 경우. 분실된 케이스 일수 있으므로 그냥 버린다. - continue; - } - weightSpanList.add(new WeightSpanBo(weightDistance, next)); - } - return weightSpanList; - } - - private long getWeightDistance(long distance) { - if (distance >= 0) { - // 양수일 경우 - return distance; - } else { - // 음수일 경우 패널티를 둔다. 네트워크 타임 동기화 시간이 길지 않을 경우 음수가 매치될 확율은 매우 적어야 한다. - // 차라리 jvm gc등으로 인해 양수 값이 많이 차이 날수 있지. 음수값이 매치될 가능성은 매우낮다고 봐야 한다. - // 네트워크 싱크 시간?? 오차 등을 추가로 더하면 될거 같은데. 모르니깐 대충 더하자. 패널티는 1초 - distance = Math.abs(distance); - return (distance * 2) + 1000; - } - } - - - public List other() { - if (nextSpanBoList.size() == 0) { - return null; - } - return nextSpanBoList; - } - - private static class WeightSpanBo { - private long weight; - private SpanBo spanBo; - - private WeightSpanBo(long weight, SpanBo spanBo) { - this.weight = weight; - this.spanBo = spanBo; - } - - private long getWeight() { - return weight; - } - - private SpanBo getSpanBo() { - return spanBo; - } - } -} +package com.nhn.pinpoint.web.calltree.span; + +import com.nhn.pinpoint.common.bo.SpanBo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * @author emeroad + */ +public class SpanIdMatcher { + private List nextSpanBoList; + + private static final long MAX_EXCLUDE_WEIGHT = 1000 * 5; + + public SpanIdMatcher(List nextSpanBoList) { + if (nextSpanBoList == null) { + throw new NullPointerException("nextSpanBoList must not be null"); + } + this.nextSpanBoList = nextSpanBoList; + } + + public SpanBo approximateMatch(long spanEventBoStartTime) { + // 매칭 알고리즘이 있어야 함. + List weightSpanList = computeWeight(spanEventBoStartTime); + if (weightSpanList.size() == 0) { + return null; + } + Collections.sort(weightSpanList, new Comparator() { + @Override + public int compare(WeightSpanBo wSpan1, WeightSpanBo wSpan2) { + final long spanWeight1 = wSpan1.getWeight(); + final long spanWeight2 = wSpan2.getWeight(); + if (spanWeight1 < spanWeight2) { + return -1; + } else { + if (spanWeight1 == spanWeight2) { + return 0; + } else { + return 1; + } + } + } + }); + + SpanBo minWeight = getMinWeight(weightSpanList); + if (minWeight != null) { + nextSpanBoList.remove(minWeight); + } + return minWeight; + } + + private SpanBo getMinWeight(List weightSpanList) { + long min = Long.MAX_VALUE; + final List minValue = new ArrayList(); + for (WeightSpanBo weightSpanBo : weightSpanList) { + long weight = weightSpanBo.getWeight(); + if (weight <= min) { + minValue.add(weightSpanBo.getSpanBo()); + min = weight; + } + } + + if (minValue.size() == 1) { + return minValue.get(0); + } + // 2개 이상일 경우일단 그냥 앞선 데이터를 던짐. + // 뭔가 로그 필요. + return minValue.get(0); + } + + private List computeWeight(long spanEventBoStartTime) { + List weightSpanList = new ArrayList(); + for (SpanBo next : nextSpanBoList) { + long startTime = next.getStartTime(); + long distance = startTime - spanEventBoStartTime; + long weightDistance = getWeightDistance(distance); + if (weightDistance > MAX_EXCLUDE_WEIGHT) { + // MAX WEIGHT보다 가중치가 높을 경우. 분실된 케이스 일수 있으므로 그냥 버린다. + continue; + } + weightSpanList.add(new WeightSpanBo(weightDistance, next)); + } + return weightSpanList; + } + + private long getWeightDistance(long distance) { + if (distance >= 0) { + // 양수일 경우 + return distance; + } else { + // 음수일 경우 패널티를 둔다. 네트워크 타임 동기화 시간이 길지 않을 경우 음수가 매치될 확율은 매우 적어야 한다. + // 차라리 jvm gc등으로 인해 양수 값이 많이 차이 날수 있지. 음수값이 매치될 가능성은 매우낮다고 봐야 한다. + // 네트워크 싱크 시간?? 오차 등을 추가로 더하면 될거 같은데. 모르니깐 대충 더하자. 패널티는 1초 + distance = Math.abs(distance); + return (distance * 2) + 1000; + } + } + + + public List other() { + if (nextSpanBoList.size() == 0) { + return null; + } + return nextSpanBoList; + } + + private static class WeightSpanBo { + private long weight; + private SpanBo spanBo; + + private WeightSpanBo(long weight, SpanBo spanBo) { + this.weight = weight; + this.spanBo = spanBo; + } + + private long getWeight() { + return weight; + } + + private SpanBo getSpanBo() { + return spanBo; + } + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanPopulator.java b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanPopulator.java index 7cfb5ff0de2a..92f4d4a3702c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanPopulator.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanPopulator.java @@ -1,89 +1,89 @@ -package com.nhn.pinpoint.web.calltree.span; - -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * @author emeroad - */ -@Deprecated -public class SpanPopulator { - private List list; - private int index = 0; - - public SpanPopulator(List list) { - this.list = list; - } - - public List populateSpanEvent() { - if (list.size() == 0) { - return Collections.emptyList(); - } - List populatedList = new ArrayList(); - - while (index < list.size()) { - populatedSpan(populatedList); - } - - return populatedList; - } - - private void populatedSpan(List populatedList) { - SpanAlign spanAlign = list.get(index); - SpanBo span = spanAlign.getSpanBo(); - populatedList.add(spanAlign); - long startTime = span.getStartTime(); - List spanEventBoList = sortSpanEvent(span); - for (SpanEventBo spanEventBo : spanEventBoList) { - long subStartTime = startTime + spanEventBo.getStartElapsed(); - long nextSpanStartTime = getNextSpanStartTime(); - if (subStartTime <= nextSpanStartTime) { - SpanAlign SpanEventAlign = new SpanAlign(spanAlign.getDepth(), span, spanEventBo); - SpanEventAlign.setSpan(false); - populatedList.add(SpanEventAlign); - } else { - if (nextSpanStartTime == Long.MAX_VALUE) { - return; - } - index++; - populatedSpan(populatedList); - } - } - index++; - } - - public long getNextSpanStartTime() { - int nextIndex = index + 1; - if (nextIndex >= list.size()) { - return Long.MAX_VALUE; - } - return list.get(nextIndex).getSpanBo().getStartTime(); - } - - private List sortSpanEvent(SpanBo span) { - List spanEventBoList = span.getSpanEventBoList(); - if (spanEventBoList == null) { - return Collections.emptyList(); - } - Collections.sort(spanEventBoList, new Comparator() { - @Override - public int compare(SpanEventBo o1, SpanEventBo o2) { - long o1Timestamp = o1.getSequence(); - long o2Timestamp = o2.getSequence(); - if (o1Timestamp > o2Timestamp) { - return 1; - } - if (o1Timestamp == o2Timestamp) { - return 0; - } - return -1; - } - }); - return spanEventBoList; - } -} +package com.nhn.pinpoint.web.calltree.span; + +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * @author emeroad + */ +@Deprecated +public class SpanPopulator { + private List list; + private int index = 0; + + public SpanPopulator(List list) { + this.list = list; + } + + public List populateSpanEvent() { + if (list.size() == 0) { + return Collections.emptyList(); + } + List populatedList = new ArrayList(); + + while (index < list.size()) { + populatedSpan(populatedList); + } + + return populatedList; + } + + private void populatedSpan(List populatedList) { + SpanAlign spanAlign = list.get(index); + SpanBo span = spanAlign.getSpanBo(); + populatedList.add(spanAlign); + long startTime = span.getStartTime(); + List spanEventBoList = sortSpanEvent(span); + for (SpanEventBo spanEventBo : spanEventBoList) { + long subStartTime = startTime + spanEventBo.getStartElapsed(); + long nextSpanStartTime = getNextSpanStartTime(); + if (subStartTime <= nextSpanStartTime) { + SpanAlign SpanEventAlign = new SpanAlign(spanAlign.getDepth(), span, spanEventBo); + SpanEventAlign.setSpan(false); + populatedList.add(SpanEventAlign); + } else { + if (nextSpanStartTime == Long.MAX_VALUE) { + return; + } + index++; + populatedSpan(populatedList); + } + } + index++; + } + + public long getNextSpanStartTime() { + int nextIndex = index + 1; + if (nextIndex >= list.size()) { + return Long.MAX_VALUE; + } + return list.get(nextIndex).getSpanBo().getStartTime(); + } + + private List sortSpanEvent(SpanBo span) { + List spanEventBoList = span.getSpanEventBoList(); + if (spanEventBoList == null) { + return Collections.emptyList(); + } + Collections.sort(spanEventBoList, new Comparator() { + @Override + public int compare(SpanEventBo o1, SpanEventBo o2) { + long o1Timestamp = o1.getSequence(); + long o2Timestamp = o2.getSequence(); + if (o1Timestamp > o2Timestamp) { + return 1; + } + if (o1Timestamp == o2Timestamp) { + return 0; + } + return -1; + } + }); + return spanEventBoList; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/AdminController.java b/web/src/main/java/com/navercorp/pinpoint/web/controller/AdminController.java index 938e4a2e89d7..aec9acf4a3fc 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/controller/AdminController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/controller/AdminController.java @@ -1,36 +1,36 @@ -package com.nhn.pinpoint.web.controller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.nhn.pinpoint.web.service.AdminService; - -/** - * @author netspider - */ -@Controller -public class AdminController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private AdminService adminService; - - @RequestMapping(value = "/admin/removeApplicationName", method = RequestMethod.GET) - @ResponseBody - public String removeApplicationName(@RequestParam("applicationName") String applicationName) { - logger.info("remove application name. {}", applicationName); - try { - adminService.removeApplicationName(applicationName); - return "OK"; - } catch (Exception e) { - return e.getMessage(); - } - } +package com.nhn.pinpoint.web.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.nhn.pinpoint.web.service.AdminService; + +/** + * @author netspider + */ +@Controller +public class AdminController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private AdminService adminService; + + @RequestMapping(value = "/admin/removeApplicationName", method = RequestMethod.GET) + @ResponseBody + public String removeApplicationName(@RequestParam("applicationName") String applicationName) { + logger.info("remove application name. {}", applicationName); + try { + adminService.removeApplicationName(applicationName); + return "OK"; + } catch (Exception e) { + return e.getMessage(); + } + } } \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/BusinessTransactionController.java b/web/src/main/java/com/navercorp/pinpoint/web/controller/BusinessTransactionController.java index 53cc4e63459e..be82d71b91a7 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/controller/BusinessTransactionController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/controller/BusinessTransactionController.java @@ -1,172 +1,172 @@ -package com.nhn.pinpoint.web.controller; - - -import java.util.Date; -import java.util.List; - -import javax.servlet.http.HttpServletResponse; - -import com.nhn.pinpoint.web.service.FilteredMapService; -import com.nhn.pinpoint.web.util.LimitUtils; -import com.nhn.pinpoint.web.vo.Range; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.ModelAndView; - -import com.nhn.pinpoint.web.applicationmap.ApplicationMap; -import com.nhn.pinpoint.web.calltree.span.SpanAlign; -import com.nhn.pinpoint.web.filter.Filter; -import com.nhn.pinpoint.web.filter.FilterBuilder; -import com.nhn.pinpoint.web.service.TransactionInfoService; -import com.nhn.pinpoint.web.service.SpanResult; -import com.nhn.pinpoint.web.service.SpanService; -import com.nhn.pinpoint.web.util.TimeUtils; -import com.nhn.pinpoint.web.vo.BusinessTransactions; -import com.nhn.pinpoint.web.vo.LimitedScanResult; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.callstacks.RecordSet; - -/** - * @author emeroad - */ -@Controller -public class BusinessTransactionController { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private SpanService spanService; - - @Autowired - private TransactionInfoService transactionInfoService; - - @Autowired - private FilteredMapService filteredMapService; - - @Autowired - private FilterBuilder filterBuilder; - - /** - * applicationname에서 from ~ to 시간대에 수행된 URL을 조회한다. - * - * @param model - * @param applicationName - * @param from - * @param to - * @return - */ - @RequestMapping(value = "/transactionList", method = RequestMethod.GET) - public String getBusinessTransactionsData(Model model, - @RequestParam("application") String applicationName, - @RequestParam("from") long from, - @RequestParam("to") long to, - @RequestParam(value = "filter", required = false) String filterText, - @RequestParam(value = "limit", required = false, defaultValue = "10000") int limit) { - limit = LimitUtils.checkRange(limit); - Range range = new Range(from, to); - // TOOD 구조개선을 위해 server map조회 로직 분리함, 임시로 분리한 상태이고 개선이 필요하다. - LimitedScanResult> traceIdList = filteredMapService.selectTraceIdsFromApplicationTraceIndex(applicationName, range, limit); - - Filter filter = filterBuilder.build(filterText); - BusinessTransactions selectBusinessTransactions = transactionInfoService.selectBusinessTransactions(traceIdList.getScanData(), applicationName, range, filter); - - model.addAttribute("lastFetchedTimestamp", traceIdList.getLimitedTime()); - model.addAttribute("rpcList", selectBusinessTransactions.getBusinessTransaction()); - model.addAttribute("requestList", selectBusinessTransactions.getBusinessTransaction()); - model.addAttribute("scatterList", selectBusinessTransactions.getBusinessTransaction()); - model.addAttribute("applicationName", applicationName); - model.addAttribute("from", new Date(from)); - model.addAttribute("to", new Date(to)); - model.addAttribute("urlCount", selectBusinessTransactions.getURLCount()); - model.addAttribute("totalCount", selectBusinessTransactions.getTotalCallCount()); - model.addAttribute("filterText", filterText); - model.addAttribute("filter", filter); - - return "transactionList"; - } - - @RequestMapping(value = "/lastTransactionList", method = RequestMethod.GET) - public String getLastBusinessTransactionsData(Model model, HttpServletResponse response, - @RequestParam("application") String applicationName, - @RequestParam("period") long period, - @RequestParam(value = "filter", required = false) String filterText, - @RequestParam(value = "limit", required = false, defaultValue = "10000") int limit) { - limit = LimitUtils.checkRange(limit); - long to = TimeUtils.getDelayLastTime(); - long from = to - period; - return getBusinessTransactionsData(model, applicationName, from, to, filterText, limit); - } - - /** - * 선택한 하나의 Transaction 정보 조회. - * - * @param traceIdParam - * @param focusTimestamp - * @return - */ - @RequestMapping(value = "/transactionInfo", method = RequestMethod.GET) - public ModelAndView transactionInfo(@RequestParam("traceId") String traceIdParam, @RequestParam("focusTimestamp") long focusTimestamp, - // FIXME jsonResult는 UI 개발 편의를 위해 임시로 추가된 변수 임. 나중에 제거. - // 기존 html view에서 json을 넘어가는 중임. - @RequestParam(value = "jsonResult", required = false, defaultValue = "false") boolean jsonResult, - @RequestParam(value = "v", required = false, defaultValue = "0") int viewVersion) { - logger.debug("traceId:{}", traceIdParam); - - final TransactionId traceId = new TransactionId(traceIdParam); - - ModelAndView mv = new ModelAndView("transactionInfo"); - - try { - // select spans - final SpanResult spanResult = this.spanService.selectSpan(traceId, focusTimestamp); - List spanAligns = spanResult.getSpanAlignList(); - - if (spanAligns.isEmpty()) { - mv.addObject("errorCode", 9); - mv.setViewName("error"); - return mv; - } - - // debug - mv.addObject("spanList", spanAligns); - - mv.addObject("traceId", traceId); - - // application map - ApplicationMap map = filteredMapService.selectApplicationMap(traceId); - mv.addObject("nodes", map.getNodes()); - mv.addObject("links", map.getLinks()); - - // call stacks - RecordSet recordSet = this.transactionInfoService.createRecordSet(spanAligns, focusTimestamp); - mv.addObject("recordSet", recordSet); - - mv.addObject("applicationName", recordSet.getApplicationName()); - mv.addObject("callstack", recordSet.getRecordList()); - mv.addObject("timeline", recordSet.getRecordList()); - mv.addObject("callstackStart", recordSet.getStartTime()); - mv.addObject("callstackEnd", recordSet.getEndTime()); - mv.addObject("completeState", spanResult.getCompleteTypeString()); - } catch (Exception e) { - logger.warn("BusinessTransactionController Error Cause" + e.getMessage(), e); - // TODO 아무래도 다시 던져야 될듯한데. Exception처리 정책을 생각해봐야 한다. - // throw e; - } - - // FIXME jsonResult는 UI 개발 편의를 위해 임시로 추가된 변수 임. 나중에 제거. - if (jsonResult) { - if (viewVersion == 2) { - mv.setViewName("transactionInfoJsonHash"); - } else { - mv.setViewName("transactionInfoJson"); - } - } - return mv; - } -} +package com.nhn.pinpoint.web.controller; + + +import java.util.Date; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import com.nhn.pinpoint.web.service.FilteredMapService; +import com.nhn.pinpoint.web.util.LimitUtils; +import com.nhn.pinpoint.web.vo.Range; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; + +import com.nhn.pinpoint.web.applicationmap.ApplicationMap; +import com.nhn.pinpoint.web.calltree.span.SpanAlign; +import com.nhn.pinpoint.web.filter.Filter; +import com.nhn.pinpoint.web.filter.FilterBuilder; +import com.nhn.pinpoint.web.service.TransactionInfoService; +import com.nhn.pinpoint.web.service.SpanResult; +import com.nhn.pinpoint.web.service.SpanService; +import com.nhn.pinpoint.web.util.TimeUtils; +import com.nhn.pinpoint.web.vo.BusinessTransactions; +import com.nhn.pinpoint.web.vo.LimitedScanResult; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.callstacks.RecordSet; + +/** + * @author emeroad + */ +@Controller +public class BusinessTransactionController { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private SpanService spanService; + + @Autowired + private TransactionInfoService transactionInfoService; + + @Autowired + private FilteredMapService filteredMapService; + + @Autowired + private FilterBuilder filterBuilder; + + /** + * applicationname에서 from ~ to 시간대에 수행된 URL을 조회한다. + * + * @param model + * @param applicationName + * @param from + * @param to + * @return + */ + @RequestMapping(value = "/transactionList", method = RequestMethod.GET) + public String getBusinessTransactionsData(Model model, + @RequestParam("application") String applicationName, + @RequestParam("from") long from, + @RequestParam("to") long to, + @RequestParam(value = "filter", required = false) String filterText, + @RequestParam(value = "limit", required = false, defaultValue = "10000") int limit) { + limit = LimitUtils.checkRange(limit); + Range range = new Range(from, to); + // TOOD 구조개선을 위해 server map조회 로직 분리함, 임시로 분리한 상태이고 개선이 필요하다. + LimitedScanResult> traceIdList = filteredMapService.selectTraceIdsFromApplicationTraceIndex(applicationName, range, limit); + + Filter filter = filterBuilder.build(filterText); + BusinessTransactions selectBusinessTransactions = transactionInfoService.selectBusinessTransactions(traceIdList.getScanData(), applicationName, range, filter); + + model.addAttribute("lastFetchedTimestamp", traceIdList.getLimitedTime()); + model.addAttribute("rpcList", selectBusinessTransactions.getBusinessTransaction()); + model.addAttribute("requestList", selectBusinessTransactions.getBusinessTransaction()); + model.addAttribute("scatterList", selectBusinessTransactions.getBusinessTransaction()); + model.addAttribute("applicationName", applicationName); + model.addAttribute("from", new Date(from)); + model.addAttribute("to", new Date(to)); + model.addAttribute("urlCount", selectBusinessTransactions.getURLCount()); + model.addAttribute("totalCount", selectBusinessTransactions.getTotalCallCount()); + model.addAttribute("filterText", filterText); + model.addAttribute("filter", filter); + + return "transactionList"; + } + + @RequestMapping(value = "/lastTransactionList", method = RequestMethod.GET) + public String getLastBusinessTransactionsData(Model model, HttpServletResponse response, + @RequestParam("application") String applicationName, + @RequestParam("period") long period, + @RequestParam(value = "filter", required = false) String filterText, + @RequestParam(value = "limit", required = false, defaultValue = "10000") int limit) { + limit = LimitUtils.checkRange(limit); + long to = TimeUtils.getDelayLastTime(); + long from = to - period; + return getBusinessTransactionsData(model, applicationName, from, to, filterText, limit); + } + + /** + * 선택한 하나의 Transaction 정보 조회. + * + * @param traceIdParam + * @param focusTimestamp + * @return + */ + @RequestMapping(value = "/transactionInfo", method = RequestMethod.GET) + public ModelAndView transactionInfo(@RequestParam("traceId") String traceIdParam, @RequestParam("focusTimestamp") long focusTimestamp, + // FIXME jsonResult는 UI 개발 편의를 위해 임시로 추가된 변수 임. 나중에 제거. + // 기존 html view에서 json을 넘어가는 중임. + @RequestParam(value = "jsonResult", required = false, defaultValue = "false") boolean jsonResult, + @RequestParam(value = "v", required = false, defaultValue = "0") int viewVersion) { + logger.debug("traceId:{}", traceIdParam); + + final TransactionId traceId = new TransactionId(traceIdParam); + + ModelAndView mv = new ModelAndView("transactionInfo"); + + try { + // select spans + final SpanResult spanResult = this.spanService.selectSpan(traceId, focusTimestamp); + List spanAligns = spanResult.getSpanAlignList(); + + if (spanAligns.isEmpty()) { + mv.addObject("errorCode", 9); + mv.setViewName("error"); + return mv; + } + + // debug + mv.addObject("spanList", spanAligns); + + mv.addObject("traceId", traceId); + + // application map + ApplicationMap map = filteredMapService.selectApplicationMap(traceId); + mv.addObject("nodes", map.getNodes()); + mv.addObject("links", map.getLinks()); + + // call stacks + RecordSet recordSet = this.transactionInfoService.createRecordSet(spanAligns, focusTimestamp); + mv.addObject("recordSet", recordSet); + + mv.addObject("applicationName", recordSet.getApplicationName()); + mv.addObject("callstack", recordSet.getRecordList()); + mv.addObject("timeline", recordSet.getRecordList()); + mv.addObject("callstackStart", recordSet.getStartTime()); + mv.addObject("callstackEnd", recordSet.getEndTime()); + mv.addObject("completeState", spanResult.getCompleteTypeString()); + } catch (Exception e) { + logger.warn("BusinessTransactionController Error Cause" + e.getMessage(), e); + // TODO 아무래도 다시 던져야 될듯한데. Exception처리 정책을 생각해봐야 한다. + // throw e; + } + + // FIXME jsonResult는 UI 개발 편의를 위해 임시로 추가된 변수 임. 나중에 제거. + if (jsonResult) { + if (viewVersion == 2) { + mv.setViewName("transactionInfoJsonHash"); + } else { + mv.setViewName("transactionInfoJson"); + } + } + return mv; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/FilteredMapController.java b/web/src/main/java/com/navercorp/pinpoint/web/controller/FilteredMapController.java index 98b13c5930b9..3cf829129c91 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/controller/FilteredMapController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/controller/FilteredMapController.java @@ -1,114 +1,114 @@ -package com.nhn.pinpoint.web.controller; - -import java.util.List; - -import com.nhn.pinpoint.web.applicationmap.FilterMapWrap; -import com.nhn.pinpoint.web.service.FilteredMapService; -import com.nhn.pinpoint.web.util.LimitUtils; -import com.nhn.pinpoint.web.vo.Range; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -import com.nhn.pinpoint.common.util.DateUtils; -import com.nhn.pinpoint.web.applicationmap.ApplicationMap; -import com.nhn.pinpoint.web.filter.Filter; -import com.nhn.pinpoint.web.filter.FilterBuilder; -import com.nhn.pinpoint.web.util.TimeUtils; -import com.nhn.pinpoint.web.vo.LimitedScanResult; -import com.nhn.pinpoint.web.vo.TransactionId; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * - * @author emeroad - * @author netspider - */ -@Controller -public class FilteredMapController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private FilteredMapService filteredMapService; - - @Autowired - private FilterBuilder filterBuilder; - - /** - * 필터가 적용된 서버맵의 FROM ~ TO기간의 데이터 조회 - * - * @param applicationName - * @param serviceTypeCode - * @param from - * @param to - * @param filterText - * @param limit - * @return - */ - @RequestMapping(value = "/getFilteredServerMapData", method = RequestMethod.GET) - @ResponseBody - public FilterMapWrap getFilteredServerMapData( - @RequestParam("applicationName") String applicationName, - @RequestParam("serviceTypeCode") short serviceTypeCode, - @RequestParam("from") long from, - @RequestParam("to") long to, - @RequestParam("originTo") long originTo, - @RequestParam(value = "filter", required = false) String filterText, - @RequestParam(value = "hint", required = false) String filterHint, - @RequestParam(value = "limit", required = false, defaultValue = "10000") int limit) { - limit = LimitUtils.checkRange(limit); - final Filter filter = filterBuilder.build(filterText, filterHint); - // scan을 해야 될 토탈 범위 - final Range range = new Range(from, to); - final LimitedScanResult> limitedScanResult = filteredMapService.selectTraceIdsFromApplicationTraceIndex(applicationName, range, limit); - - final long lastScanTime = limitedScanResult.getLimitedTime(); - // 원본 범위, 시계열 차트의 sampling을 하려면 필요함. - final Range originalRange = new Range(from, originTo); - // 정확히 스캔된 범위가 어디까지 인지 알기 위해서 필요함. - final Range scannerRange = new Range(lastScanTime, to); - logger.debug("originalRange:{} scannerRange:{} ", originalRange, scannerRange); - ApplicationMap map = filteredMapService.selectApplicationMap(limitedScanResult.getScanData(), originalRange, scannerRange, filter); - - if (logger.isDebugEnabled()) { - logger.debug("getFilteredServerMapData range scan(limit:{}) range:{} lastFetchedTimestamp:{}", limit, range.prettyToString(), DateUtils.longToDateStr(lastScanTime)); - } - - FilterMapWrap mapWrap = new FilterMapWrap(map); - mapWrap.setLastFetchedTimestamp(lastScanTime); - return mapWrap; - } - - /** - * 필터가 적용된 서버맵의 Period before 부터 현재시간까지의 데이터 조회. - * - * @param applicationName - * @param serviceTypeCode - * @param filterText - * @param limit - * @return - */ - @RequestMapping(value = "/getLastFilteredServerMapData", method = RequestMethod.GET) - @ResponseBody - public FilterMapWrap getLastFilteredServerMapData( - @RequestParam("applicationName") String applicationName, - @RequestParam("serviceTypeCode") short serviceTypeCode, - @RequestParam("period") long period, - @RequestParam(value = "filter", required = false) String filterText, - @RequestParam(value = "hint", required = false) String filterHint, - @RequestParam(value = "limit", required = false, defaultValue = "1000000") int limit) { - limit = LimitUtils.checkRange(limit); - - long to = TimeUtils.getDelayLastTime(); - long from = to - period; - // TODO 실시간 조회가 현재 disable이므로 to to로 수정하였음. 이것도 추가적으로 @RequestParam("originTo")가 필요할수 있음. - return getFilteredServerMapData(applicationName, serviceTypeCode, from, to, to, filterText, filterHint, limit); - } - - +package com.nhn.pinpoint.web.controller; + +import java.util.List; + +import com.nhn.pinpoint.web.applicationmap.FilterMapWrap; +import com.nhn.pinpoint.web.service.FilteredMapService; +import com.nhn.pinpoint.web.util.LimitUtils; +import com.nhn.pinpoint.web.vo.Range; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +import com.nhn.pinpoint.common.util.DateUtils; +import com.nhn.pinpoint.web.applicationmap.ApplicationMap; +import com.nhn.pinpoint.web.filter.Filter; +import com.nhn.pinpoint.web.filter.FilterBuilder; +import com.nhn.pinpoint.web.util.TimeUtils; +import com.nhn.pinpoint.web.vo.LimitedScanResult; +import com.nhn.pinpoint.web.vo.TransactionId; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * + * @author emeroad + * @author netspider + */ +@Controller +public class FilteredMapController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private FilteredMapService filteredMapService; + + @Autowired + private FilterBuilder filterBuilder; + + /** + * 필터가 적용된 서버맵의 FROM ~ TO기간의 데이터 조회 + * + * @param applicationName + * @param serviceTypeCode + * @param from + * @param to + * @param filterText + * @param limit + * @return + */ + @RequestMapping(value = "/getFilteredServerMapData", method = RequestMethod.GET) + @ResponseBody + public FilterMapWrap getFilteredServerMapData( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") short serviceTypeCode, + @RequestParam("from") long from, + @RequestParam("to") long to, + @RequestParam("originTo") long originTo, + @RequestParam(value = "filter", required = false) String filterText, + @RequestParam(value = "hint", required = false) String filterHint, + @RequestParam(value = "limit", required = false, defaultValue = "10000") int limit) { + limit = LimitUtils.checkRange(limit); + final Filter filter = filterBuilder.build(filterText, filterHint); + // scan을 해야 될 토탈 범위 + final Range range = new Range(from, to); + final LimitedScanResult> limitedScanResult = filteredMapService.selectTraceIdsFromApplicationTraceIndex(applicationName, range, limit); + + final long lastScanTime = limitedScanResult.getLimitedTime(); + // 원본 범위, 시계열 차트의 sampling을 하려면 필요함. + final Range originalRange = new Range(from, originTo); + // 정확히 스캔된 범위가 어디까지 인지 알기 위해서 필요함. + final Range scannerRange = new Range(lastScanTime, to); + logger.debug("originalRange:{} scannerRange:{} ", originalRange, scannerRange); + ApplicationMap map = filteredMapService.selectApplicationMap(limitedScanResult.getScanData(), originalRange, scannerRange, filter); + + if (logger.isDebugEnabled()) { + logger.debug("getFilteredServerMapData range scan(limit:{}) range:{} lastFetchedTimestamp:{}", limit, range.prettyToString(), DateUtils.longToDateStr(lastScanTime)); + } + + FilterMapWrap mapWrap = new FilterMapWrap(map); + mapWrap.setLastFetchedTimestamp(lastScanTime); + return mapWrap; + } + + /** + * 필터가 적용된 서버맵의 Period before 부터 현재시간까지의 데이터 조회. + * + * @param applicationName + * @param serviceTypeCode + * @param filterText + * @param limit + * @return + */ + @RequestMapping(value = "/getLastFilteredServerMapData", method = RequestMethod.GET) + @ResponseBody + public FilterMapWrap getLastFilteredServerMapData( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") short serviceTypeCode, + @RequestParam("period") long period, + @RequestParam(value = "filter", required = false) String filterText, + @RequestParam(value = "hint", required = false) String filterHint, + @RequestParam(value = "limit", required = false, defaultValue = "1000000") int limit) { + limit = LimitUtils.checkRange(limit); + + long to = TimeUtils.getDelayLastTime(); + long from = to - period; + // TODO 실시간 조회가 현재 disable이므로 to to로 수정하였음. 이것도 추가적으로 @RequestParam("originTo")가 필요할수 있음. + return getFilteredServerMapData(applicationName, serviceTypeCode, from, to, to, filterText, filterHint, limit); + } + + } \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/MainController.java b/web/src/main/java/com/navercorp/pinpoint/web/controller/MainController.java index d12c14537c67..4da7bbfa6350 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/controller/MainController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/controller/MainController.java @@ -1,46 +1,46 @@ -package com.nhn.pinpoint.web.controller; - -import java.util.List; - - -import com.nhn.pinpoint.web.view.ApplicationGroup; -import com.nhn.pinpoint.web.view.ServerTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ExtendedModelMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.nhn.pinpoint.web.service.CommonService; -import com.nhn.pinpoint.web.vo.Application; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * @author emeroad - * @author netspider - */ -@Controller -public class MainController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private CommonService commonService; - - @RequestMapping(value = "/applications", method = RequestMethod.GET) - @ResponseBody - public ApplicationGroup getApplicationGroup() { - List applicationList = commonService.selectAllApplicationNames(); - logger.debug("/applications {}", applicationList); - - return new ApplicationGroup(applicationList); - } - - @RequestMapping(value = "/serverTime", method = RequestMethod.GET) - @ResponseBody - public ServerTime getServerTime() { - return new ServerTime(); - } +package com.nhn.pinpoint.web.controller; + +import java.util.List; + + +import com.nhn.pinpoint.web.view.ApplicationGroup; +import com.nhn.pinpoint.web.view.ServerTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ExtendedModelMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.nhn.pinpoint.web.service.CommonService; +import com.nhn.pinpoint.web.vo.Application; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author emeroad + * @author netspider + */ +@Controller +public class MainController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private CommonService commonService; + + @RequestMapping(value = "/applications", method = RequestMethod.GET) + @ResponseBody + public ApplicationGroup getApplicationGroup() { + List applicationList = commonService.selectAllApplicationNames(); + logger.debug("/applications {}", applicationList); + + return new ApplicationGroup(applicationList); + } + + @RequestMapping(value = "/serverTime", method = RequestMethod.GET) + @ResponseBody + public ServerTime getServerTime() { + return new ServerTime(); + } } \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/MapController.java b/web/src/main/java/com/navercorp/pinpoint/web/controller/MapController.java index 3ad44d1e97bd..a016c5791a95 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/controller/MapController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/controller/MapController.java @@ -1,148 +1,148 @@ -package com.nhn.pinpoint.web.controller; - -import com.nhn.pinpoint.web.applicationmap.MapWrap; -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; -import com.nhn.pinpoint.web.service.MapService; -import com.nhn.pinpoint.web.util.Limiter; -import com.nhn.pinpoint.web.view.ResponseTimeViewModel; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; -import com.nhn.pinpoint.web.vo.Range; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -import com.nhn.pinpoint.web.applicationmap.ApplicationMap; -import com.nhn.pinpoint.web.util.TimeUtils; -import org.springframework.web.bind.annotation.ResponseBody; - -import java.io.IOException; -import java.util.List; -import java.util.concurrent.TimeUnit; - - -/** - * @author emeroad - * @author netspider - */ -@Controller -public class MapController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private MapService mapService; - - @Autowired - private Limiter dateLimit; - - /** - * FROM ~ TO기간의 서버 맵 데이터 조회 - * - * @param applicationName - * @param serviceTypeCode - * @param from - * @param to - * @return - */ - @RequestMapping(value = "/getServerMapData", method = RequestMethod.GET) - @ResponseBody - public MapWrap getServerMapData( - @RequestParam("applicationName") String applicationName, - @RequestParam("serviceTypeCode") short serviceTypeCode, - @RequestParam("from") long from, - @RequestParam("to") long to) { - final Range range = new Range(from, to); - this.dateLimit.limit(from, to); - logger.debug("range:{}", TimeUnit.MILLISECONDS.toMinutes(range.getRange())); - Application application = new Application(applicationName, serviceTypeCode); - - ApplicationMap map = mapService.selectApplicationMap(application, range); - - return new MapWrap(map); - } - - /** - * Period before 부터 현재시간까지의 서버맵 조회. - * - * @param applicationName - * @param serviceTypeCode - * @param period - * @return - */ - @RequestMapping(value = "/getLastServerMapData", method = RequestMethod.GET) - @ResponseBody - public MapWrap getLastServerMapData( - @RequestParam("applicationName") String applicationName, - @RequestParam("serviceTypeCode") short serviceTypeCode, - @RequestParam("period") long period) { - - long to = TimeUtils.getDelayLastTime(); - long from = to - period; - return getServerMapData(applicationName, serviceTypeCode, from, to); - } - - /** - * 맵에서 직접 찍어오는걸로 변경시 잘 사용하지 않는 API가 될것임. - * 필터가 사용되지 않은 서버맵의 연결선을 통과하는 요청의 통계정보 조회 - * - * @param model - * @param from - * @param to - * @param sourceApplicationName - * @param sourceServiceType - * @param targetApplicationName - * @param targetServiceType - * @return - */ - @Deprecated - @RequestMapping(value = "/linkStatistics", method = RequestMethod.GET) - public String getLinkStatistics(Model model, - @RequestParam("from") long from, - @RequestParam("to") long to, - @RequestParam("sourceApplicationName") String sourceApplicationName, - @RequestParam("sourceServiceType") short sourceServiceType, - @RequestParam("targetApplicationName") String targetApplicationName, - @RequestParam("targetServiceType") short targetServiceType) { - - final Application sourceApplication = new Application(sourceApplicationName, sourceServiceType); - final Application destinationApplication = new Application(targetApplicationName, targetServiceType); - final Range range = new Range(from, to); - - NodeHistogram nodeHistogram = mapService.linkStatistics(sourceApplication, destinationApplication, range); - - model.addAttribute("range", range); - - model.addAttribute("sourceApplication", sourceApplication); - - model.addAttribute("targetApplication", destinationApplication); - - Histogram applicationHistogram = nodeHistogram.getApplicationHistogram(); - model.addAttribute("linkStatistics", applicationHistogram); - - - List applicationTimeSeriesHistogram = nodeHistogram.getApplicationTimeHistogram(); - String applicationTimeSeriesHistogramJson = null; - try { - applicationTimeSeriesHistogramJson = MAPPER.writeValueAsString(applicationTimeSeriesHistogram); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - model.addAttribute("timeSeriesHistogram", applicationTimeSeriesHistogramJson); - - // 결과의 from, to를 다시 명시해야 되는듯 한데. 현재는 그냥 요청 데이터를 그냥 주는것으로 보임. - model.addAttribute("resultFrom", from); - model.addAttribute("resultTo", to); - - - return "linkStatistics"; - } - - private final static ObjectMapper MAPPER = new ObjectMapper(); +package com.nhn.pinpoint.web.controller; + +import com.nhn.pinpoint.web.applicationmap.MapWrap; +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; +import com.nhn.pinpoint.web.service.MapService; +import com.nhn.pinpoint.web.util.Limiter; +import com.nhn.pinpoint.web.view.ResponseTimeViewModel; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; +import com.nhn.pinpoint.web.vo.Range; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +import com.nhn.pinpoint.web.applicationmap.ApplicationMap; +import com.nhn.pinpoint.web.util.TimeUtils; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; + + +/** + * @author emeroad + * @author netspider + */ +@Controller +public class MapController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private MapService mapService; + + @Autowired + private Limiter dateLimit; + + /** + * FROM ~ TO기간의 서버 맵 데이터 조회 + * + * @param applicationName + * @param serviceTypeCode + * @param from + * @param to + * @return + */ + @RequestMapping(value = "/getServerMapData", method = RequestMethod.GET) + @ResponseBody + public MapWrap getServerMapData( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") short serviceTypeCode, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = new Range(from, to); + this.dateLimit.limit(from, to); + logger.debug("range:{}", TimeUnit.MILLISECONDS.toMinutes(range.getRange())); + Application application = new Application(applicationName, serviceTypeCode); + + ApplicationMap map = mapService.selectApplicationMap(application, range); + + return new MapWrap(map); + } + + /** + * Period before 부터 현재시간까지의 서버맵 조회. + * + * @param applicationName + * @param serviceTypeCode + * @param period + * @return + */ + @RequestMapping(value = "/getLastServerMapData", method = RequestMethod.GET) + @ResponseBody + public MapWrap getLastServerMapData( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") short serviceTypeCode, + @RequestParam("period") long period) { + + long to = TimeUtils.getDelayLastTime(); + long from = to - period; + return getServerMapData(applicationName, serviceTypeCode, from, to); + } + + /** + * 맵에서 직접 찍어오는걸로 변경시 잘 사용하지 않는 API가 될것임. + * 필터가 사용되지 않은 서버맵의 연결선을 통과하는 요청의 통계정보 조회 + * + * @param model + * @param from + * @param to + * @param sourceApplicationName + * @param sourceServiceType + * @param targetApplicationName + * @param targetServiceType + * @return + */ + @Deprecated + @RequestMapping(value = "/linkStatistics", method = RequestMethod.GET) + public String getLinkStatistics(Model model, + @RequestParam("from") long from, + @RequestParam("to") long to, + @RequestParam("sourceApplicationName") String sourceApplicationName, + @RequestParam("sourceServiceType") short sourceServiceType, + @RequestParam("targetApplicationName") String targetApplicationName, + @RequestParam("targetServiceType") short targetServiceType) { + + final Application sourceApplication = new Application(sourceApplicationName, sourceServiceType); + final Application destinationApplication = new Application(targetApplicationName, targetServiceType); + final Range range = new Range(from, to); + + NodeHistogram nodeHistogram = mapService.linkStatistics(sourceApplication, destinationApplication, range); + + model.addAttribute("range", range); + + model.addAttribute("sourceApplication", sourceApplication); + + model.addAttribute("targetApplication", destinationApplication); + + Histogram applicationHistogram = nodeHistogram.getApplicationHistogram(); + model.addAttribute("linkStatistics", applicationHistogram); + + + List applicationTimeSeriesHistogram = nodeHistogram.getApplicationTimeHistogram(); + String applicationTimeSeriesHistogramJson = null; + try { + applicationTimeSeriesHistogramJson = MAPPER.writeValueAsString(applicationTimeSeriesHistogram); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + model.addAttribute("timeSeriesHistogram", applicationTimeSeriesHistogramJson); + + // 결과의 from, to를 다시 명시해야 되는듯 한데. 현재는 그냥 요청 데이터를 그냥 주는것으로 보임. + model.addAttribute("resultFrom", from); + model.addAttribute("resultTo", to); + + + return "linkStatistics"; + } + + private final static ObjectMapper MAPPER = new ObjectMapper(); } \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/ScatterChartController.java b/web/src/main/java/com/navercorp/pinpoint/web/controller/ScatterChartController.java index 538e87b585ec..1d6671047560 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/controller/ScatterChartController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/controller/ScatterChartController.java @@ -1,312 +1,311 @@ -package com.nhn.pinpoint.web.controller; - -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.nhn.pinpoint.common.util.DateUtils; -import com.nhn.pinpoint.web.service.FilteredMapService; -import com.nhn.pinpoint.web.util.LimitUtils; -import com.nhn.pinpoint.web.filter.Filter; -import com.nhn.pinpoint.web.filter.FilterBuilder; -import com.nhn.pinpoint.web.vo.*; -import com.nhn.pinpoint.web.vo.scatter.Dot; -import com.nhn.pinpoint.web.vo.scatter.ScatterIndex; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.util.StopWatch; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.web.service.ScatterChartService; -import com.nhn.pinpoint.web.util.TimeUtils; -import org.springframework.web.servlet.ModelAndView; - -/** - * - * @author netspider - * @author emeroad - */ -@Controller -public class ScatterChartController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private ScatterChartService scatter; - - @Autowired - private FilteredMapService flow; - - @Autowired - private FilterBuilder filterBuilder; - - private static final String PREFIX_TRANSACTION_ID = "I"; - private static final String PREFIX_TIME = "T"; - private static final String PREFIX_RESPONSE_TIME = "R"; - - @RequestMapping(value = "/scatterpopup", method = RequestMethod.GET) - public String scatterPopup(Model model, - @RequestParam("application") String applicationName, - @RequestParam("from") long from, - @RequestParam("to") long to, - @RequestParam("period") long period, - @RequestParam("usePeriod") boolean usePeriod, - @RequestParam(value = "filter", required = false) String filterText) { - model.addAttribute("applicationName", applicationName); - model.addAttribute("from", from); - model.addAttribute("to", to); - model.addAttribute("period", period); - model.addAttribute("usePeriod", usePeriod); - model.addAttribute("filter", filterText); - return "scatterPopup"; - } - - /** - * - * @param applicationName - * @param from - * @param to - * @param limit - * 한번에 조회 할 데이터의 크기, 조회 결과가 이 크기를 넘어가면 limit개만 반환한다. 나머지는 다시 요청해서 - * 조회해야 한다. - * @return - */ - @RequestMapping(value = "/getScatterData", method = RequestMethod.GET) - public ModelAndView getScatterData( - @RequestParam("application") String applicationName, - @RequestParam("from") long from, - @RequestParam("to") long to, - @RequestParam("limit") int limit, - @RequestParam(value = "filter", required = false) String filterText, - @RequestParam(value = "_callback", required = false) String jsonpCallback, - @RequestParam(value = "v", required = false, defaultValue = "2") int version) { - limit = LimitUtils.checkRange(limit); - - StopWatch watch = new StopWatch(); - watch.start("selectScatterData"); - - // TODO 레인지 체크 확인 exception 발생, from값이 to 보다 더 큼. - final Range range = Range.createUncheckedRange(from, to); - logger.debug("fetch scatter data. {}, LIMIT={}, FILTER={}", range, limit, filterText); - - ModelAndView mv; - if (filterText == null) { - mv = selectScatterData(applicationName, range, limit, jsonpCallback); - } else { - mv = selectFilterScatterDataData(applicationName, range, filterText, limit, jsonpCallback); - } - - watch.stop(); - - logger.info("Fetch scatterData time : {}ms", watch.getLastTaskTimeMillis()); - - return mv; - } - - private ModelAndView selectFilterScatterDataData(String applicationName, Range range, String filterText, int limit, String jsonpCallback) { - - final LimitedScanResult> limitedScanResult = flow.selectTraceIdsFromApplicationTraceIndex(applicationName, range, limit); - - final List traceIdList = limitedScanResult.getScanData(); - logger.trace("submitted transactionId count={}", traceIdList.size()); - // TODO sorted만 하는가? tree기반으로 레인지 체크하도록 하고 삭제하도록 하자. - SortedSet traceIdSet = new TreeSet(traceIdList); - logger.debug("unified traceIdSet size={}", traceIdSet.size()); - - Filter filter = filterBuilder.build(filterText); - List scatterData = scatter.selectScatterData(traceIdSet, applicationName, filter); - if (logger.isDebugEnabled()) { - logger.debug("getScatterData range scan(limited:{}) from ~ to:{} ~ {}, limited:{}, filterDataSize:{}", - limit, DateUtils.longToDateStr(range.getFrom()), DateUtils.longToDateStr(range.getTo()), DateUtils.longToDateStr(limitedScanResult.getLimitedTime()), traceIdList.size()); - } - - Range resultRange; - if (traceIdList.isEmpty()) { - resultRange = new Range(-1, -1); - } else { - resultRange = new Range(limitedScanResult.getLimitedTime(), range.getTo()); - } - return createModelAndView(resultRange, jsonpCallback, scatterData); - } - - private ModelAndView selectScatterData(String applicationName, Range range, int limit, String jsonpCallback) { - - final List scatterData = scatter.selectScatterData(applicationName, range, limit); - Range resultRange; - if (scatterData.isEmpty()) { - resultRange = new Range(-1, -1); - } else { - resultRange = new Range(scatterData.get(scatterData.size() - 1).getAcceptedTime(), range.getTo()); - } - return createModelAndView(resultRange, jsonpCallback, scatterData); - } - - private ModelAndView createModelAndView(Range range, String jsonpCallback, List scatterData) { - ModelAndView mv = new ModelAndView(); - mv.addObject("resultFrom", range.getFrom()); - mv.addObject("resultTo", range.getTo()); - mv.addObject("scatterIndex", ScatterIndex.MATA_DATA); - mv.addObject("scatter", scatterData); - if (jsonpCallback == null) { - mv.setViewName("jsonView"); - } else { - mv.setViewName("jsonpView"); - } - return mv; - } - - /** - * NOW 버튼을 눌렀을 때 scatter 데이터 조회. - * - * @param applicationName - * @param limit - * @return - */ - @RequestMapping(value = "/getLastScatterData", method = RequestMethod.GET) - public ModelAndView getLastScatterData( - @RequestParam("application") String applicationName, - @RequestParam("period") long period, - @RequestParam("limit") int limit, - @RequestParam(value = "filter", required = false) String filterText, - @RequestParam(value = "_callback", required = false) String jsonpCallback, - @RequestParam(value = "v", required = false, defaultValue = "1") int version) { - limit = LimitUtils.checkRange(limit); - - long to = TimeUtils.getDelayLastTime(); - long from = to - period; - // TODO version은 임시로 사용됨. template변경과 서버개발을 동시에 하려고.. - return getScatterData(applicationName, from, to, limit, filterText, jsonpCallback, version); - } - - /** - * scatter에서 점 여러개를 선택했을 때 점에 대한 정보를 조회한다. - * - * @param model - * @param request - * @param response - * @return - */ - @RequestMapping(value = "/transactionmetadata", method = RequestMethod.POST) - public String transactionmetadata(Model model, HttpServletRequest request, HttpServletResponse response) { - - TransactionMetadataQuery query = parseSelectTransaction(request); - if (query.size() > 0) { - List metadata = scatter.selectTransactionMetadata(query); - model.addAttribute("metadata", metadata); - } - - return "transactionmetadata"; - } - - private TransactionMetadataQuery parseSelectTransaction(HttpServletRequest request) { - final TransactionMetadataQuery query = new TransactionMetadataQuery(); - int index = 0; - while (true) { - final String traceId = request.getParameter(PREFIX_TRANSACTION_ID + index); - final String time = request.getParameter(PREFIX_TIME + index); - final String responseTime = request.getParameter(PREFIX_RESPONSE_TIME + index); - - if (traceId == null || time == null || responseTime == null) { - break; - } - - query.addQueryCondition(traceId, Long.parseLong(time), Integer.parseInt(responseTime)); - index++; - } - logger.debug("query:{}", query); - return query; - } - - /** - * scatter chart에서 선택한 범위에 속하는 트랜잭션 목록을 조회 - * - *
-     * TEST URL = http://localhost:7080/transactionmetadata2.pinpoint?application=FRONT-WEB&from=1394432299032&to=1394433498269&responseFrom=100&responseTo=200&responseOffset=100&limit=10
-     * 
- * - * @param model - * @param request - * @param response - * @return - */ - @RequestMapping(value = "/transactionmetadata2", method = RequestMethod.GET) - public String getTransaction(Model model, - @RequestParam("application") String applicationName, - @RequestParam("from") long from, - @RequestParam("to") long to, - @RequestParam("responseFrom") int responseFrom, - @RequestParam("responseTo") int responseTo, - @RequestParam("limit") int limit, - @RequestParam(value = "offsetTime", required = false, defaultValue = "-1") long offsetTime, - @RequestParam(value = "offsetTransactionId", required = false) String offsetTransactionId, - @RequestParam(value = "offsetTransactionElapsed", required = false, defaultValue = "-1") int offsetTransactionElapsed, - @RequestParam(value = "filter", required = false) String filterText) { - - limit = LimitUtils.checkRange(limit); - - StopWatch watch = new StopWatch(); - watch.start("selectScatterData"); - - final SelectedScatterArea area = SelectedScatterArea.createUncheckedArea(from, to, responseFrom, responseTo); - logger.debug("fetch scatter data. {}, LIMIT={}, FILTER={}", area, limit, filterText); - - if (filterText == null) { - // limit에 걸려서 조회되지 않은 부분 우선 조회 - TransactionId offsetId = null; - List extraMetadata = null; - if (offsetTransactionId != null) { - offsetId = new TransactionId(offsetTransactionId); - - SelectedScatterArea extraArea = SelectedScatterArea.createUncheckedArea(offsetTime, offsetTime, responseFrom, responseTo); - List extraAreaDotList = scatter.selectScatterData(applicationName, extraArea, offsetId, offsetTransactionElapsed, limit); - extraMetadata = scatter.selectTransactionMetadata(parseSelectTransaction(extraAreaDotList)); - model.addAttribute("extraMetadata", extraMetadata); - } - - // limit에 걸려서 조회되지 않은 부분 조회 결과가 limit에 미치지 못하면 나머지 영역 추가 조회 - if (extraMetadata == null || extraMetadata.size() < limit) { - int newlimit = limit - ((extraMetadata == null) ? 0 : extraMetadata.size()); - List selectedDotList = scatter.selectScatterData(applicationName, area, null, -1, newlimit); - List metadata = scatter.selectTransactionMetadata(parseSelectTransaction(selectedDotList)); - model.addAttribute("metadata", metadata); - } - } else { - final LimitedScanResult> limitedScanResult = flow.selectTraceIdsFromApplicationTraceIndex(applicationName, area, limit); - final List traceIdList = limitedScanResult.getScanData(); - logger.trace("submitted transactionId count={}", traceIdList.size()); - - // TODO sorted만 하는가? tree기반으로 레인지 체크하도록 하고 삭제하도록 하자. - SortedSet traceIdSet = new TreeSet(traceIdList); - logger.debug("unified traceIdSet size={}", traceIdSet.size()); - - List dots = scatter.selectScatterData(traceIdSet, applicationName, filterBuilder.build(filterText)); - System.out.println(dots); - } - - watch.stop(); - logger.info("Fetch scatterData time : {}ms", watch.getLastTaskTimeMillis()); - - return "transactionmetadata2"; - } - - private TransactionMetadataQuery parseSelectTransaction(List dotList) { - TransactionMetadataQuery query = new TransactionMetadataQuery(); - if (dotList == null) { - return query; - } - for (Dot dot : dotList) { - query.addQueryCondition(dot.getTransactionId(), dot.getAcceptedTime(), dot.getElapsedTime()); - } - logger.debug("query:{}", query); - return query; - } +package com.nhn.pinpoint.web.controller; + +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.nhn.pinpoint.common.util.DateUtils; +import com.nhn.pinpoint.web.service.FilteredMapService; +import com.nhn.pinpoint.web.util.LimitUtils; +import com.nhn.pinpoint.web.filter.Filter; +import com.nhn.pinpoint.web.filter.FilterBuilder; +import com.nhn.pinpoint.web.vo.*; +import com.nhn.pinpoint.web.vo.scatter.Dot; +import com.nhn.pinpoint.web.vo.scatter.ScatterIndex; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.util.StopWatch; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.web.service.ScatterChartService; +import com.nhn.pinpoint.web.util.TimeUtils; +import org.springframework.web.servlet.ModelAndView; + +/** + * + * @author netspider + * @author emeroad + */ +@Controller +public class ScatterChartController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private ScatterChartService scatter; + + @Autowired + private FilteredMapService flow; + + @Autowired + private FilterBuilder filterBuilder; + + private static final String PREFIX_TRANSACTION_ID = "I"; + private static final String PREFIX_TIME = "T"; + private static final String PREFIX_RESPONSE_TIME = "R"; + + @RequestMapping(value = "/scatterpopup", method = RequestMethod.GET) + public String scatterPopup(Model model, + @RequestParam("application") String applicationName, + @RequestParam("from") long from, + @RequestParam("to") long to, + @RequestParam("period") long period, + @RequestParam("usePeriod") boolean usePeriod, + @RequestParam(value = "filter", required = false) String filterText) { + model.addAttribute("applicationName", applicationName); + model.addAttribute("from", from); + model.addAttribute("to", to); + model.addAttribute("period", period); + model.addAttribute("usePeriod", usePeriod); + model.addAttribute("filter", filterText); + return "scatterPopup"; + } + + /** + * + * @param applicationName + * @param from + * @param to + * @param limit + * 한번에 조회 할 데이터의 크기, 조회 결과가 이 크기를 넘어가면 limit개만 반환한다. 나머지는 다시 요청해서 + * 조회해야 한다. + * @return + */ + @RequestMapping(value = "/getScatterData", method = RequestMethod.GET) + public ModelAndView getScatterData( + @RequestParam("application") String applicationName, + @RequestParam("from") long from, + @RequestParam("to") long to, + @RequestParam("limit") int limit, + @RequestParam(value = "filter", required = false) String filterText, + @RequestParam(value = "_callback", required = false) String jsonpCallback, + @RequestParam(value = "v", required = false, defaultValue = "2") int version) { + limit = LimitUtils.checkRange(limit); + + StopWatch watch = new StopWatch(); + watch.start("selectScatterData"); + + // TODO 레인지 체크 확인 exception 발생, from값이 to 보다 더 큼. + final Range range = Range.createUncheckedRange(from, to); + logger.debug("fetch scatter data. {}, LIMIT={}, FILTER={}", range, limit, filterText); + + ModelAndView mv; + if (filterText == null) { + mv = selectScatterData(applicationName, range, limit, jsonpCallback); + } else { + mv = selectFilterScatterDataData(applicationName, range, filterText, limit, jsonpCallback); + } + + watch.stop(); + + logger.info("Fetch scatterData time : {}ms", watch.getLastTaskTimeMillis()); + + return mv; + } + + private ModelAndView selectFilterScatterDataData(String applicationName, Range range, String filterText, int limit, String jsonpCallback) { + + final LimitedScanResult> limitedScanResult = flow.selectTraceIdsFromApplicationTraceIndex(applicationName, range, limit); + + final List traceIdList = limitedScanResult.getScanData(); + logger.trace("submitted transactionId count={}", traceIdList.size()); + // TODO sorted만 하는가? tree기반으로 레인지 체크하도록 하고 삭제하도록 하자. + SortedSet traceIdSet = new TreeSet(traceIdList); + logger.debug("unified traceIdSet size={}", traceIdSet.size()); + + Filter filter = filterBuilder.build(filterText); + List scatterData = scatter.selectScatterData(traceIdSet, applicationName, filter); + if (logger.isDebugEnabled()) { + logger.debug("getScatterData range scan(limited:{}) from ~ to:{} ~ {}, limited:{}, filterDataSize:{}", + limit, DateUtils.longToDateStr(range.getFrom()), DateUtils.longToDateStr(range.getTo()), DateUtils.longToDateStr(limitedScanResult.getLimitedTime()), traceIdList.size()); + } + + Range resultRange; + if (traceIdList.isEmpty()) { + resultRange = new Range(-1, -1); + } else { + resultRange = new Range(limitedScanResult.getLimitedTime(), range.getTo()); + } + return createModelAndView(resultRange, jsonpCallback, scatterData); + } + + private ModelAndView selectScatterData(String applicationName, Range range, int limit, String jsonpCallback) { + + final List scatterData = scatter.selectScatterData(applicationName, range, limit); + Range resultRange; + if (scatterData.isEmpty()) { + resultRange = new Range(-1, -1); + } else { + resultRange = new Range(scatterData.get(scatterData.size() - 1).getAcceptedTime(), range.getTo()); + } + return createModelAndView(resultRange, jsonpCallback, scatterData); + } + + private ModelAndView createModelAndView(Range range, String jsonpCallback, List scatterData) { + ModelAndView mv = new ModelAndView(); + mv.addObject("resultFrom", range.getFrom()); + mv.addObject("resultTo", range.getTo()); + mv.addObject("scatterIndex", ScatterIndex.MATA_DATA); + mv.addObject("scatter", scatterData); + if (jsonpCallback == null) { + mv.setViewName("jsonView"); + } else { + mv.setViewName("jsonpView"); + } + return mv; + } + + /** + * NOW 버튼을 눌렀을 때 scatter 데이터 조회. + * + * @param applicationName + * @param limit + * @return + */ + @RequestMapping(value = "/getLastScatterData", method = RequestMethod.GET) + public ModelAndView getLastScatterData( + @RequestParam("application") String applicationName, + @RequestParam("period") long period, + @RequestParam("limit") int limit, + @RequestParam(value = "filter", required = false) String filterText, + @RequestParam(value = "_callback", required = false) String jsonpCallback, + @RequestParam(value = "v", required = false, defaultValue = "1") int version) { + limit = LimitUtils.checkRange(limit); + + long to = TimeUtils.getDelayLastTime(); + long from = to - period; + // TODO version은 임시로 사용됨. template변경과 서버개발을 동시에 하려고.. + return getScatterData(applicationName, from, to, limit, filterText, jsonpCallback, version); + } + + /** + * scatter에서 점 여러개를 선택했을 때 점에 대한 정보를 조회한다. + * + * @param model + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/transactionmetadata", method = RequestMethod.POST) + public String transactionmetadata(Model model, HttpServletRequest request, HttpServletResponse response) { + + TransactionMetadataQuery query = parseSelectTransaction(request); + if (query.size() > 0) { + List metadata = scatter.selectTransactionMetadata(query); + model.addAttribute("metadata", metadata); + } + + return "transactionmetadata"; + } + + private TransactionMetadataQuery parseSelectTransaction(HttpServletRequest request) { + final TransactionMetadataQuery query = new TransactionMetadataQuery(); + int index = 0; + while (true) { + final String traceId = request.getParameter(PREFIX_TRANSACTION_ID + index); + final String time = request.getParameter(PREFIX_TIME + index); + final String responseTime = request.getParameter(PREFIX_RESPONSE_TIME + index); + + if (traceId == null || time == null || responseTime == null) { + break; + } + + query.addQueryCondition(traceId, Long.parseLong(time), Integer.parseInt(responseTime)); + index++; + } + logger.debug("query:{}", query); + return query; + } + + /** + * scatter chart에서 선택한 범위에 속하는 트랜잭션 목록을 조회 + * + *
+     * TEST URL = http://localhost:7080/transactionmetadata2.pinpoint?application=FRONT-WEB&from=1394432299032&to=1394433498269&responseFrom=100&responseTo=200&responseOffset=100&limit=10
+     * 
+ * + * @param model + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/transactionmetadata2", method = RequestMethod.GET) + public String getTransaction(Model model, + @RequestParam("application") String applicationName, + @RequestParam("from") long from, + @RequestParam("to") long to, + @RequestParam("responseFrom") int responseFrom, + @RequestParam("responseTo") int responseTo, + @RequestParam("limit") int limit, + @RequestParam(value = "offsetTime", required = false, defaultValue = "-1") long offsetTime, + @RequestParam(value = "offsetTransactionId", required = false) String offsetTransactionId, + @RequestParam(value = "offsetTransactionElapsed", required = false, defaultValue = "-1") int offsetTransactionElapsed, + @RequestParam(value = "filter", required = false) String filterText) { + + limit = LimitUtils.checkRange(limit); + + StopWatch watch = new StopWatch(); + watch.start("selectScatterData"); + + final SelectedScatterArea area = SelectedScatterArea.createUncheckedArea(from, to, responseFrom, responseTo); + logger.debug("fetch scatter data. {}, LIMIT={}, FILTER={}", area, limit, filterText); + + if (filterText == null) { + // limit에 걸려서 조회되지 않은 부분 우선 조회 + TransactionId offsetId = null; + List extraMetadata = null; + if (offsetTransactionId != null) { + offsetId = new TransactionId(offsetTransactionId); + + SelectedScatterArea extraArea = SelectedScatterArea.createUncheckedArea(offsetTime, offsetTime, responseFrom, responseTo); + List extraAreaDotList = scatter.selectScatterData(applicationName, extraArea, offsetId, offsetTransactionElapsed, limit); + extraMetadata = scatter.selectTransactionMetadata(parseSelectTransaction(extraAreaDotList)); + model.addAttribute("extraMetadata", extraMetadata); + } + + // limit에 걸려서 조회되지 않은 부분 조회 결과가 limit에 미치지 못하면 나머지 영역 추가 조회 + if (extraMetadata == null || extraMetadata.size() < limit) { + int newlimit = limit - ((extraMetadata == null) ? 0 : extraMetadata.size()); + List selectedDotList = scatter.selectScatterData(applicationName, area, null, -1, newlimit); + List metadata = scatter.selectTransactionMetadata(parseSelectTransaction(selectedDotList)); + model.addAttribute("metadata", metadata); + } + } else { + final LimitedScanResult> limitedScanResult = flow.selectTraceIdsFromApplicationTraceIndex(applicationName, area, limit); + final List traceIdList = limitedScanResult.getScanData(); + logger.trace("submitted transactionId count={}", traceIdList.size()); + + // TODO sorted만 하는가? tree기반으로 레인지 체크하도록 하고 삭제하도록 하자. + SortedSet traceIdSet = new TreeSet(traceIdList); + logger.debug("unified traceIdSet size={}", traceIdSet.size()); + + List dots = scatter.selectScatterData(traceIdSet, applicationName, filterBuilder.build(filterText)); + } + + watch.stop(); + logger.info("Fetch scatterData time : {}ms", watch.getLastTaskTimeMillis()); + + return "transactionmetadata2"; + } + + private TransactionMetadataQuery parseSelectTransaction(List dotList) { + TransactionMetadataQuery query = new TransactionMetadataQuery(); + if (dotList == null) { + return query; + } + for (Dot dot : dotList) { + query.addQueryCondition(dot.getTransactionId(), dot.getAcceptedTime(), dot.getElapsedTime()); + } + logger.debug("query:{}", query); + return query; + } } \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentInfoDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentInfoDao.java index 527572381968..d68bc1ff4dca 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentInfoDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentInfoDao.java @@ -1,16 +1,16 @@ -package com.nhn.pinpoint.web.dao; - -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.web.vo.Range; - -import java.util.List; - -/** - * @author emeroad - */ -public interface AgentInfoDao { - @Deprecated - AgentInfoBo findAgentInfoBeforeStartTime(String agentId, long currentTime); - - List getAgentInfo(String agentId, Range range); -} +package com.nhn.pinpoint.web.dao; + +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.web.vo.Range; + +import java.util.List; + +/** + * @author emeroad + */ +public interface AgentInfoDao { + @Deprecated + AgentInfoBo findAgentInfoBeforeStartTime(String agentId, long currentTime); + + List getAgentInfo(String agentId, Range range); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentStatDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentStatDao.java index fbc1ff66f1a8..75cbc961f622 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentStatDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/AgentStatDao.java @@ -1,15 +1,15 @@ -package com.nhn.pinpoint.web.dao; - -import java.util.List; - -import com.nhn.pinpoint.web.vo.AgentStat; -import com.nhn.pinpoint.web.vo.Range; - -/** - * @author hyungil.jeong - */ -public interface AgentStatDao { - - List scanAgentStatList(String agentId, Range range); - -} +package com.nhn.pinpoint.web.dao; + +import java.util.List; + +import com.nhn.pinpoint.web.vo.AgentStat; +import com.nhn.pinpoint.web.vo.Range; + +/** + * @author hyungil.jeong + */ +public interface AgentStatDao { + + List scanAgentStatList(String agentId, Range range); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/AlarmResourceDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/AlarmResourceDao.java index c4ae34235bef..b57cf0103b63 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/AlarmResourceDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/AlarmResourceDao.java @@ -1,33 +1,33 @@ -package com.nhn.pinpoint.web.dao; - -import java.util.List; - -import com.nhn.pinpoint.web.alarm.vo.AlarmContactGroupResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmContactResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleGroupResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; - - -public interface AlarmResourceDao { - - int selectAlarmCount(); - - List selectAlarmList(); - - List selectAlarmRuleList(); - - List selectAlarmRuleGroupList(); - - void insertAlarmContact(AlarmContactResource resource); - List selectAlarmContactList(); - void updateAlarmCountact(AlarmContactResource resource); - void deleteAlarmCountact(AlarmContactResource resource); - - void insertAlarmContactGroup(AlarmContactGroupResource resource); - List selectAlarmContactGroupList(); - void updateAlarmContactGroup(AlarmContactGroupResource resource); - void deleteAlarmCountactGroup(AlarmContactGroupResource resource); - - -} +package com.nhn.pinpoint.web.dao; + +import java.util.List; + +import com.nhn.pinpoint.web.alarm.vo.AlarmContactGroupResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmContactResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleGroupResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; + + +public interface AlarmResourceDao { + + int selectAlarmCount(); + + List selectAlarmList(); + + List selectAlarmRuleList(); + + List selectAlarmRuleGroupList(); + + void insertAlarmContact(AlarmContactResource resource); + List selectAlarmContactList(); + void updateAlarmCountact(AlarmContactResource resource); + void deleteAlarmCountact(AlarmContactResource resource); + + void insertAlarmContactGroup(AlarmContactGroupResource resource); + List selectAlarmContactGroupList(); + void updateAlarmContactGroup(AlarmContactGroupResource resource); + void deleteAlarmCountactGroup(AlarmContactGroupResource resource); + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/ApiMetaDataDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/ApiMetaDataDao.java index 7019833f7efc..0569718fbca1 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/ApiMetaDataDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/ApiMetaDataDao.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.web.dao; - -import java.util.List; - -import com.nhn.pinpoint.common.bo.ApiMetaDataBo; - -/** - * @author emeroad - */ -public interface ApiMetaDataDao { - List getApiMetaData(String agentId, long time, int apiId); -} +package com.nhn.pinpoint.web.dao; + +import java.util.List; + +import com.nhn.pinpoint.common.bo.ApiMetaDataBo; + +/** + * @author emeroad + */ +public interface ApiMetaDataDao { + List getApiMetaData(String agentId, long time, int apiId); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/ApplicationTraceIndexDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/ApplicationTraceIndexDao.java index 24ad48ecca6f..eac86ce09d30 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/ApplicationTraceIndexDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/ApplicationTraceIndexDao.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.web.dao; - -import java.util.List; - -import com.nhn.pinpoint.web.vo.LimitedScanResult; -import com.nhn.pinpoint.web.vo.Range; -import com.nhn.pinpoint.web.vo.SelectedScatterArea; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.scatter.Dot; - -/** - * @author emeroad - * @author netspider - */ -public interface ApplicationTraceIndexDao { - - LimitedScanResult> scanTraceIndex(String applicationName, Range range, int limit); - - LimitedScanResult> scanTraceIndex(String applicationName, SelectedScatterArea range, int limit); - - List scanTraceScatter(String applicationName, Range range, int limit); - - /** - * scatter chart에서 선택한 영역에 속하는 transaction 조회 - * - * @param applicationName - * @param area - * @param offsetTransactionId - * @param offsetTransactionElapsed - * @param limit - * @return - */ - List scanTraceScatter(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit); -} +package com.nhn.pinpoint.web.dao; + +import java.util.List; + +import com.nhn.pinpoint.web.vo.LimitedScanResult; +import com.nhn.pinpoint.web.vo.Range; +import com.nhn.pinpoint.web.vo.SelectedScatterArea; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.scatter.Dot; + +/** + * @author emeroad + * @author netspider + */ +public interface ApplicationTraceIndexDao { + + LimitedScanResult> scanTraceIndex(String applicationName, Range range, int limit); + + LimitedScanResult> scanTraceIndex(String applicationName, SelectedScatterArea range, int limit); + + List scanTraceScatter(String applicationName, Range range, int limit); + + /** + * scatter chart에서 선택한 영역에 속하는 transaction 조회 + * + * @param applicationName + * @param area + * @param offsetTransactionId + * @param offsetTransactionElapsed + * @param limit + * @return + */ + List scanTraceScatter(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/SqlMetaDataDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/SqlMetaDataDao.java index 5ff44a4302f2..26c4ffbfff4d 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/SqlMetaDataDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/SqlMetaDataDao.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.web.dao; - -import com.nhn.pinpoint.common.bo.SqlMetaDataBo; - -import java.util.List; - -/** - * @author emeroad - */ -public interface SqlMetaDataDao { - List getSqlMetaData(String agentId, long time, int hashCode); -} +package com.nhn.pinpoint.web.dao; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; + +import java.util.List; + +/** + * @author emeroad + */ +public interface SqlMetaDataDao { + List getSqlMetaData(String agentId, long time, int hashCode); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/StringMetaDataDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/StringMetaDataDao.java index 402bbd80110d..fe9290208d06 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/StringMetaDataDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/StringMetaDataDao.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.web.dao; - -import com.nhn.pinpoint.common.bo.SqlMetaDataBo; -import com.nhn.pinpoint.common.bo.StringMetaDataBo; - -import java.util.List; - -/** - * @author emeroad - */ -public interface StringMetaDataDao { - List getStringMetaData(String agentId, long time, int stringId); -} +package com.nhn.pinpoint.web.dao; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import com.nhn.pinpoint.common.bo.StringMetaDataBo; + +import java.util.List; + +/** + * @author emeroad + */ +public interface StringMetaDataDao { + List getStringMetaData(String agentId, long time, int stringId); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/TraceDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/TraceDao.java index a031772f7a87..8b3e72d51440 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/TraceDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/TraceDao.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.web.dao; - - -import java.util.Collection; -import java.util.List; - -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.common.bo.SpanBo; - -/** - * @author emeroad - */ -public interface TraceDao { - - List selectSpan(TransactionId transactionId); - - List selectSpanAndAnnotation(TransactionId transactionId); - - List> selectSpans(List transactionIdList); - - List> selectAllSpans(Collection transactionIdList); - - List selectSpans(TransactionId transactionId); - -} +package com.nhn.pinpoint.web.dao; + + +import java.util.Collection; +import java.util.List; + +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.common.bo.SpanBo; + +/** + * @author emeroad + */ +public interface TraceDao { + + List selectSpan(TransactionId transactionId); + + List selectSpanAndAnnotation(TransactionId transactionId); + + List> selectSpans(List transactionIdList); + + List> selectAllSpans(Collection transactionIdList); + + List selectSpans(TransactionId transactionId); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java index 626a17f81593..027c8bae0d68 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java @@ -1,190 +1,190 @@ -package com.nhn.pinpoint.web.dao.hbase; - -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.RowKeyUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.mapper.AgentInfoMapper; -import com.nhn.pinpoint.web.vo.Range; -import org.apache.hadoop.hbase.client.*; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.hadoop.hbase.ResultsExtractor; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.web.dao.AgentInfoDao; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author emeroad - */ -@Repository -public class HbaseAgentInfoDao implements AgentInfoDao { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private HbaseOperations2 hbaseOperations2; - - private RowMapper> agentInfoMapper = new AgentInfoMapper(); - - /** - * agentId, startTime을 기반으로 유니크한 AgentInfo를 찾아낸다. - * @param agentId - * @param range - * @return - */ - @Override - public List getAgentInfo(final String agentId, final Range range) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - - - logger.debug("get agentInfo with, agentId={}, {}", agentId, range); - - Scan scan = new Scan(); - scan.setCaching(20); - - long fromTime = TimeUtils.reverseTimeMillis(range.getTo()); - long toTime = TimeUtils.reverseTimeMillis(1); - - byte[] agentIdBytes = Bytes.toBytes(agentId); - byte[] startKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, fromTime); - byte[] endKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, toTime); - - scan.setStartRow(startKeyBytes); - scan.setStopRow(endKeyBytes); - scan.addFamily(HBaseTables.AGENTINFO_CF_INFO); - - List found = hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new ResultsExtractor>() { - @Override - public List extractData(ResultScanner results) throws Exception { - final List result = new ArrayList(); - int found = 0; - for (Result next : results) { - found++; - byte[] row = next.getRow(); - long reverseStartTime = BytesUtils.bytesToLong(row, HBaseTables.AGENT_NAME_MAX_LEN); - long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime); - byte[] value = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER); - - logger.debug("found={}, {}, start={}", found, range, startTime); - - if (found > 1 && startTime <= range.getFrom()) { - logger.debug("stop finding agentInfo."); - break; - } - - final AgentInfoBo agentInfoBo = new AgentInfoBo(); - agentInfoBo.setAgentId(agentId); - agentInfoBo.setStartTime(startTime); - agentInfoBo.readValue(value); - - logger.debug("found agentInfoBo {}", agentInfoBo); - result.add(agentInfoBo); - } - logger.debug("extracted agentInfoBo {}", result); - return result; - } - }); - - logger.debug("get agentInfo result, {}", found); - - return found; - -// F 1382320380000 -// S 1382579080389 -// T 1382579580000 - -// F 1382557980000 -// S 1382579080389 -// T 1382579580000 - -// byte[] agentIdBytes = Bytes.toBytes(agentId); -// long reverseStartTime = TimeUtils.reverseTimeMillis(from); -// byte[] rowKey = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, reverseStartTime); -// -// Get get = new Get(rowKey); -// get.addFamily(HBaseTables.AGENTINFO_CF_INFO); -// -// List agentInfoBoList = hbaseOperations2.get(HBaseTables.AGENTINFO, get, agentInfoMapper); -// return agentInfoBoList; - } - - /** - * currentTime에서 가장 근접한 시간의 agent startTime을 find한다. - * - * @param agentId - * @param currentTime - * @return - */ - @Override - @Deprecated - public AgentInfoBo findAgentInfoBeforeStartTime(final String agentId, final long currentTime) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - - // TODO cache를 걸어야 될듯 하다. - Scan scan = createScan(agentId, currentTime); - AgentInfoBo agentInfoBo = hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new ResultsExtractor() { - @Override - public AgentInfoBo extractData(ResultScanner results) throws Exception { - for (Result next : results) { - byte[] row = next.getRow(); - long reverseStartTime = BytesUtils.bytesToLong(row, HBaseTables.AGENT_NAME_MAX_LEN); - long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime); - logger.debug("agent:{} startTime value {}", agentId, startTime); - // 바로 전 시작 시간을 찾아야 한다. - if (startTime < currentTime) { - byte[] value = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER); - AgentInfoBo agentInfoBo = new AgentInfoBo(); - agentInfoBo.setAgentId(agentId); - agentInfoBo.setStartTime(startTime); - agentInfoBo.readValue(value); - - logger.debug("agent:{} startTime find {}", agentId, startTime); - - return agentInfoBo; - } - } - - logger.warn("agentInfo not found. agentId={}, time={}", agentId, currentTime); - - return null; - } - }); - -// if (startTime == null) { -// return -1; -// } - return agentInfoBo; - } - - private Scan createScan(String agentInfo, long currentTime) { - Scan scan = new Scan(); - scan.setCaching(20); - - byte[] agentIdBytes = Bytes.toBytes(agentInfo); - long startTime = TimeUtils.reverseTimeMillis(currentTime); - byte[] startKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, startTime); - scan.setStartRow(startKeyBytes); - - byte[] endKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, Long.MAX_VALUE); - scan.setStopRow(endKeyBytes); - scan.addFamily(HBaseTables.AGENTINFO_CF_INFO); - - return scan; - } -} +package com.nhn.pinpoint.web.dao.hbase; + +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.RowKeyUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.mapper.AgentInfoMapper; +import com.nhn.pinpoint.web.vo.Range; +import org.apache.hadoop.hbase.client.*; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.hadoop.hbase.ResultsExtractor; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.web.dao.AgentInfoDao; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author emeroad + */ +@Repository +public class HbaseAgentInfoDao implements AgentInfoDao { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private HbaseOperations2 hbaseOperations2; + + private RowMapper> agentInfoMapper = new AgentInfoMapper(); + + /** + * agentId, startTime을 기반으로 유니크한 AgentInfo를 찾아낸다. + * @param agentId + * @param range + * @return + */ + @Override + public List getAgentInfo(final String agentId, final Range range) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + + + logger.debug("get agentInfo with, agentId={}, {}", agentId, range); + + Scan scan = new Scan(); + scan.setCaching(20); + + long fromTime = TimeUtils.reverseTimeMillis(range.getTo()); + long toTime = TimeUtils.reverseTimeMillis(1); + + byte[] agentIdBytes = Bytes.toBytes(agentId); + byte[] startKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, fromTime); + byte[] endKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, toTime); + + scan.setStartRow(startKeyBytes); + scan.setStopRow(endKeyBytes); + scan.addFamily(HBaseTables.AGENTINFO_CF_INFO); + + List found = hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new ResultsExtractor>() { + @Override + public List extractData(ResultScanner results) throws Exception { + final List result = new ArrayList(); + int found = 0; + for (Result next : results) { + found++; + byte[] row = next.getRow(); + long reverseStartTime = BytesUtils.bytesToLong(row, HBaseTables.AGENT_NAME_MAX_LEN); + long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime); + byte[] value = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER); + + logger.debug("found={}, {}, start={}", found, range, startTime); + + if (found > 1 && startTime <= range.getFrom()) { + logger.debug("stop finding agentInfo."); + break; + } + + final AgentInfoBo agentInfoBo = new AgentInfoBo(); + agentInfoBo.setAgentId(agentId); + agentInfoBo.setStartTime(startTime); + agentInfoBo.readValue(value); + + logger.debug("found agentInfoBo {}", agentInfoBo); + result.add(agentInfoBo); + } + logger.debug("extracted agentInfoBo {}", result); + return result; + } + }); + + logger.debug("get agentInfo result, {}", found); + + return found; + +// F 1382320380000 +// S 1382579080389 +// T 1382579580000 + +// F 1382557980000 +// S 1382579080389 +// T 1382579580000 + +// byte[] agentIdBytes = Bytes.toBytes(agentId); +// long reverseStartTime = TimeUtils.reverseTimeMillis(from); +// byte[] rowKey = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, reverseStartTime); +// +// Get get = new Get(rowKey); +// get.addFamily(HBaseTables.AGENTINFO_CF_INFO); +// +// List agentInfoBoList = hbaseOperations2.get(HBaseTables.AGENTINFO, get, agentInfoMapper); +// return agentInfoBoList; + } + + /** + * currentTime에서 가장 근접한 시간의 agent startTime을 find한다. + * + * @param agentId + * @param currentTime + * @return + */ + @Override + @Deprecated + public AgentInfoBo findAgentInfoBeforeStartTime(final String agentId, final long currentTime) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + + // TODO cache를 걸어야 될듯 하다. + Scan scan = createScan(agentId, currentTime); + AgentInfoBo agentInfoBo = hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new ResultsExtractor() { + @Override + public AgentInfoBo extractData(ResultScanner results) throws Exception { + for (Result next : results) { + byte[] row = next.getRow(); + long reverseStartTime = BytesUtils.bytesToLong(row, HBaseTables.AGENT_NAME_MAX_LEN); + long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime); + logger.debug("agent:{} startTime value {}", agentId, startTime); + // 바로 전 시작 시간을 찾아야 한다. + if (startTime < currentTime) { + byte[] value = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER); + AgentInfoBo agentInfoBo = new AgentInfoBo(); + agentInfoBo.setAgentId(agentId); + agentInfoBo.setStartTime(startTime); + agentInfoBo.readValue(value); + + logger.debug("agent:{} startTime find {}", agentId, startTime); + + return agentInfoBo; + } + } + + logger.warn("agentInfo not found. agentId={}, time={}", agentId, currentTime); + + return null; + } + }); + +// if (startTime == null) { +// return -1; +// } + return agentInfoBo; + } + + private Scan createScan(String agentInfo, long currentTime) { + Scan scan = new Scan(); + scan.setCaching(20); + + byte[] agentIdBytes = Bytes.toBytes(agentInfo); + long startTime = TimeUtils.reverseTimeMillis(currentTime); + byte[] startKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, startTime); + scan.setStartRow(startKeyBytes); + + byte[] endKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, Long.MAX_VALUE); + scan.setStopRow(endKeyBytes); + scan.addFamily(HBaseTables.AGENTINFO_CF_INFO); + + return scan; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentStatDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentStatDao.java index 86925ad1e81e..34840518e5ae 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentStatDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentStatDao.java @@ -1,144 +1,144 @@ -package com.nhn.pinpoint.web.dao.hbase; - -import static com.nhn.pinpoint.common.hbase.HBaseTables.AGENT_NAME_MAX_LEN; - -import java.util.ArrayList; -import java.util.List; - -import com.nhn.pinpoint.web.vo.AgentStat; -import com.nhn.pinpoint.web.vo.Range; - -import org.apache.hadoop.hbase.client.Scan; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.RowKeyUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.dao.AgentStatDao; -import com.sematext.hbase.wd.AbstractRowKeyDistributor; - -/** - * @author emeroad - * @author hyungil.jeong - */ -@Repository -public class HbaseAgentStatDao implements AgentStatDao { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private HbaseOperations2 hbaseOperations2; - - @Autowired - @Qualifier("agentStatMapper") - private RowMapper> agentStatMapper; - - @Autowired - @Qualifier("agentStatRowKeyDistributor") - private AbstractRowKeyDistributor rowKeyDistributor; - - private int scanCacheSize = 256; - - public void setScanCacheSize(int scanCacheSize) { - this.scanCacheSize = scanCacheSize; - } - - public List scanAgentStatList(String agentId, Range range) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - - if (logger.isDebugEnabled()) { - logger.debug("scanAgentStat : agentId={}, {}", agentId, range); - } - - - Scan scan = createScan(agentId, range); - - List> intermediate = hbaseOperations2.find(HBaseTables.AGENT_STAT, scan, rowKeyDistributor, agentStatMapper); - - int expectedSize = (int)(range.getRange() / 5000); // 5초간 데이터 - List merged = new ArrayList(expectedSize); - - for(List each : intermediate) { - merged.addAll(each); - } - - return merged; - } - - /** - * timestamp 기반의 row key를 만든다. - * FIXME collector에 있는 DAO에도 동일한 코드가 중복되어 있으니 참고. - */ - private byte[] getRowKey(String agentId, long timestamp) { - if (agentId == null) { - throw new IllegalArgumentException("agentId must not null"); - } - byte[] bAgentId = BytesUtils.toBytes(agentId); - return RowKeyUtils.concatFixedByteAndLong(bAgentId, AGENT_NAME_MAX_LEN, TimeUtils.reverseTimeMillis(timestamp)); - } - - private Scan createScan(String agentId, Range range) { - Scan scan = new Scan(); - scan.setCaching(this.scanCacheSize); - - byte[] startKey = getRowKey(agentId, range.getFrom()); - byte[] endKey = getRowKey(agentId, range.getTo()); - - // key가 reverse되었기 떄문에 start, end가 뒤바뀌게 된다. - scan.setStartRow(endKey); - scan.setStopRow(startKey); - - // scan.addColumn(HBaseTables.AGENT_STAT_CF_STATISTICS, HBaseTables.AGENT_STAT_CF_STATISTICS_V1); - scan.addFamily(HBaseTables.AGENT_STAT_CF_STATISTICS); - scan.setId("AgentStatScan"); - - // json으로 변화해서 로그를 찍어서. 최초 변환 속도가 느림. - logger.debug("create scan:{}", scan); - return scan; - } - - // public List scanAgentStatList(String agentId, long start, long end, final int limit) { - // if (logger.isDebugEnabled()) { - // logger.debug("scanAgentStatList"); - // } - // Scan scan = createScan(agentId, start, end); - // - // List list = hbaseOperations2.find(HBaseTables.AGENT_STAT, scan, rowKeyDistributor, new ResultsExtractor>() { - // @Override - // public List extractData(ResultScanner results) throws Exception { - // TDeserializer deserializer = new TDeserializer(); - // List list = new ArrayList(); - // for (Result result : results) { - // if (result == null) { - // continue; - // } - // - // if (list.size() >= limit) { - // break; - // } - // - // for (KeyValue kv : result.raw()) { - // AgentStat agentStat = new AgentStat(); - // deserializer.deserialize(agentStat, kv.getBuffer()); - // list.add(agentStat); - // } - // } - // return list; - // } - // }); - // return list; - // } - -} +package com.nhn.pinpoint.web.dao.hbase; + +import static com.nhn.pinpoint.common.hbase.HBaseTables.AGENT_NAME_MAX_LEN; + +import java.util.ArrayList; +import java.util.List; + +import com.nhn.pinpoint.web.vo.AgentStat; +import com.nhn.pinpoint.web.vo.Range; + +import org.apache.hadoop.hbase.client.Scan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.RowKeyUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.dao.AgentStatDao; +import com.sematext.hbase.wd.AbstractRowKeyDistributor; + +/** + * @author emeroad + * @author hyungil.jeong + */ +@Repository +public class HbaseAgentStatDao implements AgentStatDao { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private HbaseOperations2 hbaseOperations2; + + @Autowired + @Qualifier("agentStatMapper") + private RowMapper> agentStatMapper; + + @Autowired + @Qualifier("agentStatRowKeyDistributor") + private AbstractRowKeyDistributor rowKeyDistributor; + + private int scanCacheSize = 256; + + public void setScanCacheSize(int scanCacheSize) { + this.scanCacheSize = scanCacheSize; + } + + public List scanAgentStatList(String agentId, Range range) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + + if (logger.isDebugEnabled()) { + logger.debug("scanAgentStat : agentId={}, {}", agentId, range); + } + + + Scan scan = createScan(agentId, range); + + List> intermediate = hbaseOperations2.find(HBaseTables.AGENT_STAT, scan, rowKeyDistributor, agentStatMapper); + + int expectedSize = (int)(range.getRange() / 5000); // 5초간 데이터 + List merged = new ArrayList(expectedSize); + + for(List each : intermediate) { + merged.addAll(each); + } + + return merged; + } + + /** + * timestamp 기반의 row key를 만든다. + * FIXME collector에 있는 DAO에도 동일한 코드가 중복되어 있으니 참고. + */ + private byte[] getRowKey(String agentId, long timestamp) { + if (agentId == null) { + throw new IllegalArgumentException("agentId must not null"); + } + byte[] bAgentId = BytesUtils.toBytes(agentId); + return RowKeyUtils.concatFixedByteAndLong(bAgentId, AGENT_NAME_MAX_LEN, TimeUtils.reverseTimeMillis(timestamp)); + } + + private Scan createScan(String agentId, Range range) { + Scan scan = new Scan(); + scan.setCaching(this.scanCacheSize); + + byte[] startKey = getRowKey(agentId, range.getFrom()); + byte[] endKey = getRowKey(agentId, range.getTo()); + + // key가 reverse되었기 떄문에 start, end가 뒤바뀌게 된다. + scan.setStartRow(endKey); + scan.setStopRow(startKey); + + // scan.addColumn(HBaseTables.AGENT_STAT_CF_STATISTICS, HBaseTables.AGENT_STAT_CF_STATISTICS_V1); + scan.addFamily(HBaseTables.AGENT_STAT_CF_STATISTICS); + scan.setId("AgentStatScan"); + + // json으로 변화해서 로그를 찍어서. 최초 변환 속도가 느림. + logger.debug("create scan:{}", scan); + return scan; + } + + // public List scanAgentStatList(String agentId, long start, long end, final int limit) { + // if (logger.isDebugEnabled()) { + // logger.debug("scanAgentStatList"); + // } + // Scan scan = createScan(agentId, start, end); + // + // List list = hbaseOperations2.find(HBaseTables.AGENT_STAT, scan, rowKeyDistributor, new ResultsExtractor>() { + // @Override + // public List extractData(ResultScanner results) throws Exception { + // TDeserializer deserializer = new TDeserializer(); + // List list = new ArrayList(); + // for (Result result : results) { + // if (result == null) { + // continue; + // } + // + // if (list.size() >= limit) { + // break; + // } + // + // for (KeyValue kv : result.raw()) { + // AgentStat agentStat = new AgentStat(); + // deserializer.deserialize(agentStat, kv.getBuffer()); + // list.add(agentStat); + // } + // } + // return list; + // } + // }); + // return list; + // } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApiMetaDataDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApiMetaDataDao.java index cf28adcdcd27..c5dae7216a58 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApiMetaDataDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApiMetaDataDao.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.web.dao.hbase; - -import java.util.List; - -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.client.Get; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.web.dao.ApiMetaDataDao; -import com.nhn.pinpoint.common.bo.ApiMetaDataBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; - -/** - * @author emeroad - */ -@Repository -public class HbaseApiMetaDataDao implements ApiMetaDataDao { - - @Autowired - private HbaseOperations2 hbaseOperations2; - - @Autowired - @Qualifier("apiMetaDataMapper") - private RowMapper> apiMetaDataMapper; - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public List getApiMetaData(String agentId, long time, int apiId) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - - ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo(agentId, time, apiId); - byte[] sqlId = getDistributedKey(apiMetaDataBo.toRowKey()); - Get get = new Get(sqlId); - get.addFamily(HBaseTables.API_METADATA_CF_API); - - return hbaseOperations2.get(HBaseTables.API_METADATA, get, apiMetaDataMapper); - } - - private byte[] getDistributedKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); - } -} +package com.nhn.pinpoint.web.dao.hbase; + +import java.util.List; + +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.client.Get; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.web.dao.ApiMetaDataDao; +import com.nhn.pinpoint.common.bo.ApiMetaDataBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; + +/** + * @author emeroad + */ +@Repository +public class HbaseApiMetaDataDao implements ApiMetaDataDao { + + @Autowired + private HbaseOperations2 hbaseOperations2; + + @Autowired + @Qualifier("apiMetaDataMapper") + private RowMapper> apiMetaDataMapper; + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public List getApiMetaData(String agentId, long time, int apiId) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + + ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo(agentId, time, apiId); + byte[] sqlId = getDistributedKey(apiMetaDataBo.toRowKey()); + Get get = new Get(sqlId); + get.addFamily(HBaseTables.API_METADATA_CF_API); + + return hbaseOperations2.get(HBaseTables.API_METADATA, get, apiMetaDataMapper); + } + + private byte[] getDistributedKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java index 05eb7442fa13..e3ded522f63e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java @@ -1,304 +1,304 @@ -package com.nhn.pinpoint.web.dao.hbase; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.client.Scan; -import org.apache.hadoop.hbase.filter.BinaryPrefixComparator; -import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; -import org.apache.hadoop.hbase.filter.Filter; -import org.apache.hadoop.hbase.filter.FilterList; -import org.apache.hadoop.hbase.filter.FilterList.Operator; -import org.apache.hadoop.hbase.filter.QualifierFilter; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.common.PinpointConstants; -import com.nhn.pinpoint.common.buffer.AutomaticBuffer; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.common.hbase.LimitEventHandler; -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.DateUtils; -import com.nhn.pinpoint.common.util.SpanUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.dao.ApplicationTraceIndexDao; -import com.nhn.pinpoint.web.mapper.TraceIndexScatterMapper2; -import com.nhn.pinpoint.web.mapper.TransactionIdMapper; -import com.nhn.pinpoint.web.vo.LimitedScanResult; -import com.nhn.pinpoint.web.vo.Range; -import com.nhn.pinpoint.web.vo.ResponseTimeRange; -import com.nhn.pinpoint.web.vo.SelectedScatterArea; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.scatter.Dot; -import com.sematext.hbase.wd.AbstractRowKeyDistributor; - -/** - * @author emeroad - * @author netspider - */ -@Repository -public class HbaseApplicationTraceIndexDao implements ApplicationTraceIndexDao { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private HbaseOperations2 hbaseOperations2; - - @Autowired - @Qualifier("transactionIdMapper") - private RowMapper> traceIndexMapper; - - @Autowired - @Qualifier("traceIndexScatterMapper") - private RowMapper> traceIndexScatterMapper; - - @Autowired - @Qualifier("applicationTraceIndexDistributor") - private AbstractRowKeyDistributor traceIdRowKeyDistributor; - - private int scanCacheSize = 256; - - public void setScanCacheSize(int scanCacheSize) { - this.scanCacheSize = scanCacheSize; - } - - @Override - public LimitedScanResult> scanTraceIndex(final String applicationName, Range range, int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - if (limit < 0) { - throw new IllegalArgumentException("negative limit:" + limit); - } - logger.debug("scanTraceIndex"); - Scan scan = createScan(applicationName, range); - - final LimitedScanResult> limitedScanResult = new LimitedScanResult>(); - LastRowAccessor lastRowAccessor = new LastRowAccessor(); - List> traceIndexList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, - scan, traceIdRowKeyDistributor, limit, traceIndexMapper, lastRowAccessor); - - List transactionIdSum = new ArrayList(128); - for(List transactionId: traceIndexList) { - transactionIdSum.addAll(transactionId); - } - limitedScanResult.setScanData(transactionIdSum); - - if (transactionIdSum.size() >= limit) { - Long lastRowTimestamp = lastRowAccessor.getLastRowTimestamp(); - limitedScanResult.setLimitedTime(lastRowTimestamp); - if (logger.isDebugEnabled()) { - logger.debug("lastRowTimestamp lastTime:{}", DateUtils.longToDateStr(lastRowTimestamp)); - } - } else { - if (logger.isDebugEnabled()) { - logger.debug("scanner start lastTime:{}", DateUtils.longToDateStr(range.getFrom())); - } - limitedScanResult.setLimitedTime(range.getFrom()); - } - - return limitedScanResult; - } - - @Override - public LimitedScanResult> scanTraceIndex(final String applicationName, SelectedScatterArea area, int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (area == null) { - throw new NullPointerException("area must not be null"); - } - if (limit < 0) { - throw new IllegalArgumentException("negative limit:" + limit); - } - logger.debug("scanTraceIndex"); - Scan scan = createScan(applicationName, area.getTimeRange()); - - final LimitedScanResult> limitedScanResult = new LimitedScanResult>(); - LastRowAccessor lastRowAccessor = new LastRowAccessor(); - List> traceIndexList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, - scan, traceIdRowKeyDistributor, limit, traceIndexMapper, lastRowAccessor); - - List transactionIdSum = new ArrayList(128); - for(List transactionId: traceIndexList) { - transactionIdSum.addAll(transactionId); - } - limitedScanResult.setScanData(transactionIdSum); - - if (transactionIdSum.size() >= limit) { - Long lastRowTimestamp = lastRowAccessor.getLastRowTimestamp(); - limitedScanResult.setLimitedTime(lastRowTimestamp); - if (logger.isDebugEnabled()) { - logger.debug("lastRowTimestamp lastTime:{}", DateUtils.longToDateStr(lastRowTimestamp)); - } - } else { - if (logger.isDebugEnabled()) { - logger.debug("scanner start lastTime:{}", DateUtils.longToDateStr(area.getTimeRange().getFrom())); - } - limitedScanResult.setLimitedTime(area.getTimeRange().getFrom()); - } - - return limitedScanResult; - } - - private class LastRowAccessor implements LimitEventHandler { - private Long lastRowTimestamp = -1L; - private TransactionId lastTransactionId = null; - private int lastTransactionElapsed = -1; - - @Override - public void handleLastResult(Result lastResult) { - if (lastResult == null) { - return; - } - KeyValue[] keyValueArray = lastResult.raw(); - KeyValue last = keyValueArray[keyValueArray.length - 1]; - byte[] row = last.getRow(); - byte[] originalRow = traceIdRowKeyDistributor.getOriginalKey(row); - long reverseStartTime = BytesUtils.bytesToLong(originalRow, PinpointConstants.APPLICATION_NAME_MAX_LEN); - this.lastRowTimestamp = TimeUtils.recoveryTimeMillis(reverseStartTime); - - byte[] qualifier = last.getQualifier(); - this.lastTransactionId = TransactionIdMapper.parseVarTransactionId(qualifier, 0); - this.lastTransactionElapsed = BytesUtils.bytesToInt(qualifier, 0); - - if (logger.isDebugEnabled()) { - logger.debug("lastRowTimestamp={}, lastTransactionId={}, lastTransactionElapsed={}", DateUtils.longToDateStr(lastRowTimestamp), lastTransactionId, lastTransactionElapsed); - } - } - - private Long getLastRowTimestamp() { - return lastRowTimestamp; - } - - public TransactionId getLastTransactionId() { - return lastTransactionId; - } - - public int getLastTransactionElapsed() { - return lastTransactionElapsed; - } - } - - private Scan createScan(String applicationName, Range range) { - Scan scan = new Scan(); - scan.setCaching(this.scanCacheSize); - - byte[] bAgent = Bytes.toBytes(applicationName); - byte[] traceIndexStartKey = SpanUtils.getTraceIndexRowKey(bAgent, range.getFrom()); - byte[] traceIndexEndKey = SpanUtils.getTraceIndexRowKey(bAgent, range.getTo()); - - // key가 reverse되었기 떄문에 start, end가 뒤바뀌게 된다. - scan.setStartRow(traceIndexEndKey); - scan.setStopRow(traceIndexStartKey); - - scan.addFamily(HBaseTables.APPLICATION_TRACE_INDEX_CF_TRACE); - scan.setId("ApplicationTraceIndexScan"); - - // json으로 변화해서 로그를 찍어서. 최초 변환 속도가 느림. - logger.trace("create scan:{}", scan); - return scan; - } - - @Override - public List scanTraceScatter(String applicationName, Range range, final int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - if (limit < 0) { - throw new IllegalArgumentException("negative limit:" + limit); - } - logger.debug("scanTraceScatter"); - Scan scan = createScan(applicationName, range); - - List> dotListList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, scan, traceIdRowKeyDistributor, limit, traceIndexScatterMapper); - List mergeList = new ArrayList(limit + 10); - for(List dotList : dotListList) { - mergeList.addAll(dotList); - } - return mergeList; - } - - /** - * - */ - @Override - public List scanTraceScatter(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (area == null) { - throw new NullPointerException("range must not be null"); - } - if (limit < 0) { - throw new IllegalArgumentException("negative limit:" + limit); - } - logger.debug("scanTraceScatter"); - Scan scan = createScan(applicationName, area.getTimeRange()); - - // method 1 - // 아직 사용하지 않음. 대신 row mapper를 다른것을 사용. (테스트.) - // scan.setFilter(makeResponseTimeFilter(area, offsetTransactionId, offsetTransactionElapsed)); - - // method 2 - ResponseTimeRange responseTimeRange = area.getResponseTimeRange(); - TraceIndexScatterMapper2 mapper = new TraceIndexScatterMapper2(responseTimeRange.getFrom(), responseTimeRange.getTo()); - - List> dotListList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, scan, traceIdRowKeyDistributor, limit, mapper); - - List result = new ArrayList(); - for(List dotList : dotListList) { - result.addAll(dotList); - } - - return result; - } - - /** - * scatter chart에 속하는 트랜잭션을 구하기위해 선택된 y축영역(response time) 내에 속하는 값을 필터하기 위한 - * hbase filter를 생성한다. 이 필터를 사용하려면 column qualifier의 prefix로 elapsed time 4byte를 - * 붙여두어야 한다. - * - * @param area - * @param offsetTransactionId - * @param offsetTransactionElapsed - * @return - */ - private Filter makeResponseTimeFilter(final SelectedScatterArea area, final TransactionId offsetTransactionId, int offsetTransactionElapsed) { - // filter by response time - ResponseTimeRange responseTimeRange = area.getResponseTimeRange(); - byte[] responseFrom = Bytes.toBytes(responseTimeRange.getFrom()); - byte[] responseTo = Bytes.toBytes(responseTimeRange.getTo()); - FilterList filterList = new FilterList(Operator.MUST_PASS_ALL); - filterList.addFilter(new QualifierFilter(CompareOp.GREATER_OR_EQUAL, new BinaryPrefixComparator(responseFrom))); - filterList.addFilter(new QualifierFilter(CompareOp.LESS_OR_EQUAL, new BinaryPrefixComparator(responseTo))); - - // add offset - if (offsetTransactionId != null) { - final Buffer buffer = new AutomaticBuffer(32); - buffer.put(offsetTransactionElapsed); - buffer.putPrefixedString(offsetTransactionId.getAgentId()); - buffer.putSVar(offsetTransactionId.getAgentStartTime()); - buffer.putVar(offsetTransactionId.getTransactionSequence()); - byte[] qualifierOffset = buffer.getBuffer(); - - filterList.addFilter(new QualifierFilter(CompareOp.GREATER, new BinaryPrefixComparator(qualifierOffset))); - } - return filterList; - } -} +package com.nhn.pinpoint.web.dao.hbase; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.filter.BinaryPrefixComparator; +import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.FilterList; +import org.apache.hadoop.hbase.filter.FilterList.Operator; +import org.apache.hadoop.hbase.filter.QualifierFilter; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.common.PinpointConstants; +import com.nhn.pinpoint.common.buffer.AutomaticBuffer; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.common.hbase.LimitEventHandler; +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.DateUtils; +import com.nhn.pinpoint.common.util.SpanUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.dao.ApplicationTraceIndexDao; +import com.nhn.pinpoint.web.mapper.TraceIndexScatterMapper2; +import com.nhn.pinpoint.web.mapper.TransactionIdMapper; +import com.nhn.pinpoint.web.vo.LimitedScanResult; +import com.nhn.pinpoint.web.vo.Range; +import com.nhn.pinpoint.web.vo.ResponseTimeRange; +import com.nhn.pinpoint.web.vo.SelectedScatterArea; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.scatter.Dot; +import com.sematext.hbase.wd.AbstractRowKeyDistributor; + +/** + * @author emeroad + * @author netspider + */ +@Repository +public class HbaseApplicationTraceIndexDao implements ApplicationTraceIndexDao { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private HbaseOperations2 hbaseOperations2; + + @Autowired + @Qualifier("transactionIdMapper") + private RowMapper> traceIndexMapper; + + @Autowired + @Qualifier("traceIndexScatterMapper") + private RowMapper> traceIndexScatterMapper; + + @Autowired + @Qualifier("applicationTraceIndexDistributor") + private AbstractRowKeyDistributor traceIdRowKeyDistributor; + + private int scanCacheSize = 256; + + public void setScanCacheSize(int scanCacheSize) { + this.scanCacheSize = scanCacheSize; + } + + @Override + public LimitedScanResult> scanTraceIndex(final String applicationName, Range range, int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + if (limit < 0) { + throw new IllegalArgumentException("negative limit:" + limit); + } + logger.debug("scanTraceIndex"); + Scan scan = createScan(applicationName, range); + + final LimitedScanResult> limitedScanResult = new LimitedScanResult>(); + LastRowAccessor lastRowAccessor = new LastRowAccessor(); + List> traceIndexList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, + scan, traceIdRowKeyDistributor, limit, traceIndexMapper, lastRowAccessor); + + List transactionIdSum = new ArrayList(128); + for(List transactionId: traceIndexList) { + transactionIdSum.addAll(transactionId); + } + limitedScanResult.setScanData(transactionIdSum); + + if (transactionIdSum.size() >= limit) { + Long lastRowTimestamp = lastRowAccessor.getLastRowTimestamp(); + limitedScanResult.setLimitedTime(lastRowTimestamp); + if (logger.isDebugEnabled()) { + logger.debug("lastRowTimestamp lastTime:{}", DateUtils.longToDateStr(lastRowTimestamp)); + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("scanner start lastTime:{}", DateUtils.longToDateStr(range.getFrom())); + } + limitedScanResult.setLimitedTime(range.getFrom()); + } + + return limitedScanResult; + } + + @Override + public LimitedScanResult> scanTraceIndex(final String applicationName, SelectedScatterArea area, int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (area == null) { + throw new NullPointerException("area must not be null"); + } + if (limit < 0) { + throw new IllegalArgumentException("negative limit:" + limit); + } + logger.debug("scanTraceIndex"); + Scan scan = createScan(applicationName, area.getTimeRange()); + + final LimitedScanResult> limitedScanResult = new LimitedScanResult>(); + LastRowAccessor lastRowAccessor = new LastRowAccessor(); + List> traceIndexList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, + scan, traceIdRowKeyDistributor, limit, traceIndexMapper, lastRowAccessor); + + List transactionIdSum = new ArrayList(128); + for(List transactionId: traceIndexList) { + transactionIdSum.addAll(transactionId); + } + limitedScanResult.setScanData(transactionIdSum); + + if (transactionIdSum.size() >= limit) { + Long lastRowTimestamp = lastRowAccessor.getLastRowTimestamp(); + limitedScanResult.setLimitedTime(lastRowTimestamp); + if (logger.isDebugEnabled()) { + logger.debug("lastRowTimestamp lastTime:{}", DateUtils.longToDateStr(lastRowTimestamp)); + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("scanner start lastTime:{}", DateUtils.longToDateStr(area.getTimeRange().getFrom())); + } + limitedScanResult.setLimitedTime(area.getTimeRange().getFrom()); + } + + return limitedScanResult; + } + + private class LastRowAccessor implements LimitEventHandler { + private Long lastRowTimestamp = -1L; + private TransactionId lastTransactionId = null; + private int lastTransactionElapsed = -1; + + @Override + public void handleLastResult(Result lastResult) { + if (lastResult == null) { + return; + } + KeyValue[] keyValueArray = lastResult.raw(); + KeyValue last = keyValueArray[keyValueArray.length - 1]; + byte[] row = last.getRow(); + byte[] originalRow = traceIdRowKeyDistributor.getOriginalKey(row); + long reverseStartTime = BytesUtils.bytesToLong(originalRow, PinpointConstants.APPLICATION_NAME_MAX_LEN); + this.lastRowTimestamp = TimeUtils.recoveryTimeMillis(reverseStartTime); + + byte[] qualifier = last.getQualifier(); + this.lastTransactionId = TransactionIdMapper.parseVarTransactionId(qualifier, 0); + this.lastTransactionElapsed = BytesUtils.bytesToInt(qualifier, 0); + + if (logger.isDebugEnabled()) { + logger.debug("lastRowTimestamp={}, lastTransactionId={}, lastTransactionElapsed={}", DateUtils.longToDateStr(lastRowTimestamp), lastTransactionId, lastTransactionElapsed); + } + } + + private Long getLastRowTimestamp() { + return lastRowTimestamp; + } + + public TransactionId getLastTransactionId() { + return lastTransactionId; + } + + public int getLastTransactionElapsed() { + return lastTransactionElapsed; + } + } + + private Scan createScan(String applicationName, Range range) { + Scan scan = new Scan(); + scan.setCaching(this.scanCacheSize); + + byte[] bAgent = Bytes.toBytes(applicationName); + byte[] traceIndexStartKey = SpanUtils.getTraceIndexRowKey(bAgent, range.getFrom()); + byte[] traceIndexEndKey = SpanUtils.getTraceIndexRowKey(bAgent, range.getTo()); + + // key가 reverse되었기 떄문에 start, end가 뒤바뀌게 된다. + scan.setStartRow(traceIndexEndKey); + scan.setStopRow(traceIndexStartKey); + + scan.addFamily(HBaseTables.APPLICATION_TRACE_INDEX_CF_TRACE); + scan.setId("ApplicationTraceIndexScan"); + + // json으로 변화해서 로그를 찍어서. 최초 변환 속도가 느림. + logger.trace("create scan:{}", scan); + return scan; + } + + @Override + public List scanTraceScatter(String applicationName, Range range, final int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + if (limit < 0) { + throw new IllegalArgumentException("negative limit:" + limit); + } + logger.debug("scanTraceScatter"); + Scan scan = createScan(applicationName, range); + + List> dotListList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, scan, traceIdRowKeyDistributor, limit, traceIndexScatterMapper); + List mergeList = new ArrayList(limit + 10); + for(List dotList : dotListList) { + mergeList.addAll(dotList); + } + return mergeList; + } + + /** + * + */ + @Override + public List scanTraceScatter(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (area == null) { + throw new NullPointerException("range must not be null"); + } + if (limit < 0) { + throw new IllegalArgumentException("negative limit:" + limit); + } + logger.debug("scanTraceScatter"); + Scan scan = createScan(applicationName, area.getTimeRange()); + + // method 1 + // 아직 사용하지 않음. 대신 row mapper를 다른것을 사용. (테스트.) + // scan.setFilter(makeResponseTimeFilter(area, offsetTransactionId, offsetTransactionElapsed)); + + // method 2 + ResponseTimeRange responseTimeRange = area.getResponseTimeRange(); + TraceIndexScatterMapper2 mapper = new TraceIndexScatterMapper2(responseTimeRange.getFrom(), responseTimeRange.getTo()); + + List> dotListList = hbaseOperations2.find(HBaseTables.APPLICATION_TRACE_INDEX, scan, traceIdRowKeyDistributor, limit, mapper); + + List result = new ArrayList(); + for(List dotList : dotListList) { + result.addAll(dotList); + } + + return result; + } + + /** + * scatter chart에 속하는 트랜잭션을 구하기위해 선택된 y축영역(response time) 내에 속하는 값을 필터하기 위한 + * hbase filter를 생성한다. 이 필터를 사용하려면 column qualifier의 prefix로 elapsed time 4byte를 + * 붙여두어야 한다. + * + * @param area + * @param offsetTransactionId + * @param offsetTransactionElapsed + * @return + */ + private Filter makeResponseTimeFilter(final SelectedScatterArea area, final TransactionId offsetTransactionId, int offsetTransactionElapsed) { + // filter by response time + ResponseTimeRange responseTimeRange = area.getResponseTimeRange(); + byte[] responseFrom = Bytes.toBytes(responseTimeRange.getFrom()); + byte[] responseTo = Bytes.toBytes(responseTimeRange.getTo()); + FilterList filterList = new FilterList(Operator.MUST_PASS_ALL); + filterList.addFilter(new QualifierFilter(CompareOp.GREATER_OR_EQUAL, new BinaryPrefixComparator(responseFrom))); + filterList.addFilter(new QualifierFilter(CompareOp.LESS_OR_EQUAL, new BinaryPrefixComparator(responseTo))); + + // add offset + if (offsetTransactionId != null) { + final Buffer buffer = new AutomaticBuffer(32); + buffer.put(offsetTransactionElapsed); + buffer.putPrefixedString(offsetTransactionId.getAgentId()); + buffer.putSVar(offsetTransactionId.getAgentStartTime()); + buffer.putVar(offsetTransactionId.getTransactionSequence()); + byte[] qualifierOffset = buffer.getBuffer(); + + filterList.addFilter(new QualifierFilter(CompareOp.GREATER, new BinaryPrefixComparator(qualifierOffset))); + } + return filterList; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseSqlMetaDataDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseSqlMetaDataDao.java index d41d22e77542..9aa5c523c92a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseSqlMetaDataDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseSqlMetaDataDao.java @@ -1,52 +1,52 @@ -package com.nhn.pinpoint.web.dao.hbase; - -import java.util.List; - -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.client.Get; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.web.dao.SqlMetaDataDao; -import com.nhn.pinpoint.common.bo.SqlMetaDataBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; - -/** - * @author emeroad - */ -@Repository -public class HbaseSqlMetaDataDao implements SqlMetaDataDao { - - @Autowired - private HbaseOperations2 hbaseOperations2; - - @Autowired - @Qualifier("sqlMetaDataMapper") - private RowMapper> sqlMetaDataMapper; - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public List getSqlMetaData(String agentId, long time, int hashCode) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - - SqlMetaDataBo sqlMetaData = new SqlMetaDataBo(agentId, time, hashCode); - byte[] sqlId = getDistributedKey(sqlMetaData.toRowKey()); - - Get get = new Get(sqlId); - get.addFamily(HBaseTables.SQL_METADATA_CF_SQL); - - return hbaseOperations2.get(HBaseTables.SQL_METADATA, get, sqlMetaDataMapper); - } - - private byte[] getDistributedKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); - } -} +package com.nhn.pinpoint.web.dao.hbase; + +import java.util.List; + +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.client.Get; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.web.dao.SqlMetaDataDao; +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; + +/** + * @author emeroad + */ +@Repository +public class HbaseSqlMetaDataDao implements SqlMetaDataDao { + + @Autowired + private HbaseOperations2 hbaseOperations2; + + @Autowired + @Qualifier("sqlMetaDataMapper") + private RowMapper> sqlMetaDataMapper; + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public List getSqlMetaData(String agentId, long time, int hashCode) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + + SqlMetaDataBo sqlMetaData = new SqlMetaDataBo(agentId, time, hashCode); + byte[] sqlId = getDistributedKey(sqlMetaData.toRowKey()); + + Get get = new Get(sqlId); + get.addFamily(HBaseTables.SQL_METADATA_CF_SQL); + + return hbaseOperations2.get(HBaseTables.SQL_METADATA, get, sqlMetaDataMapper); + } + + private byte[] getDistributedKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseStringMetaDataDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseStringMetaDataDao.java index 9494a10b8805..1e593b5137f7 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseStringMetaDataDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseStringMetaDataDao.java @@ -1,51 +1,51 @@ -package com.nhn.pinpoint.web.dao.hbase; - -import com.nhn.pinpoint.common.bo.StringMetaDataBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; -import com.nhn.pinpoint.web.dao.StringMetaDataDao; -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.client.Get; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import java.util.List; - -/** - * @author emeroad - */ -@Repository -public class HbaseStringMetaDataDao implements StringMetaDataDao { - - @Autowired - private HbaseOperations2 hbaseOperations2; - - @Autowired - @Qualifier("stringMetaDataMapper") - private RowMapper> stringMetaDataMapper; - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public List getStringMetaData(String agentId, long time, int stringId) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - - StringMetaDataBo stringMetaData = new StringMetaDataBo(agentId, time, stringId); - byte[] rowKey = getDistributedKey(stringMetaData.toRowKey()); - - Get get = new Get(rowKey); - get.addFamily(HBaseTables.STRING_METADATA_CF_STR); - - return hbaseOperations2.get(HBaseTables.STRING_METADATA, get, stringMetaDataMapper); - } - - private byte[] getDistributedKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); - } -} +package com.nhn.pinpoint.web.dao.hbase; + +import com.nhn.pinpoint.common.bo.StringMetaDataBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.web.dao.StringMetaDataDao; +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.client.Get; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @author emeroad + */ +@Repository +public class HbaseStringMetaDataDao implements StringMetaDataDao { + + @Autowired + private HbaseOperations2 hbaseOperations2; + + @Autowired + @Qualifier("stringMetaDataMapper") + private RowMapper> stringMetaDataMapper; + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public List getStringMetaData(String agentId, long time, int stringId) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + + StringMetaDataBo stringMetaData = new StringMetaDataBo(agentId, time, stringId); + byte[] rowKey = getDistributedKey(stringMetaData.toRowKey()); + + Get get = new Get(rowKey); + get.addFamily(HBaseTables.STRING_METADATA_CF_STR); + + return hbaseOperations2.get(HBaseTables.STRING_METADATA, get, stringMetaDataMapper); + } + + private byte[] getDistributedKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getDistributedKey(rowKey); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseTraceDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseTraceDao.java index 60344ac9830a..6df5e80afb0f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseTraceDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseTraceDao.java @@ -1,111 +1,111 @@ -package com.nhn.pinpoint.web.dao.hbase; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.nhn.pinpoint.web.vo.TransactionId; -import com.sematext.hbase.wd.AbstractRowKeyDistributor; -import org.apache.hadoop.hbase.client.Get; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.web.dao.TraceDao; -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.hbase.HbaseOperations2; - -/** - * @author emeroad - */ -@Repository -public class HbaseTraceDao implements TraceDao { - - @Autowired - private HbaseOperations2 template2; - - @Autowired - @Qualifier("traceDistributor") - private AbstractRowKeyDistributor rowKeyDistributor; - - @Autowired - @Qualifier("spanMapper") - private RowMapper> spanMapper; - - @Autowired - @Qualifier("spanAnnotationMapper") - private RowMapper> spanAnnotationMapper; - - @Override - public List selectSpan(TransactionId transactionId) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - - byte[] traceIdBytes = rowKeyDistributor.getDistributedKey(transactionId.getBytes()); - return template2.get(HBaseTables.TRACES, traceIdBytes, HBaseTables.TRACES_CF_SPAN, spanMapper); - } - - public List selectSpanAndAnnotation(TransactionId transactionId) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - - final byte[] traceIdBytes = rowKeyDistributor.getDistributedKey(transactionId.getBytes()); - Get get = new Get(traceIdBytes); - get.addFamily(HBaseTables.TRACES_CF_SPAN); - get.addFamily(HBaseTables.TRACES_CF_ANNOTATION); - get.addFamily(HBaseTables.TRACES_CF_TERMINALSPAN); - return template2.get(HBaseTables.TRACES, get, spanAnnotationMapper); - } - - - @Override - public List> selectSpans(List transactionIdList) { - if (transactionIdList == null) { - throw new NullPointerException("transactionIdList must not be null"); - } - - final List getList = new ArrayList(transactionIdList.size()); - for (TransactionId traceId : transactionIdList) { - final byte[] traceIdBytes = rowKeyDistributor.getDistributedKey(traceId.getBytes()); - final Get get = new Get(traceIdBytes); - get.addFamily(HBaseTables.TRACES_CF_SPAN); - getList.add(get); - } - return template2.get(HBaseTables.TRACES, getList, spanMapper); - } - - @Override - public List> selectAllSpans(Collection transactionIdList) { - if (transactionIdList == null) { - throw new NullPointerException("transactionIdList must not be null"); - } - - final List gets = new ArrayList(transactionIdList.size()); - for (TransactionId transactionId : transactionIdList) { - final byte[] transactionIdBytes = this.rowKeyDistributor.getDistributedKey(transactionId.getBytes()); - final Get get = new Get(transactionIdBytes); - get.addFamily(HBaseTables.TRACES_CF_SPAN); - get.addFamily(HBaseTables.TRACES_CF_TERMINALSPAN); - gets.add(get); - } - return template2.get(HBaseTables.TRACES, gets, spanMapper); - } - - @Override - public List selectSpans(TransactionId transactionId) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - - final byte[] transactionIdBytes = this.rowKeyDistributor.getDistributedKey(transactionId.getBytes()); - Get get = new Get(transactionIdBytes); - get.addFamily(HBaseTables.TRACES_CF_SPAN); - get.addFamily(HBaseTables.TRACES_CF_TERMINALSPAN); - return template2.get(HBaseTables.TRACES, get, spanMapper); - } - -} +package com.nhn.pinpoint.web.dao.hbase; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.nhn.pinpoint.web.vo.TransactionId; +import com.sematext.hbase.wd.AbstractRowKeyDistributor; +import org.apache.hadoop.hbase.client.Get; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.web.dao.TraceDao; +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; + +/** + * @author emeroad + */ +@Repository +public class HbaseTraceDao implements TraceDao { + + @Autowired + private HbaseOperations2 template2; + + @Autowired + @Qualifier("traceDistributor") + private AbstractRowKeyDistributor rowKeyDistributor; + + @Autowired + @Qualifier("spanMapper") + private RowMapper> spanMapper; + + @Autowired + @Qualifier("spanAnnotationMapper") + private RowMapper> spanAnnotationMapper; + + @Override + public List selectSpan(TransactionId transactionId) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + + byte[] traceIdBytes = rowKeyDistributor.getDistributedKey(transactionId.getBytes()); + return template2.get(HBaseTables.TRACES, traceIdBytes, HBaseTables.TRACES_CF_SPAN, spanMapper); + } + + public List selectSpanAndAnnotation(TransactionId transactionId) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + + final byte[] traceIdBytes = rowKeyDistributor.getDistributedKey(transactionId.getBytes()); + Get get = new Get(traceIdBytes); + get.addFamily(HBaseTables.TRACES_CF_SPAN); + get.addFamily(HBaseTables.TRACES_CF_ANNOTATION); + get.addFamily(HBaseTables.TRACES_CF_TERMINALSPAN); + return template2.get(HBaseTables.TRACES, get, spanAnnotationMapper); + } + + + @Override + public List> selectSpans(List transactionIdList) { + if (transactionIdList == null) { + throw new NullPointerException("transactionIdList must not be null"); + } + + final List getList = new ArrayList(transactionIdList.size()); + for (TransactionId traceId : transactionIdList) { + final byte[] traceIdBytes = rowKeyDistributor.getDistributedKey(traceId.getBytes()); + final Get get = new Get(traceIdBytes); + get.addFamily(HBaseTables.TRACES_CF_SPAN); + getList.add(get); + } + return template2.get(HBaseTables.TRACES, getList, spanMapper); + } + + @Override + public List> selectAllSpans(Collection transactionIdList) { + if (transactionIdList == null) { + throw new NullPointerException("transactionIdList must not be null"); + } + + final List gets = new ArrayList(transactionIdList.size()); + for (TransactionId transactionId : transactionIdList) { + final byte[] transactionIdBytes = this.rowKeyDistributor.getDistributedKey(transactionId.getBytes()); + final Get get = new Get(transactionIdBytes); + get.addFamily(HBaseTables.TRACES_CF_SPAN); + get.addFamily(HBaseTables.TRACES_CF_TERMINALSPAN); + gets.add(get); + } + return template2.get(HBaseTables.TRACES, gets, spanMapper); + } + + @Override + public List selectSpans(TransactionId transactionId) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + + final byte[] transactionIdBytes = this.rowKeyDistributor.getDistributedKey(transactionId.getBytes()); + Get get = new Get(transactionIdBytes); + get.addFamily(HBaseTables.TRACES_CF_SPAN); + get.addFamily(HBaseTables.TRACES_CF_TERMINALSPAN); + return template2.get(HBaseTables.TRACES, get, spanMapper); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/mysql/MySqlAlarmResourceDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/mysql/MySqlAlarmResourceDao.java index 8f09724bf710..793d43e8acfc 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/mysql/MySqlAlarmResourceDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/mysql/MySqlAlarmResourceDao.java @@ -1,93 +1,93 @@ -package com.nhn.pinpoint.web.dao.mysql; - -import java.util.Date; -import java.util.List; - -import org.mybatis.spring.SqlSessionTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Repository; - -import com.nhn.pinpoint.web.alarm.vo.AlarmContactGroupResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmContactResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleGroupResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; -import com.nhn.pinpoint.web.dao.AlarmResourceDao; - -@Repository -public class MySqlAlarmResourceDao implements AlarmResourceDao { - - private static final String NAMESPACE = AlarmResourceDao.class.getPackage().getName() + "." + AlarmResourceDao.class.getSimpleName() + "."; - - @Autowired - @Qualifier("sqlSessionTemplate") - private SqlSessionTemplate sqlSessionTemplate; - - public SqlSessionTemplate getSqlSessionTemplate() { - return sqlSessionTemplate; - } - - @Override - public int selectAlarmCount() { - return 1; - } - - @Override - public List selectAlarmList() { - return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmList"); - } - - @Override - public List selectAlarmRuleList() { - return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmRuleList", 1); - } - - @Override - public List selectAlarmRuleGroupList() { - return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmRuleGroupList", 1); - } - - @Override - public List selectAlarmContactList() { - return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmContactList", 1); - } - - @Override - public List selectAlarmContactGroupList() { - return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmContactGroupList", 1); - } - - - @Override - public void insertAlarmContact(AlarmContactResource resource) { - getSqlSessionTemplate().insert(NAMESPACE + "insertAlarmContact", resource); - } - - @Override - public void updateAlarmCountact(AlarmContactResource resource) { - getSqlSessionTemplate().update(NAMESPACE + "updateAlarmContact", resource); - } - - @Override - public void deleteAlarmCountact(AlarmContactResource resource) { - getSqlSessionTemplate().update(NAMESPACE + "deleteAlarmContact", resource.getId()); - } - - @Override - public void insertAlarmContactGroup(AlarmContactGroupResource resource) { - getSqlSessionTemplate().insert(NAMESPACE + "insertAlarmContactGroup", resource); - } - - @Override - public void updateAlarmContactGroup(AlarmContactGroupResource resource) { - getSqlSessionTemplate().insert(NAMESPACE + "updateAlarmContactGroup", resource); - } - - @Override - public void deleteAlarmCountactGroup(AlarmContactGroupResource resource) { - getSqlSessionTemplate().update(NAMESPACE + "deleteAlarmContactGroup", resource.getId()); - } - - -} +package com.nhn.pinpoint.web.dao.mysql; + +import java.util.Date; +import java.util.List; + +import org.mybatis.spring.SqlSessionTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Repository; + +import com.nhn.pinpoint.web.alarm.vo.AlarmContactGroupResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmContactResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleGroupResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; +import com.nhn.pinpoint.web.dao.AlarmResourceDao; + +@Repository +public class MySqlAlarmResourceDao implements AlarmResourceDao { + + private static final String NAMESPACE = AlarmResourceDao.class.getPackage().getName() + "." + AlarmResourceDao.class.getSimpleName() + "."; + + @Autowired + @Qualifier("sqlSessionTemplate") + private SqlSessionTemplate sqlSessionTemplate; + + public SqlSessionTemplate getSqlSessionTemplate() { + return sqlSessionTemplate; + } + + @Override + public int selectAlarmCount() { + return 1; + } + + @Override + public List selectAlarmList() { + return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmList"); + } + + @Override + public List selectAlarmRuleList() { + return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmRuleList", 1); + } + + @Override + public List selectAlarmRuleGroupList() { + return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmRuleGroupList", 1); + } + + @Override + public List selectAlarmContactList() { + return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmContactList", 1); + } + + @Override + public List selectAlarmContactGroupList() { + return getSqlSessionTemplate().selectList(NAMESPACE + "selectAlarmContactGroupList", 1); + } + + + @Override + public void insertAlarmContact(AlarmContactResource resource) { + getSqlSessionTemplate().insert(NAMESPACE + "insertAlarmContact", resource); + } + + @Override + public void updateAlarmCountact(AlarmContactResource resource) { + getSqlSessionTemplate().update(NAMESPACE + "updateAlarmContact", resource); + } + + @Override + public void deleteAlarmCountact(AlarmContactResource resource) { + getSqlSessionTemplate().update(NAMESPACE + "deleteAlarmContact", resource.getId()); + } + + @Override + public void insertAlarmContactGroup(AlarmContactGroupResource resource) { + getSqlSessionTemplate().insert(NAMESPACE + "insertAlarmContactGroup", resource); + } + + @Override + public void updateAlarmContactGroup(AlarmContactGroupResource resource) { + getSqlSessionTemplate().insert(NAMESPACE + "updateAlarmContactGroup", resource); + } + + @Override + public void deleteAlarmCountactGroup(AlarmContactGroupResource resource) { + getSqlSessionTemplate().update(NAMESPACE + "deleteAlarmContactGroup", resource.getId()); + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/filter/FilterBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/filter/FilterBuilder.java index 102868bfd309..3d22f8fadf59 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/filter/FilterBuilder.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/filter/FilterBuilder.java @@ -1,11 +1,11 @@ -package com.nhn.pinpoint.web.filter; - -/** - * @author emeroad - * @author netspider - */ -public interface FilterBuilder { - Filter build(String filterText); - - Filter build(String filterText, String filterHint); -} +package com.nhn.pinpoint.web.filter; + +/** + * @author emeroad + * @author netspider + */ +public interface FilterBuilder { + Filter build(String filterText); + + Filter build(String filterText, String filterHint); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentIdMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentIdMapper.java index 341f1b440600..c4bfefd28b12 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentIdMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentIdMapper.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.web.mapper; - -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * - */ -@Component -public class AgentIdMapper implements RowMapper> { - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - final KeyValue[] raw = result.raw(); - final List agentIdList = new ArrayList(raw.length); - - for (KeyValue kv : raw) { - final String agentId = Bytes.toString(kv.getQualifier()); - agentIdList.add(agentId); - } - - return agentIdList; - } -} +package com.nhn.pinpoint.web.mapper; + +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * + */ +@Component +public class AgentIdMapper implements RowMapper> { + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + final KeyValue[] raw = result.raw(); + final List agentIdList = new ArrayList(raw.length); + + for (KeyValue kv : raw) { + final String agentId = Bytes.toString(kv.getQualifier()); + agentIdList.add(agentId); + } + + return agentIdList; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentInfoMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentInfoMapper.java index 1ba56cd25b5c..f4eb703d7e43 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentInfoMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AgentInfoMapper.java @@ -1,60 +1,60 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.common.PinpointConstants; -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * @author emeroad - */ -@Component -public class AgentInfoMapper implements RowMapper> { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - KeyValue[] raw = result.raw(); - - List agentInfoBoList = new ArrayList(raw.length); - for (KeyValue keyValue : raw) { - AgentInfoBo agentInfoBo = mappingAgentInfo(keyValue); - - agentInfoBoList.add(agentInfoBo); - } - - return agentInfoBoList; - } - - private AgentInfoBo mappingAgentInfo(KeyValue keyValue) { - AgentInfoBo agentInfoBo = new AgentInfoBo(); - agentInfoBo.readValue(keyValue.getValue()); - - byte[] rowKey = keyValue.getRow(); - String agentId = Bytes.toString(rowKey, 0, PinpointConstants.AGENT_NAME_MAX_LEN - 1).trim(); - agentInfoBo.setAgentId(agentId); - - long reverseStartTime = BytesUtils.bytesToLong(rowKey, PinpointConstants.AGENT_NAME_MAX_LEN); - long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime); - agentInfoBo.setStartTime(startTime); - - logger.debug("agentInfo:{}", agentInfoBo); - - return agentInfoBo; - } -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.PinpointConstants; +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author emeroad + */ +@Component +public class AgentInfoMapper implements RowMapper> { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + KeyValue[] raw = result.raw(); + + List agentInfoBoList = new ArrayList(raw.length); + for (KeyValue keyValue : raw) { + AgentInfoBo agentInfoBo = mappingAgentInfo(keyValue); + + agentInfoBoList.add(agentInfoBo); + } + + return agentInfoBoList; + } + + private AgentInfoBo mappingAgentInfo(KeyValue keyValue) { + AgentInfoBo agentInfoBo = new AgentInfoBo(); + agentInfoBo.readValue(keyValue.getValue()); + + byte[] rowKey = keyValue.getRow(); + String agentId = Bytes.toString(rowKey, 0, PinpointConstants.AGENT_NAME_MAX_LEN - 1).trim(); + agentInfoBo.setAgentId(agentId); + + long reverseStartTime = BytesUtils.bytesToLong(rowKey, PinpointConstants.AGENT_NAME_MAX_LEN); + long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime); + agentInfoBo.setStartTime(startTime); + + logger.debug("agentInfo:{}", agentInfoBo); + + return agentInfoBo; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java index e5bf83281fef..f948376d4201 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java @@ -1,55 +1,55 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.common.bo.AnnotationBo; -import com.nhn.pinpoint.common.bo.AnnotationBoList; -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.hadoop.hbase.RowMapper; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author emeroad - */ -public class AnnotationMapper implements RowMapper>> { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - public Map> mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyMap(); - } - KeyValue[] keyList = result.raw(); - Map> annotationList = new HashMap>(); - - for (KeyValue kv : keyList) { - final byte[] bytes = kv.getBuffer(); - Buffer buffer = new OffsetFixedBuffer(bytes, kv.getQualifierOffset()); - long spanId = buffer.readLong(); - if (Bytes.equals(kv.getFamily(), HBaseTables.TRACES_CF_ANNOTATION)) { - int valueLength = kv.getValueLength(); - if (valueLength == 0) { - continue; - } - - buffer.setOffset(kv.getValueOffset()); - AnnotationBoList annotationBoList = new AnnotationBoList(); - annotationBoList.readValue(buffer); - if (annotationBoList.size() > 0 ) { - annotationBoList.setSpanId(spanId); - annotationList.put(spanId, annotationBoList.getAnnotationBoList()); - } - } - } - return annotationList; - } -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.bo.AnnotationBo; +import com.nhn.pinpoint.common.bo.AnnotationBoList; +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.hadoop.hbase.RowMapper; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author emeroad + */ +public class AnnotationMapper implements RowMapper>> { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public Map> mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyMap(); + } + KeyValue[] keyList = result.raw(); + Map> annotationList = new HashMap>(); + + for (KeyValue kv : keyList) { + final byte[] bytes = kv.getBuffer(); + Buffer buffer = new OffsetFixedBuffer(bytes, kv.getQualifierOffset()); + long spanId = buffer.readLong(); + if (Bytes.equals(kv.getFamily(), HBaseTables.TRACES_CF_ANNOTATION)) { + int valueLength = kv.getValueLength(); + if (valueLength == 0) { + continue; + } + + buffer.setOffset(kv.getValueOffset()); + AnnotationBoList annotationBoList = new AnnotationBoList(); + annotationBoList.readValue(buffer); + if (annotationBoList.size() > 0 ) { + annotationBoList.setSpanId(spanId); + annotationList.put(spanId, annotationBoList.getAnnotationBoList()); + } + } + } + return annotationList; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApiMetaDataMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApiMetaDataMapper.java index 201b75d7ec0d..4611a757eec4 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApiMetaDataMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApiMetaDataMapper.java @@ -1,65 +1,65 @@ -package com.nhn.pinpoint.web.mapper; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.nhn.pinpoint.common.buffer.FixedBuffer; -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.common.bo.ApiMetaDataBo; -import com.nhn.pinpoint.common.buffer.Buffer; - -/** - * @author emeroad - */ -@Component -public class ApiMetaDataMapper implements RowMapper> { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - final byte[] rowKey = getOriginalKey(result.getRow()); - - List apiMetaDataList = new ArrayList(); - KeyValue[] keyList = result.raw(); - for (KeyValue keyValue : keyList) { - ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo(); - apiMetaDataBo.readRowKey(rowKey); - byte[] qualifier = keyValue.getQualifier(); - Buffer buffer = new FixedBuffer(qualifier); - String apiInfo = buffer.readPrefixedString(); - int lineNumber = buffer.readInt(); - apiMetaDataBo.setApiInfo(apiInfo); - apiMetaDataBo.setLineNumber(lineNumber); - apiMetaDataList.add(apiMetaDataBo); - if (logger.isDebugEnabled()) { - logger.debug("read apiAnnotation:{}", apiMetaDataBo); - } - } - return apiMetaDataList; - } - - private byte[] getOriginalKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getOriginalKey(rowKey); - } - - -} - +package com.nhn.pinpoint.web.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.nhn.pinpoint.common.buffer.FixedBuffer; +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.common.bo.ApiMetaDataBo; +import com.nhn.pinpoint.common.buffer.Buffer; + +/** + * @author emeroad + */ +@Component +public class ApiMetaDataMapper implements RowMapper> { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + final byte[] rowKey = getOriginalKey(result.getRow()); + + List apiMetaDataList = new ArrayList(); + KeyValue[] keyList = result.raw(); + for (KeyValue keyValue : keyList) { + ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo(); + apiMetaDataBo.readRowKey(rowKey); + byte[] qualifier = keyValue.getQualifier(); + Buffer buffer = new FixedBuffer(qualifier); + String apiInfo = buffer.readPrefixedString(); + int lineNumber = buffer.readInt(); + apiMetaDataBo.setApiInfo(apiInfo); + apiMetaDataBo.setLineNumber(lineNumber); + apiMetaDataList.add(apiMetaDataBo); + if (logger.isDebugEnabled()) { + logger.debug("read apiAnnotation:{}", apiMetaDataBo); + } + } + return apiMetaDataList; + } + + private byte[] getOriginalKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getOriginalKey(rowKey); + } + + +} + diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApplicationNameMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApplicationNameMapper.java index f0a95dc19c4d..0b0aa5d9cf8b 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApplicationNameMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/ApplicationNameMapper.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.web.mapper; - -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.web.vo.Application; - -/** - * - */ -@Component -public class ApplicationNameMapper implements RowMapper { - @Override - public Application mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return null; - } - String applicationName = Bytes.toString(result.getRow()); - short serviceType = Bytes.toShort(result.value()); - return new Application(applicationName, serviceType); - } -} +package com.nhn.pinpoint.web.mapper; + +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.web.vo.Application; + +/** + * + */ +@Component +public class ApplicationNameMapper implements RowMapper { + @Override + public Application mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return null; + } + String applicationName = Bytes.toString(result.getRow()); + short serviceType = Bytes.toShort(result.value()); + return new Application(applicationName, serviceType); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/DefaultLinkFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/DefaultLinkFilter.java index c9f1f258b142..d33cb5b07ea3 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/DefaultLinkFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/DefaultLinkFilter.java @@ -1,74 +1,74 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.web.vo.Application; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @author emeroad - */ -public class DefaultLinkFilter implements LinkFilter { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Application callerApplication; - private final Application calleeApplication; - - public DefaultLinkFilter(Application callerApplication, Application calleeApplication) { - if (callerApplication == null) { - throw new NullPointerException("callerApplication must not be null"); - } - if (calleeApplication == null) { - throw new NullPointerException("calleeApplication must not be null"); - } - this.callerApplication = callerApplication; - this.calleeApplication = calleeApplication; - } - - public boolean filter(Application foundApplication) { - if (foundApplication == null) { - throw new NullPointerException("foundApplication must not be null"); - } - if (this.calleeApplication.getServiceType().isWas() && this.callerApplication.getServiceType().isWas()) { - logger.debug("check was to was."); - // src가 같지 않으면 버림. - if (!this.callerApplication.equals(foundApplication)) { - if (logger.isDebugEnabled()) { - logger.debug(" DROP THE ROW,1, DIFFERENT SRC. fetched={} , params={}", foundApplication, calleeApplication); - } - return true; - } - } else if (this.callerApplication.getServiceType().isUser()) { - logger.debug("check client to was"); - // dest가 해당 was가 아니면 버림. - if (!this.calleeApplication.getName().equals(foundApplication.getName())) { - if (logger.isDebugEnabled()) { - logger.debug(" DROP THE ROW,2, DIFFERENT DEST. fetched={}, params={}", foundApplication, this.calleeApplication); - } - return true; - } - } else { - logger.debug("check any to any."); - // dest가 같지 않으면 버림. - if (this.calleeApplication.getServiceType().isUnknown()) { - // dest가 unknown인 경우 application name만 비교. - // TODO 다른 좋은 비교 방법 없을까?? - if (!this.calleeApplication.getName().equals(foundApplication.getName())) { - if (logger.isDebugEnabled()) { - logger.debug(" DROP THE ROW,3, DIFFERENT DEST. fetched={}, params={}", foundApplication, calleeApplication); - } - return true; - } - } else { - // dest가 unknown이 아니면 applicaiton name, type 둘 다 비교. - if (!this.calleeApplication.equals(foundApplication)) { - if (logger.isDebugEnabled()) { - logger.debug(" DROP THE ROW,4, DIFFERENT DEST. fetched={}, params={}", foundApplication, this.calleeApplication); - } - return true; - } - } - } - return false; - } -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.web.vo.Application; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author emeroad + */ +public class DefaultLinkFilter implements LinkFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Application callerApplication; + private final Application calleeApplication; + + public DefaultLinkFilter(Application callerApplication, Application calleeApplication) { + if (callerApplication == null) { + throw new NullPointerException("callerApplication must not be null"); + } + if (calleeApplication == null) { + throw new NullPointerException("calleeApplication must not be null"); + } + this.callerApplication = callerApplication; + this.calleeApplication = calleeApplication; + } + + public boolean filter(Application foundApplication) { + if (foundApplication == null) { + throw new NullPointerException("foundApplication must not be null"); + } + if (this.calleeApplication.getServiceType().isWas() && this.callerApplication.getServiceType().isWas()) { + logger.debug("check was to was."); + // src가 같지 않으면 버림. + if (!this.callerApplication.equals(foundApplication)) { + if (logger.isDebugEnabled()) { + logger.debug(" DROP THE ROW,1, DIFFERENT SRC. fetched={} , params={}", foundApplication, calleeApplication); + } + return true; + } + } else if (this.callerApplication.getServiceType().isUser()) { + logger.debug("check client to was"); + // dest가 해당 was가 아니면 버림. + if (!this.calleeApplication.getName().equals(foundApplication.getName())) { + if (logger.isDebugEnabled()) { + logger.debug(" DROP THE ROW,2, DIFFERENT DEST. fetched={}, params={}", foundApplication, this.calleeApplication); + } + return true; + } + } else { + logger.debug("check any to any."); + // dest가 같지 않으면 버림. + if (this.calleeApplication.getServiceType().isUnknown()) { + // dest가 unknown인 경우 application name만 비교. + // TODO 다른 좋은 비교 방법 없을까?? + if (!this.calleeApplication.getName().equals(foundApplication.getName())) { + if (logger.isDebugEnabled()) { + logger.debug(" DROP THE ROW,3, DIFFERENT DEST. fetched={}, params={}", foundApplication, calleeApplication); + } + return true; + } + } else { + // dest가 unknown이 아니면 applicaiton name, type 둘 다 비교. + if (!this.calleeApplication.equals(foundApplication)) { + if (logger.isDebugEnabled()) { + logger.debug(" DROP THE ROW,4, DIFFERENT DEST. fetched={}, params={}", foundApplication, this.calleeApplication); + } + return true; + } + } + } + return false; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/HostApplicationMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/HostApplicationMapper.java index 346b45eeb4f4..4dea55f93318 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/HostApplicationMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/HostApplicationMapper.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.web.mapper; - -import java.util.Arrays; - -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.common.hbase.HBaseTables; - -/** - * - * @author netspider - * - */ -@Component -public class HostApplicationMapper implements RowMapper { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - public Application mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return null; - } - byte[] value = result.value(); - - if (value.length != HBaseTables.APPLICATION_NAME_MAX_LEN + 2) { - logger.warn("Invalid value. {}", Arrays.toString(value)); - } - - String applicationName = Bytes.toString(value, 0, HBaseTables.APPLICATION_NAME_MAX_LEN - 1).trim(); - short serviceType = Bytes.toShort(value, HBaseTables.APPLICATION_NAME_MAX_LEN); - - return new Application(applicationName, serviceType); - } -} +package com.nhn.pinpoint.web.mapper; + +import java.util.Arrays; + +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.common.hbase.HBaseTables; + +/** + * + * @author netspider + * + */ +@Component +public class HostApplicationMapper implements RowMapper { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public Application mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return null; + } + byte[] value = result.value(); + + if (value.length != HBaseTables.APPLICATION_NAME_MAX_LEN + 2) { + logger.warn("Invalid value. {}", Arrays.toString(value)); + } + + String applicationName = Bytes.toString(value, 0, HBaseTables.APPLICATION_NAME_MAX_LEN - 1).trim(); + short serviceType = Bytes.toShort(value, HBaseTables.APPLICATION_NAME_MAX_LEN); + + return new Application(applicationName, serviceType); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/LinkFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/LinkFilter.java index c452b105d244..9130d31ebc2c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/LinkFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/LinkFilter.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.web.vo.Application; - -/** - * @author emeroad - */ -public interface LinkFilter { - boolean filter(Application foundApplication); -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.web.vo.Application; + +/** + * @author emeroad + */ +public interface LinkFilter { + boolean filter(Application foundApplication); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCalleeMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCalleeMapper.java index 9324e02ceceb..9fc551fd49a6 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCalleeMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCalleeMapper.java @@ -1,95 +1,95 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.FixedBuffer; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; -import com.nhn.pinpoint.web.vo.Application; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; - -/** - * - * @author netspider - * - */ -@Component -public class MapStatisticsCalleeMapper implements RowMapper { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final LinkFilter filter; - - public MapStatisticsCalleeMapper() { - this(SkipLinkFilter.FILTER); - } - - public MapStatisticsCalleeMapper(LinkFilter filter) { - if (filter == null) { - throw new NullPointerException("filter must not be null"); - } - this.filter = filter; - } - - @Override - public LinkDataMap mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return new LinkDataMap(); - } - logger.debug("mapRow:{}", rowNum); - - final Buffer row = new FixedBuffer(result.getRow()); - final Application calleeApplication = readCalleeApplication(row); - final long timestamp = TimeUtils.recoveryTimeMillis(row.readLong()); - - - final LinkDataMap linkDataMap = new LinkDataMap(); - for (KeyValue kv : result.raw()) { - - final byte[] qualifier = kv.getQualifier(); - final Application callerApplication = readCallerApplication(qualifier); - if (filter.filter(callerApplication)) { - continue; - } - - long requestCount = Bytes.toLong(kv.getBuffer(), kv.getValueOffset()); - short histogramSlot = ApplicationMapStatisticsUtils.getHistogramSlotFromColumnName(qualifier); - - String callerHost = ApplicationMapStatisticsUtils.getHost(qualifier); - boolean isError = histogramSlot == (short) -1; - - if (logger.isDebugEnabled()) { - logger.debug(" Fetched Callee. {} callerHost:{} -> {} (slot:{}/{}), ", callerApplication, callerHost, calleeApplication, histogramSlot, requestCount); - } - - - final short slotTime = (isError) ? (short) -1 : histogramSlot; - linkDataMap.addLinkData(callerApplication, callerApplication.getName(), calleeApplication, callerHost, timestamp, slotTime, requestCount); - - if (logger.isDebugEnabled()) { - logger.debug(" Fetched Callee. statistics:{}", linkDataMap); - } - } - - return linkDataMap; - } - - private Application readCallerApplication(byte[] qualifier) { - String callerApplicationName = ApplicationMapStatisticsUtils.getDestApplicationNameFromColumnName(qualifier); - short callerServiceType = ApplicationMapStatisticsUtils.getDestServiceTypeFromColumnName(qualifier); - return new Application(callerApplicationName, callerServiceType); - } - - private Application readCalleeApplication(Buffer row) { - String calleeApplicationName = row.read2PrefixedString(); - short calleeServiceType = row.readShort(); - return new Application(calleeApplicationName, calleeServiceType); - } -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.FixedBuffer; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; +import com.nhn.pinpoint.web.vo.Application; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; + +/** + * + * @author netspider + * + */ +@Component +public class MapStatisticsCalleeMapper implements RowMapper { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final LinkFilter filter; + + public MapStatisticsCalleeMapper() { + this(SkipLinkFilter.FILTER); + } + + public MapStatisticsCalleeMapper(LinkFilter filter) { + if (filter == null) { + throw new NullPointerException("filter must not be null"); + } + this.filter = filter; + } + + @Override + public LinkDataMap mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return new LinkDataMap(); + } + logger.debug("mapRow:{}", rowNum); + + final Buffer row = new FixedBuffer(result.getRow()); + final Application calleeApplication = readCalleeApplication(row); + final long timestamp = TimeUtils.recoveryTimeMillis(row.readLong()); + + + final LinkDataMap linkDataMap = new LinkDataMap(); + for (KeyValue kv : result.raw()) { + + final byte[] qualifier = kv.getQualifier(); + final Application callerApplication = readCallerApplication(qualifier); + if (filter.filter(callerApplication)) { + continue; + } + + long requestCount = Bytes.toLong(kv.getBuffer(), kv.getValueOffset()); + short histogramSlot = ApplicationMapStatisticsUtils.getHistogramSlotFromColumnName(qualifier); + + String callerHost = ApplicationMapStatisticsUtils.getHost(qualifier); + boolean isError = histogramSlot == (short) -1; + + if (logger.isDebugEnabled()) { + logger.debug(" Fetched Callee. {} callerHost:{} -> {} (slot:{}/{}), ", callerApplication, callerHost, calleeApplication, histogramSlot, requestCount); + } + + + final short slotTime = (isError) ? (short) -1 : histogramSlot; + linkDataMap.addLinkData(callerApplication, callerApplication.getName(), calleeApplication, callerHost, timestamp, slotTime, requestCount); + + if (logger.isDebugEnabled()) { + logger.debug(" Fetched Callee. statistics:{}", linkDataMap); + } + } + + return linkDataMap; + } + + private Application readCallerApplication(byte[] qualifier) { + String callerApplicationName = ApplicationMapStatisticsUtils.getDestApplicationNameFromColumnName(qualifier); + short callerServiceType = ApplicationMapStatisticsUtils.getDestServiceTypeFromColumnName(qualifier); + return new Application(callerApplicationName, callerServiceType); + } + + private Application readCalleeApplication(Buffer row) { + String calleeApplicationName = row.read2PrefixedString(); + short calleeServiceType = row.readShort(); + return new Application(calleeApplicationName, calleeServiceType); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCallerMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCallerMapper.java index 207a65bec3da..6002313befff 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCallerMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/MapStatisticsCallerMapper.java @@ -1,144 +1,144 @@ -package com.nhn.pinpoint.web.mapper; - -import java.util.*; - -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.FixedBuffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; -import com.nhn.pinpoint.web.vo.Application; -import org.apache.commons.lang3.StringUtils; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; - -/** - * rowkey = caller col = callee - * - * @author netspider - * - */ -@Component -public class MapStatisticsCallerMapper implements RowMapper { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final LinkFilter filter; - - public MapStatisticsCallerMapper() { - this(SkipLinkFilter.FILTER); - } - - public MapStatisticsCallerMapper(LinkFilter filter) { - if (filter == null) { - throw new NullPointerException("filter must not be null"); - } - this.filter = filter; - } - - @Override - public LinkDataMap mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return new LinkDataMap(); - } - logger.debug("mapRow:{}", rowNum); - - final Buffer row = new FixedBuffer(result.getRow()); - final Application caller = readCallerApplication(row); - final long timestamp = TimeUtils.recoveryTimeMillis(row.readLong()); - - // key is destApplicationName. - final LinkDataMap linkDataMap = new LinkDataMap(); - for (KeyValue kv : result.raw()) { - final byte[] family = kv.getFamily(); - if (Bytes.equals(family, HBaseTables.MAP_STATISTICS_CALLEE_CF_COUNTER)) { - final byte[] qualifier = kv.getQualifier(); - final Application callee = readCalleeApplication(qualifier); - if (filter.filter(callee)) { - continue; - } - - long requestCount = getValueToLong(kv); - - short histogramSlot = ApplicationMapStatisticsUtils.getHistogramSlotFromColumnName(qualifier); - boolean isError = histogramSlot == (short) -1; - - String calleeHost = ApplicationMapStatisticsUtils.getHost(qualifier); - - if (logger.isDebugEnabled()) { - logger.debug(" Fetched Caller. {} -> {} (slot:{}/{}) calleeHost:{}", caller, callee, histogramSlot, requestCount, calleeHost); - } - - final short slotTime = (isError) ? (short) -1 : histogramSlot; - if (StringUtils.isEmpty(calleeHost)) { - calleeHost = callee.getName(); - } - linkDataMap.addLinkData(caller, caller.getName(), callee, calleeHost, timestamp, slotTime, requestCount); - - - } else if (Bytes.equals(family, HBaseTables.MAP_STATISTICS_CALLEE_CF_VER2_COUNTER)) { - - final Buffer buffer = new OffsetFixedBuffer(kv.getBuffer(), kv.getQualifierOffset()); - final Application callee = readCalleeApplication(buffer); - if (filter.filter(callee)) { - continue; - } - - String calleeHost = buffer.readPrefixedString(); - short histogramSlot = buffer.readShort(); - - boolean isError = histogramSlot == (short) -1; - - String callerAgentId = buffer.readPrefixedString(); - - long requestCount = getValueToLong(kv); - if (logger.isDebugEnabled()) { - logger.debug(" Fetched Caller.(New) {} {} -> {} (slot:{}/{}) calleeHost:{}", caller, callerAgentId, callee, histogramSlot, requestCount, calleeHost); - } - - final short slotTime = (isError) ? (short) -1 : histogramSlot; - if (StringUtils.isEmpty(calleeHost)) { - calleeHost = callee.getName(); - } - linkDataMap.addLinkData(caller, callerAgentId, callee, calleeHost, timestamp, slotTime, requestCount); - } else { - throw new IllegalArgumentException("unknown ColumnFamily :" + Arrays.toString(family)); - } - - } - - return linkDataMap; - } - - private long getValueToLong(KeyValue kv) { - return Bytes.toLong(kv.getBuffer(), kv.getValueOffset()); - } - - - private Application readCalleeApplication(byte[] qualifier) { - String calleeApplicationName = ApplicationMapStatisticsUtils.getDestApplicationNameFromColumnName(qualifier); - short calleeServiceType = ApplicationMapStatisticsUtils.getDestServiceTypeFromColumnName(qualifier); - return new Application(calleeApplicationName, calleeServiceType); - } - - - private Application readCalleeApplication(Buffer buffer) { - short calleeServiceType = buffer.readShort(); - String calleeApplicationName = buffer.readPrefixedString(); - return new Application(calleeApplicationName, calleeServiceType); - } - - private Application readCallerApplication(Buffer row) { - String callerApplicationName = row.read2PrefixedString(); - short callerServiceType = row.readShort(); - return new Application(callerApplicationName, callerServiceType); - } -} +package com.nhn.pinpoint.web.mapper; + +import java.util.*; + +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.FixedBuffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; +import com.nhn.pinpoint.web.vo.Application; +import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.common.util.ApplicationMapStatisticsUtils; + +/** + * rowkey = caller col = callee + * + * @author netspider + * + */ +@Component +public class MapStatisticsCallerMapper implements RowMapper { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final LinkFilter filter; + + public MapStatisticsCallerMapper() { + this(SkipLinkFilter.FILTER); + } + + public MapStatisticsCallerMapper(LinkFilter filter) { + if (filter == null) { + throw new NullPointerException("filter must not be null"); + } + this.filter = filter; + } + + @Override + public LinkDataMap mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return new LinkDataMap(); + } + logger.debug("mapRow:{}", rowNum); + + final Buffer row = new FixedBuffer(result.getRow()); + final Application caller = readCallerApplication(row); + final long timestamp = TimeUtils.recoveryTimeMillis(row.readLong()); + + // key is destApplicationName. + final LinkDataMap linkDataMap = new LinkDataMap(); + for (KeyValue kv : result.raw()) { + final byte[] family = kv.getFamily(); + if (Bytes.equals(family, HBaseTables.MAP_STATISTICS_CALLEE_CF_COUNTER)) { + final byte[] qualifier = kv.getQualifier(); + final Application callee = readCalleeApplication(qualifier); + if (filter.filter(callee)) { + continue; + } + + long requestCount = getValueToLong(kv); + + short histogramSlot = ApplicationMapStatisticsUtils.getHistogramSlotFromColumnName(qualifier); + boolean isError = histogramSlot == (short) -1; + + String calleeHost = ApplicationMapStatisticsUtils.getHost(qualifier); + + if (logger.isDebugEnabled()) { + logger.debug(" Fetched Caller. {} -> {} (slot:{}/{}) calleeHost:{}", caller, callee, histogramSlot, requestCount, calleeHost); + } + + final short slotTime = (isError) ? (short) -1 : histogramSlot; + if (StringUtils.isEmpty(calleeHost)) { + calleeHost = callee.getName(); + } + linkDataMap.addLinkData(caller, caller.getName(), callee, calleeHost, timestamp, slotTime, requestCount); + + + } else if (Bytes.equals(family, HBaseTables.MAP_STATISTICS_CALLEE_CF_VER2_COUNTER)) { + + final Buffer buffer = new OffsetFixedBuffer(kv.getBuffer(), kv.getQualifierOffset()); + final Application callee = readCalleeApplication(buffer); + if (filter.filter(callee)) { + continue; + } + + String calleeHost = buffer.readPrefixedString(); + short histogramSlot = buffer.readShort(); + + boolean isError = histogramSlot == (short) -1; + + String callerAgentId = buffer.readPrefixedString(); + + long requestCount = getValueToLong(kv); + if (logger.isDebugEnabled()) { + logger.debug(" Fetched Caller.(New) {} {} -> {} (slot:{}/{}) calleeHost:{}", caller, callerAgentId, callee, histogramSlot, requestCount, calleeHost); + } + + final short slotTime = (isError) ? (short) -1 : histogramSlot; + if (StringUtils.isEmpty(calleeHost)) { + calleeHost = callee.getName(); + } + linkDataMap.addLinkData(caller, callerAgentId, callee, calleeHost, timestamp, slotTime, requestCount); + } else { + throw new IllegalArgumentException("unknown ColumnFamily :" + Arrays.toString(family)); + } + + } + + return linkDataMap; + } + + private long getValueToLong(KeyValue kv) { + return Bytes.toLong(kv.getBuffer(), kv.getValueOffset()); + } + + + private Application readCalleeApplication(byte[] qualifier) { + String calleeApplicationName = ApplicationMapStatisticsUtils.getDestApplicationNameFromColumnName(qualifier); + short calleeServiceType = ApplicationMapStatisticsUtils.getDestServiceTypeFromColumnName(qualifier); + return new Application(calleeApplicationName, calleeServiceType); + } + + + private Application readCalleeApplication(Buffer buffer) { + short calleeServiceType = buffer.readShort(); + String calleeApplicationName = buffer.readPrefixedString(); + return new Application(calleeApplicationName, calleeServiceType); + } + + private Application readCallerApplication(Buffer row) { + String callerApplicationName = row.read2PrefixedString(); + short callerServiceType = row.readShort(); + return new Application(callerApplicationName, callerServiceType); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/ResponseTimeMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/ResponseTimeMapper.java index ef15e61d5a1b..15bb3c4f58b9 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/ResponseTimeMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/ResponseTimeMapper.java @@ -1,57 +1,57 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.FixedBuffer; -import com.nhn.pinpoint.common.hbase.HBaseTables; - -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.vo.ResponseTime; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -/** - * @author emeroad - */ -@Component -public class ResponseTimeMapper implements RowMapper { - @Override - public ResponseTime mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return null; - } - final byte[] rowKey = result.getRow(); - ResponseTime responseTime = createResponseTime(rowKey); - - for (KeyValue keyValue : result.raw()) { - if (!Bytes.equals(keyValue.getFamily(), HBaseTables.MAP_STATISTICS_SELF_CF_COUNTER)) { - continue; - } - byte[] qualifier = keyValue.getQualifier(); - - recordColumn(responseTime, qualifier, keyValue.getBuffer(), keyValue.getValueOffset()); - } - return responseTime; - } - - - - void recordColumn(ResponseTime responseTime, byte[] qualifier, byte[] value, int valueOffset) { - short slotNumber = Bytes.toShort(qualifier); - // agentId도 데이터로 같이 엮어야 함. - String agentId = Bytes.toString(qualifier, 2, qualifier.length - 2); - long count = Bytes.toLong(value, valueOffset); - responseTime.addResponseTime(agentId, slotNumber, count); - } - - private ResponseTime createResponseTime(byte[] rowKey) { - final Buffer row = new FixedBuffer(rowKey); - String applicationName = row.read2PrefixedString(); - short serviceType = row.readShort(); - final long timestamp = TimeUtils.recoveryTimeMillis(row.readLong()); - return new ResponseTime(applicationName, serviceType, timestamp); - } - -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.FixedBuffer; +import com.nhn.pinpoint.common.hbase.HBaseTables; + +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.vo.ResponseTime; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +/** + * @author emeroad + */ +@Component +public class ResponseTimeMapper implements RowMapper { + @Override + public ResponseTime mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return null; + } + final byte[] rowKey = result.getRow(); + ResponseTime responseTime = createResponseTime(rowKey); + + for (KeyValue keyValue : result.raw()) { + if (!Bytes.equals(keyValue.getFamily(), HBaseTables.MAP_STATISTICS_SELF_CF_COUNTER)) { + continue; + } + byte[] qualifier = keyValue.getQualifier(); + + recordColumn(responseTime, qualifier, keyValue.getBuffer(), keyValue.getValueOffset()); + } + return responseTime; + } + + + + void recordColumn(ResponseTime responseTime, byte[] qualifier, byte[] value, int valueOffset) { + short slotNumber = Bytes.toShort(qualifier); + // agentId도 데이터로 같이 엮어야 함. + String agentId = Bytes.toString(qualifier, 2, qualifier.length - 2); + long count = Bytes.toLong(value, valueOffset); + responseTime.addResponseTime(agentId, slotNumber, count); + } + + private ResponseTime createResponseTime(byte[] rowKey) { + final Buffer row = new FixedBuffer(rowKey); + String applicationName = row.read2PrefixedString(); + short serviceType = row.readShort(); + final long timestamp = TimeUtils.recoveryTimeMillis(row.readLong()); + return new ResponseTime(applicationName, serviceType, timestamp); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SkipLinkFilter.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SkipLinkFilter.java index be4d96a5a239..b266da2589b8 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SkipLinkFilter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SkipLinkFilter.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.web.vo.Application; - -/** - * @author emeroad - */ -public class SkipLinkFilter implements LinkFilter { - public static final LinkFilter FILTER = new SkipLinkFilter(); - - private SkipLinkFilter() { - } - - @Override - public boolean filter(Application foundApplication) { - return false; - } -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.web.vo.Application; + +/** + * @author emeroad + */ +public class SkipLinkFilter implements LinkFilter { + public static final LinkFilter FILTER = new SkipLinkFilter(); + + private SkipLinkFilter() { + } + + @Override + public boolean filter(Application foundApplication) { + return false; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java index 4c71f9859575..d29863c7cfc6 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java @@ -1,111 +1,111 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.common.bo.AnnotationBo; -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.web.vo.TransactionId; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import java.util.*; - -/** - * @author emeroad - */ -@Component -public class SpanMapper implements RowMapper> { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private AnnotationMapper annotationMapper; - - public AnnotationMapper getAnnotationMapper() { - return annotationMapper; - } - - public void setAnnotationMapper(AnnotationMapper annotationMapper) { - this.annotationMapper = annotationMapper; - } - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - - byte[] rowKey = result.getRow(); - final TransactionId transactionId = new TransactionId(rowKey, TransactionId.DISTRIBUTE_HASH_SIZE); - - KeyValue[] keyList = result.raw(); - List spanList = new ArrayList(); - Map spanMap = new HashMap(); - List spanEventBoList = new ArrayList(); - for (KeyValue kv : keyList) { - // family name "span"일때로만 한정. - byte[] family = kv.getFamily(); - if (Bytes.equals(family, HBaseTables.TRACES_CF_SPAN)) { - - SpanBo spanBo = new SpanBo(); - spanBo.setTraceAgentId(transactionId.getAgentId()); - spanBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); - spanBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); - spanBo.setCollectorAcceptTime(kv.getTimestamp()); - - spanBo.setSpanID(Bytes.toLong(kv.getBuffer(), kv.getQualifierOffset())); - spanBo.readValue(kv.getBuffer(), kv.getValueOffset()); - if (logger.isDebugEnabled()) { - logger.debug("read span :{}", spanBo); - } - spanList.add(spanBo); - spanMap.put(spanBo.getSpanId(), spanBo); - } else if (Bytes.equals(family, HBaseTables.TRACES_CF_TERMINALSPAN)) { - SpanEventBo spanEventBo = new SpanEventBo(); - spanEventBo.setTraceAgentId(transactionId.getAgentId()); - spanEventBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); - spanEventBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); - - long spanId = Bytes.toLong(kv.getBuffer(), kv.getQualifierOffset()); - // 앞의 spanid가 int이므로 4. - final int spanIdOffset = 8; - short sequence = Bytes.toShort(kv.getBuffer(), kv.getQualifierOffset() + spanIdOffset); - spanEventBo.setSpanId(spanId); - spanEventBo.setSequence(sequence); - - spanEventBo.readValue(kv.getBuffer(), kv.getValueOffset()); - if (logger.isDebugEnabled()) { - logger.debug("read spanEvent :{}", spanEventBo); - } - spanEventBoList.add(spanEventBo); - } - } - for (SpanEventBo spanEventBo : spanEventBoList) { - SpanBo spanBo = spanMap.get(spanEventBo.getSpanId()); - if (spanBo != null) { - spanBo.addSpanEvent(spanEventBo); - } - } - if (annotationMapper != null) { - Map> annotationMap = annotationMapper.mapRow(result, rowNum); - addAnnotation(spanList, annotationMap); - } - - - return spanList; - - } - - private void addAnnotation(List spanList, Map> annotationMap) { - for (SpanBo bo : spanList) { - long spanID = bo.getSpanId(); - List anoList = annotationMap.get(spanID); - bo.setAnnotationBoList(anoList); - } - } -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.bo.AnnotationBo; +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.web.vo.TransactionId; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import java.util.*; + +/** + * @author emeroad + */ +@Component +public class SpanMapper implements RowMapper> { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private AnnotationMapper annotationMapper; + + public AnnotationMapper getAnnotationMapper() { + return annotationMapper; + } + + public void setAnnotationMapper(AnnotationMapper annotationMapper) { + this.annotationMapper = annotationMapper; + } + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + + byte[] rowKey = result.getRow(); + final TransactionId transactionId = new TransactionId(rowKey, TransactionId.DISTRIBUTE_HASH_SIZE); + + KeyValue[] keyList = result.raw(); + List spanList = new ArrayList(); + Map spanMap = new HashMap(); + List spanEventBoList = new ArrayList(); + for (KeyValue kv : keyList) { + // family name "span"일때로만 한정. + byte[] family = kv.getFamily(); + if (Bytes.equals(family, HBaseTables.TRACES_CF_SPAN)) { + + SpanBo spanBo = new SpanBo(); + spanBo.setTraceAgentId(transactionId.getAgentId()); + spanBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); + spanBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); + spanBo.setCollectorAcceptTime(kv.getTimestamp()); + + spanBo.setSpanID(Bytes.toLong(kv.getBuffer(), kv.getQualifierOffset())); + spanBo.readValue(kv.getBuffer(), kv.getValueOffset()); + if (logger.isDebugEnabled()) { + logger.debug("read span :{}", spanBo); + } + spanList.add(spanBo); + spanMap.put(spanBo.getSpanId(), spanBo); + } else if (Bytes.equals(family, HBaseTables.TRACES_CF_TERMINALSPAN)) { + SpanEventBo spanEventBo = new SpanEventBo(); + spanEventBo.setTraceAgentId(transactionId.getAgentId()); + spanEventBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); + spanEventBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); + + long spanId = Bytes.toLong(kv.getBuffer(), kv.getQualifierOffset()); + // 앞의 spanid가 int이므로 4. + final int spanIdOffset = 8; + short sequence = Bytes.toShort(kv.getBuffer(), kv.getQualifierOffset() + spanIdOffset); + spanEventBo.setSpanId(spanId); + spanEventBo.setSequence(sequence); + + spanEventBo.readValue(kv.getBuffer(), kv.getValueOffset()); + if (logger.isDebugEnabled()) { + logger.debug("read spanEvent :{}", spanEventBo); + } + spanEventBoList.add(spanEventBo); + } + } + for (SpanEventBo spanEventBo : spanEventBoList) { + SpanBo spanBo = spanMap.get(spanEventBo.getSpanId()); + if (spanBo != null) { + spanBo.addSpanEvent(spanEventBo); + } + } + if (annotationMapper != null) { + Map> annotationMap = annotationMapper.mapRow(result, rowNum); + addAnnotation(spanList, annotationMap); + } + + + return spanList; + + } + + private void addAnnotation(List spanList, Map> annotationMap) { + for (SpanBo bo : spanList) { + long spanID = bo.getSpanId(); + List anoList = annotationMap.get(spanID); + bo.setAnnotationBoList(anoList); + } + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SqlMetaDataMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SqlMetaDataMapper.java index 7a9cbf639d2d..0b7579640b9b 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SqlMetaDataMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SqlMetaDataMapper.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.web.mapper; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.common.bo.SqlMetaDataBo; - -/** - * @author emeroad - */ -@Component -public class SqlMetaDataMapper implements RowMapper> { - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - final byte[] rowKey = getOriginalKey(result.getRow()); - - List sqlMetaDataList = new ArrayList(); - KeyValue[] keyList = result.raw(); - for (KeyValue keyValue : keyList) { - SqlMetaDataBo sqlMetaDataBo = new SqlMetaDataBo(); - sqlMetaDataBo.readRowKey(rowKey); - String sql = Bytes.toString(keyValue.getBuffer(), keyValue.getQualifierOffset(), keyValue.getQualifierLength()); - sqlMetaDataBo.setSql(sql); - sqlMetaDataList.add(sqlMetaDataBo); - } - return sqlMetaDataList; - } - - private byte[] getOriginalKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getOriginalKey(rowKey); - } -} +package com.nhn.pinpoint.web.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; + +/** + * @author emeroad + */ +@Component +public class SqlMetaDataMapper implements RowMapper> { + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + final byte[] rowKey = getOriginalKey(result.getRow()); + + List sqlMetaDataList = new ArrayList(); + KeyValue[] keyList = result.raw(); + for (KeyValue keyValue : keyList) { + SqlMetaDataBo sqlMetaDataBo = new SqlMetaDataBo(); + sqlMetaDataBo.readRowKey(rowKey); + String sql = Bytes.toString(keyValue.getBuffer(), keyValue.getQualifierOffset(), keyValue.getQualifierLength()); + sqlMetaDataBo.setSql(sql); + sqlMetaDataList.add(sqlMetaDataBo); + } + return sqlMetaDataList; + } + + private byte[] getOriginalKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getOriginalKey(rowKey); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/StringMetaDataMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/StringMetaDataMapper.java index 0b25f1a3bda5..8496c1294b72 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/StringMetaDataMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/StringMetaDataMapper.java @@ -1,50 +1,50 @@ -package com.nhn.pinpoint.web.mapper; - -import com.nhn.pinpoint.common.bo.SqlMetaDataBo; -import com.nhn.pinpoint.common.bo.StringMetaDataBo; -import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * @author emeroad - */ -@Component -public class StringMetaDataMapper implements RowMapper> { - - @Autowired - @Qualifier("metadataRowKeyDistributor") - private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - final byte[] rowKey = getOriginalKey(result.getRow()); - - List stringMetaDataList = new ArrayList(); - KeyValue[] keyList = result.raw(); - for (KeyValue keyValue : keyList) { - StringMetaDataBo sqlMetaDataBo = new StringMetaDataBo(); - sqlMetaDataBo.readRowKey(rowKey); - String stringValue = Bytes.toString(keyValue.getBuffer(), keyValue.getQualifierOffset(), keyValue.getQualifierLength()); - sqlMetaDataBo.setStringValue(stringValue); - stringMetaDataList.add(sqlMetaDataBo); - } - return stringMetaDataList; - } - - private byte[] getOriginalKey(byte[] rowKey) { - return rowKeyDistributorByHashPrefix.getOriginalKey(rowKey); - } -} +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import com.nhn.pinpoint.common.bo.StringMetaDataBo; +import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author emeroad + */ +@Component +public class StringMetaDataMapper implements RowMapper> { + + @Autowired + @Qualifier("metadataRowKeyDistributor") + private RowKeyDistributorByHashPrefix rowKeyDistributorByHashPrefix; + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + final byte[] rowKey = getOriginalKey(result.getRow()); + + List stringMetaDataList = new ArrayList(); + KeyValue[] keyList = result.raw(); + for (KeyValue keyValue : keyList) { + StringMetaDataBo sqlMetaDataBo = new StringMetaDataBo(); + sqlMetaDataBo.readRowKey(rowKey); + String stringValue = Bytes.toString(keyValue.getBuffer(), keyValue.getQualifierOffset(), keyValue.getQualifierLength()); + sqlMetaDataBo.setStringValue(stringValue); + stringMetaDataList.add(sqlMetaDataBo); + } + return stringMetaDataList; + } + + private byte[] getOriginalKey(byte[] rowKey) { + return rowKeyDistributorByHashPrefix.getOriginalKey(rowKey); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper.java index 34a0e425cf22..e5300b9e5d0d 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper.java @@ -1,81 +1,81 @@ -package com.nhn.pinpoint.web.mapper; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.scatter.Dot; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.common.util.BytesUtils; - -/** - * @author emeroad - * @author netspider - */ -@Component -public class TraceIndexScatterMapper implements RowMapper> { - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - - KeyValue[] raw = result.raw(); - List list = new ArrayList(raw.length); - for (KeyValue kv : raw) { - final Dot dot = createDot(kv); - list.add(dot); - } - - return list; - } - - private Dot createDot(KeyValue kv) { - final byte[] buffer = kv.getBuffer(); - - final int valueOffset = kv.getValueOffset(); - final Buffer valueBuffer = new OffsetFixedBuffer(buffer, valueOffset); - int elapsed = valueBuffer.readVarInt(); - int exceptionCode = valueBuffer.readSVarInt(); - String agentId = valueBuffer.readPrefixedString(); - - long reverseAcceptedTime = BytesUtils.bytesToLong(buffer, kv.getRowOffset() + HBaseTables.APPLICATION_NAME_MAX_LEN + HBaseTables.APPLICATION_TRACE_INDEX_ROW_DISTRIBUTE_SIZE); - long acceptedTime = TimeUtils.recoveryTimeMillis(reverseAcceptedTime); - - final int qualifierOffset = kv.getQualifierOffset(); - - // TransactionId transactionId = new TransactionId(buffer, qualifierOffset); - // 잠시 TransactionIdMapper의 것을 사용하도록 함. - TransactionId transactionId = TransactionIdMapper.parseVarTransactionId(buffer, qualifierOffset); - - return new Dot(transactionId, acceptedTime, elapsed, exceptionCode, agentId); - } - - /* - public static TransactionId parseVarTransactionId(byte[] bytes, int offset) { - if (bytes == null) { - throw new NullPointerException("bytes must not be null"); - } - final Buffer buffer = new OffsetFixedBuffer(bytes, offset); - - // skip elapsed time (not used) hbase column prefix filter에서 filter용도로만 사용함. - // 데이터 사이즈를 줄일 수 있는지 모르겠음. - buffer.readInt(); - - String agentId = buffer.readPrefixedString(); - long agentStartTime = buffer.readSVarLong(); - long transactionSequence = buffer.readVarLong(); - return new TransactionId(agentId, agentStartTime, transactionSequence); - } - */ -} +package com.nhn.pinpoint.web.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.scatter.Dot; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.common.util.BytesUtils; + +/** + * @author emeroad + * @author netspider + */ +@Component +public class TraceIndexScatterMapper implements RowMapper> { + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + + KeyValue[] raw = result.raw(); + List list = new ArrayList(raw.length); + for (KeyValue kv : raw) { + final Dot dot = createDot(kv); + list.add(dot); + } + + return list; + } + + private Dot createDot(KeyValue kv) { + final byte[] buffer = kv.getBuffer(); + + final int valueOffset = kv.getValueOffset(); + final Buffer valueBuffer = new OffsetFixedBuffer(buffer, valueOffset); + int elapsed = valueBuffer.readVarInt(); + int exceptionCode = valueBuffer.readSVarInt(); + String agentId = valueBuffer.readPrefixedString(); + + long reverseAcceptedTime = BytesUtils.bytesToLong(buffer, kv.getRowOffset() + HBaseTables.APPLICATION_NAME_MAX_LEN + HBaseTables.APPLICATION_TRACE_INDEX_ROW_DISTRIBUTE_SIZE); + long acceptedTime = TimeUtils.recoveryTimeMillis(reverseAcceptedTime); + + final int qualifierOffset = kv.getQualifierOffset(); + + // TransactionId transactionId = new TransactionId(buffer, qualifierOffset); + // 잠시 TransactionIdMapper의 것을 사용하도록 함. + TransactionId transactionId = TransactionIdMapper.parseVarTransactionId(buffer, qualifierOffset); + + return new Dot(transactionId, acceptedTime, elapsed, exceptionCode, agentId); + } + + /* + public static TransactionId parseVarTransactionId(byte[] bytes, int offset) { + if (bytes == null) { + throw new NullPointerException("bytes must not be null"); + } + final Buffer buffer = new OffsetFixedBuffer(bytes, offset); + + // skip elapsed time (not used) hbase column prefix filter에서 filter용도로만 사용함. + // 데이터 사이즈를 줄일 수 있는지 모르겠음. + buffer.readInt(); + + String agentId = buffer.readPrefixedString(); + long agentStartTime = buffer.readSVarLong(); + long transactionSequence = buffer.readVarLong(); + return new TransactionId(agentId, agentStartTime, transactionSequence); + } + */ +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper2.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper2.java index 9b9068bbb52b..b0437cbfa6d0 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper2.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/TraceIndexScatterMapper2.java @@ -1,76 +1,76 @@ -package com.nhn.pinpoint.web.mapper; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.springframework.data.hadoop.hbase.RowMapper; - -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import com.nhn.pinpoint.common.hbase.HBaseTables; -import com.nhn.pinpoint.common.util.BytesUtils; -import com.nhn.pinpoint.common.util.TimeUtils; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.scatter.Dot; - -/** - * @author netspider - */ -public class TraceIndexScatterMapper2 implements RowMapper> { - - private final int responseOffsetFrom; - private final int responseOffsetTo; - - public TraceIndexScatterMapper2(int responseOffsetFrom, int responseOffsetTo) { - this.responseOffsetFrom = responseOffsetFrom; - this.responseOffsetTo = responseOffsetTo; - } - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - - KeyValue[] raw = result.raw(); - List list = new ArrayList(raw.length); - for (KeyValue kv : raw) { - final Dot dot = createDot(kv); - if (dot != null) { - list.add(dot); - } - } - - return list; - } - - private Dot createDot(KeyValue kv) { - final byte[] buffer = kv.getBuffer(); - - final int valueOffset = kv.getValueOffset(); - final Buffer valueBuffer = new OffsetFixedBuffer(buffer, valueOffset); - int elapsed = valueBuffer.readVarInt(); - - if (elapsed < responseOffsetFrom || elapsed > responseOffsetTo) { - return null; - } - - int exceptionCode = valueBuffer.readSVarInt(); - String agentId = valueBuffer.readPrefixedString(); - - long reverseAcceptedTime = BytesUtils.bytesToLong(buffer, kv.getRowOffset() + HBaseTables.APPLICATION_NAME_MAX_LEN + HBaseTables.APPLICATION_TRACE_INDEX_ROW_DISTRIBUTE_SIZE); - long acceptedTime = TimeUtils.recoveryTimeMillis(reverseAcceptedTime); - - final int qualifierOffset = kv.getQualifierOffset(); - - // TransactionId transactionId = new TransactionId(buffer, - // qualifierOffset); - // 잠시 TransactionIdMapper의 것을 사용하도록 함. - TransactionId transactionId = TransactionIdMapper.parseVarTransactionId(buffer, qualifierOffset); - - return new Dot(transactionId, acceptedTime, elapsed, exceptionCode, agentId); - } -} +package com.nhn.pinpoint.web.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.springframework.data.hadoop.hbase.RowMapper; + +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.scatter.Dot; + +/** + * @author netspider + */ +public class TraceIndexScatterMapper2 implements RowMapper> { + + private final int responseOffsetFrom; + private final int responseOffsetTo; + + public TraceIndexScatterMapper2(int responseOffsetFrom, int responseOffsetTo) { + this.responseOffsetFrom = responseOffsetFrom; + this.responseOffsetTo = responseOffsetTo; + } + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + + KeyValue[] raw = result.raw(); + List list = new ArrayList(raw.length); + for (KeyValue kv : raw) { + final Dot dot = createDot(kv); + if (dot != null) { + list.add(dot); + } + } + + return list; + } + + private Dot createDot(KeyValue kv) { + final byte[] buffer = kv.getBuffer(); + + final int valueOffset = kv.getValueOffset(); + final Buffer valueBuffer = new OffsetFixedBuffer(buffer, valueOffset); + int elapsed = valueBuffer.readVarInt(); + + if (elapsed < responseOffsetFrom || elapsed > responseOffsetTo) { + return null; + } + + int exceptionCode = valueBuffer.readSVarInt(); + String agentId = valueBuffer.readPrefixedString(); + + long reverseAcceptedTime = BytesUtils.bytesToLong(buffer, kv.getRowOffset() + HBaseTables.APPLICATION_NAME_MAX_LEN + HBaseTables.APPLICATION_TRACE_INDEX_ROW_DISTRIBUTE_SIZE); + long acceptedTime = TimeUtils.recoveryTimeMillis(reverseAcceptedTime); + + final int qualifierOffset = kv.getQualifierOffset(); + + // TransactionId transactionId = new TransactionId(buffer, + // qualifierOffset); + // 잠시 TransactionIdMapper의 것을 사용하도록 함. + TransactionId transactionId = TransactionIdMapper.parseVarTransactionId(buffer, qualifierOffset); + + return new Dot(transactionId, acceptedTime, elapsed, exceptionCode, agentId); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/TransactionIdMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/TransactionIdMapper.java index ad27244d25ae..14ad40969e72 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/TransactionIdMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/TransactionIdMapper.java @@ -1,65 +1,65 @@ -package com.nhn.pinpoint.web.mapper; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.nhn.pinpoint.common.buffer.Buffer; -import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.pinpoint.web.vo.TransactionId; - -/** - * @author emeroad - * @author netspider - */ -@Component -public class TransactionIdMapper implements RowMapper> { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - // @Autowired - // private AbstractRowKeyDistributor rowKeyDistributor; - - @Override - public List mapRow(Result result, int rowNum) throws Exception { - if (result.isEmpty()) { - return Collections.emptyList(); - } - KeyValue[] raw = result.raw(); - List traceIdList = new ArrayList(raw.length); - for (KeyValue kv : raw) { - byte[] buffer = kv.getBuffer(); - int qualifierOffset = kv.getQualifierOffset(); - // key값만큼 1증가 시킴 - TransactionId traceId = parseVarTransactionId(buffer, qualifierOffset); - traceIdList.add(traceId); - - logger.debug("found traceId {}", traceId); - } - return traceIdList; - } - - // 중복시킴. TraceIndexScatterMapper랑 동일하므로 같이 변경하거나 리팩토링 할것. - public static TransactionId parseVarTransactionId(byte[] bytes, int offset) { - if (bytes == null) { - throw new NullPointerException("bytes must not be null"); - } - final Buffer buffer = new OffsetFixedBuffer(bytes, offset); - - // skip elapsed time (not used) hbase column prefix filter에서 filter용도로만 사용함. - // 데이터 사이즈를 줄일 수 있는지 모르겠음. - // buffer.readInt(); - - String agentId = buffer.readPrefixedString(); - long agentStartTime = buffer.readSVarLong(); - long transactionSequence = buffer.readVarLong(); - return new TransactionId(agentId, agentStartTime, transactionSequence); - } -} +package com.nhn.pinpoint.web.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.nhn.pinpoint.common.buffer.Buffer; +import com.nhn.pinpoint.common.buffer.OffsetFixedBuffer; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import com.nhn.pinpoint.web.vo.TransactionId; + +/** + * @author emeroad + * @author netspider + */ +@Component +public class TransactionIdMapper implements RowMapper> { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + // @Autowired + // private AbstractRowKeyDistributor rowKeyDistributor; + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + if (result.isEmpty()) { + return Collections.emptyList(); + } + KeyValue[] raw = result.raw(); + List traceIdList = new ArrayList(raw.length); + for (KeyValue kv : raw) { + byte[] buffer = kv.getBuffer(); + int qualifierOffset = kv.getQualifierOffset(); + // key값만큼 1증가 시킴 + TransactionId traceId = parseVarTransactionId(buffer, qualifierOffset); + traceIdList.add(traceId); + + logger.debug("found traceId {}", traceId); + } + return traceIdList; + } + + // 중복시킴. TraceIndexScatterMapper랑 동일하므로 같이 변경하거나 리팩토링 할것. + public static TransactionId parseVarTransactionId(byte[] bytes, int offset) { + if (bytes == null) { + throw new NullPointerException("bytes must not be null"); + } + final Buffer buffer = new OffsetFixedBuffer(bytes, offset); + + // skip elapsed time (not used) hbase column prefix filter에서 filter용도로만 사용함. + // 데이터 사이즈를 줄일 수 있는지 모르겠음. + // buffer.readInt(); + + String agentId = buffer.readPrefixedString(); + long agentStartTime = buffer.readSVarLong(); + long transactionSequence = buffer.readVarLong(); + return new TransactionId(agentId, agentStartTime, transactionSequence); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/scheduler/AlarmScheduler.java b/web/src/main/java/com/navercorp/pinpoint/web/scheduler/AlarmScheduler.java index a120d2db5cc8..893150207784 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/scheduler/AlarmScheduler.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/scheduler/AlarmScheduler.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.web.scheduler; - - -public interface AlarmScheduler { - - void initialize(); - - void execute(); - -} +package com.nhn.pinpoint.web.scheduler; + + +public interface AlarmScheduler { + + void initialize(); + + void execute(); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/scheduler/DefaultAlarmScheduler.java b/web/src/main/java/com/navercorp/pinpoint/web/scheduler/DefaultAlarmScheduler.java index bb02e63ba7aa..43347b0c7409 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/scheduler/DefaultAlarmScheduler.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/scheduler/DefaultAlarmScheduler.java @@ -1,227 +1,227 @@ -package com.nhn.pinpoint.web.scheduler; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.CollectionUtils; - -import com.nhn.pinpoint.web.alarm.AlarmEvent; -import com.nhn.pinpoint.web.alarm.AlarmJob; -import com.nhn.pinpoint.web.alarm.AlarmJobsRepository; -import com.nhn.pinpoint.web.alarm.DefaultAlarmEvent; -import com.nhn.pinpoint.web.alarm.DefaultAlarmJob; -import com.nhn.pinpoint.web.alarm.DefaultAlarmJobsRepository; -import com.nhn.pinpoint.web.alarm.MainCategory; -import com.nhn.pinpoint.web.alarm.SubCategory; -import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; -import com.nhn.pinpoint.web.alarm.filter.AlarmMailSendFilter; -import com.nhn.pinpoint.web.alarm.filter.AlarmSendFilter; -import com.nhn.pinpoint.web.alarm.filter.AlarmSmsSendFilter; -import com.nhn.pinpoint.web.alarm.resource.MailResource; -import com.nhn.pinpoint.web.alarm.resource.SmsResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmContactGroupResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmContactResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleGroupResource; -import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; -import com.nhn.pinpoint.web.dao.AlarmResourceDao; -import com.nhn.pinpoint.web.dao.ApplicationIndexDao; -import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; -import com.nhn.pinpoint.web.vo.Application; - -/** - * - * @author koo.taejin - */ -public class DefaultAlarmScheduler implements AlarmScheduler { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private AlarmJobsRepository repository; - - @Autowired - MailResource mailResource; - - @Autowired - SmsResource smsResource; - - @Autowired - private AlarmResourceDao alarmResourceDao; - - @Autowired - private ApplicationIndexDao applicationIndexDao; - - @Autowired - private MapStatisticsCallerDao mapStatisticsCallerDao; - - @Override - public void initialize() { - logger.info("{} initialize.", this.getClass().getName()); - - DefaultAlarmJobsRepository repository = new DefaultAlarmJobsRepository(); - - List applicationList = applicationIndexDao.selectAllApplicationNames(); - List alarmResourceList = alarmResourceDao.selectAlarmList(); - - for (AlarmResource alarmResource : alarmResourceList) { - String agentId = alarmResource.getAgentId(); - - Application application = findApplication(agentId, applicationList); - if (application == null) { - logger.warn("Can't find Application({}).", agentId); - continue; - } - - AlarmJob job = createAlarmJob(application, alarmResource); - if (job == null) { - continue; - } - - repository.addAlarmJob(application, job); - } - - logger.info("{} initilization success(Registred {} Jobs). ", this.getClass().getName(), repository.getTotalJobCount()); - - synchronized (this) { - this.repository = repository; - } - } - - @Override - public void execute() { - logger.info("{} execute.", this.getClass().getName()); - - AlarmEvent event = createAlarmEvent(); - - synchronized (this) { - if (this.repository == null) { - logger.warn("{}'s repository is null. this job will be skipped.", this.getClass().getName()); - return; - } - - int totalJobCount = this.repository.getTotalJobCount(); - - List applicationList = this.repository.getRegistedApplicationList(); - for (Application application : applicationList) { - executeEachApplication(application, event, totalJobCount); - } - } - - } - - private Application findApplication(String applicationName, List applicationList) { - for (Application application : applicationList) { - if (application.getName().equalsIgnoreCase(applicationName)) { - return application; - } - } - - return null; - } - - private AlarmJob createAlarmJob(Application application, AlarmResource resource) { - DefaultAlarmJob alarmJob = new DefaultAlarmJob(application); - - String applicationName = application.getName(); - String alarmName = resource.getAlarmGroupName(); - - AlarmContactGroupResource contactGroup = resource.getAlarmContactGroup(); - if (contactGroup == null || CollectionUtils.isEmpty(contactGroup.getAlarmContactList())) { - logger.warn("Application={}, Rule={} does not have contact resource.", applicationName, alarmName); - return null; - } - List contactResourceList = contactGroup.getAlarmContactList(); - List alarmSendFilterList = createAlarmSendFilter(application, contactResourceList); - if (CollectionUtils.isEmpty(alarmSendFilterList)) { - logger.warn("Application={}, Rule={} can't find valid contact resource.", applicationName, alarmName); - return null; - } - alarmJob.addFilter(alarmSendFilterList); - - AlarmRuleGroupResource ruleGroup = resource.getAlarmRuleGroup(); - if (ruleGroup == null || CollectionUtils.isEmpty(ruleGroup.getAlarmRuleList())) { - logger.warn("Application={}, Rule={} does not have rule resource.", applicationName, alarmName); - return null; - } - List alarmRuleList = ruleGroup.getAlarmRuleList(); - List alarmCheckFilterList = createAlarmCheckFilter(application, alarmRuleList); - alarmJob.addFilter(alarmCheckFilterList); - if (CollectionUtils.isEmpty(alarmCheckFilterList)) { - logger.warn("Application={}, Rule={} can't find valid rule resource.", applicationName, alarmName); - return null; - } - - return alarmJob; - } - - private List createAlarmSendFilter(Application application, List contactResourceList) { - List phoneNumberList = new ArrayList(); - List emailAddressList = new ArrayList(); - - for (AlarmContactResource contactResource : contactResourceList) { - String phoneNumber = contactResource.getPhoneNum(); - if (!StringUtils.isEmpty(phoneNumber)) { - phoneNumberList.add(phoneNumber); - } - - String emailAddress = contactResource.getEmailAddress(); - if (!StringUtils.isEmpty(emailAddress)) { - emailAddressList.add(emailAddress); - } - } - - List alarmSendFilter = new ArrayList(); - - if (!CollectionUtils.isEmpty(phoneNumberList)) { - AlarmSendFilter smsSendFilter = new AlarmSmsSendFilter(application, smsResource, phoneNumberList); - alarmSendFilter.add(smsSendFilter); - } - - if (!CollectionUtils.isEmpty(emailAddressList)) { - AlarmSendFilter emailSendFilter = new AlarmMailSendFilter(application, mailResource, emailAddressList); - alarmSendFilter.add(emailSendFilter); - } - - return alarmSendFilter; - } - - private List createAlarmCheckFilter(Application application, List ruleResourceList) { - List alarmCheckFilterList = new ArrayList(); - - for (AlarmRuleResource ruleResource : ruleResourceList) { - MainCategory mainCategory = ruleResource.getMainCategory(); - SubCategory subCategory = ruleResource.getSubCategory(); - - AlarmCheckFilter alarmCheckFilter = subCategory.createAlarmFilter(application, mainCategory, ruleResource); - if (alarmCheckFilter == null) { - logger.warn("{}({}) can't build Filter.", ruleResource.getAlarmRuleName(), ruleResource.getId()); - continue; - } - alarmCheckFilterList.add(alarmCheckFilter); - } - - return alarmCheckFilterList; - } - - private AlarmEvent createAlarmEvent() { - DefaultAlarmEvent event = new DefaultAlarmEvent(System.currentTimeMillis()); - event.setMapStatisticsCallerDao(mapStatisticsCallerDao); - - return event; - } - - private void executeEachApplication(Application application, AlarmEvent event, int totalJobCount) { - List jobList = repository.getAlarmJob(application); - AtomicInteger index = new AtomicInteger(1); - for (AlarmJob job : jobList) { - logger.debug("{} ({}/{}) jobs start(TotalJobCount={}).", application.getName(), index.getAndIncrement(), jobList.size(), totalJobCount); - job.execute(event); - } - } - -} +package com.nhn.pinpoint.web.scheduler; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; + +import com.nhn.pinpoint.web.alarm.AlarmEvent; +import com.nhn.pinpoint.web.alarm.AlarmJob; +import com.nhn.pinpoint.web.alarm.AlarmJobsRepository; +import com.nhn.pinpoint.web.alarm.DefaultAlarmEvent; +import com.nhn.pinpoint.web.alarm.DefaultAlarmJob; +import com.nhn.pinpoint.web.alarm.DefaultAlarmJobsRepository; +import com.nhn.pinpoint.web.alarm.MainCategory; +import com.nhn.pinpoint.web.alarm.SubCategory; +import com.nhn.pinpoint.web.alarm.filter.AlarmCheckFilter; +import com.nhn.pinpoint.web.alarm.filter.AlarmMailSendFilter; +import com.nhn.pinpoint.web.alarm.filter.AlarmSendFilter; +import com.nhn.pinpoint.web.alarm.filter.AlarmSmsSendFilter; +import com.nhn.pinpoint.web.alarm.resource.MailResource; +import com.nhn.pinpoint.web.alarm.resource.SmsResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmContactGroupResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmContactResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleGroupResource; +import com.nhn.pinpoint.web.alarm.vo.AlarmRuleResource; +import com.nhn.pinpoint.web.dao.AlarmResourceDao; +import com.nhn.pinpoint.web.dao.ApplicationIndexDao; +import com.nhn.pinpoint.web.dao.MapStatisticsCallerDao; +import com.nhn.pinpoint.web.vo.Application; + +/** + * + * @author koo.taejin + */ +public class DefaultAlarmScheduler implements AlarmScheduler { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private AlarmJobsRepository repository; + + @Autowired + MailResource mailResource; + + @Autowired + SmsResource smsResource; + + @Autowired + private AlarmResourceDao alarmResourceDao; + + @Autowired + private ApplicationIndexDao applicationIndexDao; + + @Autowired + private MapStatisticsCallerDao mapStatisticsCallerDao; + + @Override + public void initialize() { + logger.info("{} initialize.", this.getClass().getName()); + + DefaultAlarmJobsRepository repository = new DefaultAlarmJobsRepository(); + + List applicationList = applicationIndexDao.selectAllApplicationNames(); + List alarmResourceList = alarmResourceDao.selectAlarmList(); + + for (AlarmResource alarmResource : alarmResourceList) { + String agentId = alarmResource.getAgentId(); + + Application application = findApplication(agentId, applicationList); + if (application == null) { + logger.warn("Can't find Application({}).", agentId); + continue; + } + + AlarmJob job = createAlarmJob(application, alarmResource); + if (job == null) { + continue; + } + + repository.addAlarmJob(application, job); + } + + logger.info("{} initilization success(Registred {} Jobs). ", this.getClass().getName(), repository.getTotalJobCount()); + + synchronized (this) { + this.repository = repository; + } + } + + @Override + public void execute() { + logger.info("{} execute.", this.getClass().getName()); + + AlarmEvent event = createAlarmEvent(); + + synchronized (this) { + if (this.repository == null) { + logger.warn("{}'s repository is null. this job will be skipped.", this.getClass().getName()); + return; + } + + int totalJobCount = this.repository.getTotalJobCount(); + + List applicationList = this.repository.getRegistedApplicationList(); + for (Application application : applicationList) { + executeEachApplication(application, event, totalJobCount); + } + } + + } + + private Application findApplication(String applicationName, List applicationList) { + for (Application application : applicationList) { + if (application.getName().equalsIgnoreCase(applicationName)) { + return application; + } + } + + return null; + } + + private AlarmJob createAlarmJob(Application application, AlarmResource resource) { + DefaultAlarmJob alarmJob = new DefaultAlarmJob(application); + + String applicationName = application.getName(); + String alarmName = resource.getAlarmGroupName(); + + AlarmContactGroupResource contactGroup = resource.getAlarmContactGroup(); + if (contactGroup == null || CollectionUtils.isEmpty(contactGroup.getAlarmContactList())) { + logger.warn("Application={}, Rule={} does not have contact resource.", applicationName, alarmName); + return null; + } + List contactResourceList = contactGroup.getAlarmContactList(); + List alarmSendFilterList = createAlarmSendFilter(application, contactResourceList); + if (CollectionUtils.isEmpty(alarmSendFilterList)) { + logger.warn("Application={}, Rule={} can't find valid contact resource.", applicationName, alarmName); + return null; + } + alarmJob.addFilter(alarmSendFilterList); + + AlarmRuleGroupResource ruleGroup = resource.getAlarmRuleGroup(); + if (ruleGroup == null || CollectionUtils.isEmpty(ruleGroup.getAlarmRuleList())) { + logger.warn("Application={}, Rule={} does not have rule resource.", applicationName, alarmName); + return null; + } + List alarmRuleList = ruleGroup.getAlarmRuleList(); + List alarmCheckFilterList = createAlarmCheckFilter(application, alarmRuleList); + alarmJob.addFilter(alarmCheckFilterList); + if (CollectionUtils.isEmpty(alarmCheckFilterList)) { + logger.warn("Application={}, Rule={} can't find valid rule resource.", applicationName, alarmName); + return null; + } + + return alarmJob; + } + + private List createAlarmSendFilter(Application application, List contactResourceList) { + List phoneNumberList = new ArrayList(); + List emailAddressList = new ArrayList(); + + for (AlarmContactResource contactResource : contactResourceList) { + String phoneNumber = contactResource.getPhoneNum(); + if (!StringUtils.isEmpty(phoneNumber)) { + phoneNumberList.add(phoneNumber); + } + + String emailAddress = contactResource.getEmailAddress(); + if (!StringUtils.isEmpty(emailAddress)) { + emailAddressList.add(emailAddress); + } + } + + List alarmSendFilter = new ArrayList(); + + if (!CollectionUtils.isEmpty(phoneNumberList)) { + AlarmSendFilter smsSendFilter = new AlarmSmsSendFilter(application, smsResource, phoneNumberList); + alarmSendFilter.add(smsSendFilter); + } + + if (!CollectionUtils.isEmpty(emailAddressList)) { + AlarmSendFilter emailSendFilter = new AlarmMailSendFilter(application, mailResource, emailAddressList); + alarmSendFilter.add(emailSendFilter); + } + + return alarmSendFilter; + } + + private List createAlarmCheckFilter(Application application, List ruleResourceList) { + List alarmCheckFilterList = new ArrayList(); + + for (AlarmRuleResource ruleResource : ruleResourceList) { + MainCategory mainCategory = ruleResource.getMainCategory(); + SubCategory subCategory = ruleResource.getSubCategory(); + + AlarmCheckFilter alarmCheckFilter = subCategory.createAlarmFilter(application, mainCategory, ruleResource); + if (alarmCheckFilter == null) { + logger.warn("{}({}) can't build Filter.", ruleResource.getAlarmRuleName(), ruleResource.getId()); + continue; + } + alarmCheckFilterList.add(alarmCheckFilter); + } + + return alarmCheckFilterList; + } + + private AlarmEvent createAlarmEvent() { + DefaultAlarmEvent event = new DefaultAlarmEvent(System.currentTimeMillis()); + event.setMapStatisticsCallerDao(mapStatisticsCallerDao); + + return event; + } + + private void executeEachApplication(Application application, AlarmEvent event, int totalJobCount) { + List jobList = repository.getAlarmJob(application); + AtomicInteger index = new AtomicInteger(1); + for (AlarmJob job : jobList) { + logger.debug("{} ({}/{}) jobs start(TotalJobCount={}).", application.getName(), index.getAndIncrement(), jobList.size(), totalJobCount); + job.execute(event); + } + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java b/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java index f820d41e78ce..0fab39390412 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java @@ -76,6 +76,7 @@ public void start() throws KeeperException, IOException, InterruptedException { this.clusterManager = new ZookeeperClusterManager(config.getClusterZookeeperAddress(), config.getClusterZookeeperSessionTimeout(), config.getClusterZookeeperRetryInterval()); + // TODO 여기서 수정이 필요함 // json list는 표준규칙이 아니기 때문에 ip\r\n으로 저장 this.clusterManager.registerWebCluster(nodeName, convertIpListToBytes(localIpList, "\r\n")); } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentIdNotFoundException.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentIdNotFoundException.java index 138a3a12010d..e846219aedde 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentIdNotFoundException.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentIdNotFoundException.java @@ -1,25 +1,25 @@ -package com.nhn.pinpoint.web.service; - -/** - * @author emeroad - */ -public class AgentIdNotFoundException extends RuntimeException { - - private String agentId; - private long startTime; - - public AgentIdNotFoundException(String agentId, long startTime) { - super("agentId:" + agentId + " startTime:" + startTime + " not found"); - this.agentId = agentId; - this.startTime = startTime; - } - - public String getAgentId() { - return agentId; - } - - public long getStartTime() { - return startTime; - } - -} +package com.nhn.pinpoint.web.service; + +/** + * @author emeroad + */ +public class AgentIdNotFoundException extends RuntimeException { + + private String agentId; + private long startTime; + + public AgentIdNotFoundException(String agentId, long startTime) { + super("agentId:" + agentId + " startTime:" + startTime + " not found"); + this.agentId = agentId; + this.startTime = startTime; + } + + public String getAgentId() { + return agentId; + } + + public long getStartTime() { + return startTime; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java index 6a1c48d2aee3..d72ef9827547 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.web.service; - -import java.util.List; -import java.util.Set; -import java.util.SortedMap; - -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.web.vo.Range; - -/** - * @author netspider - */ -public interface AgentInfoService { - SortedMap> getApplicationAgentList(String applicationName, Range range); - - - Set selectAgent(String applicationId, Range range); -} +package com.nhn.pinpoint.web.service; + +import java.util.List; +import java.util.Set; +import java.util.SortedMap; + +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.web.vo.Range; + +/** + * @author netspider + */ +public interface AgentInfoService { + SortedMap> getApplicationAgentList(String applicationName, Range range); + + + Set selectAgent(String applicationId, Range range); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java index 5896d46c8222..5e76e9b20f5e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java @@ -1,102 +1,102 @@ -package com.nhn.pinpoint.web.service; - -import java.util.*; - -import com.nhn.pinpoint.web.vo.Range; -import org.apache.commons.collections.CollectionUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.nhn.pinpoint.common.bo.AgentInfoBo; -import com.nhn.pinpoint.web.dao.AgentInfoDao; -import com.nhn.pinpoint.web.dao.ApplicationIndexDao; - -/** - * - * @author netspider - * - */ -@Service -public class AgentInfoServiceImpl implements AgentInfoService { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private ApplicationIndexDao applicationIndexDao; - - @Autowired - private AgentInfoDao agentInfoDao; - - /** - * FIXME 인터페이스에 from, to가 있으나 실제로 사용되지 않음. 나중에 agent list snapshot기능이 추가되면 - * 사용될 것임. - */ - @Override - public SortedMap> getApplicationAgentList(String applicationName, Range range) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - final List agentIdList = applicationIndexDao.selectAgentIds(applicationName); - if (logger.isDebugEnabled()) { - logger.debug("agentIdList={}", agentIdList); - } - - if (CollectionUtils.isEmpty(agentIdList)) { - logger.debug("agentIdList is empty. applicationName={}, {}", applicationName, range); - return new TreeMap>(); - } - - // key = hostname - // value= list fo agentinfo - SortedMap> result = new TreeMap>(); - - for (String agentId : agentIdList) { - List agentInfoList = agentInfoDao.getAgentInfo(agentId, range); - - if (agentInfoList.isEmpty()) { - logger.debug("agentinfolist is empty. agentid={}, {}", agentId, range); - continue; - } - - // FIXME 지금은 그냥 첫 번재꺼 사용. 여러개 검사?는 나중에 생각해볼 예정. - AgentInfoBo agentInfo = agentInfoList.get(0); - String hostname = agentInfo.getHostname(); - - if (result.containsKey(hostname)) { - result.get(hostname).add(agentInfo); - } else { - List list = new ArrayList(); - list.add(agentInfo); - result.put(hostname, list); - } - } - - for (List agentInfoBoList : result.values()) { - Collections.sort(agentInfoBoList, AgentInfoBo.AGENT_NAME_ASC_COMPARATOR); - } - - logger.info("getApplicationAgentList={}", result); - - return result; - } - - public Set selectAgent(String applicationId, Range range) { - if (applicationId == null) { - throw new NullPointerException("applicationId must not be null"); - } - - List agentIds = applicationIndexDao.selectAgentIds(applicationId); - Set agentSet = new HashSet(); - for (String agentId : agentIds) { - // TODO 조회 시간대에 따라서 agent info row timestamp를 변경하여 조회해야하는지는 모르겠음. - // 과거에 조회하였을 경우 이를 과거 시간을 기준으로 거슬러 올라가도록 to를 넣어서 조회하도록 임시 수정. - AgentInfoBo info = agentInfoDao.findAgentInfoBeforeStartTime(agentId, range.getTo()); - if (info != null) { - agentSet.add(info); - } - } - return agentSet; - } -} +package com.nhn.pinpoint.web.service; + +import java.util.*; + +import com.nhn.pinpoint.web.vo.Range; +import org.apache.commons.collections.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.web.dao.AgentInfoDao; +import com.nhn.pinpoint.web.dao.ApplicationIndexDao; + +/** + * + * @author netspider + * + */ +@Service +public class AgentInfoServiceImpl implements AgentInfoService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private ApplicationIndexDao applicationIndexDao; + + @Autowired + private AgentInfoDao agentInfoDao; + + /** + * FIXME 인터페이스에 from, to가 있으나 실제로 사용되지 않음. 나중에 agent list snapshot기능이 추가되면 + * 사용될 것임. + */ + @Override + public SortedMap> getApplicationAgentList(String applicationName, Range range) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + final List agentIdList = applicationIndexDao.selectAgentIds(applicationName); + if (logger.isDebugEnabled()) { + logger.debug("agentIdList={}", agentIdList); + } + + if (CollectionUtils.isEmpty(agentIdList)) { + logger.debug("agentIdList is empty. applicationName={}, {}", applicationName, range); + return new TreeMap>(); + } + + // key = hostname + // value= list fo agentinfo + SortedMap> result = new TreeMap>(); + + for (String agentId : agentIdList) { + List agentInfoList = agentInfoDao.getAgentInfo(agentId, range); + + if (agentInfoList.isEmpty()) { + logger.debug("agentinfolist is empty. agentid={}, {}", agentId, range); + continue; + } + + // FIXME 지금은 그냥 첫 번재꺼 사용. 여러개 검사?는 나중에 생각해볼 예정. + AgentInfoBo agentInfo = agentInfoList.get(0); + String hostname = agentInfo.getHostname(); + + if (result.containsKey(hostname)) { + result.get(hostname).add(agentInfo); + } else { + List list = new ArrayList(); + list.add(agentInfo); + result.put(hostname, list); + } + } + + for (List agentInfoBoList : result.values()) { + Collections.sort(agentInfoBoList, AgentInfoBo.AGENT_NAME_ASC_COMPARATOR); + } + + logger.info("getApplicationAgentList={}", result); + + return result; + } + + public Set selectAgent(String applicationId, Range range) { + if (applicationId == null) { + throw new NullPointerException("applicationId must not be null"); + } + + List agentIds = applicationIndexDao.selectAgentIds(applicationId); + Set agentSet = new HashSet(); + for (String agentId : agentIds) { + // TODO 조회 시간대에 따라서 agent info row timestamp를 변경하여 조회해야하는지는 모르겠음. + // 과거에 조회하였을 경우 이를 과거 시간을 기준으로 거슬러 올라가도록 to를 넣어서 조회하도록 임시 수정. + AgentInfoBo info = agentInfoDao.findAgentInfoBeforeStartTime(agentId, range.getTo()); + if (info != null) { + agentSet.add(info); + } + } + return agentSet; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentStatServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentStatServiceImpl.java index cd40ac0f18bf..1250aab37383 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentStatServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentStatServiceImpl.java @@ -1,30 +1,30 @@ -package com.nhn.pinpoint.web.service; - -import java.util.List; - -import com.nhn.pinpoint.web.vo.AgentStat; -import com.nhn.pinpoint.web.vo.Range; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.nhn.pinpoint.web.dao.AgentStatDao; - -/** - * @author harebox - * @author hyungil.jeong - */ -@Service -public class AgentStatServiceImpl implements AgentStatService { - - @Autowired - private AgentStatDao agentStatDao; - - public List selectAgentStatList(String agentId, Range range) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - return agentStatDao.scanAgentStatList(agentId, range); - } - -} +package com.nhn.pinpoint.web.service; + +import java.util.List; + +import com.nhn.pinpoint.web.vo.AgentStat; +import com.nhn.pinpoint.web.vo.Range; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.nhn.pinpoint.web.dao.AgentStatDao; + +/** + * @author harebox + * @author hyungil.jeong + */ +@Service +public class AgentStatServiceImpl implements AgentStatService { + + @Autowired + private AgentStatDao agentStatDao; + + public List selectAgentStatList(String agentId, Range range) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + return agentStatDao.scanAgentStatList(agentId, range); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/CommonService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/CommonService.java index 01876696aa94..8d0e0b6f89c2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/CommonService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/CommonService.java @@ -1,14 +1,14 @@ -package com.nhn.pinpoint.web.service; - -import java.util.List; - -import com.nhn.pinpoint.web.vo.Application; - -/** - * @author netspider - */ -public interface CommonService { - - public List selectAllApplicationNames(); - -} +package com.nhn.pinpoint.web.service; + +import java.util.List; + +import com.nhn.pinpoint.web.vo.Application; + +/** + * @author netspider + */ +public interface CommonService { + + public List selectAllApplicationNames(); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/CommonServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/CommonServiceImpl.java index 112727a3ae52..0d6e100a79be 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/CommonServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/CommonServiceImpl.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.web.service; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.nhn.pinpoint.web.dao.ApplicationIndexDao; -import com.nhn.pinpoint.web.vo.Application; - -/** - * @author netspider - */ -@Service -public class CommonServiceImpl implements CommonService { - - @Autowired - private ApplicationIndexDao applicationIndexDao; - - @Override - public List selectAllApplicationNames() { - return applicationIndexDao.selectAllApplicationNames(); - } -} +package com.nhn.pinpoint.web.service; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.nhn.pinpoint.web.dao.ApplicationIndexDao; +import com.nhn.pinpoint.web.vo.Application; + +/** + * @author netspider + */ +@Service +public class CommonServiceImpl implements CommonService { + + @Autowired + private ApplicationIndexDao applicationIndexDao; + + @Override + public List selectAllApplicationNames() { + return applicationIndexDao.selectAllApplicationNames(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/DotExtractor.java b/web/src/main/java/com/navercorp/pinpoint/web/service/DotExtractor.java index c1fe3b6d8aa3..cf207863386b 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/DotExtractor.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/DotExtractor.java @@ -1,66 +1,66 @@ -package com.nhn.pinpoint.web.service; - -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.web.vo.*; -import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; -import com.nhn.pinpoint.web.vo.scatter.Dot; -import com.nhn.pinpoint.web.vo.scatter.ScatterScanResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author emeroad - */ -public class DotExtractor { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final Range range; - - private Map> dotMap = new HashMap>(); - - public DotExtractor(Range range) { - if (range == null) { - throw new NullPointerException("range must not be null"); - } - this.range = range; - } - - public void addDot(SpanBo span) { - if (span == null) { - throw new NullPointerException("span must not be null"); - } - - Application spanApplication = new Application(span.getApplicationId(), span.getServiceType()); - final List dotList = getDotList(spanApplication); - - final TransactionId transactionId = new TransactionId(span.getTraceAgentId(), span.getTraceAgentStartTime(), span.getTraceTransactionSequence()); - final Dot dot = new Dot(transactionId, span.getCollectorAcceptTime(), span.getElapsed(), span.getErrCode(), span.getAgentId()); - dotList.add(dot); - logger.trace("Application:{} Dot:{}", spanApplication, dot); - } - - private List getDotList(Application spanApplication) { - List dotList = this.dotMap.get(spanApplication); - if(dotList == null) { - dotList = new ArrayList(); - this.dotMap.put(spanApplication, dotList); - } - return dotList; - } - - public List getApplicationScatterScanResult() { - List applicationScatterScanResult = new ArrayList(); - for (Map.Entry> entry : this.dotMap.entrySet()) { - List dotList = entry.getValue(); - Application application = entry.getKey(); - ScatterScanResult scatterScanResult = new ScatterScanResult(range.getFrom(), range.getTo(), dotList); - applicationScatterScanResult.add(new ApplicationScatterScanResult(application, scatterScanResult)); - } - return applicationScatterScanResult; - } -} +package com.nhn.pinpoint.web.service; + +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.web.vo.*; +import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; +import com.nhn.pinpoint.web.vo.scatter.Dot; +import com.nhn.pinpoint.web.vo.scatter.ScatterScanResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author emeroad + */ +public class DotExtractor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Range range; + + private Map> dotMap = new HashMap>(); + + public DotExtractor(Range range) { + if (range == null) { + throw new NullPointerException("range must not be null"); + } + this.range = range; + } + + public void addDot(SpanBo span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + + Application spanApplication = new Application(span.getApplicationId(), span.getServiceType()); + final List dotList = getDotList(spanApplication); + + final TransactionId transactionId = new TransactionId(span.getTraceAgentId(), span.getTraceAgentStartTime(), span.getTraceTransactionSequence()); + final Dot dot = new Dot(transactionId, span.getCollectorAcceptTime(), span.getElapsed(), span.getErrCode(), span.getAgentId()); + dotList.add(dot); + logger.trace("Application:{} Dot:{}", spanApplication, dot); + } + + private List getDotList(Application spanApplication) { + List dotList = this.dotMap.get(spanApplication); + if(dotList == null) { + dotList = new ArrayList(); + this.dotMap.put(spanApplication, dotList); + } + return dotList; + } + + public List getApplicationScatterScanResult() { + List applicationScatterScanResult = new ArrayList(); + for (Map.Entry> entry : this.dotMap.entrySet()) { + List dotList = entry.getValue(); + Application application = entry.getKey(); + ScatterScanResult scatterScanResult = new ScatterScanResult(range.getFrom(), range.getTo(), dotList); + applicationScatterScanResult.add(new ApplicationScatterScanResult(application, scatterScanResult)); + } + return applicationScatterScanResult; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapService.java index 140ab0c9333d..6e5756e6e2a3 100755 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapService.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.web.service; - -import java.util.List; - -import com.nhn.pinpoint.web.applicationmap.ApplicationMap; -import com.nhn.pinpoint.web.filter.Filter; -import com.nhn.pinpoint.web.vo.*; - -/** - * @author netspider - * @author emeroad - */ -public interface FilteredMapService { - - public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, Range range, int limit); - - public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, SelectedScatterArea area, int limit); - - public LoadFactor linkStatistics(Range range, List traceIdSet, Application sourceApplication, Application destinationApplication, Filter filter); - - public ApplicationMap selectApplicationMap(List traceIdList, Range originalRange, Range scanRange, Filter filter); - - public ApplicationMap selectApplicationMap(TransactionId transactionId); -} +package com.nhn.pinpoint.web.service; + +import java.util.List; + +import com.nhn.pinpoint.web.applicationmap.ApplicationMap; +import com.nhn.pinpoint.web.filter.Filter; +import com.nhn.pinpoint.web.vo.*; + +/** + * @author netspider + * @author emeroad + */ +public interface FilteredMapService { + + public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, Range range, int limit); + + public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, SelectedScatterArea area, int limit); + + public LoadFactor linkStatistics(Range range, List traceIdSet, Application sourceApplication, Application destinationApplication, Filter filter); + + public ApplicationMap selectApplicationMap(List traceIdList, Range originalRange, Range scanRange, Filter filter); + + public ApplicationMap selectApplicationMap(TransactionId transactionId); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapServiceImpl.java index 2338e5909aa6..051dbc9384e0 100755 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/FilteredMapServiceImpl.java @@ -1,391 +1,391 @@ -package com.nhn.pinpoint.web.service; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.HistogramSlot; -import com.nhn.pinpoint.web.applicationmap.ApplicationMapBuilder; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataDuplexMap; -import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; -import com.nhn.pinpoint.web.util.TimeWindow; -import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; -import com.nhn.pinpoint.web.dao.*; -import com.nhn.pinpoint.web.vo.*; -import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.StopWatch; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.web.applicationmap.ApplicationMap; -import com.nhn.pinpoint.web.filter.Filter; - -/** - * @author netspider - * @author emeroad - */ -@Service -public class FilteredMapServiceImpl implements FilteredMapService { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private TraceDao traceDao; - - @Autowired - private ApplicationTraceIndexDao applicationTraceIndexDao; - - @Autowired - private AgentInfoService agentInfoService; - - - private static final Object V = new Object(); - - @Override - public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, Range range, int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - if (logger.isTraceEnabled()) { - logger.trace("scan(selectTraceIdsFromApplicationTraceIndex) {}, {}", applicationName, range); - } - - return this.applicationTraceIndexDao.scanTraceIndex(applicationName, range, limit); - } - - @Override - public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, SelectedScatterArea area, int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (area == null) { - throw new NullPointerException("area must not be null"); - } - if (logger.isTraceEnabled()) { - logger.trace("scan(selectTraceIdsFromApplicationTraceIndex) {}, {}", applicationName, area); - } - - return this.applicationTraceIndexDao.scanTraceIndex(applicationName, area, limit); - } - - @Override - @Deprecated - public LoadFactor linkStatistics(Range range, List traceIdSet, Application sourceApplication, Application destinationApplication, Filter filter) { - if (sourceApplication == null) { - throw new NullPointerException("sourceApplication must not be null"); - } - if (destinationApplication == null) { - throw new NullPointerException("destApplicationName must not be null"); - } - if (filter == null) { - throw new NullPointerException("filter must not be null"); - } - - StopWatch watch = new StopWatch(); - watch.start(); - - List> originalList = this.traceDao.selectAllSpans(traceIdSet); - List filteredTransactionList = filterList(originalList, filter); - - LoadFactor statistics = new LoadFactor(range); - - // TODO fromToFilter처럼. node의 타입에 따른 처리 필요함. - - // scan transaction list - for (SpanBo span : filteredTransactionList) { - if (sourceApplication.equals(span.getApplicationId(), span.getServiceType())) { - List spanEventBoList = span.getSpanEventBoList(); - if (spanEventBoList == null) { - continue; - } - - // find dest elapsed time - for (SpanEventBo spanEventBo : spanEventBoList) { - if (destinationApplication.equals(spanEventBo.getDestinationId(), spanEventBo.getServiceType())) { - // find exception - boolean hasException = spanEventBo.hasException(); - // add sample - // TODO : 실제값 대신 slot값을 넣어야 함. - statistics.addSample(span.getStartTime() + spanEventBo.getStartElapsed(), spanEventBo.getEndElapsed(), 1, hasException); - break; - } - } - } - } - - watch.stop(); - logger.info("Fetch link statistics elapsed. {}ms", watch.getLastTaskTimeMillis()); - - return statistics; - } - - private List filterList(List> transactionList, Filter filter) { - final List filteredResult = new ArrayList(); - for (List transaction : transactionList) { - if (filter.include(transaction)) { - filteredResult.addAll(transaction); - } - } - return filteredResult; - } - - private List> filterList2(List> transactionList, Filter filter) { - final List> filteredResult = new ArrayList>(); - for (List transaction : transactionList) { - if (filter.include(transaction)) { - filteredResult.add(transaction); - } - } - return filteredResult; - } - - @Override - public ApplicationMap selectApplicationMap(TransactionId transactionId) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - List transactionIdList = new ArrayList(); - transactionIdList.add(transactionId); - // FIXME from,to -1 땜방임. - Range range = new Range(-1, -1); - return selectApplicationMap(transactionIdList, range, range, Filter.NONE); - } - - /** - * filtered application map - */ - @Override - public ApplicationMap selectApplicationMap(List transactionIdList, Range originalRange, Range scanRange, Filter filter) { - if (transactionIdList == null) { - throw new NullPointerException("transactionIdList must not be null"); - } - if (filter == null) { - throw new NullPointerException("filter must not be null"); - } - - StopWatch watch = new StopWatch(); - watch.start(); - - final List> filterList = selectFilteredSpan(transactionIdList, filter); - - ApplicationMap map = createMap(originalRange, scanRange, filterList); - - watch.stop(); - logger.debug("Select filtered application map elapsed. {}ms", watch.getTotalTimeMillis()); - - return map; - } - - private List> selectFilteredSpan(List transactionIdList, Filter filter) { - // 개별 객체를 각각 보고 재귀 내용을 삭제함. - // 향후 tree base로 충돌구간을 점검하여 없앨 경우 여기서 filter를 치면 안됨. - final Collection recursiveFilterList = recursiveCallFilter(transactionIdList); - - // FIXME 나중에 List을 순회하면서 실행할 process chain을 두는것도 괜찮을듯. - final List> originalList = this.traceDao.selectAllSpans(recursiveFilterList); - - return filterList2(originalList, filter); - } - - private ApplicationMap createMap(Range range, Range scanRange, List> filterList) { - - // Window의 설정은 따로 inject받던지 해야 될듯함. - final TimeWindow window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); - - - final LinkDataDuplexMap linkDataDuplexMap = new LinkDataDuplexMap(); - - final DotExtractor dotExtractor = new DotExtractor(scanRange); - final ResponseHistogramBuilder mapHistogramSummary = new ResponseHistogramBuilder(range); - /** - * 통계정보로 변환한다. - */ - for (List transaction : filterList) { - final Map transactionSpanMap = checkDuplicatedSpanId(transaction); - - for (SpanBo span : transaction) { - final Application parentApplication = createParentApplication(span, transactionSpanMap); - final Application spanApplication = new Application(span.getApplicationId(), span.getServiceType()); - - // SPAN의 respoinseTime의 통계를 저장한다. - recordSpanResponseTime(spanApplication, span, mapHistogramSummary, span.getCollectorAcceptTime()); - - // 사실상 여기서 걸리는것은 span의 serviceType이 잘못되었다고 할수 있음. - if (!spanApplication.getServiceType().isRecordStatistics() || spanApplication.getServiceType().isRpcClient()) { - logger.warn("invalid span application:{}", spanApplication); - continue; - } - - final short slotTime = getHistogramSlotTime(span, spanApplication.getServiceType()); - // link의 통계값에 collector acceptor time을 넣는것이 맞는것인지는 다시 생각해볼 필요가 있음. - // 통계값의 window의 time으로 전환해야함. 안그러면 slot이 맞지 않아 oom이 발생할수 있음. - long timestamp = window.refineTimestamp(span.getCollectorAcceptTime()); - - if (parentApplication.getServiceType() == ServiceType.USER) { - // 정방향 데이터 - if (logger.isTraceEnabled()) { - logger.trace("span user:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId()); - } - final LinkDataMap sourceLinkData = linkDataDuplexMap.getSourceLinkDataMap(); - sourceLinkData.addLinkData(parentApplication, span.getAgentId(), spanApplication, span.getAgentId(), timestamp, slotTime, 1); - - if (logger.isTraceEnabled()) { - logger.trace("span target user:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId()); - } - // 역관계 데이터 - final LinkDataMap targetLinkDataMap = linkDataDuplexMap.getTargetLinkDataMap(); - targetLinkDataMap.addLinkData(parentApplication, span.getAgentId(), spanApplication, span.getAgentId(), timestamp, slotTime, 1); - } else { - // 역관계 데이터 - if (logger.isTraceEnabled()) { - logger.trace("span target parent:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId()); - } - final LinkDataMap targetLinkDataMap = linkDataDuplexMap.getTargetLinkDataMap(); - targetLinkDataMap.addLinkData(parentApplication, span.getAgentId(), spanApplication, span.getAgentId(), timestamp, slotTime, 1); - } - - - addNodeFromSpanEvent(span, window, linkDataDuplexMap, transactionSpanMap); - dotExtractor.addDot(span); - } - } - List applicationScatterScanResult = dotExtractor.getApplicationScatterScanResult(); - - ApplicationMapBuilder applicationMapBuilder = new ApplicationMapBuilder(range); - mapHistogramSummary.build(); - ApplicationMap map = applicationMapBuilder.build(linkDataDuplexMap, agentInfoService, mapHistogramSummary); - - map.setApplicationScatterScanResult(applicationScatterScanResult); - - return map; - } - - private Map checkDuplicatedSpanId(List transaction) { - final Map transactionSpanMap = new HashMap(); - for (SpanBo span : transaction) { - final SpanBo old = transactionSpanMap.put(span.getSpanId(), span); - if (old != null) { - logger.warn("duplicated span found:{}", old); - } - } - return transactionSpanMap; - } - - private void recordSpanResponseTime(Application application, SpanBo span, ResponseHistogramBuilder responseHistogramBuilder, long timeStamp) { - responseHistogramBuilder.addHistogram(application, span, timeStamp); - } - - - private void addNodeFromSpanEvent(SpanBo span, TimeWindow window, LinkDataDuplexMap linkDataDuplexMap, Map transactionSpanMap) { - /** - * span event의 statistics추가. - */ - final List spanEventBoList = span.getSpanEventBoList(); - if (CollectionUtils.isEmpty(spanEventBoList)) { - return; - } - final Application srcApplication = new Application(span.getApplicationId(), span.getServiceType()); - - LinkDataMap sourceLinkDataMap = linkDataDuplexMap.getSourceLinkDataMap(); - for (SpanEventBo spanEvent : spanEventBoList) { - - ServiceType destServiceType = spanEvent.getServiceType(); - if (!destServiceType.isRecordStatistics()) { - // internal 메소드 - continue; - } - // rpc client이면서 acceptor가 없으면 unknown으로 변환시킨다. - // 내가 아는 next spanid를 spanid로 가진 span이 있으면 acceptor가 존재하는 셈. - // acceptor check로직 - if (destServiceType.isRpcClient()) { - if (!transactionSpanMap.containsKey(spanEvent.getNextSpanId())) { - destServiceType = ServiceType.UNKNOWN; - } - } - - final String dest = spanEvent.getDestinationId(); - final Application destApplication = new Application(dest, destServiceType); - - final short slotTime = getHistogramSlotTime(spanEvent, destServiceType); - - // FIXME - final long spanEventTimeStamp = window.refineTimestamp(span.getStartTime() + spanEvent.getStartElapsed()); - if (logger.isTraceEnabled()) { - logger.trace("spanEvent src:{} {} -> dest:{} {}", srcApplication, span.getAgentId(), destApplication, spanEvent.getEndPoint()); - } - // endPoint는 null이 될수 있음. - final String destinationAgentId = StringUtils.defaultString(spanEvent.getEndPoint()); - sourceLinkDataMap.addLinkData(srcApplication, span.getAgentId(), destApplication, destinationAgentId, spanEventTimeStamp, slotTime, 1); - } - } - - private Application createParentApplication(SpanBo span, Map transactionSpanMap) { - final SpanBo parentSpan = transactionSpanMap.get(span.getParentSpanId()); - if (span.isRoot() || parentSpan == null) { - String applicationName = span.getApplicationId(); - ServiceType serviceType = ServiceType.USER; - return new Application(applicationName, serviceType); - } else { - String parentApplicationName = parentSpan.getApplicationId(); - ServiceType serviceType = parentSpan.getServiceType(); - return new Application(parentApplicationName, serviceType); - } - } - - private short getHistogramSlotTime(SpanEventBo spanEvent, ServiceType serviceType) { - return getHistogramSlotTime(spanEvent.hasException(), spanEvent.getEndElapsed(), serviceType); - } - - private short getHistogramSlotTime(SpanBo span, ServiceType serviceType) { - boolean allException = span.getErrCode() != 0; - return getHistogramSlotTime(allException, span.getElapsed(), serviceType); - } - - private short getHistogramSlotTime(boolean hasException, int elapsedTime, ServiceType serviceType) { - if (hasException) { - return serviceType.getHistogramSchema().getErrorSlot().getSlotTime(); - } else { - final HistogramSchema schema = serviceType.getHistogramSchema(); - final HistogramSlot histogramSlot = schema.findHistogramSlot(elapsedTime); - return histogramSlot.getSlotTime(); - } - } - - private Collection recursiveCallFilter(List transactionIdList) { - if (transactionIdList == null) { - throw new NullPointerException("transactionIdList must not be null"); - } - - List crashKey = new ArrayList(); - Map filterMap = new LinkedHashMap(transactionIdList.size()); - for (TransactionId transactionId : transactionIdList) { - Object old = filterMap.put(transactionId, V); - if (old != null) { - crashKey.add(transactionId); - } - } - if (crashKey.size() != 0) { - Set filteredTrasnactionId = filterMap.keySet(); - logger.info("transactionId crash found. original:{} filter:{} crashKey:{}", transactionIdList.size(), filteredTrasnactionId.size(), crashKey); - return filteredTrasnactionId; - } - return transactionIdList; - } - - -} +package com.nhn.pinpoint.web.service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.HistogramSlot; +import com.nhn.pinpoint.web.applicationmap.ApplicationMapBuilder; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataDuplexMap; +import com.nhn.pinpoint.web.applicationmap.rawdata.LinkDataMap; +import com.nhn.pinpoint.web.util.TimeWindow; +import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; +import com.nhn.pinpoint.web.dao.*; +import com.nhn.pinpoint.web.vo.*; +import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StopWatch; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.web.applicationmap.ApplicationMap; +import com.nhn.pinpoint.web.filter.Filter; + +/** + * @author netspider + * @author emeroad + */ +@Service +public class FilteredMapServiceImpl implements FilteredMapService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private TraceDao traceDao; + + @Autowired + private ApplicationTraceIndexDao applicationTraceIndexDao; + + @Autowired + private AgentInfoService agentInfoService; + + + private static final Object V = new Object(); + + @Override + public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, Range range, int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + if (logger.isTraceEnabled()) { + logger.trace("scan(selectTraceIdsFromApplicationTraceIndex) {}, {}", applicationName, range); + } + + return this.applicationTraceIndexDao.scanTraceIndex(applicationName, range, limit); + } + + @Override + public LimitedScanResult> selectTraceIdsFromApplicationTraceIndex(String applicationName, SelectedScatterArea area, int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (area == null) { + throw new NullPointerException("area must not be null"); + } + if (logger.isTraceEnabled()) { + logger.trace("scan(selectTraceIdsFromApplicationTraceIndex) {}, {}", applicationName, area); + } + + return this.applicationTraceIndexDao.scanTraceIndex(applicationName, area, limit); + } + + @Override + @Deprecated + public LoadFactor linkStatistics(Range range, List traceIdSet, Application sourceApplication, Application destinationApplication, Filter filter) { + if (sourceApplication == null) { + throw new NullPointerException("sourceApplication must not be null"); + } + if (destinationApplication == null) { + throw new NullPointerException("destApplicationName must not be null"); + } + if (filter == null) { + throw new NullPointerException("filter must not be null"); + } + + StopWatch watch = new StopWatch(); + watch.start(); + + List> originalList = this.traceDao.selectAllSpans(traceIdSet); + List filteredTransactionList = filterList(originalList, filter); + + LoadFactor statistics = new LoadFactor(range); + + // TODO fromToFilter처럼. node의 타입에 따른 처리 필요함. + + // scan transaction list + for (SpanBo span : filteredTransactionList) { + if (sourceApplication.equals(span.getApplicationId(), span.getServiceType())) { + List spanEventBoList = span.getSpanEventBoList(); + if (spanEventBoList == null) { + continue; + } + + // find dest elapsed time + for (SpanEventBo spanEventBo : spanEventBoList) { + if (destinationApplication.equals(spanEventBo.getDestinationId(), spanEventBo.getServiceType())) { + // find exception + boolean hasException = spanEventBo.hasException(); + // add sample + // TODO : 실제값 대신 slot값을 넣어야 함. + statistics.addSample(span.getStartTime() + spanEventBo.getStartElapsed(), spanEventBo.getEndElapsed(), 1, hasException); + break; + } + } + } + } + + watch.stop(); + logger.info("Fetch link statistics elapsed. {}ms", watch.getLastTaskTimeMillis()); + + return statistics; + } + + private List filterList(List> transactionList, Filter filter) { + final List filteredResult = new ArrayList(); + for (List transaction : transactionList) { + if (filter.include(transaction)) { + filteredResult.addAll(transaction); + } + } + return filteredResult; + } + + private List> filterList2(List> transactionList, Filter filter) { + final List> filteredResult = new ArrayList>(); + for (List transaction : transactionList) { + if (filter.include(transaction)) { + filteredResult.add(transaction); + } + } + return filteredResult; + } + + @Override + public ApplicationMap selectApplicationMap(TransactionId transactionId) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + List transactionIdList = new ArrayList(); + transactionIdList.add(transactionId); + // FIXME from,to -1 땜방임. + Range range = new Range(-1, -1); + return selectApplicationMap(transactionIdList, range, range, Filter.NONE); + } + + /** + * filtered application map + */ + @Override + public ApplicationMap selectApplicationMap(List transactionIdList, Range originalRange, Range scanRange, Filter filter) { + if (transactionIdList == null) { + throw new NullPointerException("transactionIdList must not be null"); + } + if (filter == null) { + throw new NullPointerException("filter must not be null"); + } + + StopWatch watch = new StopWatch(); + watch.start(); + + final List> filterList = selectFilteredSpan(transactionIdList, filter); + + ApplicationMap map = createMap(originalRange, scanRange, filterList); + + watch.stop(); + logger.debug("Select filtered application map elapsed. {}ms", watch.getTotalTimeMillis()); + + return map; + } + + private List> selectFilteredSpan(List transactionIdList, Filter filter) { + // 개별 객체를 각각 보고 재귀 내용을 삭제함. + // 향후 tree base로 충돌구간을 점검하여 없앨 경우 여기서 filter를 치면 안됨. + final Collection recursiveFilterList = recursiveCallFilter(transactionIdList); + + // FIXME 나중에 List을 순회하면서 실행할 process chain을 두는것도 괜찮을듯. + final List> originalList = this.traceDao.selectAllSpans(recursiveFilterList); + + return filterList2(originalList, filter); + } + + private ApplicationMap createMap(Range range, Range scanRange, List> filterList) { + + // Window의 설정은 따로 inject받던지 해야 될듯함. + final TimeWindow window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); + + + final LinkDataDuplexMap linkDataDuplexMap = new LinkDataDuplexMap(); + + final DotExtractor dotExtractor = new DotExtractor(scanRange); + final ResponseHistogramBuilder mapHistogramSummary = new ResponseHistogramBuilder(range); + /** + * 통계정보로 변환한다. + */ + for (List transaction : filterList) { + final Map transactionSpanMap = checkDuplicatedSpanId(transaction); + + for (SpanBo span : transaction) { + final Application parentApplication = createParentApplication(span, transactionSpanMap); + final Application spanApplication = new Application(span.getApplicationId(), span.getServiceType()); + + // SPAN의 respoinseTime의 통계를 저장한다. + recordSpanResponseTime(spanApplication, span, mapHistogramSummary, span.getCollectorAcceptTime()); + + // 사실상 여기서 걸리는것은 span의 serviceType이 잘못되었다고 할수 있음. + if (!spanApplication.getServiceType().isRecordStatistics() || spanApplication.getServiceType().isRpcClient()) { + logger.warn("invalid span application:{}", spanApplication); + continue; + } + + final short slotTime = getHistogramSlotTime(span, spanApplication.getServiceType()); + // link의 통계값에 collector acceptor time을 넣는것이 맞는것인지는 다시 생각해볼 필요가 있음. + // 통계값의 window의 time으로 전환해야함. 안그러면 slot이 맞지 않아 oom이 발생할수 있음. + long timestamp = window.refineTimestamp(span.getCollectorAcceptTime()); + + if (parentApplication.getServiceType() == ServiceType.USER) { + // 정방향 데이터 + if (logger.isTraceEnabled()) { + logger.trace("span user:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId()); + } + final LinkDataMap sourceLinkData = linkDataDuplexMap.getSourceLinkDataMap(); + sourceLinkData.addLinkData(parentApplication, span.getAgentId(), spanApplication, span.getAgentId(), timestamp, slotTime, 1); + + if (logger.isTraceEnabled()) { + logger.trace("span target user:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId()); + } + // 역관계 데이터 + final LinkDataMap targetLinkDataMap = linkDataDuplexMap.getTargetLinkDataMap(); + targetLinkDataMap.addLinkData(parentApplication, span.getAgentId(), spanApplication, span.getAgentId(), timestamp, slotTime, 1); + } else { + // 역관계 데이터 + if (logger.isTraceEnabled()) { + logger.trace("span target parent:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId()); + } + final LinkDataMap targetLinkDataMap = linkDataDuplexMap.getTargetLinkDataMap(); + targetLinkDataMap.addLinkData(parentApplication, span.getAgentId(), spanApplication, span.getAgentId(), timestamp, slotTime, 1); + } + + + addNodeFromSpanEvent(span, window, linkDataDuplexMap, transactionSpanMap); + dotExtractor.addDot(span); + } + } + List applicationScatterScanResult = dotExtractor.getApplicationScatterScanResult(); + + ApplicationMapBuilder applicationMapBuilder = new ApplicationMapBuilder(range); + mapHistogramSummary.build(); + ApplicationMap map = applicationMapBuilder.build(linkDataDuplexMap, agentInfoService, mapHistogramSummary); + + map.setApplicationScatterScanResult(applicationScatterScanResult); + + return map; + } + + private Map checkDuplicatedSpanId(List transaction) { + final Map transactionSpanMap = new HashMap(); + for (SpanBo span : transaction) { + final SpanBo old = transactionSpanMap.put(span.getSpanId(), span); + if (old != null) { + logger.warn("duplicated span found:{}", old); + } + } + return transactionSpanMap; + } + + private void recordSpanResponseTime(Application application, SpanBo span, ResponseHistogramBuilder responseHistogramBuilder, long timeStamp) { + responseHistogramBuilder.addHistogram(application, span, timeStamp); + } + + + private void addNodeFromSpanEvent(SpanBo span, TimeWindow window, LinkDataDuplexMap linkDataDuplexMap, Map transactionSpanMap) { + /** + * span event의 statistics추가. + */ + final List spanEventBoList = span.getSpanEventBoList(); + if (CollectionUtils.isEmpty(spanEventBoList)) { + return; + } + final Application srcApplication = new Application(span.getApplicationId(), span.getServiceType()); + + LinkDataMap sourceLinkDataMap = linkDataDuplexMap.getSourceLinkDataMap(); + for (SpanEventBo spanEvent : spanEventBoList) { + + ServiceType destServiceType = spanEvent.getServiceType(); + if (!destServiceType.isRecordStatistics()) { + // internal 메소드 + continue; + } + // rpc client이면서 acceptor가 없으면 unknown으로 변환시킨다. + // 내가 아는 next spanid를 spanid로 가진 span이 있으면 acceptor가 존재하는 셈. + // acceptor check로직 + if (destServiceType.isRpcClient()) { + if (!transactionSpanMap.containsKey(spanEvent.getNextSpanId())) { + destServiceType = ServiceType.UNKNOWN; + } + } + + final String dest = spanEvent.getDestinationId(); + final Application destApplication = new Application(dest, destServiceType); + + final short slotTime = getHistogramSlotTime(spanEvent, destServiceType); + + // FIXME + final long spanEventTimeStamp = window.refineTimestamp(span.getStartTime() + spanEvent.getStartElapsed()); + if (logger.isTraceEnabled()) { + logger.trace("spanEvent src:{} {} -> dest:{} {}", srcApplication, span.getAgentId(), destApplication, spanEvent.getEndPoint()); + } + // endPoint는 null이 될수 있음. + final String destinationAgentId = StringUtils.defaultString(spanEvent.getEndPoint()); + sourceLinkDataMap.addLinkData(srcApplication, span.getAgentId(), destApplication, destinationAgentId, spanEventTimeStamp, slotTime, 1); + } + } + + private Application createParentApplication(SpanBo span, Map transactionSpanMap) { + final SpanBo parentSpan = transactionSpanMap.get(span.getParentSpanId()); + if (span.isRoot() || parentSpan == null) { + String applicationName = span.getApplicationId(); + ServiceType serviceType = ServiceType.USER; + return new Application(applicationName, serviceType); + } else { + String parentApplicationName = parentSpan.getApplicationId(); + ServiceType serviceType = parentSpan.getServiceType(); + return new Application(parentApplicationName, serviceType); + } + } + + private short getHistogramSlotTime(SpanEventBo spanEvent, ServiceType serviceType) { + return getHistogramSlotTime(spanEvent.hasException(), spanEvent.getEndElapsed(), serviceType); + } + + private short getHistogramSlotTime(SpanBo span, ServiceType serviceType) { + boolean allException = span.getErrCode() != 0; + return getHistogramSlotTime(allException, span.getElapsed(), serviceType); + } + + private short getHistogramSlotTime(boolean hasException, int elapsedTime, ServiceType serviceType) { + if (hasException) { + return serviceType.getHistogramSchema().getErrorSlot().getSlotTime(); + } else { + final HistogramSchema schema = serviceType.getHistogramSchema(); + final HistogramSlot histogramSlot = schema.findHistogramSlot(elapsedTime); + return histogramSlot.getSlotTime(); + } + } + + private Collection recursiveCallFilter(List transactionIdList) { + if (transactionIdList == null) { + throw new NullPointerException("transactionIdList must not be null"); + } + + List crashKey = new ArrayList(); + Map filterMap = new LinkedHashMap(transactionIdList.size()); + for (TransactionId transactionId : transactionIdList) { + Object old = filterMap.put(transactionId, V); + if (old != null) { + crashKey.add(transactionId); + } + } + if (crashKey.size() != 0) { + Set filteredTrasnactionId = filterMap.keySet(); + logger.info("transactionId crash found. original:{} filter:{} crashKey:{}", transactionIdList.size(), filteredTrasnactionId.size(), crashKey); + return filteredTrasnactionId; + } + return transactionIdList; + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/LinkVisitChecker.java b/web/src/main/java/com/navercorp/pinpoint/web/service/LinkVisitChecker.java index ad5cd4b4ca20..0839ffa16494 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/LinkVisitChecker.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/LinkVisitChecker.java @@ -1,48 +1,48 @@ -package com.nhn.pinpoint.web.service; - -import com.nhn.pinpoint.web.vo.Application; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashSet; -import java.util.Set; - -/** - * @author emeroad - */ -public class LinkVisitChecker { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final Set calleeFound = new HashSet(); - private final Set callerFound = new HashSet(); - - public boolean visitCaller(Application caller) { - if (caller == null) { - throw new NullPointerException("caller must not be null"); - } - final boolean found = !callerFound.add(caller); - if (logger.isDebugEnabled()) { - if (found) { - logger.debug("Finding Caller. caller={}", caller); - } else { - logger.debug("LinkData exists. Skip finding caller. {} ", caller); - } - } - return found; - } - - public boolean visitCallee(Application callee) { - if (callee == null) { - throw new NullPointerException("callee must not be null"); - } - final boolean found = !this.calleeFound.add(callee); - if (logger.isDebugEnabled()) { - if (found) { - logger.debug("Finding Callee. callee={}", callee); - } else { - logger.debug("LinkData exists. Skip finding callee. {} ", callee); - } - } - return found; - } -} +package com.nhn.pinpoint.web.service; + +import com.nhn.pinpoint.web.vo.Application; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author emeroad + */ +public class LinkVisitChecker { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final Set calleeFound = new HashSet(); + private final Set callerFound = new HashSet(); + + public boolean visitCaller(Application caller) { + if (caller == null) { + throw new NullPointerException("caller must not be null"); + } + final boolean found = !callerFound.add(caller); + if (logger.isDebugEnabled()) { + if (found) { + logger.debug("Finding Caller. caller={}", caller); + } else { + logger.debug("LinkData exists. Skip finding caller. {} ", caller); + } + } + return found; + } + + public boolean visitCallee(Application callee) { + if (callee == null) { + throw new NullPointerException("callee must not be null"); + } + final boolean found = !this.calleeFound.add(callee); + if (logger.isDebugEnabled()) { + if (found) { + logger.debug("Finding Callee. callee={}", callee); + } else { + logger.debug("LinkData exists. Skip finding callee. {} ", callee); + } + } + return found; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/MapService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/MapService.java index 51ca6985b871..599cbd00308a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/MapService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/MapService.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.web.service; - -import com.nhn.pinpoint.web.applicationmap.ApplicationMap; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; -import com.nhn.pinpoint.web.vo.Range; - -/** - * @author netspider - */ -public interface MapService { - /** - * 메인 화면의 서버 맵 조회. - * - * @param sourceApplication - * @param range - * @return - */ - public ApplicationMap selectApplicationMap(Application sourceApplication, Range range); - - @Deprecated - public NodeHistogram linkStatistics(Application sourceApplication, Application destinationApplication, Range range); -} +package com.nhn.pinpoint.web.service; + +import com.nhn.pinpoint.web.applicationmap.ApplicationMap; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; +import com.nhn.pinpoint.web.vo.Range; + +/** + * @author netspider + */ +public interface MapService { + /** + * 메인 화면의 서버 맵 조회. + * + * @param sourceApplication + * @param range + * @return + */ + public ApplicationMap selectApplicationMap(Application sourceApplication, Range range); + + @Deprecated + public NodeHistogram linkStatistics(Application sourceApplication, Application destinationApplication, Range range); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/MapServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/MapServiceImpl.java index f02f0311ab2d..0051083eee1f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/MapServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/MapServiceImpl.java @@ -1,130 +1,130 @@ -package com.nhn.pinpoint.web.service; - -import java.util.*; - -import com.nhn.pinpoint.web.applicationmap.ApplicationMapBuilder; -import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.*; -import com.nhn.pinpoint.web.dao.*; -import com.nhn.pinpoint.web.vo.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.StopWatch; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.web.applicationmap.ApplicationMap; - -/** - * @author netspider - * @author emeroad - */ -@Service -public class MapServiceImpl implements MapService { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private AgentInfoService agentInfoService; - - @Autowired - private MapResponseDao mapResponseDao; - - @Autowired - private MapStatisticsCalleeDao mapStatisticsCalleeDao; - - @Autowired - private MapStatisticsCallerDao mapStatisticsCallerDao; - - @Autowired - private HostApplicationMapDao hostApplicationMapDao; - - - - - /** - * 메인화면에서 사용. 시간별로 TimeSlot을 조회하여 서버 맵을 그릴 때 사용한다. - */ - @Override - public ApplicationMap selectApplicationMap(Application sourceApplication, Range range) { - if (sourceApplication == null) { - throw new NullPointerException("sourceApplication must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - logger.debug("SelectApplicationMap"); - - StopWatch watch = new StopWatch("applicationMapWatch"); - watch.start(); - LinkDataSelector linkDataSelector = new LinkDataSelector(this.mapStatisticsCalleeDao, this.mapStatisticsCallerDao, hostApplicationMapDao); - LinkDataDuplexMap linkDataDuplexMap = linkDataSelector.select(sourceApplication, range); - - ApplicationMapBuilder builder = new ApplicationMapBuilder(range); - ApplicationMap map = builder.build(linkDataDuplexMap, agentInfoService, this.mapResponseDao); - - watch.stop(); - logger.info("Fetch applicationmap elapsed. {}ms", watch.getLastTaskTimeMillis()); - - return map; - } - - - @Override - @Deprecated - public NodeHistogram linkStatistics(Application sourceApplication, Application destinationApplication, Range range) { - if (sourceApplication == null) { - throw new NullPointerException("sourceApplication must not be null"); - } - if (destinationApplication == null) { - throw new NullPointerException("destinationApplication must not be null"); - } - - List list = selectLink(sourceApplication, destinationApplication, range); - logger.debug("Fetched statistics data size={}", list.size()); - - ResponseHistogramBuilder responseHistogramSummary = new ResponseHistogramBuilder(range); - for (LinkDataMap entry : list) { - for (LinkData linkData : entry.getLinkDataList()) { - AgentHistogramList sourceList = linkData.getSourceList(); - Collection agentHistogramList = sourceList.getAgentHistogramList(); - for (AgentHistogram histogram : agentHistogramList) { - for (TimeHistogram timeHistogram : histogram.getTimeHistogram()) { - Application toApplication = linkData.getToApplication(); - if (toApplication.getServiceType().isRpcClient()) { - toApplication = new Application(toApplication.getName(), ServiceType.UNKNOWN); - } - responseHistogramSummary.addLinkHistogram(toApplication, histogram.getId(), timeHistogram); - } - } - } - } - responseHistogramSummary.build(); - List responseTimeList = responseHistogramSummary.getResponseTimeList(destinationApplication); - final NodeHistogram histogramSummary = new NodeHistogram(destinationApplication, range, responseTimeList); - return histogramSummary; - } - - @Deprecated - private List selectLink(Application sourceApplication, Application destinationApplication, Range range) { - if (sourceApplication.getServiceType().isUser()) { - logger.debug("Find 'client -> any' link statistics"); - // client는 applicatinname + servicetype.client로 기록된다. - // 그래서 src, dest가 둘 다 dest로 같음. - Application userApplication = new Application(destinationApplication.getName(), sourceApplication.getServiceTypeCode()); - return mapStatisticsCallerDao.selectCallerStatistics(userApplication, destinationApplication, range); - } else if (destinationApplication.getServiceType().isWas()) { - logger.debug("Find 'any -> was' link statistics"); - // destination이 was인 경우에는 중간에 client event가 끼어있기 때문에 callee에서 - // caller가 - // 같은녀석을 찾아야 한다. - return mapStatisticsCalleeDao.selectCalleeStatistics(sourceApplication, destinationApplication, range); - } else { - logger.debug("Find 'was -> terminal' link statistics"); - // 일반적으로 was -> terminal 간의 통계정보 조회. - return mapStatisticsCallerDao.selectCallerStatistics(sourceApplication, destinationApplication, range); - } - } -} +package com.nhn.pinpoint.web.service; + +import java.util.*; + +import com.nhn.pinpoint.web.applicationmap.ApplicationMapBuilder; +import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.*; +import com.nhn.pinpoint.web.dao.*; +import com.nhn.pinpoint.web.vo.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StopWatch; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.web.applicationmap.ApplicationMap; + +/** + * @author netspider + * @author emeroad + */ +@Service +public class MapServiceImpl implements MapService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private AgentInfoService agentInfoService; + + @Autowired + private MapResponseDao mapResponseDao; + + @Autowired + private MapStatisticsCalleeDao mapStatisticsCalleeDao; + + @Autowired + private MapStatisticsCallerDao mapStatisticsCallerDao; + + @Autowired + private HostApplicationMapDao hostApplicationMapDao; + + + + + /** + * 메인화면에서 사용. 시간별로 TimeSlot을 조회하여 서버 맵을 그릴 때 사용한다. + */ + @Override + public ApplicationMap selectApplicationMap(Application sourceApplication, Range range) { + if (sourceApplication == null) { + throw new NullPointerException("sourceApplication must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + logger.debug("SelectApplicationMap"); + + StopWatch watch = new StopWatch("applicationMapWatch"); + watch.start(); + LinkDataSelector linkDataSelector = new LinkDataSelector(this.mapStatisticsCalleeDao, this.mapStatisticsCallerDao, hostApplicationMapDao); + LinkDataDuplexMap linkDataDuplexMap = linkDataSelector.select(sourceApplication, range); + + ApplicationMapBuilder builder = new ApplicationMapBuilder(range); + ApplicationMap map = builder.build(linkDataDuplexMap, agentInfoService, this.mapResponseDao); + + watch.stop(); + logger.info("Fetch applicationmap elapsed. {}ms", watch.getLastTaskTimeMillis()); + + return map; + } + + + @Override + @Deprecated + public NodeHistogram linkStatistics(Application sourceApplication, Application destinationApplication, Range range) { + if (sourceApplication == null) { + throw new NullPointerException("sourceApplication must not be null"); + } + if (destinationApplication == null) { + throw new NullPointerException("destinationApplication must not be null"); + } + + List list = selectLink(sourceApplication, destinationApplication, range); + logger.debug("Fetched statistics data size={}", list.size()); + + ResponseHistogramBuilder responseHistogramSummary = new ResponseHistogramBuilder(range); + for (LinkDataMap entry : list) { + for (LinkData linkData : entry.getLinkDataList()) { + AgentHistogramList sourceList = linkData.getSourceList(); + Collection agentHistogramList = sourceList.getAgentHistogramList(); + for (AgentHistogram histogram : agentHistogramList) { + for (TimeHistogram timeHistogram : histogram.getTimeHistogram()) { + Application toApplication = linkData.getToApplication(); + if (toApplication.getServiceType().isRpcClient()) { + toApplication = new Application(toApplication.getName(), ServiceType.UNKNOWN); + } + responseHistogramSummary.addLinkHistogram(toApplication, histogram.getId(), timeHistogram); + } + } + } + } + responseHistogramSummary.build(); + List responseTimeList = responseHistogramSummary.getResponseTimeList(destinationApplication); + final NodeHistogram histogramSummary = new NodeHistogram(destinationApplication, range, responseTimeList); + return histogramSummary; + } + + @Deprecated + private List selectLink(Application sourceApplication, Application destinationApplication, Range range) { + if (sourceApplication.getServiceType().isUser()) { + logger.debug("Find 'client -> any' link statistics"); + // client는 applicatinname + servicetype.client로 기록된다. + // 그래서 src, dest가 둘 다 dest로 같음. + Application userApplication = new Application(destinationApplication.getName(), sourceApplication.getServiceTypeCode()); + return mapStatisticsCallerDao.selectCallerStatistics(userApplication, destinationApplication, range); + } else if (destinationApplication.getServiceType().isWas()) { + logger.debug("Find 'any -> was' link statistics"); + // destination이 was인 경우에는 중간에 client event가 끼어있기 때문에 callee에서 + // caller가 + // 같은녀석을 찾아야 한다. + return mapStatisticsCalleeDao.selectCalleeStatistics(sourceApplication, destinationApplication, range); + } else { + logger.debug("Find 'was -> terminal' link statistics"); + // 일반적으로 was -> terminal 간의 통계정보 조회. + return mapStatisticsCallerDao.selectCallerStatistics(sourceApplication, destinationApplication, range); + } + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/ScatterChartServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/ScatterChartServiceImpl.java index 2882e9c9bd71..3882c315ec24 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/ScatterChartServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/ScatterChartServiceImpl.java @@ -1,133 +1,133 @@ -package com.nhn.pinpoint.web.service; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.web.dao.ApplicationTraceIndexDao; -import com.nhn.pinpoint.web.dao.TraceDao; -import com.nhn.pinpoint.web.filter.Filter; -import com.nhn.pinpoint.web.vo.Range; -import com.nhn.pinpoint.web.vo.SelectedScatterArea; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.TransactionMetadataQuery; -import com.nhn.pinpoint.web.vo.scatter.Dot; - -/** - * @author netspider - * @author emeroad - */ -@Service -public class ScatterChartServiceImpl implements ScatterChartService { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private ApplicationTraceIndexDao applicationTraceIndexDao; - - @Autowired - private TraceDao traceDao; - - @Override - public List selectScatterData(String applicationName, Range range, int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (range == null) { - throw new NullPointerException("range must not be null"); - } - return applicationTraceIndexDao.scanTraceScatter(applicationName, range, limit); - } - - @Override - public List selectScatterData(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (area == null) { - throw new NullPointerException("area must not be null"); - } - return applicationTraceIndexDao.scanTraceScatter(applicationName, area, offsetTransactionId, offsetTransactionElapsed, limit); - } - - @Override - public List selectScatterData(Collection transactionIdList, String applicationName, Filter filter) { - if (transactionIdList == null) { - throw new NullPointerException("transactionIdList must not be null"); - } - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (filter == null) { - throw new NullPointerException("filter must not be null"); - } - - final List> traceList = traceDao.selectAllSpans(transactionIdList); - - final List result = new ArrayList(); - - for (List trace : traceList) { - if (!filter.include(trace)) { - continue; - } - - for (SpanBo span : trace) { - if (applicationName.equals(span.getApplicationId())) { - final TransactionId transactionId = new TransactionId(span.getTraceAgentId(), span.getTraceAgentStartTime(), span.getTraceTransactionSequence()); - final Dot dot = new Dot(transactionId, span.getCollectorAcceptTime(), span.getElapsed(), span.getErrCode(), span.getAgentId()); - result.add(dot); - } - } - } - - return result; - } - - /** - * scatter chart에서 선택한 점에 대한 정보를 조회 하는 메소드. - */ - @Override - public List selectTransactionMetadata(final TransactionMetadataQuery query) { - if (query == null) { - throw new NullPointerException("query must not be null"); - } - final List transactionIdList = query.getTransactionIdList(); - final List> selectedSpans = traceDao.selectSpans(transactionIdList); - - - final List result = new ArrayList(query.size()); - int index = 0; - for (List spans : selectedSpans) { - if (spans.size() == 0) { - // 조회에 실패한 경우 span저장에 실패함. - // skip한다. - } else if (spans.size() == 1) { - // 1개 뿐이 없는 유일 케이스. - result.add(spans.get(0)); - } else { - // 재귀일 경우 자신이 선택한 span이 어느 span인지를 선별해야 한다. - // 조회된 녀석들 중에서 transactionId, collectorAcceptor, responseTime이 같은것들만 선별. - for (SpanBo span : spans) { - - // 정확히 인덱스에 맞는 필터링 조건을 찾아야 함. - final TransactionMetadataQuery.QueryCondition filterQueryCondition = query.getQueryConditionByIndex(index); - - final TransactionId transactionId = new TransactionId(span.getTraceAgentId(), span.getTraceAgentStartTime(), span.getTraceTransactionSequence()); - final TransactionMetadataQuery.QueryCondition queryConditionKey = new TransactionMetadataQuery.QueryCondition(transactionId, span.getCollectorAcceptTime(), span.getElapsed()); - if (queryConditionKey.equals(filterQueryCondition)) { - result.add(span); - } - } - } - index++; - } - - return result; - } -} +package com.nhn.pinpoint.web.service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.web.dao.ApplicationTraceIndexDao; +import com.nhn.pinpoint.web.dao.TraceDao; +import com.nhn.pinpoint.web.filter.Filter; +import com.nhn.pinpoint.web.vo.Range; +import com.nhn.pinpoint.web.vo.SelectedScatterArea; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.TransactionMetadataQuery; +import com.nhn.pinpoint.web.vo.scatter.Dot; + +/** + * @author netspider + * @author emeroad + */ +@Service +public class ScatterChartServiceImpl implements ScatterChartService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private ApplicationTraceIndexDao applicationTraceIndexDao; + + @Autowired + private TraceDao traceDao; + + @Override + public List selectScatterData(String applicationName, Range range, int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (range == null) { + throw new NullPointerException("range must not be null"); + } + return applicationTraceIndexDao.scanTraceScatter(applicationName, range, limit); + } + + @Override + public List selectScatterData(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (area == null) { + throw new NullPointerException("area must not be null"); + } + return applicationTraceIndexDao.scanTraceScatter(applicationName, area, offsetTransactionId, offsetTransactionElapsed, limit); + } + + @Override + public List selectScatterData(Collection transactionIdList, String applicationName, Filter filter) { + if (transactionIdList == null) { + throw new NullPointerException("transactionIdList must not be null"); + } + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (filter == null) { + throw new NullPointerException("filter must not be null"); + } + + final List> traceList = traceDao.selectAllSpans(transactionIdList); + + final List result = new ArrayList(); + + for (List trace : traceList) { + if (!filter.include(trace)) { + continue; + } + + for (SpanBo span : trace) { + if (applicationName.equals(span.getApplicationId())) { + final TransactionId transactionId = new TransactionId(span.getTraceAgentId(), span.getTraceAgentStartTime(), span.getTraceTransactionSequence()); + final Dot dot = new Dot(transactionId, span.getCollectorAcceptTime(), span.getElapsed(), span.getErrCode(), span.getAgentId()); + result.add(dot); + } + } + } + + return result; + } + + /** + * scatter chart에서 선택한 점에 대한 정보를 조회 하는 메소드. + */ + @Override + public List selectTransactionMetadata(final TransactionMetadataQuery query) { + if (query == null) { + throw new NullPointerException("query must not be null"); + } + final List transactionIdList = query.getTransactionIdList(); + final List> selectedSpans = traceDao.selectSpans(transactionIdList); + + + final List result = new ArrayList(query.size()); + int index = 0; + for (List spans : selectedSpans) { + if (spans.size() == 0) { + // 조회에 실패한 경우 span저장에 실패함. + // skip한다. + } else if (spans.size() == 1) { + // 1개 뿐이 없는 유일 케이스. + result.add(spans.get(0)); + } else { + // 재귀일 경우 자신이 선택한 span이 어느 span인지를 선별해야 한다. + // 조회된 녀석들 중에서 transactionId, collectorAcceptor, responseTime이 같은것들만 선별. + for (SpanBo span : spans) { + + // 정확히 인덱스에 맞는 필터링 조건을 찾아야 함. + final TransactionMetadataQuery.QueryCondition filterQueryCondition = query.getQueryConditionByIndex(index); + + final TransactionId transactionId = new TransactionId(span.getTraceAgentId(), span.getTraceAgentStartTime(), span.getTraceTransactionSequence()); + final TransactionMetadataQuery.QueryCondition queryConditionKey = new TransactionMetadataQuery.QueryCondition(transactionId, span.getCollectorAcceptTime(), span.getElapsed()); + if (queryConditionKey.equals(filterQueryCondition)) { + result.add(span); + } + } + } + index++; + } + + return result; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanDepth.java b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanDepth.java index addbedd91156..7c03745ed1af 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanDepth.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanDepth.java @@ -1,34 +1,34 @@ -package com.nhn.pinpoint.web.service; - -import com.nhn.pinpoint.web.calltree.span.SpanAlign; - -/** - * @author emeroad - */ -public class SpanDepth { - private final SpanAlign spanAlign; - private final int id; - // gap 을 구하기 위해 바로 전 lastExecuteTime을 구함 - private final long lastExecuteTime; - - public SpanDepth(SpanAlign spanAlign, int id, long lastExecuteTime) { - if (spanAlign == null) { - throw new NullPointerException("spanAlign must not be null"); - } - this.spanAlign = spanAlign; - this.id = id; - this.lastExecuteTime = lastExecuteTime; - } - - public SpanAlign getSpanAlign() { - return spanAlign; - } - - public int getId() { - return id; - } - - public long getLastExecuteTime() { - return lastExecuteTime; - } -} +package com.nhn.pinpoint.web.service; + +import com.nhn.pinpoint.web.calltree.span.SpanAlign; + +/** + * @author emeroad + */ +public class SpanDepth { + private final SpanAlign spanAlign; + private final int id; + // gap 을 구하기 위해 바로 전 lastExecuteTime을 구함 + private final long lastExecuteTime; + + public SpanDepth(SpanAlign spanAlign, int id, long lastExecuteTime) { + if (spanAlign == null) { + throw new NullPointerException("spanAlign must not be null"); + } + this.spanAlign = spanAlign; + this.id = id; + this.lastExecuteTime = lastExecuteTime; + } + + public SpanAlign getSpanAlign() { + return spanAlign; + } + + public int getId() { + return id; + } + + public long getLastExecuteTime() { + return lastExecuteTime; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanResult.java b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanResult.java index 6c03d7e8f545..c701affd31f8 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanResult.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanResult.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.web.service; - -import com.nhn.pinpoint.web.calltree.span.SpanAlign; -import com.nhn.pinpoint.web.calltree.span.SpanAligner2; - -import java.util.List; - -/** - * @author emeroad - */ -public class SpanResult { - private int completeType; - private List spanAlignList; - - public SpanResult(int completeType, List spanAlignList) { - if (spanAlignList == null) { - throw new NullPointerException("spanAlignList must not be null"); - } - this.completeType = completeType; - this.spanAlignList = spanAlignList; - } - - - - public int getCompleteType() { - return completeType; - } - - public List getSpanAlignList() { - return spanAlignList; - } - - public String getCompleteTypeString() { - switch (completeType) { - case SpanAligner2.BEST_MATCH: - return "Complete"; - case SpanAligner2.START_TIME_MATCH: - return "Progress"; - case SpanAligner2.FAIL_MATCH: - return "Error"; - } - return "Error"; - } -} +package com.nhn.pinpoint.web.service; + +import com.nhn.pinpoint.web.calltree.span.SpanAlign; +import com.nhn.pinpoint.web.calltree.span.SpanAligner2; + +import java.util.List; + +/** + * @author emeroad + */ +public class SpanResult { + private int completeType; + private List spanAlignList; + + public SpanResult(int completeType, List spanAlignList) { + if (spanAlignList == null) { + throw new NullPointerException("spanAlignList must not be null"); + } + this.completeType = completeType; + this.spanAlignList = spanAlignList; + } + + + + public int getCompleteType() { + return completeType; + } + + public List getSpanAlignList() { + return spanAlignList; + } + + public String getCompleteTypeString() { + switch (completeType) { + case SpanAligner2.BEST_MATCH: + return "Complete"; + case SpanAligner2.START_TIME_MATCH: + return "Progress"; + case SpanAligner2.FAIL_MATCH: + return "Error"; + } + return "Error"; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanService.java index 58765dc112a7..d83f0c659435 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanService.java @@ -1,13 +1,13 @@ -package com.nhn.pinpoint.web.service; - -import java.util.List; - -import com.nhn.pinpoint.web.calltree.span.SpanAlign; -import com.nhn.pinpoint.web.vo.TransactionId; - -/** - * @author emeroad - */ -public interface SpanService { - SpanResult selectSpan(TransactionId transactionId, long selectedSpanHint); -} +package com.nhn.pinpoint.web.service; + +import java.util.List; + +import com.nhn.pinpoint.web.calltree.span.SpanAlign; +import com.nhn.pinpoint.web.vo.TransactionId; + +/** + * @author emeroad + */ +public interface SpanService { + SpanResult selectSpan(TransactionId transactionId, long selectedSpanHint); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanServiceImpl.java index 06dd19262afd..13d7f4aba24f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/SpanServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/SpanServiceImpl.java @@ -1,405 +1,405 @@ -package com.nhn.pinpoint.web.service; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.nhn.pinpoint.common.bo.*; -import com.nhn.pinpoint.web.dao.StringMetaDataDao; -import com.nhn.pinpoint.web.vo.TransactionId; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.nhn.pinpoint.web.calltree.span.SpanAlign; -import com.nhn.pinpoint.web.calltree.span.SpanAligner2; -import com.nhn.pinpoint.web.dao.ApiMetaDataDao; -import com.nhn.pinpoint.web.dao.SqlMetaDataDao; -import com.nhn.pinpoint.web.dao.TraceDao; -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.util.OutputParameterParser; -import com.nhn.pinpoint.common.util.SqlParser; - -/** - * @author emeroad - */ -@Service -public class SpanServiceImpl implements SpanService { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private TraceDao traceDao; - - @Autowired - private SqlMetaDataDao sqlMetaDataDao; - - @Autowired - private ApiMetaDataDao apiMetaDataDao; - - @Autowired - private StringMetaDataDao stringMetaDataDao; - - private final SqlParser sqlParser = new SqlParser(); - private final OutputParameterParser outputParameterParser = new OutputParameterParser(); - - @Override - public SpanResult selectSpan(TransactionId transactionId, long selectedSpanHint) { - if (transactionId == null) { - throw new NullPointerException("transactionId must not be null"); - } - - List spans = traceDao.selectSpanAndAnnotation(transactionId); - if (spans == null || spans.isEmpty()) { - return new SpanResult(SpanAligner2.FAIL_MATCH, Collections.emptyList()); - } - - SpanResult result = order(spans, selectedSpanHint); - List order = result.getSpanAlignList(); -// transitionApiId(order); - transitionDynamicApiId(order); - transitionSqlId(order); - transitionCachedString(order); - transitionException(order); - // TODO root span not found시 row data라도 보여줘야 됨. - return result; - } - - - - private void transitionAnnotation(List spans, AnnotationReplacementCallback annotationReplacementCallback) { - for (SpanAlign spanAlign : spans) { - List annotationBoList; - if (spanAlign.isSpan()) { - annotationBoList = spanAlign.getSpanBo().getAnnotationBoList(); - if (annotationBoList == null) { - annotationBoList = new ArrayList(); - spanAlign.getSpanBo().setAnnotationBoList(annotationBoList); - } - annotationReplacementCallback.replacement(spanAlign, annotationBoList); - } else { - annotationBoList = spanAlign.getSpanEventBo().getAnnotationBoList(); - if (annotationBoList == null) { - annotationBoList = new ArrayList(); - spanAlign.getSpanBo().setAnnotationBoList(annotationBoList); - } - annotationReplacementCallback.replacement(spanAlign, annotationBoList); - } - } - } - - private void transitionSqlId(final List spans) { - this.transitionAnnotation(spans, new AnnotationReplacementCallback() { - @Override - public void replacement(SpanAlign spanAlign, List annotationBoList) { - AnnotationBo sqlIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.SQL_ID.getCode()); - if (sqlIdAnnotation == null) { - return; - } - - final AgentKey agentKey = getAgentKey(spanAlign); - - // sqlId에 대한 annotation은 멀티 value가 날라옴. - final IntStringStringValue sqlValue = (IntStringStringValue) sqlIdAnnotation.getValue(); - final int hashCode = sqlValue.getIntValue(); - final String sqlParam = sqlValue.getStringValue1(); - final List sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentKey.getAgentId(), agentKey.getAgentStartTime(), hashCode); - final int size = sqlMetaDataList.size(); - if (size == 0) { - AnnotationBo api = new AnnotationBo(); - api.setKey(AnnotationKey.SQL.getCode()); - api.setValue("SQL-ID not found hashCode:" + hashCode); - annotationBoList.add(api); - } else if (size == 1) { - final SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(0); - if (StringUtils.isEmpty(sqlParam)) { - AnnotationBo sqlMeta = new AnnotationBo(); - sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); - sqlMeta.setValue(sqlMetaDataBo.getSql()); - annotationBoList.add(sqlMeta); - -// AnnotationBo checkFail = checkIdentifier(spanAlign, sqlMetaDataBo); -// if (checkFail != null) { -// // 실패 -// annotationBoList.add(checkFail); -// return; -// } - - AnnotationBo sql = new AnnotationBo(); - sql.setKey(AnnotationKey.SQL.getCode()); - sql.setValue(sqlMetaDataBo.getSql()); - annotationBoList.add(sql); - } else { - logger.debug("sqlMetaDataBo:{}", sqlMetaDataBo); - final String outputParams = sqlParam; - List parsedOutputParams = outputParameterParser.parseOutputParameter(outputParams); - logger.debug("outputPrams:{}, parsedOutputPrams:{}", outputParams, parsedOutputParams); - String originalSql = sqlParser.combineOutputParams(sqlMetaDataBo.getSql(), parsedOutputParams); - logger.debug("outputPrams{}, originalSql:{}", outputParams, originalSql); - - AnnotationBo sqlMeta = new AnnotationBo(); - sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); - sqlMeta.setValue(sqlMetaDataBo.getSql()); - annotationBoList.add(sqlMeta); - - - AnnotationBo sql = new AnnotationBo(); - sql.setKey(AnnotationKey.SQL.getCode()); - sql.setValue(originalSql); - annotationBoList.add(sql); - - } - } else { - // TODO 보완해야됨. - AnnotationBo api = new AnnotationBo(); - api.setKey(AnnotationKey.SQL.getCode()); - api.setValue(collisionSqlHashCodeMessage(hashCode, sqlMetaDataList)); - annotationBoList.add(api); - } - // bindValue가 존재할 경우 따라 넣어준다. - final String bindValue = sqlValue.getStringValue2(); - if (StringUtils.isNotEmpty(bindValue)) { - AnnotationBo bindValueAnnotation = new AnnotationBo(); - bindValueAnnotation.setKey(AnnotationKey.SQL_BINDVALUE.getCode()); - bindValueAnnotation.setValue(bindValue); - annotationBoList.add(bindValueAnnotation); - } - - } - - }); - } - - private AnnotationBo findAnnotation(List annotationBoList, int key) { - for (AnnotationBo annotationBo : annotationBoList) { - if (key == annotationBo.getKey()) { - return annotationBo; - } - } - return null; - } - - private String collisionSqlHashCodeMessage(int hashCode, List sqlMetaDataList) { - // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. - StringBuilder sb = new StringBuilder(64); - sb.append("Collision Sql hashCode:"); - sb.append(hashCode); - sb.append('\n'); - for (int i = 0; i < sqlMetaDataList.size(); i++) { - if (i != 0) { - sb.append("or\n"); - } - SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(i); - sb.append(sqlMetaDataBo.getSql()); - } - return sb.toString(); - } - - - private void transitionDynamicApiId(List spans) { - this.transitionAnnotation(spans, new AnnotationReplacementCallback() { - @Override - public void replacement(SpanAlign spanAlign, List annotationBoList) { - final AgentKey key = getAgentKey(spanAlign); - final int apiId = getApiId(spanAlign); - // agentIdentifer를 기준으로 좀더 정확한 데이터를 찾을수 있을 듯 하다. - List apiMetaDataList = apiMetaDataDao.getApiMetaData(key.getAgentId(), key.getAgentStartTime(), apiId); - int size = apiMetaDataList.size(); - if (size == 0) { - AnnotationBo api = new AnnotationBo(); - api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode()); - api.setValue("API-DynamicID not found. api:" + apiId); - annotationBoList.add(api); - } else if (size == 1) { - ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(0); - AnnotationBo apiMetaData = new AnnotationBo(); - apiMetaData.setKey(AnnotationKey.API_METADATA.getCode()); - apiMetaData.setValue(apiMetaDataBo); - annotationBoList.add(apiMetaData); - - AnnotationBo apiAnnotation = new AnnotationBo(); - apiAnnotation.setKey(AnnotationKey.API.getCode()); - String apiInfo = getApiInfo(apiMetaDataBo); - apiAnnotation.setValue(apiInfo); - annotationBoList.add(apiAnnotation); - } else { - AnnotationBo apiAnnotation = new AnnotationBo(); - apiAnnotation.setKey(AnnotationKey.ERROR_API_METADATA_DID_COLLSION.getCode()); - String collisonMessage = collisionApiDidMessage(apiId, apiMetaDataList); - apiAnnotation.setValue(collisonMessage); - annotationBoList.add(apiAnnotation); - } - - } - - }); - } - - private void transitionCachedString(List spans) { - this.transitionAnnotation(spans, new AnnotationReplacementCallback() { - @Override - public void replacement(SpanAlign spanAlign, List annotationBoList) { - final AgentKey key = getAgentKey(spanAlign); - List cachedStringAnnotation = findCachedStringAnnotation(annotationBoList); - if (cachedStringAnnotation.isEmpty()) { - return; - } - for (AnnotationBo annotationBo : cachedStringAnnotation) { - final int cachedArgsKey = annotationBo.getKey(); - int stringMetaDataId = (Integer) annotationBo.getValue(); - List stringMetaList = stringMetaDataDao.getStringMetaData(key.getAgentId(), key.getAgentStartTime(), stringMetaDataId); - int size = stringMetaList.size(); - if (size == 0) { - logger.warn("StringMetaData not Found {}/{}/{}", key.getAgentId(), stringMetaDataId, key.getAgentStartTime()); - AnnotationBo api = new AnnotationBo(); - // API METADATA ERROR가 아님. 추후 수정. - api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode()); - api.setValue("CACHED-STRING-ID not found. stringId:" + cachedArgsKey); - annotationBoList.add(api); - } else if (size >= 1) { - // key 충돌 경우는 후추 처리한다. 실제 상황에서는 일부러 만들지 않는한 발생할수 없다. - StringMetaDataBo stringMetaDataBo = stringMetaList.get(0); - - AnnotationBo stringMetaData = new AnnotationBo(); - stringMetaData.setKey(AnnotationKey.cachedArgsToArgs(cachedArgsKey)); - stringMetaData.setValue(stringMetaDataBo.getStringValue()); - annotationBoList.add(stringMetaData); - if (size > 1) { - logger.warn("stringMetaData size not 1 :{}", stringMetaList); - } - } - } - } - - }); - } - - private List findCachedStringAnnotation(List annotationBoList) { - List findAnnotationBoList = new ArrayList(annotationBoList.size()); - for (AnnotationBo annotationBo : annotationBoList) { - if (AnnotationKey.isCachedArgsKey(annotationBo.getKey())) { - findAnnotationBoList.add(annotationBo); - } - } - return findAnnotationBoList; - } - - private void transitionException(List spanAlignList) { - for (SpanAlign spanAlign : spanAlignList) { - if (spanAlign.isSpan()) { - final SpanBo spanBo = spanAlign.getSpanBo(); - if (spanBo.hasException()) { - StringMetaDataBo stringMetaData = selectStringMetaData(spanBo.getAgentId(), spanBo.getExceptionId(), spanBo.getAgentStartTime()); - spanBo.setExceptionClass(stringMetaData.getStringValue()); - } - } else { - final SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); - if (spanEventBo.hasException()) { - StringMetaDataBo stringMetaData = selectStringMetaData(spanEventBo.getAgentId(), spanEventBo.getExceptionId(), spanEventBo.getAgentStartTime()); - if (stringMetaData != null) { - spanEventBo.setExceptionClass(stringMetaData.getStringValue()); - } - } - } - } - - } - - private StringMetaDataBo selectStringMetaData(String agentId, int cacheId, long agentStartTime) { - final List metaDataList = stringMetaDataDao.getStringMetaData(agentId, agentStartTime, cacheId); - if (metaDataList == null || metaDataList.isEmpty()) { - logger.warn("StringMetaData not Found agent:{}, cacheId{}, agentStartTime:{}", agentId, cacheId, agentStartTime); - StringMetaDataBo stringMetaDataBo = new StringMetaDataBo(agentId, agentStartTime, cacheId); - stringMetaDataBo.setStringValue("STRING-META-DATA-NOT-FOUND"); - return stringMetaDataBo; - } - if (metaDataList.size() == 1) { - return metaDataList.get(0); - } else { - // 일단 로그 찍고 처리. - logger.warn("stringMetaData size not 1 :{}", metaDataList); - return metaDataList.get(0); - } - } - - private int getApiId(SpanAlign spanAlign) { - if (spanAlign.isSpan()) { - return spanAlign.getSpanBo().getApiId(); - } else { - return spanAlign.getSpanEventBo().getApiId(); - } - } - - private AgentKey getAgentKey(SpanAlign spanAlign) { - if (spanAlign.isSpan()) { - SpanBo spanBo = spanAlign.getSpanBo(); - return new AgentKey(spanBo.getAgentId(), spanBo.getAgentStartTime()); - } else { - final SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); - return new AgentKey(spanEventBo.getAgentId(), spanEventBo.getAgentStartTime()); - } - } - - private String collisionApiDidMessage(int apidId, List apiMetaDataList) { - // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. - StringBuilder sb = new StringBuilder(64); - sb.append("Collision Api DynamicId:"); - sb.append(apidId); - sb.append('\n'); - for (int i = 0; i < apiMetaDataList.size(); i++) { - if (i != 0) { - sb.append("or\n"); - } - ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(i); - sb.append(getApiInfo(apiMetaDataBo)); - } - return sb.toString(); - } - - private String getApiInfo(ApiMetaDataBo apiMetaDataBo) { - if (apiMetaDataBo.getLineNumber() != -1) { - return apiMetaDataBo.getApiInfo() + ":" + apiMetaDataBo.getLineNumber(); - } else { - return apiMetaDataBo.getApiInfo(); - } - } - - public static interface AnnotationReplacementCallback { - void replacement(SpanAlign spanAlign, List annotationBoList); - } - - private SpanResult order(List spans, long selectedSpanHint) { - SpanAligner2 spanAligner = new SpanAligner2(spans, selectedSpanHint); - List sort = spanAligner.sort(); - - logger.trace("SpanAlignList:{}", sort); - return new SpanResult(spanAligner.getMatchType(), sort); - - } - - - private static final class AgentKey { - - private final String agentId; - private final long agentStartTime; - - private AgentKey(String agentId, long agentStartTime) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - this.agentId = agentId; - this.agentStartTime = agentStartTime; - } - - private String getAgentId() { - return agentId; - } - - private long getAgentStartTime() { - return agentStartTime; - } - } -} - +package com.nhn.pinpoint.web.service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.nhn.pinpoint.common.bo.*; +import com.nhn.pinpoint.web.dao.StringMetaDataDao; +import com.nhn.pinpoint.web.vo.TransactionId; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.nhn.pinpoint.web.calltree.span.SpanAlign; +import com.nhn.pinpoint.web.calltree.span.SpanAligner2; +import com.nhn.pinpoint.web.dao.ApiMetaDataDao; +import com.nhn.pinpoint.web.dao.SqlMetaDataDao; +import com.nhn.pinpoint.web.dao.TraceDao; +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.util.OutputParameterParser; +import com.nhn.pinpoint.common.util.SqlParser; + +/** + * @author emeroad + */ +@Service +public class SpanServiceImpl implements SpanService { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private TraceDao traceDao; + + @Autowired + private SqlMetaDataDao sqlMetaDataDao; + + @Autowired + private ApiMetaDataDao apiMetaDataDao; + + @Autowired + private StringMetaDataDao stringMetaDataDao; + + private final SqlParser sqlParser = new SqlParser(); + private final OutputParameterParser outputParameterParser = new OutputParameterParser(); + + @Override + public SpanResult selectSpan(TransactionId transactionId, long selectedSpanHint) { + if (transactionId == null) { + throw new NullPointerException("transactionId must not be null"); + } + + List spans = traceDao.selectSpanAndAnnotation(transactionId); + if (spans == null || spans.isEmpty()) { + return new SpanResult(SpanAligner2.FAIL_MATCH, Collections.emptyList()); + } + + SpanResult result = order(spans, selectedSpanHint); + List order = result.getSpanAlignList(); +// transitionApiId(order); + transitionDynamicApiId(order); + transitionSqlId(order); + transitionCachedString(order); + transitionException(order); + // TODO root span not found시 row data라도 보여줘야 됨. + return result; + } + + + + private void transitionAnnotation(List spans, AnnotationReplacementCallback annotationReplacementCallback) { + for (SpanAlign spanAlign : spans) { + List annotationBoList; + if (spanAlign.isSpan()) { + annotationBoList = spanAlign.getSpanBo().getAnnotationBoList(); + if (annotationBoList == null) { + annotationBoList = new ArrayList(); + spanAlign.getSpanBo().setAnnotationBoList(annotationBoList); + } + annotationReplacementCallback.replacement(spanAlign, annotationBoList); + } else { + annotationBoList = spanAlign.getSpanEventBo().getAnnotationBoList(); + if (annotationBoList == null) { + annotationBoList = new ArrayList(); + spanAlign.getSpanBo().setAnnotationBoList(annotationBoList); + } + annotationReplacementCallback.replacement(spanAlign, annotationBoList); + } + } + } + + private void transitionSqlId(final List spans) { + this.transitionAnnotation(spans, new AnnotationReplacementCallback() { + @Override + public void replacement(SpanAlign spanAlign, List annotationBoList) { + AnnotationBo sqlIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.SQL_ID.getCode()); + if (sqlIdAnnotation == null) { + return; + } + + final AgentKey agentKey = getAgentKey(spanAlign); + + // sqlId에 대한 annotation은 멀티 value가 날라옴. + final IntStringStringValue sqlValue = (IntStringStringValue) sqlIdAnnotation.getValue(); + final int hashCode = sqlValue.getIntValue(); + final String sqlParam = sqlValue.getStringValue1(); + final List sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentKey.getAgentId(), agentKey.getAgentStartTime(), hashCode); + final int size = sqlMetaDataList.size(); + if (size == 0) { + AnnotationBo api = new AnnotationBo(); + api.setKey(AnnotationKey.SQL.getCode()); + api.setValue("SQL-ID not found hashCode:" + hashCode); + annotationBoList.add(api); + } else if (size == 1) { + final SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(0); + if (StringUtils.isEmpty(sqlParam)) { + AnnotationBo sqlMeta = new AnnotationBo(); + sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); + sqlMeta.setValue(sqlMetaDataBo.getSql()); + annotationBoList.add(sqlMeta); + +// AnnotationBo checkFail = checkIdentifier(spanAlign, sqlMetaDataBo); +// if (checkFail != null) { +// // 실패 +// annotationBoList.add(checkFail); +// return; +// } + + AnnotationBo sql = new AnnotationBo(); + sql.setKey(AnnotationKey.SQL.getCode()); + sql.setValue(sqlMetaDataBo.getSql()); + annotationBoList.add(sql); + } else { + logger.debug("sqlMetaDataBo:{}", sqlMetaDataBo); + final String outputParams = sqlParam; + List parsedOutputParams = outputParameterParser.parseOutputParameter(outputParams); + logger.debug("outputPrams:{}, parsedOutputPrams:{}", outputParams, parsedOutputParams); + String originalSql = sqlParser.combineOutputParams(sqlMetaDataBo.getSql(), parsedOutputParams); + logger.debug("outputPrams{}, originalSql:{}", outputParams, originalSql); + + AnnotationBo sqlMeta = new AnnotationBo(); + sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); + sqlMeta.setValue(sqlMetaDataBo.getSql()); + annotationBoList.add(sqlMeta); + + + AnnotationBo sql = new AnnotationBo(); + sql.setKey(AnnotationKey.SQL.getCode()); + sql.setValue(originalSql); + annotationBoList.add(sql); + + } + } else { + // TODO 보완해야됨. + AnnotationBo api = new AnnotationBo(); + api.setKey(AnnotationKey.SQL.getCode()); + api.setValue(collisionSqlHashCodeMessage(hashCode, sqlMetaDataList)); + annotationBoList.add(api); + } + // bindValue가 존재할 경우 따라 넣어준다. + final String bindValue = sqlValue.getStringValue2(); + if (StringUtils.isNotEmpty(bindValue)) { + AnnotationBo bindValueAnnotation = new AnnotationBo(); + bindValueAnnotation.setKey(AnnotationKey.SQL_BINDVALUE.getCode()); + bindValueAnnotation.setValue(bindValue); + annotationBoList.add(bindValueAnnotation); + } + + } + + }); + } + + private AnnotationBo findAnnotation(List annotationBoList, int key) { + for (AnnotationBo annotationBo : annotationBoList) { + if (key == annotationBo.getKey()) { + return annotationBo; + } + } + return null; + } + + private String collisionSqlHashCodeMessage(int hashCode, List sqlMetaDataList) { + // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. + StringBuilder sb = new StringBuilder(64); + sb.append("Collision Sql hashCode:"); + sb.append(hashCode); + sb.append('\n'); + for (int i = 0; i < sqlMetaDataList.size(); i++) { + if (i != 0) { + sb.append("or\n"); + } + SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(i); + sb.append(sqlMetaDataBo.getSql()); + } + return sb.toString(); + } + + + private void transitionDynamicApiId(List spans) { + this.transitionAnnotation(spans, new AnnotationReplacementCallback() { + @Override + public void replacement(SpanAlign spanAlign, List annotationBoList) { + final AgentKey key = getAgentKey(spanAlign); + final int apiId = getApiId(spanAlign); + // agentIdentifer를 기준으로 좀더 정확한 데이터를 찾을수 있을 듯 하다. + List apiMetaDataList = apiMetaDataDao.getApiMetaData(key.getAgentId(), key.getAgentStartTime(), apiId); + int size = apiMetaDataList.size(); + if (size == 0) { + AnnotationBo api = new AnnotationBo(); + api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode()); + api.setValue("API-DynamicID not found. api:" + apiId); + annotationBoList.add(api); + } else if (size == 1) { + ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(0); + AnnotationBo apiMetaData = new AnnotationBo(); + apiMetaData.setKey(AnnotationKey.API_METADATA.getCode()); + apiMetaData.setValue(apiMetaDataBo); + annotationBoList.add(apiMetaData); + + AnnotationBo apiAnnotation = new AnnotationBo(); + apiAnnotation.setKey(AnnotationKey.API.getCode()); + String apiInfo = getApiInfo(apiMetaDataBo); + apiAnnotation.setValue(apiInfo); + annotationBoList.add(apiAnnotation); + } else { + AnnotationBo apiAnnotation = new AnnotationBo(); + apiAnnotation.setKey(AnnotationKey.ERROR_API_METADATA_DID_COLLSION.getCode()); + String collisonMessage = collisionApiDidMessage(apiId, apiMetaDataList); + apiAnnotation.setValue(collisonMessage); + annotationBoList.add(apiAnnotation); + } + + } + + }); + } + + private void transitionCachedString(List spans) { + this.transitionAnnotation(spans, new AnnotationReplacementCallback() { + @Override + public void replacement(SpanAlign spanAlign, List annotationBoList) { + final AgentKey key = getAgentKey(spanAlign); + List cachedStringAnnotation = findCachedStringAnnotation(annotationBoList); + if (cachedStringAnnotation.isEmpty()) { + return; + } + for (AnnotationBo annotationBo : cachedStringAnnotation) { + final int cachedArgsKey = annotationBo.getKey(); + int stringMetaDataId = (Integer) annotationBo.getValue(); + List stringMetaList = stringMetaDataDao.getStringMetaData(key.getAgentId(), key.getAgentStartTime(), stringMetaDataId); + int size = stringMetaList.size(); + if (size == 0) { + logger.warn("StringMetaData not Found {}/{}/{}", key.getAgentId(), stringMetaDataId, key.getAgentStartTime()); + AnnotationBo api = new AnnotationBo(); + // API METADATA ERROR가 아님. 추후 수정. + api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode()); + api.setValue("CACHED-STRING-ID not found. stringId:" + cachedArgsKey); + annotationBoList.add(api); + } else if (size >= 1) { + // key 충돌 경우는 후추 처리한다. 실제 상황에서는 일부러 만들지 않는한 발생할수 없다. + StringMetaDataBo stringMetaDataBo = stringMetaList.get(0); + + AnnotationBo stringMetaData = new AnnotationBo(); + stringMetaData.setKey(AnnotationKey.cachedArgsToArgs(cachedArgsKey)); + stringMetaData.setValue(stringMetaDataBo.getStringValue()); + annotationBoList.add(stringMetaData); + if (size > 1) { + logger.warn("stringMetaData size not 1 :{}", stringMetaList); + } + } + } + } + + }); + } + + private List findCachedStringAnnotation(List annotationBoList) { + List findAnnotationBoList = new ArrayList(annotationBoList.size()); + for (AnnotationBo annotationBo : annotationBoList) { + if (AnnotationKey.isCachedArgsKey(annotationBo.getKey())) { + findAnnotationBoList.add(annotationBo); + } + } + return findAnnotationBoList; + } + + private void transitionException(List spanAlignList) { + for (SpanAlign spanAlign : spanAlignList) { + if (spanAlign.isSpan()) { + final SpanBo spanBo = spanAlign.getSpanBo(); + if (spanBo.hasException()) { + StringMetaDataBo stringMetaData = selectStringMetaData(spanBo.getAgentId(), spanBo.getExceptionId(), spanBo.getAgentStartTime()); + spanBo.setExceptionClass(stringMetaData.getStringValue()); + } + } else { + final SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); + if (spanEventBo.hasException()) { + StringMetaDataBo stringMetaData = selectStringMetaData(spanEventBo.getAgentId(), spanEventBo.getExceptionId(), spanEventBo.getAgentStartTime()); + if (stringMetaData != null) { + spanEventBo.setExceptionClass(stringMetaData.getStringValue()); + } + } + } + } + + } + + private StringMetaDataBo selectStringMetaData(String agentId, int cacheId, long agentStartTime) { + final List metaDataList = stringMetaDataDao.getStringMetaData(agentId, agentStartTime, cacheId); + if (metaDataList == null || metaDataList.isEmpty()) { + logger.warn("StringMetaData not Found agent:{}, cacheId{}, agentStartTime:{}", agentId, cacheId, agentStartTime); + StringMetaDataBo stringMetaDataBo = new StringMetaDataBo(agentId, agentStartTime, cacheId); + stringMetaDataBo.setStringValue("STRING-META-DATA-NOT-FOUND"); + return stringMetaDataBo; + } + if (metaDataList.size() == 1) { + return metaDataList.get(0); + } else { + // 일단 로그 찍고 처리. + logger.warn("stringMetaData size not 1 :{}", metaDataList); + return metaDataList.get(0); + } + } + + private int getApiId(SpanAlign spanAlign) { + if (spanAlign.isSpan()) { + return spanAlign.getSpanBo().getApiId(); + } else { + return spanAlign.getSpanEventBo().getApiId(); + } + } + + private AgentKey getAgentKey(SpanAlign spanAlign) { + if (spanAlign.isSpan()) { + SpanBo spanBo = spanAlign.getSpanBo(); + return new AgentKey(spanBo.getAgentId(), spanBo.getAgentStartTime()); + } else { + final SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); + return new AgentKey(spanEventBo.getAgentId(), spanEventBo.getAgentStartTime()); + } + } + + private String collisionApiDidMessage(int apidId, List apiMetaDataList) { + // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. + StringBuilder sb = new StringBuilder(64); + sb.append("Collision Api DynamicId:"); + sb.append(apidId); + sb.append('\n'); + for (int i = 0; i < apiMetaDataList.size(); i++) { + if (i != 0) { + sb.append("or\n"); + } + ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(i); + sb.append(getApiInfo(apiMetaDataBo)); + } + return sb.toString(); + } + + private String getApiInfo(ApiMetaDataBo apiMetaDataBo) { + if (apiMetaDataBo.getLineNumber() != -1) { + return apiMetaDataBo.getApiInfo() + ":" + apiMetaDataBo.getLineNumber(); + } else { + return apiMetaDataBo.getApiInfo(); + } + } + + public static interface AnnotationReplacementCallback { + void replacement(SpanAlign spanAlign, List annotationBoList); + } + + private SpanResult order(List spans, long selectedSpanHint) { + SpanAligner2 spanAligner = new SpanAligner2(spans, selectedSpanHint); + List sort = spanAligner.sort(); + + logger.trace("SpanAlignList:{}", sort); + return new SpanResult(spanAligner.getMatchType(), sort); + + } + + + private static final class AgentKey { + + private final String agentId; + private final long agentStartTime; + + private AgentKey(String agentId, long agentStartTime) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + this.agentId = agentId; + this.agentStartTime = agentStartTime; + } + + private String getAgentId() { + return agentId; + } + + private long getAgentStartTime() { + return agentStartTime; + } + } +} + diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoService.java index 241a7a242f4c..b287c5b3f610 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoService.java @@ -1,19 +1,19 @@ -package com.nhn.pinpoint.web.service; - -import java.util.List; - -import com.nhn.pinpoint.web.calltree.span.SpanAlign; -import com.nhn.pinpoint.web.filter.Filter; -import com.nhn.pinpoint.web.vo.BusinessTransactions; -import com.nhn.pinpoint.web.vo.Range; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.callstacks.RecordSet; - -/** - * - */ -public interface TransactionInfoService { - RecordSet createRecordSet(List spanAligns, long focusTimestamp); - - BusinessTransactions selectBusinessTransactions(List traceIds, String applicationName, Range range, Filter filter); -} +package com.nhn.pinpoint.web.service; + +import java.util.List; + +import com.nhn.pinpoint.web.calltree.span.SpanAlign; +import com.nhn.pinpoint.web.filter.Filter; +import com.nhn.pinpoint.web.vo.BusinessTransactions; +import com.nhn.pinpoint.web.vo.Range; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.callstacks.RecordSet; + +/** + * + */ +public interface TransactionInfoService { + RecordSet createRecordSet(List spanAligns, long focusTimestamp); + + BusinessTransactions selectBusinessTransactions(List traceIds, String applicationName, Range range, Filter filter); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java index 2239d0be84ac..8ef7aba35505 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java @@ -1,539 +1,539 @@ -package com.nhn.pinpoint.web.service; - - -import java.util.ArrayList; -import java.util.List; - -import com.nhn.pinpoint.web.util.Stack; -import com.nhn.pinpoint.web.vo.Range; -import org.apache.commons.lang.ObjectUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.nhn.pinpoint.common.AnnotationKey; -import com.nhn.pinpoint.common.bo.AnnotationBo; -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.common.bo.SpanEventBo; -import com.nhn.pinpoint.common.util.AnnotationUtils; -import com.nhn.pinpoint.common.util.ApiDescription; -import com.nhn.pinpoint.common.util.ApiDescriptionParser; -import com.nhn.pinpoint.web.calltree.span.SpanAlign; -import com.nhn.pinpoint.web.dao.TraceDao; -import com.nhn.pinpoint.web.filter.Filter; -import com.nhn.pinpoint.web.vo.BusinessTransactions; -import com.nhn.pinpoint.web.vo.TransactionId; -import com.nhn.pinpoint.web.vo.callstacks.Record; -import com.nhn.pinpoint.web.vo.callstacks.RecordSet; - -/** - * - */ -@Service -public class TransactionInfoServiceImpl implements TransactionInfoService { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private TraceDao traceDao; - - @Override - public BusinessTransactions selectBusinessTransactions(List transactionIdList, String applicationName, Range range, Filter filter) { - if (transactionIdList == null) { - throw new NullPointerException("transactionIdList must not be null"); - } - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - if (filter == null) { - throw new NullPointerException("filter must not be null"); - } - if (range == null) { - // TODO 레인지를 사용하지 않네. 확인필요. - throw new NullPointerException("range must not be null"); - } - - - List> traceList; - - if (filter == Filter.NONE) { - traceList = this.traceDao.selectSpans(transactionIdList); - } else { - traceList = this.traceDao.selectAllSpans(transactionIdList); - } - - BusinessTransactions businessTransactions = new BusinessTransactions(); - for (List trace : traceList) { - if (!filter.include(trace)) { - continue; - } - - for (SpanBo spanBo : trace) { - // 해당 application으로 인입된 요청만 보여준다. - if (applicationName.equals(spanBo.getApplicationId())) { - businessTransactions.add(spanBo); - } - } - } - - return businessTransactions; - } - - @Override - public RecordSet createRecordSet(List spanAlignList, long focusTimestamp) { - if (spanAlignList == null) { - throw new NullPointerException("spanAlignList must not be null"); - } - - RecordSet recordSet = new RecordSet(); - - // focusTimeStamp 를 찾아서 마크한다. - // span이 2개 이상으로 구성되었을 경우, 내가 어떤 span을 기준으로 보는지 알려면 focus시점을 찾아야 한다. - // 오류로 인해 foucs를 못찾을수 도있으므로, 없을 경우 별도 mark가 추가적으로 있어야 함. - // TODO 잘못 될수 있는점 foucusTime은 실제로 2개 이상 나올수 잇음. 서버의 time을 사용하므로 오차로 인해 2개가 나올수도 있음. - SpanBo focusTimeSpanBo = findFocusTimeSpanBo(spanAlignList, focusTimestamp); - // focusTimeSpanBO를 못찾을 경우에 대한 임시 패치를 하였으나 근본적으로 해결된게 아님. - if (focusTimeSpanBo != null) { - recordSet.setAgentId(focusTimeSpanBo.getAgentId()); - recordSet.setApplicationId(focusTimeSpanBo.getApplicationId()); - - final String applicationName = getRpcArgument(focusTimeSpanBo); - recordSet.setApplicationName(applicationName); - } - - - // 기준이 되는 시작시간을 찾는다. - long startTime = getStartTime(spanAlignList); - recordSet.setStartTime(startTime); - - // 기준이 되는 종료 시간을 찾는다. - long endTime = getEndTime(spanAlignList); - recordSet.setEndTime(endTime); - - final SpanAlignPopulate spanAlignPopulate = new SpanAlignPopulate(); - List recordList = spanAlignPopulate.populateSpanRecord(spanAlignList); - logger.debug("RecordList:{}", recordList); - - if (focusTimeSpanBo != null) { - // focus 대상 record를 체크한다. - long beginTimeStamp = focusTimeSpanBo.getStartTime(); - markFocusRecord(recordList, beginTimeStamp); - recordSet.setBeginTimestamp(beginTimeStamp); - } - - recordSet.setRecordList(recordList); - return recordSet; - } - - private void markFocusRecord(List recordList, long beginTimeStamp) { - for (Record record : recordList) { - if (record.getBegin() == beginTimeStamp) { - record.setFocused(true); - break; - } - } - } - - - private long getStartTime(List spanAlignList) { - if (spanAlignList == null || spanAlignList.size() == 0) { - return 0; - } - SpanAlign spanAlign = spanAlignList.get(0); - if (spanAlign.isSpan()) { - SpanBo spanBo = spanAlign.getSpanBo(); - return spanBo.getStartTime(); - } else { - SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); - return spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); - } - } - - private long getEndTime(List spanAlignList) { - if (spanAlignList == null || spanAlignList.size() == 0) { - return 0; - } - SpanAlign spanAlign = spanAlignList.get(0); - if (spanAlign.isSpan()) { - SpanBo spanBo = spanAlign.getSpanBo(); - return spanBo.getElapsed(); - } else { - SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); - long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); - long elapsed = spanEventBo.getEndElapsed(); - return begin + elapsed; - } - } - - - private SpanBo findFocusTimeSpanBo(List spanAlignList, long focusTimestamp) { - SpanBo firstSpan = null; - for (SpanAlign spanAlign : spanAlignList) { - if (spanAlign.isSpan()) { - SpanBo spanBo = spanAlign.getSpanBo(); - if (spanBo.getCollectorAcceptTime() == focusTimestamp) { - return spanBo; - } - if (firstSpan == null) { - firstSpan = spanBo; - } - } - } - // foucus된 Span을 찾지 못할 경우 firstSpan을 리턴한다. - return firstSpan; - } - - private static class SpanAlignPopulate { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final ApiDescriptionParser apiDescriptionParser = new ApiDescriptionParser(); - - // id가 0일 경우 root로 취급하는 문제가 있어 1부터 시작하도록 함. - private int idGen = 1; - private final Stack stack = new Stack(); - - private int getNextId() { - return idGen++; - } - - private List populateSpanRecord(List spanAlignList) { - if (spanAlignList == null) { - throw new NullPointerException("spanAlignList must not be null"); - } - final List recordList = new ArrayList(spanAlignList.size() * 2); - - // annotation id는 spanalign의 seq와 무관하게 순서대로 따도 됨. 겹치지만 않으면 됨. - for (int i = 0; i < spanAlignList.size(); i++) { - final SpanAlign spanAlign = spanAlignList.get(i); - if (i == 0) { - if (!spanAlign.isSpan()) { - throw new IllegalArgumentException("root is not span"); - } - // spanAlign의 startTime을 넣을 경우 동일 시간으로 빼면 0이 나오므로 동일 값을 넣는다.. - final SpanDepth spanDepth = new SpanDepth(spanAlign, getNextId(), spanAlign.getSpanBo().getStartTime()); - stack.push(spanDepth); - } else { - final SpanDepth lastSpanDepth = stack.getLast(); - final int parentDepth = lastSpanDepth.getSpanAlign().getDepth(); - final int currentDepth = spanAlign.getDepth(); - logger.debug("parentDepth:{} currentDepth:{} sequence:{}", parentDepth, currentDepth, lastSpanDepth.getId()); - - if (parentDepth < spanAlign.getDepth()) { - // 부모의 깊이가 더 작을 경우 push해야 한다. - final SpanDepth last = stack.getLast(); - final long beforeStartTime = getStartTime(last.getSpanAlign()); - final SpanDepth spanDepth = new SpanDepth(spanAlign, getNextId(), beforeStartTime); - stack.push(spanDepth); - } else { - if (parentDepth > currentDepth) { - // 부모의 깊이가 클 경우 pop해야 한다. - // 단 depth차가 1depth이상 날수 있기 때문에. depth를 확인하면서 pop을 해야 한다. - SpanDepth lastPopSpanDepth; - while (true) { - logger.trace("pop"); - lastPopSpanDepth = stack.pop(); - SpanDepth popLast = stack.getLast(); - if (popLast.getSpanAlign().getDepth() < currentDepth) { - break; - } - } - final long beforeLastEndTime = getLastTime(lastPopSpanDepth.getSpanAlign()); - stack.push(new SpanDepth(spanAlign, getNextId(), beforeLastEndTime)); - } else { - // 바로 앞 동일 depth의 object는 버려야 한다. - final SpanDepth before = stack.pop(); - final long beforeLastEndTime = getLastTime(before.getSpanAlign()); - stack.push(new SpanDepth(spanAlign, getNextId(), beforeLastEndTime)); - } - } - } - - if (spanAlign.isSpan()) { - SpanBo spanBo = spanAlign.getSpanBo(); - - String argument = getRpcArgument(spanBo); - - final long begin = spanBo.getStartTime(); - final long elapsed = spanBo.getElapsed(); - final int spanBoSequence = stack.getLast().getId(); - int parentSequence; - final SpanDepth parent = stack.getParent(); - if (parent == null) { - // 자기 자신이 root인 경우 - parentSequence = 0; - } else { - parentSequence = parent.getId(); - } - logger.debug("spanBoSequence:{}, parentSequence:{}", spanBoSequence, parentSequence); - - - String method = AnnotationUtils.findApiAnnotation(spanBo.getAnnotationBoList()); - if (method != null) { - ApiDescription apiDescription = apiDescriptionParser.parse(method); - Record record = new Record(spanAlign.getDepth(), - spanBoSequence, - parentSequence, - true, - apiDescription.getSimpleMethodDescription(), - argument, - begin, - elapsed, - getGap(stack), - spanBo.getAgentId(), - spanBo.getApplicationId(), - spanBo.getServiceType(), - null, - spanAlign.isHasChild(), - false); - record.setSimpleClassName(apiDescription.getSimpleClassName()); - record.setFullApiDescription(method); - recordList.add(record); - } else { - AnnotationKey apiMetaDataError = AnnotationUtils.getApiMetaDataError(spanBo.getAnnotationBoList()); - Record record = new Record(spanAlign.getDepth(), - spanBoSequence, - parentSequence, - true, - apiMetaDataError.getValue(), - argument, - begin, - elapsed, - getGap(stack), - spanBo.getAgentId(), - spanBo.getApplicationId(), - spanBo.getServiceType(), - null, - spanAlign.isHasChild(), - false); - record.setSimpleClassName(""); - record.setFullApiDescription(""); - recordList.add(record); - } - // exception이 발생했을 경우 record추가. - final Record exceptionRecord = getExceptionRecord(spanAlign, spanBoSequence); - if (exceptionRecord != null) { - recordList.add(exceptionRecord); - } - - List annotationRecord = createAnnotationRecord(spanAlign.getDepth() + 1, spanBoSequence, spanBo.getAnnotationBoList()); - recordList.addAll(annotationRecord); - if (spanBo.getRemoteAddr() != null) { - Record remoteAddress = createParameterRecord(spanAlign.getDepth() + 1, spanBoSequence, "REMOTE_ADDRESS", spanBo.getRemoteAddr()); - recordList.add(remoteAddress); - } - } else { - SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); - SpanBo spanBo = spanAlign.getSpanBo(); - - String argument = getDisplayArgument(spanEventBo); - final int spanBoEventSequence = stack.getLast().getId(); - final SpanDepth parent = stack.getParent(); - if (parent == null) { - throw new IllegalStateException("parent is null. stack:" + stack); - } - final int parentSequence = parent.getId(); - logger.debug("spanBoEventSequence:{}, parentSequence:{}", spanBoEventSequence, parentSequence); - - final String method = AnnotationUtils.findApiAnnotation(spanEventBo.getAnnotationBoList()); - if (method != null) { - ApiDescription apiDescription = apiDescriptionParser.parse(method); - String destinationId = spanEventBo.getDestinationId(); - - long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); - long elapsed = spanEventBo.getEndElapsed(); - - // stacktrace에 호출한 application name을 보여주기 위해서 eventbo.destinationid 대신에 spanbo.applicaitonid를 넣어줌. - Record record = new Record(spanAlign.getDepth(), - spanBoEventSequence, - parentSequence, - true, - apiDescription.getSimpleMethodDescription(), - argument, - begin, - elapsed, - getGap(stack), - spanEventBo.getAgentId(), - spanBo.getApplicationId(), - spanEventBo.getServiceType(), - /* spanEventBo.getDestinationId(), spanEventBo.getServiceType(),*/ - destinationId, - spanAlign.isHasChild(), - false); - record.setSimpleClassName(apiDescription.getSimpleClassName()); - record.setFullApiDescription(method); - - recordList.add(record); - } else { - AnnotationKey apiMetaDataError = AnnotationUtils.getApiMetaDataError(spanEventBo.getAnnotationBoList()); - String destinationId = spanEventBo.getDestinationId(); - - long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); - long elapsed = spanEventBo.getEndElapsed(); - - // stacktrace에 호출한 application name을 보여주기 위해서 eventbo.destinationid 대신에 spanbo.applicaitonid를 넣어줌. - Record record = new Record(spanAlign.getDepth(), - spanBoEventSequence, - parentSequence, - true, - apiMetaDataError.getValue(), - argument, - begin, - elapsed, - getGap(stack), - spanEventBo.getAgentId(), - spanBo.getApplicationId(), - spanEventBo.getServiceType(), - /*spanEventBo.getDestinationId(), spanEventBo.getServiceType(),*/ - destinationId, - spanAlign.isHasChild(), - false); - record.setSimpleClassName(""); - record.setFullApiDescription(method); - - recordList.add(record); - } - // exception이 발생했을 경우 record추가. - final Record exceptionRecord = getExceptionRecord(spanAlign, spanBoEventSequence); - if (exceptionRecord != null) { - recordList.add(exceptionRecord); - } - - List annotationRecord = createAnnotationRecord(spanAlign.getDepth() + 1, spanBoEventSequence, spanEventBo.getAnnotationBoList()); - recordList.addAll(annotationRecord); - } - } - return recordList; - } - - private Record getExceptionRecord(SpanAlign spanAlign, int parentSequence) { - if (spanAlign.isSpan()) { - final SpanBo spanBo = spanAlign.getSpanBo(); - if (spanBo.hasException()) { - String simpleExceptionClass = getSimpleExceptionName(spanBo.getExceptionClass()); - return new Record(spanAlign.getDepth() + 1, - getNextId(), - parentSequence, - false, - simpleExceptionClass, - spanBo.getExceptionMessage(), - 0L, - 0L, - 0, - null, - null, - null, - null, - false, - false); - } - } else { - final SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); - if (spanEventBo.hasException()) { - String simpleExceptionClass = getSimpleExceptionName(spanEventBo.getExceptionClass()); - return new Record(spanAlign.getDepth() + 1, - getNextId(), - parentSequence, - false, - simpleExceptionClass, - spanEventBo.getExceptionMessage(), - 0L, - 0L, - 0, - null, - null, - null, - null, - false, - true); - } - } - return null; - } - - private String getSimpleExceptionName(String exceptionClass) { - if (exceptionClass == null) { - return ""; - } - final int index = exceptionClass.lastIndexOf('.'); - if (index != -1) { - exceptionClass = exceptionClass.substring(index+1, exceptionClass.length()); - } - return exceptionClass; - } - - - private long getGap(Stack stack) { - SpanDepth last = stack.getLast(); - final long lastExecuteTime = last.getLastExecuteTime(); - SpanAlign spanAlign = last.getSpanAlign(); - if (spanAlign.isSpan()) { - return spanAlign.getSpanBo().getStartTime() - lastExecuteTime; - } else { - return (spanAlign.getSpanBo().getStartTime() + spanAlign.getSpanEventBo().getStartElapsed()) - lastExecuteTime; - } - } - - private long getLastTime(SpanAlign spanAlign) { - final SpanBo spanBo = spanAlign.getSpanBo(); - if (spanAlign.isSpan()) { - return spanBo.getStartTime() + spanBo.getElapsed(); - } else { - SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); - return spanBo.getStartTime() + spanEventBo.getStartElapsed() + spanEventBo.getEndElapsed(); - } - } - - private long getStartTime(SpanAlign spanAlign) { - final SpanBo spanBo = spanAlign.getSpanBo(); - if (spanAlign.isSpan()) { - return spanBo.getStartTime(); - } else { - return spanBo.getStartTime() + spanAlign.getSpanEventBo().getStartElapsed(); - } - } - - - private List createAnnotationRecord(int depth, int parentId, List annotationBoList) { - List recordList = new ArrayList(annotationBoList.size()); - - for (AnnotationBo ann : annotationBoList) { - AnnotationKey annotation = AnnotationKey.findAnnotationKey(ann.getKey()); - if (annotation.isViewInRecordSet()) { - Record record = new Record(depth, getNextId(), parentId, false, annotation.getValue(), ann.getValue().toString(), 0L, 0L, 0, null, null, null, null, false, false); - recordList.add(record); - } - } - - return recordList; - } - - private Record createParameterRecord(int depth, int parentId, String method, String argument) { - return new Record(depth, getNextId(), parentId, false, method, argument, 0L, 0L, 0, null, null, null, null, false, false); - } - } - - private static String getDisplayArgument(SpanBo spanBo) { - AnnotationBo displayArgument = AnnotationUtils.getDisplayArgument(spanBo); - if (displayArgument == null) { - return ""; - } - return ObjectUtils.toString(displayArgument.getValue()); - } - - private static String getDisplayArgument(SpanEventBo spanEventBo) { - AnnotationBo displayArgument = AnnotationUtils.getDisplayArgument(spanEventBo); - if (displayArgument == null) { - return ""; - } - return ObjectUtils.toString(displayArgument.getValue()); - } - - private static String getRpcArgument(SpanBo spanBo) { - String rpc = spanBo.getRpc(); - if (rpc != null) { - return rpc; - } - return getDisplayArgument(spanBo); - } -} +package com.nhn.pinpoint.web.service; + + +import java.util.ArrayList; +import java.util.List; + +import com.nhn.pinpoint.web.util.Stack; +import com.nhn.pinpoint.web.vo.Range; +import org.apache.commons.lang.ObjectUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.nhn.pinpoint.common.AnnotationKey; +import com.nhn.pinpoint.common.bo.AnnotationBo; +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.common.bo.SpanEventBo; +import com.nhn.pinpoint.common.util.AnnotationUtils; +import com.nhn.pinpoint.common.util.ApiDescription; +import com.nhn.pinpoint.common.util.ApiDescriptionParser; +import com.nhn.pinpoint.web.calltree.span.SpanAlign; +import com.nhn.pinpoint.web.dao.TraceDao; +import com.nhn.pinpoint.web.filter.Filter; +import com.nhn.pinpoint.web.vo.BusinessTransactions; +import com.nhn.pinpoint.web.vo.TransactionId; +import com.nhn.pinpoint.web.vo.callstacks.Record; +import com.nhn.pinpoint.web.vo.callstacks.RecordSet; + +/** + * + */ +@Service +public class TransactionInfoServiceImpl implements TransactionInfoService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private TraceDao traceDao; + + @Override + public BusinessTransactions selectBusinessTransactions(List transactionIdList, String applicationName, Range range, Filter filter) { + if (transactionIdList == null) { + throw new NullPointerException("transactionIdList must not be null"); + } + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (filter == null) { + throw new NullPointerException("filter must not be null"); + } + if (range == null) { + // TODO 레인지를 사용하지 않네. 확인필요. + throw new NullPointerException("range must not be null"); + } + + + List> traceList; + + if (filter == Filter.NONE) { + traceList = this.traceDao.selectSpans(transactionIdList); + } else { + traceList = this.traceDao.selectAllSpans(transactionIdList); + } + + BusinessTransactions businessTransactions = new BusinessTransactions(); + for (List trace : traceList) { + if (!filter.include(trace)) { + continue; + } + + for (SpanBo spanBo : trace) { + // 해당 application으로 인입된 요청만 보여준다. + if (applicationName.equals(spanBo.getApplicationId())) { + businessTransactions.add(spanBo); + } + } + } + + return businessTransactions; + } + + @Override + public RecordSet createRecordSet(List spanAlignList, long focusTimestamp) { + if (spanAlignList == null) { + throw new NullPointerException("spanAlignList must not be null"); + } + + RecordSet recordSet = new RecordSet(); + + // focusTimeStamp 를 찾아서 마크한다. + // span이 2개 이상으로 구성되었을 경우, 내가 어떤 span을 기준으로 보는지 알려면 focus시점을 찾아야 한다. + // 오류로 인해 foucs를 못찾을수 도있으므로, 없을 경우 별도 mark가 추가적으로 있어야 함. + // TODO 잘못 될수 있는점 foucusTime은 실제로 2개 이상 나올수 잇음. 서버의 time을 사용하므로 오차로 인해 2개가 나올수도 있음. + SpanBo focusTimeSpanBo = findFocusTimeSpanBo(spanAlignList, focusTimestamp); + // focusTimeSpanBO를 못찾을 경우에 대한 임시 패치를 하였으나 근본적으로 해결된게 아님. + if (focusTimeSpanBo != null) { + recordSet.setAgentId(focusTimeSpanBo.getAgentId()); + recordSet.setApplicationId(focusTimeSpanBo.getApplicationId()); + + final String applicationName = getRpcArgument(focusTimeSpanBo); + recordSet.setApplicationName(applicationName); + } + + + // 기준이 되는 시작시간을 찾는다. + long startTime = getStartTime(spanAlignList); + recordSet.setStartTime(startTime); + + // 기준이 되는 종료 시간을 찾는다. + long endTime = getEndTime(spanAlignList); + recordSet.setEndTime(endTime); + + final SpanAlignPopulate spanAlignPopulate = new SpanAlignPopulate(); + List recordList = spanAlignPopulate.populateSpanRecord(spanAlignList); + logger.debug("RecordList:{}", recordList); + + if (focusTimeSpanBo != null) { + // focus 대상 record를 체크한다. + long beginTimeStamp = focusTimeSpanBo.getStartTime(); + markFocusRecord(recordList, beginTimeStamp); + recordSet.setBeginTimestamp(beginTimeStamp); + } + + recordSet.setRecordList(recordList); + return recordSet; + } + + private void markFocusRecord(List recordList, long beginTimeStamp) { + for (Record record : recordList) { + if (record.getBegin() == beginTimeStamp) { + record.setFocused(true); + break; + } + } + } + + + private long getStartTime(List spanAlignList) { + if (spanAlignList == null || spanAlignList.size() == 0) { + return 0; + } + SpanAlign spanAlign = spanAlignList.get(0); + if (spanAlign.isSpan()) { + SpanBo spanBo = spanAlign.getSpanBo(); + return spanBo.getStartTime(); + } else { + SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); + return spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); + } + } + + private long getEndTime(List spanAlignList) { + if (spanAlignList == null || spanAlignList.size() == 0) { + return 0; + } + SpanAlign spanAlign = spanAlignList.get(0); + if (spanAlign.isSpan()) { + SpanBo spanBo = spanAlign.getSpanBo(); + return spanBo.getElapsed(); + } else { + SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); + long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); + long elapsed = spanEventBo.getEndElapsed(); + return begin + elapsed; + } + } + + + private SpanBo findFocusTimeSpanBo(List spanAlignList, long focusTimestamp) { + SpanBo firstSpan = null; + for (SpanAlign spanAlign : spanAlignList) { + if (spanAlign.isSpan()) { + SpanBo spanBo = spanAlign.getSpanBo(); + if (spanBo.getCollectorAcceptTime() == focusTimestamp) { + return spanBo; + } + if (firstSpan == null) { + firstSpan = spanBo; + } + } + } + // foucus된 Span을 찾지 못할 경우 firstSpan을 리턴한다. + return firstSpan; + } + + private static class SpanAlignPopulate { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ApiDescriptionParser apiDescriptionParser = new ApiDescriptionParser(); + + // id가 0일 경우 root로 취급하는 문제가 있어 1부터 시작하도록 함. + private int idGen = 1; + private final Stack stack = new Stack(); + + private int getNextId() { + return idGen++; + } + + private List populateSpanRecord(List spanAlignList) { + if (spanAlignList == null) { + throw new NullPointerException("spanAlignList must not be null"); + } + final List recordList = new ArrayList(spanAlignList.size() * 2); + + // annotation id는 spanalign의 seq와 무관하게 순서대로 따도 됨. 겹치지만 않으면 됨. + for (int i = 0; i < spanAlignList.size(); i++) { + final SpanAlign spanAlign = spanAlignList.get(i); + if (i == 0) { + if (!spanAlign.isSpan()) { + throw new IllegalArgumentException("root is not span"); + } + // spanAlign의 startTime을 넣을 경우 동일 시간으로 빼면 0이 나오므로 동일 값을 넣는다.. + final SpanDepth spanDepth = new SpanDepth(spanAlign, getNextId(), spanAlign.getSpanBo().getStartTime()); + stack.push(spanDepth); + } else { + final SpanDepth lastSpanDepth = stack.getLast(); + final int parentDepth = lastSpanDepth.getSpanAlign().getDepth(); + final int currentDepth = spanAlign.getDepth(); + logger.debug("parentDepth:{} currentDepth:{} sequence:{}", parentDepth, currentDepth, lastSpanDepth.getId()); + + if (parentDepth < spanAlign.getDepth()) { + // 부모의 깊이가 더 작을 경우 push해야 한다. + final SpanDepth last = stack.getLast(); + final long beforeStartTime = getStartTime(last.getSpanAlign()); + final SpanDepth spanDepth = new SpanDepth(spanAlign, getNextId(), beforeStartTime); + stack.push(spanDepth); + } else { + if (parentDepth > currentDepth) { + // 부모의 깊이가 클 경우 pop해야 한다. + // 단 depth차가 1depth이상 날수 있기 때문에. depth를 확인하면서 pop을 해야 한다. + SpanDepth lastPopSpanDepth; + while (true) { + logger.trace("pop"); + lastPopSpanDepth = stack.pop(); + SpanDepth popLast = stack.getLast(); + if (popLast.getSpanAlign().getDepth() < currentDepth) { + break; + } + } + final long beforeLastEndTime = getLastTime(lastPopSpanDepth.getSpanAlign()); + stack.push(new SpanDepth(spanAlign, getNextId(), beforeLastEndTime)); + } else { + // 바로 앞 동일 depth의 object는 버려야 한다. + final SpanDepth before = stack.pop(); + final long beforeLastEndTime = getLastTime(before.getSpanAlign()); + stack.push(new SpanDepth(spanAlign, getNextId(), beforeLastEndTime)); + } + } + } + + if (spanAlign.isSpan()) { + SpanBo spanBo = spanAlign.getSpanBo(); + + String argument = getRpcArgument(spanBo); + + final long begin = spanBo.getStartTime(); + final long elapsed = spanBo.getElapsed(); + final int spanBoSequence = stack.getLast().getId(); + int parentSequence; + final SpanDepth parent = stack.getParent(); + if (parent == null) { + // 자기 자신이 root인 경우 + parentSequence = 0; + } else { + parentSequence = parent.getId(); + } + logger.debug("spanBoSequence:{}, parentSequence:{}", spanBoSequence, parentSequence); + + + String method = AnnotationUtils.findApiAnnotation(spanBo.getAnnotationBoList()); + if (method != null) { + ApiDescription apiDescription = apiDescriptionParser.parse(method); + Record record = new Record(spanAlign.getDepth(), + spanBoSequence, + parentSequence, + true, + apiDescription.getSimpleMethodDescription(), + argument, + begin, + elapsed, + getGap(stack), + spanBo.getAgentId(), + spanBo.getApplicationId(), + spanBo.getServiceType(), + null, + spanAlign.isHasChild(), + false); + record.setSimpleClassName(apiDescription.getSimpleClassName()); + record.setFullApiDescription(method); + recordList.add(record); + } else { + AnnotationKey apiMetaDataError = AnnotationUtils.getApiMetaDataError(spanBo.getAnnotationBoList()); + Record record = new Record(spanAlign.getDepth(), + spanBoSequence, + parentSequence, + true, + apiMetaDataError.getValue(), + argument, + begin, + elapsed, + getGap(stack), + spanBo.getAgentId(), + spanBo.getApplicationId(), + spanBo.getServiceType(), + null, + spanAlign.isHasChild(), + false); + record.setSimpleClassName(""); + record.setFullApiDescription(""); + recordList.add(record); + } + // exception이 발생했을 경우 record추가. + final Record exceptionRecord = getExceptionRecord(spanAlign, spanBoSequence); + if (exceptionRecord != null) { + recordList.add(exceptionRecord); + } + + List annotationRecord = createAnnotationRecord(spanAlign.getDepth() + 1, spanBoSequence, spanBo.getAnnotationBoList()); + recordList.addAll(annotationRecord); + if (spanBo.getRemoteAddr() != null) { + Record remoteAddress = createParameterRecord(spanAlign.getDepth() + 1, spanBoSequence, "REMOTE_ADDRESS", spanBo.getRemoteAddr()); + recordList.add(remoteAddress); + } + } else { + SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); + SpanBo spanBo = spanAlign.getSpanBo(); + + String argument = getDisplayArgument(spanEventBo); + final int spanBoEventSequence = stack.getLast().getId(); + final SpanDepth parent = stack.getParent(); + if (parent == null) { + throw new IllegalStateException("parent is null. stack:" + stack); + } + final int parentSequence = parent.getId(); + logger.debug("spanBoEventSequence:{}, parentSequence:{}", spanBoEventSequence, parentSequence); + + final String method = AnnotationUtils.findApiAnnotation(spanEventBo.getAnnotationBoList()); + if (method != null) { + ApiDescription apiDescription = apiDescriptionParser.parse(method); + String destinationId = spanEventBo.getDestinationId(); + + long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); + long elapsed = spanEventBo.getEndElapsed(); + + // stacktrace에 호출한 application name을 보여주기 위해서 eventbo.destinationid 대신에 spanbo.applicaitonid를 넣어줌. + Record record = new Record(spanAlign.getDepth(), + spanBoEventSequence, + parentSequence, + true, + apiDescription.getSimpleMethodDescription(), + argument, + begin, + elapsed, + getGap(stack), + spanEventBo.getAgentId(), + spanBo.getApplicationId(), + spanEventBo.getServiceType(), + /* spanEventBo.getDestinationId(), spanEventBo.getServiceType(),*/ + destinationId, + spanAlign.isHasChild(), + false); + record.setSimpleClassName(apiDescription.getSimpleClassName()); + record.setFullApiDescription(method); + + recordList.add(record); + } else { + AnnotationKey apiMetaDataError = AnnotationUtils.getApiMetaDataError(spanEventBo.getAnnotationBoList()); + String destinationId = spanEventBo.getDestinationId(); + + long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed(); + long elapsed = spanEventBo.getEndElapsed(); + + // stacktrace에 호출한 application name을 보여주기 위해서 eventbo.destinationid 대신에 spanbo.applicaitonid를 넣어줌. + Record record = new Record(spanAlign.getDepth(), + spanBoEventSequence, + parentSequence, + true, + apiMetaDataError.getValue(), + argument, + begin, + elapsed, + getGap(stack), + spanEventBo.getAgentId(), + spanBo.getApplicationId(), + spanEventBo.getServiceType(), + /*spanEventBo.getDestinationId(), spanEventBo.getServiceType(),*/ + destinationId, + spanAlign.isHasChild(), + false); + record.setSimpleClassName(""); + record.setFullApiDescription(method); + + recordList.add(record); + } + // exception이 발생했을 경우 record추가. + final Record exceptionRecord = getExceptionRecord(spanAlign, spanBoEventSequence); + if (exceptionRecord != null) { + recordList.add(exceptionRecord); + } + + List annotationRecord = createAnnotationRecord(spanAlign.getDepth() + 1, spanBoEventSequence, spanEventBo.getAnnotationBoList()); + recordList.addAll(annotationRecord); + } + } + return recordList; + } + + private Record getExceptionRecord(SpanAlign spanAlign, int parentSequence) { + if (spanAlign.isSpan()) { + final SpanBo spanBo = spanAlign.getSpanBo(); + if (spanBo.hasException()) { + String simpleExceptionClass = getSimpleExceptionName(spanBo.getExceptionClass()); + return new Record(spanAlign.getDepth() + 1, + getNextId(), + parentSequence, + false, + simpleExceptionClass, + spanBo.getExceptionMessage(), + 0L, + 0L, + 0, + null, + null, + null, + null, + false, + false); + } + } else { + final SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); + if (spanEventBo.hasException()) { + String simpleExceptionClass = getSimpleExceptionName(spanEventBo.getExceptionClass()); + return new Record(spanAlign.getDepth() + 1, + getNextId(), + parentSequence, + false, + simpleExceptionClass, + spanEventBo.getExceptionMessage(), + 0L, + 0L, + 0, + null, + null, + null, + null, + false, + true); + } + } + return null; + } + + private String getSimpleExceptionName(String exceptionClass) { + if (exceptionClass == null) { + return ""; + } + final int index = exceptionClass.lastIndexOf('.'); + if (index != -1) { + exceptionClass = exceptionClass.substring(index+1, exceptionClass.length()); + } + return exceptionClass; + } + + + private long getGap(Stack stack) { + SpanDepth last = stack.getLast(); + final long lastExecuteTime = last.getLastExecuteTime(); + SpanAlign spanAlign = last.getSpanAlign(); + if (spanAlign.isSpan()) { + return spanAlign.getSpanBo().getStartTime() - lastExecuteTime; + } else { + return (spanAlign.getSpanBo().getStartTime() + spanAlign.getSpanEventBo().getStartElapsed()) - lastExecuteTime; + } + } + + private long getLastTime(SpanAlign spanAlign) { + final SpanBo spanBo = spanAlign.getSpanBo(); + if (spanAlign.isSpan()) { + return spanBo.getStartTime() + spanBo.getElapsed(); + } else { + SpanEventBo spanEventBo = spanAlign.getSpanEventBo(); + return spanBo.getStartTime() + spanEventBo.getStartElapsed() + spanEventBo.getEndElapsed(); + } + } + + private long getStartTime(SpanAlign spanAlign) { + final SpanBo spanBo = spanAlign.getSpanBo(); + if (spanAlign.isSpan()) { + return spanBo.getStartTime(); + } else { + return spanBo.getStartTime() + spanAlign.getSpanEventBo().getStartElapsed(); + } + } + + + private List createAnnotationRecord(int depth, int parentId, List annotationBoList) { + List recordList = new ArrayList(annotationBoList.size()); + + for (AnnotationBo ann : annotationBoList) { + AnnotationKey annotation = AnnotationKey.findAnnotationKey(ann.getKey()); + if (annotation.isViewInRecordSet()) { + Record record = new Record(depth, getNextId(), parentId, false, annotation.getValue(), ann.getValue().toString(), 0L, 0L, 0, null, null, null, null, false, false); + recordList.add(record); + } + } + + return recordList; + } + + private Record createParameterRecord(int depth, int parentId, String method, String argument) { + return new Record(depth, getNextId(), parentId, false, method, argument, 0L, 0L, 0, null, null, null, null, false, false); + } + } + + private static String getDisplayArgument(SpanBo spanBo) { + AnnotationBo displayArgument = AnnotationUtils.getDisplayArgument(spanBo); + if (displayArgument == null) { + return ""; + } + return ObjectUtils.toString(displayArgument.getValue()); + } + + private static String getDisplayArgument(SpanEventBo spanEventBo) { + AnnotationBo displayArgument = AnnotationUtils.getDisplayArgument(spanEventBo); + if (displayArgument == null) { + return ""; + } + return ObjectUtils.toString(displayArgument.getValue()); + } + + private static String getRpcArgument(SpanBo spanBo) { + String rpc = spanBo.getRpc(); + if (rpc != null) { + return rpc; + } + return getDisplayArgument(spanBo); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/DateLimiter.java b/web/src/main/java/com/navercorp/pinpoint/web/util/DateLimiter.java index 2cb3184a6973..8ffbafb57bac 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/DateLimiter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/DateLimiter.java @@ -1,53 +1,53 @@ -package com.nhn.pinpoint.web.util; - -import com.nhn.pinpoint.web.vo.Range; -import org.springframework.stereotype.Component; - -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - */ -@Component -public class DateLimiter implements Limiter { - - private final long limitDay; - private final long limitDayMillis; - - public DateLimiter() { - this(2); - } - - public DateLimiter(int limitDay) { - if (limitDay < 0) { - throw new IllegalArgumentException("limitDay < 0 " + limitDay); - } - this.limitDay = limitDay; - this.limitDayMillis = TimeUnit.DAYS.toMillis((long) limitDay); - } - - @Override - public void limit(long from, long to) { - final long elapsedTime = to - from; - if (elapsedTime < 0) { - throw new IllegalArgumentException("to - from < 0 from:" + from + " to:" + to); - } - if (limitDayMillis < elapsedTime) { - throw new IllegalArgumentException("limitDay:"+ limitDay + " from:" + from + " to:" + to); - } - } - - @Override - public void limit(Range range) { - if (range == null) { - throw new NullPointerException("range must not be null"); - } - final long elapsedTime = range.getRange(); - if (elapsedTime < 0) { - throw new IllegalArgumentException("to - from < 0 " + range); - } - if (limitDayMillis < elapsedTime) { - throw new IllegalArgumentException("limitDay:"+ limitDay + " " + range); - } - } -} +package com.nhn.pinpoint.web.util; + +import com.nhn.pinpoint.web.vo.Range; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + */ +@Component +public class DateLimiter implements Limiter { + + private final long limitDay; + private final long limitDayMillis; + + public DateLimiter() { + this(2); + } + + public DateLimiter(int limitDay) { + if (limitDay < 0) { + throw new IllegalArgumentException("limitDay < 0 " + limitDay); + } + this.limitDay = limitDay; + this.limitDayMillis = TimeUnit.DAYS.toMillis((long) limitDay); + } + + @Override + public void limit(long from, long to) { + final long elapsedTime = to - from; + if (elapsedTime < 0) { + throw new IllegalArgumentException("to - from < 0 from:" + from + " to:" + to); + } + if (limitDayMillis < elapsedTime) { + throw new IllegalArgumentException("limitDay:"+ limitDay + " from:" + from + " to:" + to); + } + } + + @Override + public void limit(Range range) { + if (range == null) { + throw new NullPointerException("range must not be null"); + } + final long elapsedTime = range.getRange(); + if (elapsedTime < 0) { + throw new IllegalArgumentException("to - from < 0 " + range); + } + if (limitDayMillis < elapsedTime) { + throw new IllegalArgumentException("limitDay:"+ limitDay + " " + range); + } + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/KeyValueUtils.java b/web/src/main/java/com/navercorp/pinpoint/web/util/KeyValueUtils.java index 647be721bcb2..fdd16426e5d2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/KeyValueUtils.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/KeyValueUtils.java @@ -1,23 +1,23 @@ -package com.nhn.pinpoint.web.util; - -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.util.Bytes; - -/** - * @author emeroad - */ -public class KeyValueUtils { - - public static boolean equalsFamily(KeyValue keyValue, byte[] familyName) { - if (keyValue == null) { - throw new NullPointerException("keyValue must not be null"); - } - if (familyName == null) { - throw new NullPointerException("familyName must not be null"); - } - final byte[] buffer = keyValue.getBuffer(); - final int familyOffset = keyValue.getFamilyOffset(); - final byte familyLength = keyValue.getFamilyLength(familyOffset); - return Bytes.equals(buffer, familyOffset, familyLength, familyName, 0, familyName.length); - } -} +package com.nhn.pinpoint.web.util; + +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.util.Bytes; + +/** + * @author emeroad + */ +public class KeyValueUtils { + + public static boolean equalsFamily(KeyValue keyValue, byte[] familyName) { + if (keyValue == null) { + throw new NullPointerException("keyValue must not be null"); + } + if (familyName == null) { + throw new NullPointerException("familyName must not be null"); + } + final byte[] buffer = keyValue.getBuffer(); + final int familyOffset = keyValue.getFamilyOffset(); + final byte familyLength = keyValue.getFamilyLength(familyOffset); + return Bytes.equals(buffer, familyOffset, familyLength, familyName, 0, familyName.length); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/LimitUtils.java b/web/src/main/java/com/navercorp/pinpoint/web/util/LimitUtils.java index f2f9c40b4cd5..1dfd7d950b5e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/LimitUtils.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/LimitUtils.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.web.util; - -/** - * @author emeroad - */ -public final class LimitUtils { - public static final int MAX = 10000; - - public static int checkRange(final int limit) { - if (limit < 0) { - throw new IllegalArgumentException("negative limit:" + limit); - } - if (limit > MAX) { - return MAX; - } - return limit; - } -} +package com.nhn.pinpoint.web.util; + +/** + * @author emeroad + */ +public final class LimitUtils { + public static final int MAX = 10000; + + public static int checkRange(final int limit) { + if (limit < 0) { + throw new IllegalArgumentException("negative limit:" + limit); + } + if (limit > MAX) { + return MAX; + } + return limit; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/Limiter.java b/web/src/main/java/com/navercorp/pinpoint/web/util/Limiter.java index 922987767a1a..83a1676a87a1 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/Limiter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/Limiter.java @@ -1,12 +1,12 @@ -package com.nhn.pinpoint.web.util; - -import com.nhn.pinpoint.web.vo.Range; - -/** - * @author emeroad - */ -public interface Limiter { - void limit(long from, long to); - - void limit(Range range); -} +package com.nhn.pinpoint.web.util; + +import com.nhn.pinpoint.web.vo.Range; + +/** + * @author emeroad + */ +public interface Limiter { + void limit(long from, long to); + + void limit(Range range); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/MappingJackson2JsonpView.java b/web/src/main/java/com/navercorp/pinpoint/web/util/MappingJackson2JsonpView.java index c8c285fc3639..fbf8a466c59e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/MappingJackson2JsonpView.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/MappingJackson2JsonpView.java @@ -1,212 +1,212 @@ -package com.nhn.pinpoint.web.util; - -import com.fasterxml.jackson.core.JsonEncoding; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.lang3.StringUtils; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.validation.BindingResult; -import org.springframework.web.servlet.view.AbstractView; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * 상속해서 할려고 했으나, objectMapper등이 private이라. 사용할수가 없어서 그냥 복사해서 고침.. - * renderMergedOutputModel만 수정함. - * @author emeroad - */ -public class MappingJackson2JsonpView extends AbstractView { - - private static final String cbPrefix = "("; - private static final String cbSuffix = ")"; - private static final String cbEnd = ";"; - - private static final String DEFAULT_CALLBACK_PARAMETER = "_callback"; - - /** - * Default content type. Overridable as bean property. - */ - public static final String DEFAULT_CONTENT_TYPE = "application/jsonp"; - - - private ObjectMapper objectMapper = new ObjectMapper(); - - private JsonEncoding encoding = JsonEncoding.UTF8; - - private boolean prefixJson = false; - - private Set modelKeys; - - private boolean extractValueFromSingleKeyModel = false; - - private boolean disableCaching = true; - - - /** - * Construct a new {@code JacksonJsonView}, setting the content type to {@code application/json}. - */ - public MappingJackson2JsonpView() { - setContentType(DEFAULT_CONTENT_TYPE); - setExposePathVariables(false); - } - - - /** - * Sets the {@code ObjectMapper} for this view. - * If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper} is used. - *

Setting a custom-configured {@code ObjectMapper} is one way to take further control - * of the JSON serialization process. For example, an extended {@code SerializerFactory} - * can be configured that provides custom serializers for specific types. The other option - * for refining the serialization process is to use Jackson's provided annotations on the - * types to be serialized, in which case a custom-configured ObjectMapper is unnecessary. - */ - public void setObjectMapper(ObjectMapper objectMapper) { - Assert.notNull(objectMapper, "'objectMapper' must not be null"); - this.objectMapper = objectMapper; - } - - /** - * Set the {@code JsonEncoding} for this converter. - * By default, {@linkplain JsonEncoding#UTF8 UTF-8} is used. - */ - public void setEncoding(JsonEncoding encoding) { - Assert.notNull(encoding, "'encoding' must not be null"); - this.encoding = encoding; - } - - /** - * Indicates whether the JSON output by this view should be prefixed with "{} && ". - * Default is false. - *

Prefixing the JSON string in this manner is used to help prevent JSON Hijacking. - * The prefix renders the string syntactically invalid as a script so that it cannot be hijacked. - * This prefix does not affect the evaluation of JSON, but if JSON validation is performed - * on the string, the prefix would need to be ignored. - */ - public void setPrefixJson(boolean prefixJson) { - this.prefixJson = prefixJson; - } - - /** - * Set the attribute in the model that should be rendered by this view. - * When set, all other model attributes will be ignored. - */ - public void setModelKey(String modelKey) { - this.modelKeys = Collections.singleton(modelKey); - } - - /** - * Set the attributes in the model that should be rendered by this view. - * When set, all other model attributes will be ignored. - */ - public void setModelKeys(Set modelKeys) { - this.modelKeys = modelKeys; - } - - /** - * Return the attributes in the model that should be rendered by this view. - */ - public Set getModelKeys() { - return this.modelKeys; - } - - /** - * Set the attributes in the model that should be rendered by this view. - * When set, all other model attributes will be ignored. - * @deprecated use {@link #setModelKeys(Set)} instead - */ - @Deprecated - public void setRenderedAttributes(Set renderedAttributes) { - this.modelKeys = renderedAttributes; - } - - /** - * Return the attributes in the model that should be rendered by this view. - * @deprecated use {@link #getModelKeys()} instead - */ - @Deprecated - public Set getRenderedAttributes() { - return this.modelKeys; - } - - /** - * Set whether to serialize models containing a single attribute as a map or whether to - * extract the single value from the model and serialize it directly. - *

The effect of setting this flag is similar to using {@code MappingJacksonHttpMessageConverter} - * with an {@code @ResponseBody} request-handling method. - *

Default is {@code false}. - */ - public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) { - this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel; - } - - /** - * Disables caching of the generated JSON. - *

Default is {@code true}, which will prevent the client from caching the generated JSON. - */ - public void setDisableCaching(boolean disableCaching) { - this.disableCaching = disableCaching; - } - - - @Override - protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { - response.setContentType(getContentType()); - response.setCharacterEncoding(this.encoding.getJavaName()); - if (this.disableCaching) { - response.addHeader("Pragma", "no-cache"); - response.addHeader("Cache-Control", "no-cache, no-store, max-age=0"); - response.addDateHeader("Expires", 1L); - } - } - - @Override - protected void renderMergedOutputModel(Map model, HttpServletRequest request, - HttpServletResponse response) throws Exception { - - Object value = filterModel(model); - JsonGenerator generator = this.objectMapper.getFactory().createGenerator(response.getOutputStream(), this.encoding); - if (this.prefixJson) { - generator.writeRaw("{} && "); - } - final String callBackParameter = getCallBackParameter(request); - if (StringUtils.isEmpty(callBackParameter)) { - this.objectMapper.writeValue(generator, value); - } else { - generator.writeRaw(callBackParameter); - generator.writeRaw(cbPrefix); - this.objectMapper.writeValue(generator, value); - generator.writeRaw(cbSuffix); - generator.writeRaw(cbEnd); - } - generator.flush(); - } - - private String getCallBackParameter(HttpServletRequest request) { - return request.getParameter(DEFAULT_CALLBACK_PARAMETER); - } - - /** - * Filters out undesired attributes from the given model. - * The return value can be either another {@link Map} or a single value object. - *

The default implementation removes {@link org.springframework.validation.BindingResult} instances and entries - * not included in the {@link #setRenderedAttributes renderedAttributes} property. - * @param model the model, as passed on to {@link #renderMergedOutputModel} - * @return the object to be rendered - */ - protected Object filterModel(Map model) { - Map result = new HashMap(model.size()); - Set renderedAttributes = (!CollectionUtils.isEmpty(this.modelKeys) ? this.modelKeys : model.keySet()); - for (Map.Entry entry : model.entrySet()) { - if (!(entry.getValue() instanceof BindingResult) && renderedAttributes.contains(entry.getKey())) { - result.put(entry.getKey(), entry.getValue()); - } - } - return (this.extractValueFromSingleKeyModel && result.size() == 1 ? result.values().iterator().next() : result); - } -} +package com.nhn.pinpoint.web.util; + +import com.fasterxml.jackson.core.JsonEncoding; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.validation.BindingResult; +import org.springframework.web.servlet.view.AbstractView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * 상속해서 할려고 했으나, objectMapper등이 private이라. 사용할수가 없어서 그냥 복사해서 고침.. + * renderMergedOutputModel만 수정함. + * @author emeroad + */ +public class MappingJackson2JsonpView extends AbstractView { + + private static final String cbPrefix = "("; + private static final String cbSuffix = ")"; + private static final String cbEnd = ";"; + + private static final String DEFAULT_CALLBACK_PARAMETER = "_callback"; + + /** + * Default content type. Overridable as bean property. + */ + public static final String DEFAULT_CONTENT_TYPE = "application/jsonp"; + + + private ObjectMapper objectMapper = new ObjectMapper(); + + private JsonEncoding encoding = JsonEncoding.UTF8; + + private boolean prefixJson = false; + + private Set modelKeys; + + private boolean extractValueFromSingleKeyModel = false; + + private boolean disableCaching = true; + + + /** + * Construct a new {@code JacksonJsonView}, setting the content type to {@code application/json}. + */ + public MappingJackson2JsonpView() { + setContentType(DEFAULT_CONTENT_TYPE); + setExposePathVariables(false); + } + + + /** + * Sets the {@code ObjectMapper} for this view. + * If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper} is used. + *

Setting a custom-configured {@code ObjectMapper} is one way to take further control + * of the JSON serialization process. For example, an extended {@code SerializerFactory} + * can be configured that provides custom serializers for specific types. The other option + * for refining the serialization process is to use Jackson's provided annotations on the + * types to be serialized, in which case a custom-configured ObjectMapper is unnecessary. + */ + public void setObjectMapper(ObjectMapper objectMapper) { + Assert.notNull(objectMapper, "'objectMapper' must not be null"); + this.objectMapper = objectMapper; + } + + /** + * Set the {@code JsonEncoding} for this converter. + * By default, {@linkplain JsonEncoding#UTF8 UTF-8} is used. + */ + public void setEncoding(JsonEncoding encoding) { + Assert.notNull(encoding, "'encoding' must not be null"); + this.encoding = encoding; + } + + /** + * Indicates whether the JSON output by this view should be prefixed with "{} && ". + * Default is false. + *

Prefixing the JSON string in this manner is used to help prevent JSON Hijacking. + * The prefix renders the string syntactically invalid as a script so that it cannot be hijacked. + * This prefix does not affect the evaluation of JSON, but if JSON validation is performed + * on the string, the prefix would need to be ignored. + */ + public void setPrefixJson(boolean prefixJson) { + this.prefixJson = prefixJson; + } + + /** + * Set the attribute in the model that should be rendered by this view. + * When set, all other model attributes will be ignored. + */ + public void setModelKey(String modelKey) { + this.modelKeys = Collections.singleton(modelKey); + } + + /** + * Set the attributes in the model that should be rendered by this view. + * When set, all other model attributes will be ignored. + */ + public void setModelKeys(Set modelKeys) { + this.modelKeys = modelKeys; + } + + /** + * Return the attributes in the model that should be rendered by this view. + */ + public Set getModelKeys() { + return this.modelKeys; + } + + /** + * Set the attributes in the model that should be rendered by this view. + * When set, all other model attributes will be ignored. + * @deprecated use {@link #setModelKeys(Set)} instead + */ + @Deprecated + public void setRenderedAttributes(Set renderedAttributes) { + this.modelKeys = renderedAttributes; + } + + /** + * Return the attributes in the model that should be rendered by this view. + * @deprecated use {@link #getModelKeys()} instead + */ + @Deprecated + public Set getRenderedAttributes() { + return this.modelKeys; + } + + /** + * Set whether to serialize models containing a single attribute as a map or whether to + * extract the single value from the model and serialize it directly. + *

The effect of setting this flag is similar to using {@code MappingJacksonHttpMessageConverter} + * with an {@code @ResponseBody} request-handling method. + *

Default is {@code false}. + */ + public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) { + this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel; + } + + /** + * Disables caching of the generated JSON. + *

Default is {@code true}, which will prevent the client from caching the generated JSON. + */ + public void setDisableCaching(boolean disableCaching) { + this.disableCaching = disableCaching; + } + + + @Override + protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { + response.setContentType(getContentType()); + response.setCharacterEncoding(this.encoding.getJavaName()); + if (this.disableCaching) { + response.addHeader("Pragma", "no-cache"); + response.addHeader("Cache-Control", "no-cache, no-store, max-age=0"); + response.addDateHeader("Expires", 1L); + } + } + + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, + HttpServletResponse response) throws Exception { + + Object value = filterModel(model); + JsonGenerator generator = this.objectMapper.getFactory().createGenerator(response.getOutputStream(), this.encoding); + if (this.prefixJson) { + generator.writeRaw("{} && "); + } + final String callBackParameter = getCallBackParameter(request); + if (StringUtils.isEmpty(callBackParameter)) { + this.objectMapper.writeValue(generator, value); + } else { + generator.writeRaw(callBackParameter); + generator.writeRaw(cbPrefix); + this.objectMapper.writeValue(generator, value); + generator.writeRaw(cbSuffix); + generator.writeRaw(cbEnd); + } + generator.flush(); + } + + private String getCallBackParameter(HttpServletRequest request) { + return request.getParameter(DEFAULT_CALLBACK_PARAMETER); + } + + /** + * Filters out undesired attributes from the given model. + * The return value can be either another {@link Map} or a single value object. + *

The default implementation removes {@link org.springframework.validation.BindingResult} instances and entries + * not included in the {@link #setRenderedAttributes renderedAttributes} property. + * @param model the model, as passed on to {@link #renderMergedOutputModel} + * @return the object to be rendered + */ + protected Object filterModel(Map model) { + Map result = new HashMap(model.size()); + Set renderedAttributes = (!CollectionUtils.isEmpty(this.modelKeys) ? this.modelKeys : model.keySet()); + for (Map.Entry entry : model.entrySet()) { + if (!(entry.getValue() instanceof BindingResult) && renderedAttributes.contains(entry.getKey())) { + result.put(entry.getKey(), entry.getValue()); + } + } + return (this.extractValueFromSingleKeyModel && result.size() == 1 ? result.values().iterator().next() : result); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/Stack.java b/web/src/main/java/com/navercorp/pinpoint/web/util/Stack.java index 8f42b9a0ecd3..38aba6b99367 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/Stack.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/Stack.java @@ -1,42 +1,42 @@ -package com.nhn.pinpoint.web.util; - -import java.util.LinkedList; - -/** - * @author emeroad - */ -public class Stack { - - private final LinkedList stack = new LinkedList(); - - public void push(T obj) { - if (obj == null) { - throw new NullPointerException("obj must not be null"); - } - - stack.add(obj); - } - - public T getLast() { - return stack.getLast(); - } - - public T pop() { - return stack.pollLast(); - } - - public T getParent() { - final int parent = stack.size() - 2; - if (parent < 0) { - return null; - } - return stack.get(parent); - } - - @Override - public String toString() { - return "Stack{" + - "stack=" + stack + - '}'; - } -} +package com.nhn.pinpoint.web.util; + +import java.util.LinkedList; + +/** + * @author emeroad + */ +public class Stack { + + private final LinkedList stack = new LinkedList(); + + public void push(T obj) { + if (obj == null) { + throw new NullPointerException("obj must not be null"); + } + + stack.add(obj); + } + + public T getLast() { + return stack.getLast(); + } + + public T pop() { + return stack.pollLast(); + } + + public T getParent() { + final int parent = stack.size() - 2; + if (parent < 0) { + return null; + } + return stack.get(parent); + } + + @Override + public String toString() { + return "Stack{" + + "stack=" + stack + + '}'; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeUtils.java b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeUtils.java index fd8292e1b023..19bed2d985c2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeUtils.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeUtils.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.web.util; - -/** - * - */ -public class TimeUtils { - public static long getDelayLastTime() { - return System.currentTimeMillis() - 3000; - } -} +package com.nhn.pinpoint.web.util; + +/** + * + */ +public class TimeUtils { + public static long getDelayLastTime() { + return System.currentTimeMillis() - 3000; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindow.java b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindow.java index d39c350e0b44..6c4462ed42c4 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindow.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindow.java @@ -1,115 +1,115 @@ -package com.nhn.pinpoint.web.util; - -import com.nhn.pinpoint.web.vo.Range; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * - * @author netspider - * - */ -public class TimeWindow implements Iterable { - - private static final int ONE_MINUTE = 60000; - private static final int ONE_HOUR = ONE_MINUTE * 60; - private static final int SIX_HOURS = ONE_HOUR * 6; - private static final int ONE_DAY = SIX_HOURS * 4; - - private final long windowSlotSize; - - private final Range range; - - private final Range windowRange; - - public TimeWindow(Range range) { - this(range, TimeWindowDownSampler.SAMPLER); - } - - public TimeWindow(Range range, TimeWindowSampler sampler) { - if (range == null) { - throw new NullPointerException("range must not be null"); - } - if (sampler == null) { - throw new NullPointerException("sampler must not be null"); - } - this.windowSlotSize = TimeWindowDownSampler.SAMPLER.getWindowSize(range); - this.range = range; - this.windowRange = createWindowRange(); - } - - public Iterator iterator() { - return new Itr(); - } - - - - /** - * timestamp를 윈도우 사이즈에 맞는 timestamp로 변환. - * - * @param timestamp - * @return - */ - public long refineTimestamp(long timestamp) { - long time = (timestamp / windowSlotSize) * windowSlotSize; - return time; - } - - public Range getWindowRange() { - return windowRange; - } - - public long getWindowSlotSize() { - return windowSlotSize; - } - - public long getWindowRangeCount() { - return (windowRange.getRange() / windowSlotSize) + 1; - } - - private Range createWindowRange() { - long from = refineTimestamp(range.getFrom()); - long to = refineTimestamp(range.getTo()); - return new Range(from, to); - } - - - public int getWindowIndex(long time) { - long index = (time - windowRange.getFrom()) / this.windowSlotSize; - return (int)index; - } - - private class Itr implements Iterator { - - private long cursor; - - public Itr() { - this.cursor = windowRange.getFrom(); - } - - @Override - public boolean hasNext() { - if (cursor > windowRange.getTo()) { - return false; - } - return true; - } - - - @Override - public Long next() { - long current = cursor; - if (hasNext()) { - cursor += windowSlotSize; - return current; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } -} +package com.nhn.pinpoint.web.util; + +import com.nhn.pinpoint.web.vo.Range; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * + * @author netspider + * + */ +public class TimeWindow implements Iterable { + + private static final int ONE_MINUTE = 60000; + private static final int ONE_HOUR = ONE_MINUTE * 60; + private static final int SIX_HOURS = ONE_HOUR * 6; + private static final int ONE_DAY = SIX_HOURS * 4; + + private final long windowSlotSize; + + private final Range range; + + private final Range windowRange; + + public TimeWindow(Range range) { + this(range, TimeWindowDownSampler.SAMPLER); + } + + public TimeWindow(Range range, TimeWindowSampler sampler) { + if (range == null) { + throw new NullPointerException("range must not be null"); + } + if (sampler == null) { + throw new NullPointerException("sampler must not be null"); + } + this.windowSlotSize = TimeWindowDownSampler.SAMPLER.getWindowSize(range); + this.range = range; + this.windowRange = createWindowRange(); + } + + public Iterator iterator() { + return new Itr(); + } + + + + /** + * timestamp를 윈도우 사이즈에 맞는 timestamp로 변환. + * + * @param timestamp + * @return + */ + public long refineTimestamp(long timestamp) { + long time = (timestamp / windowSlotSize) * windowSlotSize; + return time; + } + + public Range getWindowRange() { + return windowRange; + } + + public long getWindowSlotSize() { + return windowSlotSize; + } + + public long getWindowRangeCount() { + return (windowRange.getRange() / windowSlotSize) + 1; + } + + private Range createWindowRange() { + long from = refineTimestamp(range.getFrom()); + long to = refineTimestamp(range.getTo()); + return new Range(from, to); + } + + + public int getWindowIndex(long time) { + long index = (time - windowRange.getFrom()) / this.windowSlotSize; + return (int)index; + } + + private class Itr implements Iterator { + + private long cursor; + + public Itr() { + this.cursor = windowRange.getFrom(); + } + + @Override + public boolean hasNext() { + if (cursor > windowRange.getTo()) { + return false; + } + return true; + } + + + @Override + public Long next() { + long current = cursor; + if (hasNext()) { + cursor += windowSlotSize; + return current; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowDownSampler.java b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowDownSampler.java index 4b26e1e3f96f..0bd600c0ebb0 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowDownSampler.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowDownSampler.java @@ -1,43 +1,43 @@ -package com.nhn.pinpoint.web.util; - -import com.nhn.pinpoint.web.vo.Range; - -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - */ -public class TimeWindowDownSampler implements TimeWindowSampler { - - private static final long ONE_MINUTE = 6000 * 10; - private static final long ONE_HOUR = TimeUnit.HOURS.toMillis(1); - private static final long SIX_HOURS = TimeUnit.HOURS.toMillis(6); - private static final long TWELVE_HOURS = TimeUnit.HOURS.toMillis(12); - private static final long ONE_DAY = TimeUnit.DAYS.toMillis(1); - private static final long TWO_DAY = TimeUnit.DAYS.toMillis(2); - - - public static final TimeWindowSampler SAMPLER = new TimeWindowDownSampler(); - - @Override - public long getWindowSize(Range range) { - final long diff = range.getRange(); - long size; - // 구간 설정 부분은 제고의 여지가 있음. - if (diff <= ONE_HOUR) { - size = ONE_MINUTE; - } else if (diff <= SIX_HOURS) { - size = ONE_MINUTE * 5; - } else if (diff <= TWELVE_HOURS) { - size = ONE_MINUTE * 10; - } else if (diff <= ONE_DAY) { - size = ONE_MINUTE * 20; - } else if (diff <= TWO_DAY) { - size = ONE_MINUTE * 30; - } else { - size = ONE_MINUTE * 60; - } - - return size; - } -} +package com.nhn.pinpoint.web.util; + +import com.nhn.pinpoint.web.vo.Range; + +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + */ +public class TimeWindowDownSampler implements TimeWindowSampler { + + private static final long ONE_MINUTE = 6000 * 10; + private static final long ONE_HOUR = TimeUnit.HOURS.toMillis(1); + private static final long SIX_HOURS = TimeUnit.HOURS.toMillis(6); + private static final long TWELVE_HOURS = TimeUnit.HOURS.toMillis(12); + private static final long ONE_DAY = TimeUnit.DAYS.toMillis(1); + private static final long TWO_DAY = TimeUnit.DAYS.toMillis(2); + + + public static final TimeWindowSampler SAMPLER = new TimeWindowDownSampler(); + + @Override + public long getWindowSize(Range range) { + final long diff = range.getRange(); + long size; + // 구간 설정 부분은 제고의 여지가 있음. + if (diff <= ONE_HOUR) { + size = ONE_MINUTE; + } else if (diff <= SIX_HOURS) { + size = ONE_MINUTE * 5; + } else if (diff <= TWELVE_HOURS) { + size = ONE_MINUTE * 10; + } else if (diff <= ONE_DAY) { + size = ONE_MINUTE * 20; + } else if (diff <= TWO_DAY) { + size = ONE_MINUTE * 30; + } else { + size = ONE_MINUTE * 60; + } + + return size; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowOneMinuteSampler.java b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowOneMinuteSampler.java index dda093b87433..1648dbfa91e8 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowOneMinuteSampler.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowOneMinuteSampler.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.web.util; - -import com.nhn.pinpoint.web.vo.Range; - -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - */ -public class TimeWindowOneMinuteSampler implements TimeWindowSampler { - - public static final TimeWindowSampler SAMPLER = new TimeWindowOneMinuteSampler(); - - @Override - public long getWindowSize(Range range) { - return 1000*60; - } -} +package com.nhn.pinpoint.web.util; + +import com.nhn.pinpoint.web.vo.Range; + +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + */ +public class TimeWindowOneMinuteSampler implements TimeWindowSampler { + + public static final TimeWindowSampler SAMPLER = new TimeWindowOneMinuteSampler(); + + @Override + public long getWindowSize(Range range) { + return 1000*60; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowSampler.java b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowSampler.java index 98361caed7e4..9981fe02887f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowSampler.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/TimeWindowSampler.java @@ -1,10 +1,10 @@ -package com.nhn.pinpoint.web.util; - -import com.nhn.pinpoint.web.vo.Range; - -/** - * @author emeroad - */ -public interface TimeWindowSampler { - long getWindowSize(Range range); -} +package com.nhn.pinpoint.web.util; + +import com.nhn.pinpoint.web.vo.Range; + +/** + * @author emeroad + */ +public interface TimeWindowSampler { + long getWindowSize(Range range); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/util/UnwrapRootJackson2ObjectMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/util/UnwrapRootJackson2ObjectMapper.java index 43d9c8e819fb..306b0dff1119 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/util/UnwrapRootJackson2ObjectMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/util/UnwrapRootJackson2ObjectMapper.java @@ -1,14 +1,14 @@ -package com.nhn.pinpoint.web.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -/** - * @author emeroad - */ -public class UnwrapRootJackson2ObjectMapper extends ObjectMapper { - public UnwrapRootJackson2ObjectMapper() { - super(); - this.configure(SerializationFeature.WRAP_ROOT_VALUE, false); - } -} +package com.nhn.pinpoint.web.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * @author emeroad + */ +public class UnwrapRootJackson2ObjectMapper extends ObjectMapper { + public UnwrapRootJackson2ObjectMapper() { + super(); + this.configure(SerializationFeature.WRAP_ROOT_VALUE, false); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModel.java b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModel.java index ffdb8f91f1aa..3918e507ec94 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModel.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModel.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.nhn.pinpoint.web.vo.Application; - -import java.util.List; - -/** - * @author emeroad - */ -@JsonSerialize(using=AgentResponseTimeViewModelSerializer.class) -public class AgentResponseTimeViewModel { - - private final Application agentName; - - private final List responseTimeViewModel; - - public AgentResponseTimeViewModel(Application agentName, List responseTimeViewModel) { - if (agentName == null) { - throw new NullPointerException("agentName must not be null"); - } - if (responseTimeViewModel == null) { - throw new NullPointerException("responseTimeViewModel must not be null"); - } - this.agentName = agentName; - this.responseTimeViewModel = responseTimeViewModel; - } - - public String getAgentName() { - return agentName.getName(); - } - - public List getResponseTimeViewModel() { - return responseTimeViewModel; - } - -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.nhn.pinpoint.web.vo.Application; + +import java.util.List; + +/** + * @author emeroad + */ +@JsonSerialize(using=AgentResponseTimeViewModelSerializer.class) +public class AgentResponseTimeViewModel { + + private final Application agentName; + + private final List responseTimeViewModel; + + public AgentResponseTimeViewModel(Application agentName, List responseTimeViewModel) { + if (agentName == null) { + throw new NullPointerException("agentName must not be null"); + } + if (responseTimeViewModel == null) { + throw new NullPointerException("responseTimeViewModel must not be null"); + } + this.agentName = agentName; + this.responseTimeViewModel = responseTimeViewModel; + } + + public String getAgentName() { + return agentName.getName(); + } + + public List getResponseTimeViewModel() { + return responseTimeViewModel; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelList.java b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelList.java index 6a551870ae06..249b421f074e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelList.java @@ -1,44 +1,44 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import java.util.List; - -/** - * @author emeroad - */ -@JsonSerialize(using = AgentResponseTimeViewModelListSerializer.class) -public class AgentResponseTimeViewModelList { - - public static final String DEFAULT_FIELD_NAME = "agentTimeSeriesHistogram"; - - private String fieldName; - private final List agentResponseTimeViewModelList; - - public AgentResponseTimeViewModelList(List agentResponseTimeViewModelList) { - this(DEFAULT_FIELD_NAME, agentResponseTimeViewModelList); - } - - public AgentResponseTimeViewModelList(String fieldName, List agentResponseTimeViewModelList) { - if (fieldName == null) { - throw new NullPointerException("fieldName must not be null"); - } - if (agentResponseTimeViewModelList == null) { - throw new NullPointerException("agentResponseTimeViewModelList must not be null"); - } - this.fieldName = fieldName; - this.agentResponseTimeViewModelList = agentResponseTimeViewModelList; - } - - public void setFieldName(String fieldName) { - this.fieldName = fieldName; - } - - public String getFieldName() { - return fieldName; - } - - public List getAgentResponseTimeViewModelList() { - return agentResponseTimeViewModelList; - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.util.List; + +/** + * @author emeroad + */ +@JsonSerialize(using = AgentResponseTimeViewModelListSerializer.class) +public class AgentResponseTimeViewModelList { + + public static final String DEFAULT_FIELD_NAME = "agentTimeSeriesHistogram"; + + private String fieldName; + private final List agentResponseTimeViewModelList; + + public AgentResponseTimeViewModelList(List agentResponseTimeViewModelList) { + this(DEFAULT_FIELD_NAME, agentResponseTimeViewModelList); + } + + public AgentResponseTimeViewModelList(String fieldName, List agentResponseTimeViewModelList) { + if (fieldName == null) { + throw new NullPointerException("fieldName must not be null"); + } + if (agentResponseTimeViewModelList == null) { + throw new NullPointerException("agentResponseTimeViewModelList must not be null"); + } + this.fieldName = fieldName; + this.agentResponseTimeViewModelList = agentResponseTimeViewModelList; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String getFieldName() { + return fieldName; + } + + public List getAgentResponseTimeViewModelList() { + return agentResponseTimeViewModelList; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelListSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelListSerializer.java index ae57556914ec..82014dc58dd7 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelListSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelListSerializer.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -/** - * @author emeroad - */ -public class AgentResponseTimeViewModelListSerializer extends JsonSerializer { - - @Override - public void serialize(AgentResponseTimeViewModelList viewModelList, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeFieldName(viewModelList.getFieldName()); - jgen.writeStartObject(); - for (AgentResponseTimeViewModel agentResponseTimeViewModel : viewModelList.getAgentResponseTimeViewModelList()) { - jgen.writeObject(agentResponseTimeViewModel); - } - jgen.writeEndObject(); - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * @author emeroad + */ +public class AgentResponseTimeViewModelListSerializer extends JsonSerializer { + + @Override + public void serialize(AgentResponseTimeViewModelList viewModelList, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeFieldName(viewModelList.getFieldName()); + jgen.writeStartObject(); + for (AgentResponseTimeViewModel agentResponseTimeViewModel : viewModelList.getAgentResponseTimeViewModelList()) { + jgen.writeObject(agentResponseTimeViewModel); + } + jgen.writeEndObject(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelSerializer.java index 28ee8df5c854..6e64068032e1 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/AgentResponseTimeViewModelSerializer.java @@ -1,18 +1,18 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; -/** - * @author emeroad - */ -public class AgentResponseTimeViewModelSerializer extends JsonSerializer { - @Override - public void serialize(AgentResponseTimeViewModel value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeFieldName(value.getAgentName()); - jgen.writeObject(value.getResponseTimeViewModel()); - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +/** + * @author emeroad + */ +public class AgentResponseTimeViewModelSerializer extends JsonSerializer { + @Override + public void serialize(AgentResponseTimeViewModel value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeFieldName(value.getAgentName()); + jgen.writeObject(value.getResponseTimeViewModel()); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroup.java b/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroup.java index 0b776238cde6..0a0726a76f68 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroup.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroup.java @@ -1,26 +1,26 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.nhn.pinpoint.web.vo.Application; - -import java.util.List; - -/** - * @author emeroad - */ -@JsonSerialize(using = ApplicationGroupSerializer.class) -public class ApplicationGroup { - - private final List applicationList; - - public ApplicationGroup(List applicationList) { - if (applicationList == null) { - throw new NullPointerException("applicationList must not be null"); - } - this.applicationList = applicationList; - } - - public List getApplicationList() { - return applicationList; - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.nhn.pinpoint.web.vo.Application; + +import java.util.List; + +/** + * @author emeroad + */ +@JsonSerialize(using = ApplicationGroupSerializer.class) +public class ApplicationGroup { + + private final List applicationList; + + public ApplicationGroup(List applicationList) { + if (applicationList == null) { + throw new NullPointerException("applicationList must not be null"); + } + this.applicationList = applicationList; + } + + public List getApplicationList() { + return applicationList; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroupSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroupSerializer.java index 31f8ddfc9d25..71f9d88a7bd5 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroupSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationGroupSerializer.java @@ -1,35 +1,35 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.nhn.pinpoint.web.vo.Application; - -import java.io.IOException; -import java.util.List; - -/** - * @author emeroad - */ -public class ApplicationGroupSerializer extends JsonSerializer { - - @Override - public void serialize(ApplicationGroup applicationGroup, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartArray(); - - List applicationList = applicationGroup.getApplicationList(); - for (Application application : applicationList) { - writeApplication(jgen, application); - } - jgen.writeEndArray(); - } - - private void writeApplication(JsonGenerator jgen, Application application) throws IOException { - jgen.writeStartObject(); - jgen.writeStringField("applicationName", application.getName()); - jgen.writeStringField("serviceType", application.getServiceType().getDesc()); - jgen.writeNumberField("code", application.getServiceType().getCode()); - jgen.writeEndObject(); - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.nhn.pinpoint.web.vo.Application; + +import java.io.IOException; +import java.util.List; + +/** + * @author emeroad + */ +public class ApplicationGroupSerializer extends JsonSerializer { + + @Override + public void serialize(ApplicationGroup applicationGroup, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartArray(); + + List applicationList = applicationGroup.getApplicationList(); + for (Application application : applicationList) { + writeApplication(jgen, application); + } + jgen.writeEndArray(); + } + + private void writeApplication(JsonGenerator jgen, Application application) throws IOException { + jgen.writeStartObject(); + jgen.writeStringField("applicationName", application.getName()); + jgen.writeStringField("serviceType", application.getServiceType().getDesc()); + jgen.writeNumberField("code", application.getServiceType().getCode()); + jgen.writeEndObject(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationScatterScanResultSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationScatterScanResultSerializer.java index 0a7f27b21a2f..45e14c19863b 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationScatterScanResultSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/ApplicationScatterScanResultSerializer.java @@ -1,28 +1,28 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; - -import java.io.IOException; - -/** - * @author emeroad - */ -public class ApplicationScatterScanResultSerializer extends JsonSerializer { - @Override - public void serialize(ApplicationScatterScanResult value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartObject(); - Application application = value.getApplication(); - jgen.writeStringField("applicationName", application.getName()); - jgen.writeNumberField("applicationServiceType", application.getServiceTypeCode()); - - jgen.writeFieldName("scatter"); - jgen.writeObject(value.getScatterScanResult()); - - jgen.writeEndObject(); - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; + +import java.io.IOException; + +/** + * @author emeroad + */ +public class ApplicationScatterScanResultSerializer extends JsonSerializer { + @Override + public void serialize(ApplicationScatterScanResult value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + Application application = value.getApplication(); + jgen.writeStringField("applicationName", application.getName()); + jgen.writeNumberField("applicationServiceType", application.getServiceTypeCode()); + + jgen.writeFieldName("scatter"); + jgen.writeObject(value.getScatterScanResult()); + + jgen.writeEndObject(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/DotSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/DotSerializer.java index bb2ade18359f..e96e3202e1e2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/DotSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/DotSerializer.java @@ -1,24 +1,24 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.nhn.pinpoint.web.vo.scatter.Dot; - -import java.io.IOException; - -/** - * @author emeroad - */ -public class DotSerializer extends JsonSerializer { - @Override - public void serialize(Dot dot, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartArray(); - jgen.writeNumber(dot.getAcceptedTime()); - jgen.writeNumber(dot.getElapsedTime()); - jgen.writeString(dot.getTransactionId()); - jgen.writeNumber(dot.getSimpleExceptionCode()); - jgen.writeEndArray(); - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.nhn.pinpoint.web.vo.scatter.Dot; + +import java.io.IOException; + +/** + * @author emeroad + */ +public class DotSerializer extends JsonSerializer { + @Override + public void serialize(Dot dot, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartArray(); + jgen.writeNumber(dot.getAcceptedTime()); + jgen.writeNumber(dot.getElapsedTime()); + jgen.writeString(dot.getTransactionId()); + jgen.writeNumber(dot.getSimpleExceptionCode()); + jgen.writeEndArray(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/FilterMapWrapSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/FilterMapWrapSerializer.java index 6ca70dcb845e..3d9daf405b74 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/FilterMapWrapSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/FilterMapWrapSerializer.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.nhn.pinpoint.web.applicationmap.FilterMapWrap; -import com.nhn.pinpoint.web.applicationmap.Node; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; - -import java.io.IOException; -import java.util.List; - -/** - * @author emeroad - */ -public class FilterMapWrapSerializer extends JsonSerializer { - @Override - public void serialize(FilterMapWrap wrap, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartObject(); - - jgen.writeObjectField("applicationMapData", wrap.getApplicationMap()); - - jgen.writeNumberField("lastFetchedTimestamp", wrap.getLastFetchedTimestamp()); - - final List applicationScatterScanResult = wrap.getApplicationScatterScanResult(); - - jgen.writeFieldName("applicationScatterScanResult"); - jgen.writeStartObject(); - for (ApplicationScatterScanResult scatterScanResult : applicationScatterScanResult) { - Application application = scatterScanResult.getApplication(); - String name = application.getName() + Node.NODE_DELIMITER + application.getServiceType().toString(); - jgen.writeObjectField(name, scatterScanResult.getScatterScanResult()); - } - jgen.writeEndObject(); - - - jgen.writeEndObject(); - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.nhn.pinpoint.web.applicationmap.FilterMapWrap; +import com.nhn.pinpoint.web.applicationmap.Node; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.scatter.ApplicationScatterScanResult; + +import java.io.IOException; +import java.util.List; + +/** + * @author emeroad + */ +public class FilterMapWrapSerializer extends JsonSerializer { + @Override + public void serialize(FilterMapWrap wrap, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + + jgen.writeObjectField("applicationMapData", wrap.getApplicationMap()); + + jgen.writeNumberField("lastFetchedTimestamp", wrap.getLastFetchedTimestamp()); + + final List applicationScatterScanResult = wrap.getApplicationScatterScanResult(); + + jgen.writeFieldName("applicationScatterScanResult"); + jgen.writeStartObject(); + for (ApplicationScatterScanResult scatterScanResult : applicationScatterScanResult) { + Application application = scatterScanResult.getApplication(); + String name = application.getName() + Node.NODE_DELIMITER + application.getServiceType().toString(); + jgen.writeObjectField(name, scatterScanResult.getScatterScanResult()); + } + jgen.writeEndObject(); + + + jgen.writeEndObject(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/HistogramSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/HistogramSerializer.java index 8006400b0c9a..719e6f3d3995 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/HistogramSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/HistogramSerializer.java @@ -1,40 +1,40 @@ -package com.nhn.pinpoint.web.view; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -/** - * @author emeroad - */ -public class HistogramSerializer extends JsonSerializer { - - - @Override - public void serialize(Histogram histogram, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartObject(); - final HistogramSchema schema = histogram.getHistogramSchema(); - - jgen.writeFieldName(schema.getFastSlot().getSlotName()); - jgen.writeNumber(histogram.getFastCount()); - - jgen.writeFieldName(schema.getNormalSlot().getSlotName()); - jgen.writeNumber(histogram.getNormalCount()); - - jgen.writeFieldName(schema.getSlowSlot().getSlotName()); - jgen.writeNumber(histogram.getSlowCount()); - - jgen.writeFieldName(schema.getVerySlowSlot().getSlotName()); - jgen.writeNumber(histogram.getVerySlowCount()); - - jgen.writeFieldName(schema.getErrorSlot().getSlotName()); - jgen.writeNumber(histogram.getErrorCount()); - - jgen.writeEndObject(); - } -} +package com.nhn.pinpoint.web.view; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * @author emeroad + */ +public class HistogramSerializer extends JsonSerializer { + + + @Override + public void serialize(Histogram histogram, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + final HistogramSchema schema = histogram.getHistogramSchema(); + + jgen.writeFieldName(schema.getFastSlot().getSlotName()); + jgen.writeNumber(histogram.getFastCount()); + + jgen.writeFieldName(schema.getNormalSlot().getSlotName()); + jgen.writeNumber(histogram.getNormalCount()); + + jgen.writeFieldName(schema.getSlowSlot().getSlotName()); + jgen.writeNumber(histogram.getSlowCount()); + + jgen.writeFieldName(schema.getVerySlowSlot().getSlotName()); + jgen.writeNumber(histogram.getVerySlowCount()); + + jgen.writeFieldName(schema.getErrorSlot().getSlotName()); + jgen.writeNumber(histogram.getErrorCount()); + + jgen.writeEndObject(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/LinkSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/LinkSerializer.java index 7ea95a484706..bcef6888ec9a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/LinkSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/LinkSerializer.java @@ -1,117 +1,117 @@ -package com.nhn.pinpoint.web.view; - -import com.nhn.pinpoint.web.applicationmap.Link; -import com.nhn.pinpoint.web.applicationmap.Node; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; -import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; -import com.nhn.pinpoint.web.vo.Application; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; -import java.util.Collection; -import java.util.List; - -/** - * @author emeroad - * @author netspider - */ -public class LinkSerializer extends JsonSerializer { - @Override - public void serialize(Link link, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartObject(); - - jgen.writeStringField("key", link.getLinkName()); // for servermap - - jgen.writeStringField("from", link.getFrom().getNodeName()); // necessary for go.js - jgen.writeStringField("to", link.getTo().getNodeName()); // necessary for go.js - - - writeSimpleNode("sourceInfo", link.getFrom(), jgen); - writeSimpleNode("targetInfo", link.getTo(), jgen); - - Application filterApplication = link.getFilterApplication(); - jgen.writeStringField("filterApplicationName", filterApplication.getName()); - jgen.writeNumberField("filterApplicationServiceTypeCode", filterApplication.getServiceTypeCode()); - if (link.isWasToWasLink()) { - writeWasToWasTargetRpcList(link, jgen); - } - - Histogram histogram = link.getHistogram(); - jgen.writeNumberField("totalCount", histogram.getTotalCount()); // for go.js - jgen.writeNumberField("errorCount", histogram.getErrorCount()); - jgen.writeNumberField("slowCount", histogram.getSlowCount()); - - jgen.writeObjectField("histogram", histogram); - - // 링크별 각 agent가 어떻게 호출했는지 데이터 - writeAgentHistogram("sourceHistogram", link.getSourceList(), jgen); - writeAgentHistogram("targetHistogram", link.getTargetList(), jgen); - - writeTimeSeriesHistogram(link, jgen); - writeSourceAgentTimeSeriesHistogram(link, jgen); - - -// String state = link.getLinkState(); -// jgen.writeStringField("state", state); // for go.js - jgen.writeBooleanField("hasAlert", link.getLinkAlert()); // for go.js - - jgen.writeEndObject(); - } - - private void writeWasToWasTargetRpcList(Link link, JsonGenerator jgen) throws IOException { - // was -> was 연결일 경우 호출실패시의 이벤트를 filtering 하기 위한 추가적인 호출정보를 알려준다. - jgen.writeFieldName("filterTargetRpcList"); - jgen.writeStartArray(); - Collection sourceLinkTargetAgentList = link.getSourceLinkTargetAgentList(); - for (Application application : sourceLinkTargetAgentList) { - jgen.writeStartObject(); - jgen.writeStringField("rpc", application.getName()); - jgen.writeNumberField("rpcServiceTypeCode", application.getServiceTypeCode()); - jgen.writeEndObject(); - } - jgen.writeEndArray(); - - } - - - - private void writeTimeSeriesHistogram(Link link, JsonGenerator jgen) throws IOException { - List sourceApplicationTimeSeriesHistogram = link.getLinkApplicationTimeSeriesHistogram(); - - jgen.writeFieldName("timeSeriesHistogram"); - jgen.writeObject(sourceApplicationTimeSeriesHistogram); - } - - - private void writeAgentHistogram(String fieldName, AgentHistogramList agentHistogramList, JsonGenerator jgen) throws IOException { - jgen.writeFieldName(fieldName); - jgen.writeStartObject(); - for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { - jgen.writeFieldName(agentHistogram.getId()); - jgen.writeObject(agentHistogram.getHistogram()); - } - jgen.writeEndObject(); - } - - private void writeSourceAgentTimeSeriesHistogram(Link link, JsonGenerator jgen) throws IOException { - AgentResponseTimeViewModelList sourceAgentTimeSeriesHistogram = link.getSourceAgentTimeSeriesHistogram(); - sourceAgentTimeSeriesHistogram.setFieldName("sourceTimeSeriesHistogram"); - jgen.writeObject(sourceAgentTimeSeriesHistogram); - } - - private void writeSimpleNode(String fieldName, Node node, JsonGenerator jgen) throws IOException { - jgen.writeFieldName(fieldName); - - jgen.writeStartObject(); - Application application = node.getApplication(); - jgen.writeStringField("applicationName", application.getName()); - jgen.writeStringField("serviceType", application.getServiceType().toString()); - jgen.writeNumberField("serviceTypeCode", application.getServiceTypeCode()); - jgen.writeBooleanField("isWas", application.getServiceType().isWas()); - jgen.writeEndObject(); - } -} +package com.nhn.pinpoint.web.view; + +import com.nhn.pinpoint.web.applicationmap.Link; +import com.nhn.pinpoint.web.applicationmap.Node; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogram; +import com.nhn.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; +import com.nhn.pinpoint.web.vo.Application; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +/** + * @author emeroad + * @author netspider + */ +public class LinkSerializer extends JsonSerializer { + @Override + public void serialize(Link link, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + + jgen.writeStringField("key", link.getLinkName()); // for servermap + + jgen.writeStringField("from", link.getFrom().getNodeName()); // necessary for go.js + jgen.writeStringField("to", link.getTo().getNodeName()); // necessary for go.js + + + writeSimpleNode("sourceInfo", link.getFrom(), jgen); + writeSimpleNode("targetInfo", link.getTo(), jgen); + + Application filterApplication = link.getFilterApplication(); + jgen.writeStringField("filterApplicationName", filterApplication.getName()); + jgen.writeNumberField("filterApplicationServiceTypeCode", filterApplication.getServiceTypeCode()); + if (link.isWasToWasLink()) { + writeWasToWasTargetRpcList(link, jgen); + } + + Histogram histogram = link.getHistogram(); + jgen.writeNumberField("totalCount", histogram.getTotalCount()); // for go.js + jgen.writeNumberField("errorCount", histogram.getErrorCount()); + jgen.writeNumberField("slowCount", histogram.getSlowCount()); + + jgen.writeObjectField("histogram", histogram); + + // 링크별 각 agent가 어떻게 호출했는지 데이터 + writeAgentHistogram("sourceHistogram", link.getSourceList(), jgen); + writeAgentHistogram("targetHistogram", link.getTargetList(), jgen); + + writeTimeSeriesHistogram(link, jgen); + writeSourceAgentTimeSeriesHistogram(link, jgen); + + +// String state = link.getLinkState(); +// jgen.writeStringField("state", state); // for go.js + jgen.writeBooleanField("hasAlert", link.getLinkAlert()); // for go.js + + jgen.writeEndObject(); + } + + private void writeWasToWasTargetRpcList(Link link, JsonGenerator jgen) throws IOException { + // was -> was 연결일 경우 호출실패시의 이벤트를 filtering 하기 위한 추가적인 호출정보를 알려준다. + jgen.writeFieldName("filterTargetRpcList"); + jgen.writeStartArray(); + Collection sourceLinkTargetAgentList = link.getSourceLinkTargetAgentList(); + for (Application application : sourceLinkTargetAgentList) { + jgen.writeStartObject(); + jgen.writeStringField("rpc", application.getName()); + jgen.writeNumberField("rpcServiceTypeCode", application.getServiceTypeCode()); + jgen.writeEndObject(); + } + jgen.writeEndArray(); + + } + + + + private void writeTimeSeriesHistogram(Link link, JsonGenerator jgen) throws IOException { + List sourceApplicationTimeSeriesHistogram = link.getLinkApplicationTimeSeriesHistogram(); + + jgen.writeFieldName("timeSeriesHistogram"); + jgen.writeObject(sourceApplicationTimeSeriesHistogram); + } + + + private void writeAgentHistogram(String fieldName, AgentHistogramList agentHistogramList, JsonGenerator jgen) throws IOException { + jgen.writeFieldName(fieldName); + jgen.writeStartObject(); + for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { + jgen.writeFieldName(agentHistogram.getId()); + jgen.writeObject(agentHistogram.getHistogram()); + } + jgen.writeEndObject(); + } + + private void writeSourceAgentTimeSeriesHistogram(Link link, JsonGenerator jgen) throws IOException { + AgentResponseTimeViewModelList sourceAgentTimeSeriesHistogram = link.getSourceAgentTimeSeriesHistogram(); + sourceAgentTimeSeriesHistogram.setFieldName("sourceTimeSeriesHistogram"); + jgen.writeObject(sourceAgentTimeSeriesHistogram); + } + + private void writeSimpleNode(String fieldName, Node node, JsonGenerator jgen) throws IOException { + jgen.writeFieldName(fieldName); + + jgen.writeStartObject(); + Application application = node.getApplication(); + jgen.writeStringField("applicationName", application.getName()); + jgen.writeStringField("serviceType", application.getServiceType().toString()); + jgen.writeNumberField("serviceTypeCode", application.getServiceTypeCode()); + jgen.writeBooleanField("isWas", application.getServiceType().isWas()); + jgen.writeEndObject(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/NodeSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/NodeSerializer.java index 074ac254bc80..15009d146a2c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/NodeSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/NodeSerializer.java @@ -1,126 +1,126 @@ -package com.nhn.pinpoint.web.view; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.web.applicationmap.Node; -import com.nhn.pinpoint.web.applicationmap.ServerInstanceList; -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; -import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * @author emeroad - */ -public class NodeSerializer extends JsonSerializer { - @Override - public void serialize(Node node, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartObject(); -// jgen.writeStringField("id", node.getNodeName()); - jgen.writeStringField("key", node.getNodeName()); // necessary for go.js - - jgen.writeStringField("applicationName", node.getApplicationTextName()); // for go.js - - jgen.writeStringField("category", node.getServiceType().toString()); // necessary for go.js - jgen.writeStringField("serviceType", node.getServiceType().toString()); - - final ServiceType serviceType = node.getApplication().getServiceType(); -// if (serviceType.isUser()) { -// jgen.writeStringField("fig", "Ellipse"); -// } else if(serviceType.isWas()) { -// jgen.writeStringField("fig", "RoundedRectangle"); -// } else { -// jgen.writeStringField("fig", "Rectangle"); -// } - - jgen.writeStringField("serviceTypeCode", Short.toString(serviceType.getCode())); -// jgen.writeStringField("terminal", Boolean.toString(serviceType.isTerminal())); - jgen.writeBooleanField("isWas", serviceType.isWas()); // for go.js - - - - writeHistogram(jgen, node); - if (node.getServiceType().isUnknown()) { - writeEmptyObject(jgen, "serverList"); - jgen.writeNumberField("instanceCount", 0); - } else { - final ServerInstanceList serverInstanceList = node.getServerInstanceList(); - if (serverInstanceList != null) { - jgen.writeObjectField("serverList", serverInstanceList); - jgen.writeNumberField("instanceCount", serverInstanceList.getInstanceCount()); - } else { - writeEmptyObject(jgen, "serverList"); - jgen.writeNumberField("instanceCount", 0); - } - } - - jgen.writeEndObject(); - } - - private void writeHistogram(JsonGenerator jgen, Node node) throws IOException { - final ServiceType serviceType = node.getServiceType(); - final NodeHistogram nodeHistogram = node.getNodeHistogram(); - if (serviceType.isWas() || serviceType.isTerminal() || serviceType.isUnknown() || serviceType.isUser()) { - Histogram applicationHistogram = nodeHistogram.getApplicationHistogram(); - if (applicationHistogram == null) { - writeEmptyObject(jgen, "histogram"); - jgen.writeBooleanField("hasAlert", false); // for go.js - } else { - jgen.writeObjectField("histogram", applicationHistogram); - jgen.writeNumberField("totalCount", applicationHistogram.getTotalCount()); // for go.js - jgen.writeNumberField("errorCount", applicationHistogram.getErrorCount()); - jgen.writeNumberField("slowCount", applicationHistogram.getSlowCount()); - - if (applicationHistogram.getTotalCount() == 0) { - jgen.writeBooleanField("hasAlert", false); // for go.js - } else { - long error = applicationHistogram.getErrorCount() / applicationHistogram.getTotalCount(); - if (error * 100 > 10) { - jgen.writeBooleanField("hasAlert", true); // for go.js - } else { - jgen.writeBooleanField("hasAlert", false); // for go.js - } - } - } - - Map agentHistogramMap = nodeHistogram.getAgentHistogramMap(); - if(agentHistogramMap == null) { - writeEmptyObject(jgen, "agentHistogram"); - } else { - jgen.writeObjectField("agentHistogram", agentHistogramMap); - } - } else { - jgen.writeBooleanField("hasAlert", false); // for go.js - } - if (serviceType.isWas() || serviceType.isUser() || serviceType.isTerminal() || serviceType.isUnknown()) { - List applicationTimeSeriesHistogram = nodeHistogram.getApplicationTimeHistogram(); - if (applicationTimeSeriesHistogram == null) { - writeEmptyArray(jgen, "timeSeriesHistogram"); - } else { - jgen.writeObjectField("timeSeriesHistogram", applicationTimeSeriesHistogram); - } - - AgentResponseTimeViewModelList agentTimeSeriesHistogram = nodeHistogram.getAgentTimeHistogram(); - jgen.writeObject(agentTimeSeriesHistogram); - } - } - - private void writeEmptyArray(JsonGenerator jgen, String fieldName) throws IOException { - jgen.writeFieldName(fieldName); - jgen.writeStartArray(); - jgen.writeEndArray(); - } - - private void writeEmptyObject(JsonGenerator jgen, String fieldName) throws IOException { - jgen.writeFieldName(fieldName); - jgen.writeStartObject(); - jgen.writeEndObject(); - } - - -} +package com.nhn.pinpoint.web.view; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.web.applicationmap.Node; +import com.nhn.pinpoint.web.applicationmap.ServerInstanceList; +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; +import com.nhn.pinpoint.web.applicationmap.histogram.NodeHistogram; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * @author emeroad + */ +public class NodeSerializer extends JsonSerializer { + @Override + public void serialize(Node node, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); +// jgen.writeStringField("id", node.getNodeName()); + jgen.writeStringField("key", node.getNodeName()); // necessary for go.js + + jgen.writeStringField("applicationName", node.getApplicationTextName()); // for go.js + + jgen.writeStringField("category", node.getServiceType().toString()); // necessary for go.js + jgen.writeStringField("serviceType", node.getServiceType().toString()); + + final ServiceType serviceType = node.getApplication().getServiceType(); +// if (serviceType.isUser()) { +// jgen.writeStringField("fig", "Ellipse"); +// } else if(serviceType.isWas()) { +// jgen.writeStringField("fig", "RoundedRectangle"); +// } else { +// jgen.writeStringField("fig", "Rectangle"); +// } + + jgen.writeStringField("serviceTypeCode", Short.toString(serviceType.getCode())); +// jgen.writeStringField("terminal", Boolean.toString(serviceType.isTerminal())); + jgen.writeBooleanField("isWas", serviceType.isWas()); // for go.js + + + + writeHistogram(jgen, node); + if (node.getServiceType().isUnknown()) { + writeEmptyObject(jgen, "serverList"); + jgen.writeNumberField("instanceCount", 0); + } else { + final ServerInstanceList serverInstanceList = node.getServerInstanceList(); + if (serverInstanceList != null) { + jgen.writeObjectField("serverList", serverInstanceList); + jgen.writeNumberField("instanceCount", serverInstanceList.getInstanceCount()); + } else { + writeEmptyObject(jgen, "serverList"); + jgen.writeNumberField("instanceCount", 0); + } + } + + jgen.writeEndObject(); + } + + private void writeHistogram(JsonGenerator jgen, Node node) throws IOException { + final ServiceType serviceType = node.getServiceType(); + final NodeHistogram nodeHistogram = node.getNodeHistogram(); + if (serviceType.isWas() || serviceType.isTerminal() || serviceType.isUnknown() || serviceType.isUser()) { + Histogram applicationHistogram = nodeHistogram.getApplicationHistogram(); + if (applicationHistogram == null) { + writeEmptyObject(jgen, "histogram"); + jgen.writeBooleanField("hasAlert", false); // for go.js + } else { + jgen.writeObjectField("histogram", applicationHistogram); + jgen.writeNumberField("totalCount", applicationHistogram.getTotalCount()); // for go.js + jgen.writeNumberField("errorCount", applicationHistogram.getErrorCount()); + jgen.writeNumberField("slowCount", applicationHistogram.getSlowCount()); + + if (applicationHistogram.getTotalCount() == 0) { + jgen.writeBooleanField("hasAlert", false); // for go.js + } else { + long error = applicationHistogram.getErrorCount() / applicationHistogram.getTotalCount(); + if (error * 100 > 10) { + jgen.writeBooleanField("hasAlert", true); // for go.js + } else { + jgen.writeBooleanField("hasAlert", false); // for go.js + } + } + } + + Map agentHistogramMap = nodeHistogram.getAgentHistogramMap(); + if(agentHistogramMap == null) { + writeEmptyObject(jgen, "agentHistogram"); + } else { + jgen.writeObjectField("agentHistogram", agentHistogramMap); + } + } else { + jgen.writeBooleanField("hasAlert", false); // for go.js + } + if (serviceType.isWas() || serviceType.isUser() || serviceType.isTerminal() || serviceType.isUnknown()) { + List applicationTimeSeriesHistogram = nodeHistogram.getApplicationTimeHistogram(); + if (applicationTimeSeriesHistogram == null) { + writeEmptyArray(jgen, "timeSeriesHistogram"); + } else { + jgen.writeObjectField("timeSeriesHistogram", applicationTimeSeriesHistogram); + } + + AgentResponseTimeViewModelList agentTimeSeriesHistogram = nodeHistogram.getAgentTimeHistogram(); + jgen.writeObject(agentTimeSeriesHistogram); + } + } + + private void writeEmptyArray(JsonGenerator jgen, String fieldName) throws IOException { + jgen.writeFieldName(fieldName); + jgen.writeStartArray(); + jgen.writeEndArray(); + } + + private void writeEmptyObject(JsonGenerator jgen, String fieldName) throws IOException { + jgen.writeFieldName(fieldName); + jgen.writeStartObject(); + jgen.writeEndObject(); + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/ResponseTimeViewModel.java b/web/src/main/java/com/navercorp/pinpoint/web/view/ResponseTimeViewModel.java index 3a38dc632136..ff7a077b0e71 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/ResponseTimeViewModel.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/ResponseTimeViewModel.java @@ -1,58 +1,58 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import java.io.IOException; -import java.util.List; - -/** - * @author emeroad - */ -public class ResponseTimeViewModel { - - private final String columnName; - private final List columnValue; - - public ResponseTimeViewModel(String columnName, List columnValue) { - if (columnName == null) { - throw new NullPointerException("columnName must not be null"); - } - if (columnValue == null) { - throw new NullPointerException("columnValue must not be null"); - } - this.columnName = columnName; - this.columnValue = columnValue; - } - - @JsonProperty("key") - public String getColumnName() { - return columnName; - } - - @JsonProperty("values") - public List getColumnValue() { - return columnValue; - } - - @JsonSerialize(using=TimeCountSerializer.class) - public static class TimeCount { - - private final long time; - private final long count; - - public TimeCount(long time, long count) { - this.time = time; - this.count = count; - } - - public long getTime() { - return time; - } - - public long getCount() { - return count; - } - } - -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; +import java.util.List; + +/** + * @author emeroad + */ +public class ResponseTimeViewModel { + + private final String columnName; + private final List columnValue; + + public ResponseTimeViewModel(String columnName, List columnValue) { + if (columnName == null) { + throw new NullPointerException("columnName must not be null"); + } + if (columnValue == null) { + throw new NullPointerException("columnValue must not be null"); + } + this.columnName = columnName; + this.columnValue = columnValue; + } + + @JsonProperty("key") + public String getColumnName() { + return columnName; + } + + @JsonProperty("values") + public List getColumnValue() { + return columnValue; + } + + @JsonSerialize(using=TimeCountSerializer.class) + public static class TimeCount { + + private final long time; + private final long count; + + public TimeCount(long time, long count) { + this.time = time; + this.count = count; + } + + public long getTime() { + return time; + } + + public long getCount() { + return count; + } + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/ServerInstanceListSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/ServerInstanceListSerializer.java index c4c7dd623c6e..aef0c7e4b707 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/ServerInstanceListSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/ServerInstanceListSerializer.java @@ -1,54 +1,54 @@ -package com.nhn.pinpoint.web.view; - -import com.nhn.pinpoint.web.applicationmap.ServerInstance; -import com.nhn.pinpoint.web.applicationmap.ServerInstanceList; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * @author emeroad - */ -public class ServerInstanceListSerializer extends JsonSerializer { - - @Override - public void serialize(ServerInstanceList serverInstanceList, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - - jgen.writeStartObject(); - - Map> map = serverInstanceList.getServerInstanceList(); - for (Map.Entry> entry : map.entrySet()) { - jgen.writeFieldName(entry.getKey()); - jgen.writeStartObject(); - - jgen.writeStringField("name", entry.getKey()); - jgen.writeStringField("status", null); - - jgen.writeFieldName("instanceList"); - writeInstanceList(jgen, entry.getValue()); - - jgen.writeEndObject(); - } - - - jgen.writeEndObject(); - - } - - private void writeInstanceList(JsonGenerator jgen, List serverList) throws IOException { - jgen.writeStartObject(); - for (ServerInstance serverInstance : serverList) { - jgen.writeFieldName(serverInstance.getName()); - jgen.writeObject(serverInstance); - } - - jgen.writeEndObject(); - } - - -} +package com.nhn.pinpoint.web.view; + +import com.nhn.pinpoint.web.applicationmap.ServerInstance; +import com.nhn.pinpoint.web.applicationmap.ServerInstanceList; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * @author emeroad + */ +public class ServerInstanceListSerializer extends JsonSerializer { + + @Override + public void serialize(ServerInstanceList serverInstanceList, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + + jgen.writeStartObject(); + + Map> map = serverInstanceList.getServerInstanceList(); + for (Map.Entry> entry : map.entrySet()) { + jgen.writeFieldName(entry.getKey()); + jgen.writeStartObject(); + + jgen.writeStringField("name", entry.getKey()); + jgen.writeStringField("status", null); + + jgen.writeFieldName("instanceList"); + writeInstanceList(jgen, entry.getValue()); + + jgen.writeEndObject(); + } + + + jgen.writeEndObject(); + + } + + private void writeInstanceList(JsonGenerator jgen, List serverList) throws IOException { + jgen.writeStartObject(); + for (ServerInstance serverInstance : serverList) { + jgen.writeFieldName(serverInstance.getName()); + jgen.writeObject(serverInstance); + } + + jgen.writeEndObject(); + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/ServerTime.java b/web/src/main/java/com/navercorp/pinpoint/web/view/ServerTime.java index 9890d87ac8d8..04aafffa25ba 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/ServerTime.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/ServerTime.java @@ -1,20 +1,20 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * @author emeroad - */ -public class ServerTime { - - private final long currentServerTime; - - public ServerTime() { - this.currentServerTime = System.currentTimeMillis(); - } - - @JsonProperty("currentServerTime") - public long getCurrentServerTime() { - return currentServerTime; - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author emeroad + */ +public class ServerTime { + + private final long currentServerTime; + + public ServerTime() { + this.currentServerTime = System.currentTimeMillis(); + } + + @JsonProperty("currentServerTime") + public long getCurrentServerTime() { + return currentServerTime; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/TimeCountSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/TimeCountSerializer.java index 6d552d99cc80..7272b741ca39 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/TimeCountSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/TimeCountSerializer.java @@ -1,21 +1,21 @@ -package com.nhn.pinpoint.web.view; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -/** - * @author emeroad - */ -public class TimeCountSerializer extends JsonSerializer { - @Override - public void serialize(ResponseTimeViewModel.TimeCount value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeStartArray(); - jgen.writeNumber(value.getTime()); - jgen.writeNumber(value.getCount()); - jgen.writeEndArray(); - } -} +package com.nhn.pinpoint.web.view; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * @author emeroad + */ +public class TimeCountSerializer extends JsonSerializer { + @Override + public void serialize(ResponseTimeViewModel.TimeCount value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartArray(); + jgen.writeNumber(value.getTime()); + jgen.writeNumber(value.getCount()); + jgen.writeEndArray(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/AgentStat.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/AgentStat.java index d12838405f62..62a50e8cf10c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/AgentStat.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/AgentStat.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.web.vo; - -import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; -import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; - -/** - * @author hyungil.jeong - */ -public class AgentStat { - - private AgentStatMemoryGcBo memoryGc; - private AgentStatCpuLoadBo cpuLoad; - - public AgentStatMemoryGcBo getMemoryGc() { - return memoryGc; - } - - public void setMemoryGc(AgentStatMemoryGcBo memoryGc) { - this.memoryGc = memoryGc; - } - - public AgentStatCpuLoadBo getCpuLoad() { - return cpuLoad; - } - - public void setCpuLoad(AgentStatCpuLoadBo cpuLoad) { - this.cpuLoad = cpuLoad; - } -} +package com.nhn.pinpoint.web.vo; + +import com.nhn.pinpoint.common.bo.AgentStatCpuLoadBo; +import com.nhn.pinpoint.common.bo.AgentStatMemoryGcBo; + +/** + * @author hyungil.jeong + */ +public class AgentStat { + + private AgentStatMemoryGcBo memoryGc; + private AgentStatCpuLoadBo cpuLoad; + + public AgentStatMemoryGcBo getMemoryGc() { + return memoryGc; + } + + public void setMemoryGc(AgentStatMemoryGcBo memoryGc) { + this.memoryGc = memoryGc; + } + + public AgentStatCpuLoadBo getCpuLoad() { + return cpuLoad; + } + + public void setCpuLoad(AgentStatCpuLoadBo cpuLoad) { + this.cpuLoad = cpuLoad; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/LinkKey.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/LinkKey.java index 015d329975e1..be9fe5a3ade8 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/LinkKey.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/LinkKey.java @@ -1,110 +1,110 @@ -package com.nhn.pinpoint.web.vo; - -import com.nhn.pinpoint.common.ServiceType; - -/** - * @author emeroad - */ -public final class LinkKey { - - private final String fromApplication; - private final ServiceType fromServiceType; - - private final String toApplication; - private final ServiceType toServiceType; - - private int hash; - - public LinkKey(Application fromApplication, Application toApplication) { - if (fromApplication == null) { - throw new NullPointerException("fromApplication must not be null"); - } - if (toApplication == null) { - throw new NullPointerException("toApplication must not be null"); - } - this.fromApplication = fromApplication.getName(); - this.fromServiceType = fromApplication.getServiceType(); - - this.toApplication = toApplication.getName(); - this.toServiceType = toApplication.getServiceType(); - } - - public LinkKey(String fromApplication, ServiceType fromServiceType, String toApplication, ServiceType toServiceType) { - if (fromApplication == null) { - throw new NullPointerException("fromApplication must not be null"); - } - if (fromServiceType == null) { - throw new NullPointerException("fromServiceType must not be null"); - } - if (toApplication == null) { - throw new NullPointerException("toApplication must not be null"); - } - if (toServiceType == null) { - throw new NullPointerException("toServiceType must not be null"); - } - - this.fromApplication = fromApplication; - this.fromServiceType = fromServiceType; - - this.toApplication = toApplication; - this.toServiceType = toServiceType; - } - - public String getFromApplication() { - return fromApplication; - } - - public ServiceType getFromServiceType() { - return fromServiceType; - } - - public String getToApplication() { - return toApplication; - } - - public ServiceType getToServiceType() { - return toServiceType; - } - - - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - LinkKey linkKey = (LinkKey) o; - - if (fromServiceType != linkKey.fromServiceType) return false; - if (toServiceType != linkKey.toServiceType) return false; - if (!fromApplication.equals(linkKey.fromApplication)) return false; - if (!toApplication.equals(linkKey.toApplication)) return false; - - return true; - } - - @Override - public int hashCode() { - final int hash = this.hash; - if (hash == 0) { - return hash; - } - int result = fromApplication.hashCode(); - result = 31 * result + fromServiceType.hashCode(); - result = 31 * result + toApplication.hashCode(); - result = 31 * result + toServiceType.hashCode(); - this.hash = result; - return result; - } - - @Override - public String toString() { - return "LinkKey{" + - "fromApplication='" + fromApplication + '\'' + - ", fromServiceType=" + fromServiceType + - ", toApplication='" + toApplication + '\'' + - ", toServiceType=" + toServiceType + - '}'; - } -} +package com.nhn.pinpoint.web.vo; + +import com.nhn.pinpoint.common.ServiceType; + +/** + * @author emeroad + */ +public final class LinkKey { + + private final String fromApplication; + private final ServiceType fromServiceType; + + private final String toApplication; + private final ServiceType toServiceType; + + private int hash; + + public LinkKey(Application fromApplication, Application toApplication) { + if (fromApplication == null) { + throw new NullPointerException("fromApplication must not be null"); + } + if (toApplication == null) { + throw new NullPointerException("toApplication must not be null"); + } + this.fromApplication = fromApplication.getName(); + this.fromServiceType = fromApplication.getServiceType(); + + this.toApplication = toApplication.getName(); + this.toServiceType = toApplication.getServiceType(); + } + + public LinkKey(String fromApplication, ServiceType fromServiceType, String toApplication, ServiceType toServiceType) { + if (fromApplication == null) { + throw new NullPointerException("fromApplication must not be null"); + } + if (fromServiceType == null) { + throw new NullPointerException("fromServiceType must not be null"); + } + if (toApplication == null) { + throw new NullPointerException("toApplication must not be null"); + } + if (toServiceType == null) { + throw new NullPointerException("toServiceType must not be null"); + } + + this.fromApplication = fromApplication; + this.fromServiceType = fromServiceType; + + this.toApplication = toApplication; + this.toServiceType = toServiceType; + } + + public String getFromApplication() { + return fromApplication; + } + + public ServiceType getFromServiceType() { + return fromServiceType; + } + + public String getToApplication() { + return toApplication; + } + + public ServiceType getToServiceType() { + return toServiceType; + } + + + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + LinkKey linkKey = (LinkKey) o; + + if (fromServiceType != linkKey.fromServiceType) return false; + if (toServiceType != linkKey.toServiceType) return false; + if (!fromApplication.equals(linkKey.fromApplication)) return false; + if (!toApplication.equals(linkKey.toApplication)) return false; + + return true; + } + + @Override + public int hashCode() { + final int hash = this.hash; + if (hash == 0) { + return hash; + } + int result = fromApplication.hashCode(); + result = 31 * result + fromServiceType.hashCode(); + result = 31 * result + toApplication.hashCode(); + result = 31 * result + toServiceType.hashCode(); + this.hash = result; + return result; + } + + @Override + public String toString() { + return "LinkKey{" + + "fromApplication='" + fromApplication + '\'' + + ", fromServiceType=" + fromServiceType + + ", toApplication='" + toApplication + '\'' + + ", toServiceType=" + toServiceType + + '}'; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/Range.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/Range.java index dbf1c73d8897..033037414277 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/Range.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/Range.java @@ -1,88 +1,88 @@ -package com.nhn.pinpoint.web.vo; - -import com.nhn.pinpoint.common.util.DateUtils; - -import java.util.concurrent.TimeUnit; - -/** - * @author emeroad - * @author netspider - */ -public final class Range { - private final long from; - private final long to; - - public Range(long from, long to) { - this.from = from; - this.to = to; - validate(); - } - - public Range(long from, long to, boolean check) { - this.from = from; - this.to = to; - if (check) { - validate(); - } - } - - public static Range createUncheckedRange(long from, long to) { - return new Range(from, to, false); - } - - public long getFrom() { - return from; - } - - public long getTo() { - return to; - } - - public long getRange() { - return to - from; - } - - public void validate() { - if (this.to < this.from) { - throw new IllegalArgumentException("invalid range:" + this); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Range range = (Range) o; - - if (from != range.from) return false; - if (to != range.to) return false; - - return true; - } - - @Override - public int hashCode() { - int result = (int) (from ^ (from >>> 32)); - result = 31 * result + (int) (to ^ (to >>> 32)); - return result; - } - - @Override - public String toString() { - return "Range{" + - "from=" + from + - ", to=" + to + - ", range=" + getRange() + - '}'; - } - - - public String prettyToString() { - return "Range{" + - "from=" + DateUtils.longToDateStr(from) + - ", to=" + DateUtils.longToDateStr(to) + - ", range s=" + TimeUnit.MILLISECONDS.toSeconds(getRange()) + - '}'; - } -} +package com.nhn.pinpoint.web.vo; + +import com.nhn.pinpoint.common.util.DateUtils; + +import java.util.concurrent.TimeUnit; + +/** + * @author emeroad + * @author netspider + */ +public final class Range { + private final long from; + private final long to; + + public Range(long from, long to) { + this.from = from; + this.to = to; + validate(); + } + + public Range(long from, long to, boolean check) { + this.from = from; + this.to = to; + if (check) { + validate(); + } + } + + public static Range createUncheckedRange(long from, long to) { + return new Range(from, to, false); + } + + public long getFrom() { + return from; + } + + public long getTo() { + return to; + } + + public long getRange() { + return to - from; + } + + public void validate() { + if (this.to < this.from) { + throw new IllegalArgumentException("invalid range:" + this); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Range range = (Range) o; + + if (from != range.from) return false; + if (to != range.to) return false; + + return true; + } + + @Override + public int hashCode() { + int result = (int) (from ^ (from >>> 32)); + result = 31 * result + (int) (to ^ (to >>> 32)); + return result; + } + + @Override + public String toString() { + return "Range{" + + "from=" + from + + ", to=" + to + + ", range=" + getRange() + + '}'; + } + + + public String prettyToString() { + return "Range{" + + "from=" + DateUtils.longToDateStr(from) + + ", to=" + DateUtils.longToDateStr(to) + + ", range s=" + TimeUnit.MILLISECONDS.toSeconds(getRange()) + + '}'; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/RangeFactory.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/RangeFactory.java index fe9f68e072b7..ccb5cfa66989 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/RangeFactory.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/RangeFactory.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.web.vo; - -import com.nhn.pinpoint.common.util.TimeSlot; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * @author emeroad - */ -public class RangeFactory { - @Autowired - private TimeSlot timeSlot; - - /** - * 역방향 분단위 통계 ragne 를 생성한다. - * @param range - * @return - */ - public Range createStatisticsRange(Range range) { - if (range == null) { - throw new NullPointerException("range must not be null"); - } - // hbase의 scanner를 사용하여 검색시 endTime은 검색 대상에 포함되지 않기 때문에, +1을 해줘야 된다. - // 단 key가 역으로 치환되어 있으므로 startTime에 -1을 해야함. - final long startTime = timeSlot.getTimeSlot(range.getFrom()) - 1; - final long endTime = timeSlot.getTimeSlot(range.getTo()); - return Range.createUncheckedRange(startTime, endTime); - } - -} +package com.nhn.pinpoint.web.vo; + +import com.nhn.pinpoint.common.util.TimeSlot; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author emeroad + */ +public class RangeFactory { + @Autowired + private TimeSlot timeSlot; + + /** + * 역방향 분단위 통계 ragne 를 생성한다. + * @param range + * @return + */ + public Range createStatisticsRange(Range range) { + if (range == null) { + throw new NullPointerException("range must not be null"); + } + // hbase의 scanner를 사용하여 검색시 endTime은 검색 대상에 포함되지 않기 때문에, +1을 해줘야 된다. + // 단 key가 역으로 치환되어 있으므로 startTime에 -1을 해야함. + final long startTime = timeSlot.getTimeSlot(range.getFrom()) - 1; + final long endTime = timeSlot.getTimeSlot(range.getTo()); + return Range.createUncheckedRange(startTime, endTime); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseHistogramBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseHistogramBuilder.java index f8c49b0de29a..7ace6925f95d 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseHistogramBuilder.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseHistogramBuilder.java @@ -1,95 +1,95 @@ -package com.nhn.pinpoint.web.vo; - -import com.nhn.pinpoint.common.HistogramSchema; -import com.nhn.pinpoint.common.bo.SpanBo; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; -import com.nhn.pinpoint.web.util.TimeWindow; -import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * @author emeroad - */ -public class ResponseHistogramBuilder { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final TimeWindow window; - - private Map> responseTimeApplicationMap = new HashMap>(); - private Map> result = new HashMap>(); - - - public ResponseHistogramBuilder(Range range) { - if (range == null) { - throw new NullPointerException("range must not be null"); - } - // 일단 샘플링을 하지 않도록한다. - this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); - - } - - public void addHistogram(Application application, SpanBo span, long timeStamp) { - timeStamp = window.refineTimestamp(timeStamp); - - - final ResponseTime responseTime = getResponseTime(application, timeStamp); - if (span.getErrCode() != 0) { - responseTime.addResponseTime(span.getAgentId(), HistogramSchema.ERROR_SLOT_TIME); - } else { - responseTime.addResponseTime(span.getAgentId(), span.getElapsed()); - } - - } - - - public void addLinkHistogram(Application application, String agentId, TimeHistogram timeHistogram) { - long timeStamp = timeHistogram.getTimeStamp(); - timeStamp = window.refineTimestamp(timeStamp); - final ResponseTime responseTime = getResponseTime(application, timeStamp); - responseTime.addResponseTime(agentId, timeHistogram); - } - - private ResponseTime getResponseTime(Application application, Long timeStamp) { - Map responseTimeMap = responseTimeApplicationMap.get(timeStamp); - if (responseTimeMap == null) { - responseTimeMap = new HashMap(); - responseTimeApplicationMap.put(timeStamp, responseTimeMap); - } - ResponseTime responseTime = responseTimeMap.get(application); - if (responseTime == null) { - responseTime = new ResponseTime(application.getName(), application.getServiceTypeCode(), timeStamp); - responseTimeMap.put(application, responseTime); - } - return responseTime; - } - - public void build() { - final Map> result = new HashMap>(); - - for (Map entry : responseTimeApplicationMap.values()) { - for (Map.Entry applicationResponseTimeEntry : entry.entrySet()) { - List responseTimeList = result.get(applicationResponseTimeEntry.getKey()); - if (responseTimeList == null) { - responseTimeList = new ArrayList(); - Application key = applicationResponseTimeEntry.getKey(); - result.put(key, responseTimeList); - } - responseTimeList.add(applicationResponseTimeEntry.getValue()); - } - } - - this.responseTimeApplicationMap = null; - this.result = result; - - } - - public List getResponseTimeList(Application application) { - List responseTimes = this.result.get(application); - return responseTimes; - } - - -} +package com.nhn.pinpoint.web.vo; + +import com.nhn.pinpoint.common.HistogramSchema; +import com.nhn.pinpoint.common.bo.SpanBo; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.nhn.pinpoint.web.util.TimeWindow; +import com.nhn.pinpoint.web.util.TimeWindowOneMinuteSampler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @author emeroad + */ +public class ResponseHistogramBuilder { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final TimeWindow window; + + private Map> responseTimeApplicationMap = new HashMap>(); + private Map> result = new HashMap>(); + + + public ResponseHistogramBuilder(Range range) { + if (range == null) { + throw new NullPointerException("range must not be null"); + } + // 일단 샘플링을 하지 않도록한다. + this.window = new TimeWindow(range, TimeWindowOneMinuteSampler.SAMPLER); + + } + + public void addHistogram(Application application, SpanBo span, long timeStamp) { + timeStamp = window.refineTimestamp(timeStamp); + + + final ResponseTime responseTime = getResponseTime(application, timeStamp); + if (span.getErrCode() != 0) { + responseTime.addResponseTime(span.getAgentId(), HistogramSchema.ERROR_SLOT_TIME); + } else { + responseTime.addResponseTime(span.getAgentId(), span.getElapsed()); + } + + } + + + public void addLinkHistogram(Application application, String agentId, TimeHistogram timeHistogram) { + long timeStamp = timeHistogram.getTimeStamp(); + timeStamp = window.refineTimestamp(timeStamp); + final ResponseTime responseTime = getResponseTime(application, timeStamp); + responseTime.addResponseTime(agentId, timeHistogram); + } + + private ResponseTime getResponseTime(Application application, Long timeStamp) { + Map responseTimeMap = responseTimeApplicationMap.get(timeStamp); + if (responseTimeMap == null) { + responseTimeMap = new HashMap(); + responseTimeApplicationMap.put(timeStamp, responseTimeMap); + } + ResponseTime responseTime = responseTimeMap.get(application); + if (responseTime == null) { + responseTime = new ResponseTime(application.getName(), application.getServiceTypeCode(), timeStamp); + responseTimeMap.put(application, responseTime); + } + return responseTime; + } + + public void build() { + final Map> result = new HashMap>(); + + for (Map entry : responseTimeApplicationMap.values()) { + for (Map.Entry applicationResponseTimeEntry : entry.entrySet()) { + List responseTimeList = result.get(applicationResponseTimeEntry.getKey()); + if (responseTimeList == null) { + responseTimeList = new ArrayList(); + Application key = applicationResponseTimeEntry.getKey(); + result.put(key, responseTimeList); + } + responseTimeList.add(applicationResponseTimeEntry.getValue()); + } + } + + this.responseTimeApplicationMap = null; + this.result = result; + + } + + public List getResponseTimeList(Application application) { + List responseTimes = this.result.get(application); + return responseTimes; + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTime.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTime.java index 98afed174891..9d0364f1adfd 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTime.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTime.java @@ -1,108 +1,108 @@ -package com.nhn.pinpoint.web.vo; - -import com.nhn.pinpoint.common.ServiceType; -import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; -import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; - -import java.util.*; - -/** - * @author emeroad - */ -public class ResponseTime { - // rowKey - private final String applicationName; - private final ServiceType applicationServiceType; - private final long timeStamp; - - // agentId 가 key임. - private final Map responseHistogramMap = new HashMap(); - - - public ResponseTime(String applicationName, short applicationServiceType, long timeStamp) { - if (applicationName == null) { - throw new NullPointerException("applicationName must not be null"); - } - this.applicationName = applicationName; - this.applicationServiceType = ServiceType.findServiceType(applicationServiceType); - this.timeStamp = timeStamp; - } - - - public String getApplicationName() { - return applicationName; - } - - public short getApplicationServiceType() { - return applicationServiceType.getCode(); - } - - public long getTimeStamp() { - return timeStamp; - } - - public Histogram findHistogram(String agentId) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - return responseHistogramMap.get(agentId); - } - - private Histogram getHistogram(String agentId) { - if (agentId == null) { - throw new NullPointerException("agentId must not be null"); - } - TimeHistogram histogram = responseHistogramMap.get(agentId); - if (histogram == null) { - histogram = new TimeHistogram(applicationServiceType, timeStamp); - responseHistogramMap.put(agentId, histogram); - } - return histogram; - } - - public void addResponseTime(String agentId, short slotNumber, long count) { - Histogram histogram = getHistogram(agentId); - histogram.addCallCount(slotNumber, count); - } - - - public void addResponseTime(String agentId, Histogram copyHistogram) { - if (copyHistogram == null) { - throw new NullPointerException("copyHistogram must not be null"); - } - Histogram histogram = getHistogram(agentId); - histogram.add(copyHistogram); - } - - public void addResponseTime(String agentId, int elapsedTime) { - Histogram histogram = getHistogram(agentId); - histogram.addCallCountByElapsedTime(elapsedTime); - } - - public Collection getAgentResponseHistogramList() { - return responseHistogramMap.values(); - } - - public Histogram getApplicationResponseHistogram() { - Histogram result = new Histogram(applicationServiceType); - for (Histogram histogram : responseHistogramMap.values()) { - result.add(histogram); - } - return result; - } - - public Set> getAgentHistogram() { - return this.responseHistogramMap.entrySet(); - } - - @Override - public String toString() { - return "ResponseTime{" + - "applicationName='" + applicationName + '\'' + - ", applicationServiceType=" + applicationServiceType + - ", timeStamp=" + timeStamp + - ", responseHistogramMap=" + responseHistogramMap + - '}'; - } - -} +package com.nhn.pinpoint.web.vo; + +import com.nhn.pinpoint.common.ServiceType; +import com.nhn.pinpoint.web.applicationmap.histogram.Histogram; +import com.nhn.pinpoint.web.applicationmap.histogram.TimeHistogram; + +import java.util.*; + +/** + * @author emeroad + */ +public class ResponseTime { + // rowKey + private final String applicationName; + private final ServiceType applicationServiceType; + private final long timeStamp; + + // agentId 가 key임. + private final Map responseHistogramMap = new HashMap(); + + + public ResponseTime(String applicationName, short applicationServiceType, long timeStamp) { + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + this.applicationName = applicationName; + this.applicationServiceType = ServiceType.findServiceType(applicationServiceType); + this.timeStamp = timeStamp; + } + + + public String getApplicationName() { + return applicationName; + } + + public short getApplicationServiceType() { + return applicationServiceType.getCode(); + } + + public long getTimeStamp() { + return timeStamp; + } + + public Histogram findHistogram(String agentId) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + return responseHistogramMap.get(agentId); + } + + private Histogram getHistogram(String agentId) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + TimeHistogram histogram = responseHistogramMap.get(agentId); + if (histogram == null) { + histogram = new TimeHistogram(applicationServiceType, timeStamp); + responseHistogramMap.put(agentId, histogram); + } + return histogram; + } + + public void addResponseTime(String agentId, short slotNumber, long count) { + Histogram histogram = getHistogram(agentId); + histogram.addCallCount(slotNumber, count); + } + + + public void addResponseTime(String agentId, Histogram copyHistogram) { + if (copyHistogram == null) { + throw new NullPointerException("copyHistogram must not be null"); + } + Histogram histogram = getHistogram(agentId); + histogram.add(copyHistogram); + } + + public void addResponseTime(String agentId, int elapsedTime) { + Histogram histogram = getHistogram(agentId); + histogram.addCallCountByElapsedTime(elapsedTime); + } + + public Collection getAgentResponseHistogramList() { + return responseHistogramMap.values(); + } + + public Histogram getApplicationResponseHistogram() { + Histogram result = new Histogram(applicationServiceType); + for (Histogram histogram : responseHistogramMap.values()) { + result.add(histogram); + } + return result; + } + + public Set> getAgentHistogram() { + return this.responseHistogramMap.entrySet(); + } + + @Override + public String toString() { + return "ResponseTime{" + + "applicationName='" + applicationName + '\'' + + ", applicationServiceType=" + applicationServiceType + + ", timeStamp=" + timeStamp + + ", responseHistogramMap=" + responseHistogramMap + + '}'; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTimeRange.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTimeRange.java index c590faebd29f..4cf9838716b7 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTimeRange.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/ResponseTimeRange.java @@ -1,78 +1,78 @@ -package com.nhn.pinpoint.web.vo; - -/** - * FIXME 그냥 Range를 활용해도 될 듯.. - * - * @author netspider - * - */ -public final class ResponseTimeRange { - private final int from; - private final int to; - - public ResponseTimeRange(int from, int to) { - this.from = from; - this.to = to; - validate(); - } - - public ResponseTimeRange(int from, int to, boolean check) { - this.from = from; - this.to = to; - if (check) { - validate(); - } - } - - public static ResponseTimeRange createUncheckedRange(int from, int to) { - return new ResponseTimeRange(from, to, false); - } - - public int getFrom() { - return from; - } - - public int getTo() { - return to; - } - - public int getRange() { - return to - from; - } - - public void validate() { - if (this.to < this.from) { - throw new IllegalArgumentException("invalid range:" + this); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + from; - result = prime * result + to; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ResponseTimeRange other = (ResponseTimeRange) obj; - if (from != other.from) - return false; - if (to != other.to) - return false; - return true; - } - - @Override - public String toString() { - return "ResponseTimeRange [from=" + from + ", to=" + to + "]"; - } -} +package com.nhn.pinpoint.web.vo; + +/** + * FIXME 그냥 Range를 활용해도 될 듯.. + * + * @author netspider + * + */ +public final class ResponseTimeRange { + private final int from; + private final int to; + + public ResponseTimeRange(int from, int to) { + this.from = from; + this.to = to; + validate(); + } + + public ResponseTimeRange(int from, int to, boolean check) { + this.from = from; + this.to = to; + if (check) { + validate(); + } + } + + public static ResponseTimeRange createUncheckedRange(int from, int to) { + return new ResponseTimeRange(from, to, false); + } + + public int getFrom() { + return from; + } + + public int getTo() { + return to; + } + + public int getRange() { + return to - from; + } + + public void validate() { + if (this.to < this.from) { + throw new IllegalArgumentException("invalid range:" + this); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + from; + result = prime * result + to; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ResponseTimeRange other = (ResponseTimeRange) obj; + if (from != other.from) + return false; + if (to != other.to) + return false; + return true; + } + + @Override + public String toString() { + return "ResponseTimeRange [from=" + from + ", to=" + to + "]"; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/SelectedScatterArea.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/SelectedScatterArea.java index b8f36da3cfcd..a5a92da0dbe3 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/SelectedScatterArea.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/SelectedScatterArea.java @@ -1,78 +1,78 @@ -package com.nhn.pinpoint.web.vo; - -/** - * scatter chart에서 마우스로 드래그해서 선택한 영역의 정보 - * - * @author netspider - * - */ -public final class SelectedScatterArea { - - private final Range timeRange; - private final ResponseTimeRange responseTimeRange; - - public SelectedScatterArea(long timeFrom, long timeTo, int responseTimeFrom, int responseTimeTo) { - this.timeRange = new Range(timeFrom, timeTo); - this.responseTimeRange = new ResponseTimeRange(responseTimeFrom, responseTimeTo); - } - - public SelectedScatterArea(long timeFrom, long timeTo, int responseTimeFrom, int responseTimeTo, boolean check) { - this(timeFrom, timeTo, responseTimeFrom, responseTimeTo); - if (check) { - isValid(); - } - } - - public static SelectedScatterArea createUncheckedArea(long timeFrom, long timeTo, int responseTimeFrom, int responseTimeTo) { - return new SelectedScatterArea(timeFrom, timeTo, responseTimeFrom, responseTimeTo); - } - - private void isValid() { - timeRange.validate(); - responseTimeRange.validate(); - } - - public Range getTimeRange() { - return timeRange; - } - - public ResponseTimeRange getResponseTimeRange() { - return responseTimeRange; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((responseTimeRange == null) ? 0 : responseTimeRange.hashCode()); - result = prime * result + ((timeRange == null) ? 0 : timeRange.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SelectedScatterArea other = (SelectedScatterArea) obj; - if (responseTimeRange == null) { - if (other.responseTimeRange != null) - return false; - } else if (!responseTimeRange.equals(other.responseTimeRange)) - return false; - if (timeRange == null) { - if (other.timeRange != null) - return false; - } else if (!timeRange.equals(other.timeRange)) - return false; - return true; - } - - @Override - public String toString() { - return "SelectedScatterArea [timeRange=" + timeRange + ", responseTimeRange=" + responseTimeRange + "]"; - } -} +package com.nhn.pinpoint.web.vo; + +/** + * scatter chart에서 마우스로 드래그해서 선택한 영역의 정보 + * + * @author netspider + * + */ +public final class SelectedScatterArea { + + private final Range timeRange; + private final ResponseTimeRange responseTimeRange; + + public SelectedScatterArea(long timeFrom, long timeTo, int responseTimeFrom, int responseTimeTo) { + this.timeRange = new Range(timeFrom, timeTo); + this.responseTimeRange = new ResponseTimeRange(responseTimeFrom, responseTimeTo); + } + + public SelectedScatterArea(long timeFrom, long timeTo, int responseTimeFrom, int responseTimeTo, boolean check) { + this(timeFrom, timeTo, responseTimeFrom, responseTimeTo); + if (check) { + isValid(); + } + } + + public static SelectedScatterArea createUncheckedArea(long timeFrom, long timeTo, int responseTimeFrom, int responseTimeTo) { + return new SelectedScatterArea(timeFrom, timeTo, responseTimeFrom, responseTimeTo); + } + + private void isValid() { + timeRange.validate(); + responseTimeRange.validate(); + } + + public Range getTimeRange() { + return timeRange; + } + + public ResponseTimeRange getResponseTimeRange() { + return responseTimeRange; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((responseTimeRange == null) ? 0 : responseTimeRange.hashCode()); + result = prime * result + ((timeRange == null) ? 0 : timeRange.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SelectedScatterArea other = (SelectedScatterArea) obj; + if (responseTimeRange == null) { + if (other.responseTimeRange != null) + return false; + } else if (!responseTimeRange.equals(other.responseTimeRange)) + return false; + if (timeRange == null) { + if (other.timeRange != null) + return false; + } else if (!timeRange.equals(other.timeRange)) + return false; + return true; + } + + @Override + public String toString() { + return "SelectedScatterArea [timeRange=" + timeRange + ", responseTimeRange=" + responseTimeRange + "]"; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/linechart/SampledDoubleLineChart.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/linechart/SampledDoubleLineChart.java index a89916e8dbac..864e15e6edba 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/linechart/SampledDoubleLineChart.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/linechart/SampledDoubleLineChart.java @@ -1,37 +1,37 @@ -package com.nhn.pinpoint.web.vo.linechart; - -/** - * @author hyungil.jeong - */ -public class SampledDoubleLineChart extends LineChart { - - int sampleRate; - int sampleIndex; - Double[] sampleBuffer; - - public SampledDoubleLineChart(int sampleRate) { - this.sampleRate = sampleRate; - this.sampleBuffer = new Double[sampleRate]; - this.sampleIndex = 0; - } - - @Override - public void addPoint(Long xVal, Double yVal) { - sampleBuffer[sampleIndex++] = yVal; - - // FIXME 선택 가능하게. 모두 다 하는 경우에는 그냥 메소드 한번으로 끝낼 수도 있지만 일단... - if (sampleIndex == sampleRate) { - // point[x, minY, maxY, avgY] - Number[] samplePoint = new Number[4]; - samplePoint[0] = xVal; - samplePoint[1] = DownSamplers.MIN.sampleDouble(sampleBuffer); - samplePoint[2] = DownSamplers.MAX.sampleDouble(sampleBuffer); - samplePoint[3] = DownSamplers.AVG.sampleDouble(sampleBuffer); - - getPoints().add(samplePoint); - sampleIndex = 0; - } - } - - -} +package com.nhn.pinpoint.web.vo.linechart; + +/** + * @author hyungil.jeong + */ +public class SampledDoubleLineChart extends LineChart { + + int sampleRate; + int sampleIndex; + Double[] sampleBuffer; + + public SampledDoubleLineChart(int sampleRate) { + this.sampleRate = sampleRate; + this.sampleBuffer = new Double[sampleRate]; + this.sampleIndex = 0; + } + + @Override + public void addPoint(Long xVal, Double yVal) { + sampleBuffer[sampleIndex++] = yVal; + + // FIXME 선택 가능하게. 모두 다 하는 경우에는 그냥 메소드 한번으로 끝낼 수도 있지만 일단... + if (sampleIndex == sampleRate) { + // point[x, minY, maxY, avgY] + Number[] samplePoint = new Number[4]; + samplePoint[0] = xVal; + samplePoint[1] = DownSamplers.MIN.sampleDouble(sampleBuffer); + samplePoint[2] = DownSamplers.MAX.sampleDouble(sampleBuffer); + samplePoint[3] = DownSamplers.AVG.sampleDouble(sampleBuffer); + + getPoints().add(samplePoint); + sampleIndex = 0; + } + } + + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ApplicationScatterScanResult.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ApplicationScatterScanResult.java index 6da4f8a70e5d..0d78330e885a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ApplicationScatterScanResult.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ApplicationScatterScanResult.java @@ -1,29 +1,29 @@ -package com.nhn.pinpoint.web.vo.scatter; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.nhn.pinpoint.web.view.ApplicationScatterScanResultSerializer; -import com.nhn.pinpoint.web.vo.Application; -import com.nhn.pinpoint.web.vo.scatter.ScatterScanResult; - -/** - * @author emeroad - */ -@JsonSerialize(using = ApplicationScatterScanResultSerializer.class) -public class ApplicationScatterScanResult { - - private final Application application; - private final ScatterScanResult scatterScanResult; - - public ApplicationScatterScanResult(Application application, ScatterScanResult scatterScanResult) { - this.application = application; - this.scatterScanResult = scatterScanResult; - } - - public Application getApplication() { - return application; - } - - public ScatterScanResult getScatterScanResult() { - return scatterScanResult; - } -} +package com.nhn.pinpoint.web.vo.scatter; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.nhn.pinpoint.web.view.ApplicationScatterScanResultSerializer; +import com.nhn.pinpoint.web.vo.Application; +import com.nhn.pinpoint.web.vo.scatter.ScatterScanResult; + +/** + * @author emeroad + */ +@JsonSerialize(using = ApplicationScatterScanResultSerializer.class) +public class ApplicationScatterScanResult { + + private final Application application; + private final ScatterScanResult scatterScanResult; + + public ApplicationScatterScanResult(Application application, ScatterScanResult scatterScanResult) { + this.application = application; + this.scatterScanResult = scatterScanResult; + } + + public Application getApplication() { + return application; + } + + public ScatterScanResult getScatterScanResult() { + return scatterScanResult; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterIndex.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterIndex.java index 7a9435cb21d2..6d6abeec7e9a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterIndex.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterIndex.java @@ -1,41 +1,41 @@ -package com.nhn.pinpoint.web.vo.scatter; - -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * @author emeroad - */ -public class ScatterIndex { - public static final ScatterIndex MATA_DATA = new ScatterIndex(); -// "scatterIndex" : { -// "x":0, -// "y":1, -// "transactionId":2, -// "type":3 -// }, - - private final int x = 0; - private final int y = 1; - private final int transactionId = 2; - private final int type = 3; - - @JsonProperty("x") - public int getX() { - return x; - } - - @JsonProperty("y") - public int getY() { - return y; - } - - @JsonProperty("transactionId") - public int getTransactionId() { - return transactionId; - } - - @JsonProperty("type") - public int getType() { - return type; - } -} +package com.nhn.pinpoint.web.vo.scatter; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author emeroad + */ +public class ScatterIndex { + public static final ScatterIndex MATA_DATA = new ScatterIndex(); +// "scatterIndex" : { +// "x":0, +// "y":1, +// "transactionId":2, +// "type":3 +// }, + + private final int x = 0; + private final int y = 1; + private final int transactionId = 2; + private final int type = 3; + + @JsonProperty("x") + public int getX() { + return x; + } + + @JsonProperty("y") + public int getY() { + return y; + } + + @JsonProperty("transactionId") + public int getTransactionId() { + return transactionId; + } + + @JsonProperty("type") + public int getType() { + return type; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterScanResult.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterScanResult.java index d9875151f0b0..abf9b56bdd6e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterScanResult.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/scatter/ScatterScanResult.java @@ -1,65 +1,65 @@ -package com.nhn.pinpoint.web.vo.scatter; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.nhn.pinpoint.web.vo.scatter.Dot; -import com.nhn.pinpoint.web.vo.scatter.ScatterIndex; - -import java.util.Collections; -import java.util.List; - -/** - * 나중에 @ResponseBody로 변경시 사용. - * @author emeroad - */ -public class ScatterScanResult { - private long resultFrom; - private long resultTo; - - private final ScatterIndex scatterIndex = ScatterIndex.MATA_DATA; - - private List scatter = Collections.emptyList(); - - public ScatterScanResult(long resultFrom, long resultTo, List scatterList) { - if (scatterList == null) { - throw new NullPointerException("resultFrom must not be null"); - } - this.resultFrom = resultFrom; - this.resultTo = resultTo; - this.scatter = scatterList; - } - - public ScatterScanResult() { - } - - public void setResultFrom(long resultFrom) { - this.resultFrom = resultFrom; - } - - public void setResultTo(long resultTo) { - this.resultTo = resultTo; - } - - public void setScatter(List scatter) { - this.scatter = scatter; - } - - @JsonProperty("resultFrom") - public long getResultFrom() { - return resultFrom; - } - - @JsonProperty("resultTo") - public long getResultTo() { - return resultTo; - } - - @JsonProperty("scatterIndex") - public ScatterIndex getScatterIndex() { - return scatterIndex; - } - - @JsonProperty("scatter") - public List getScatter() { - return scatter; - } -} +package com.nhn.pinpoint.web.vo.scatter; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.nhn.pinpoint.web.vo.scatter.Dot; +import com.nhn.pinpoint.web.vo.scatter.ScatterIndex; + +import java.util.Collections; +import java.util.List; + +/** + * 나중에 @ResponseBody로 변경시 사용. + * @author emeroad + */ +public class ScatterScanResult { + private long resultFrom; + private long resultTo; + + private final ScatterIndex scatterIndex = ScatterIndex.MATA_DATA; + + private List scatter = Collections.emptyList(); + + public ScatterScanResult(long resultFrom, long resultTo, List scatterList) { + if (scatterList == null) { + throw new NullPointerException("resultFrom must not be null"); + } + this.resultFrom = resultFrom; + this.resultTo = resultTo; + this.scatter = scatterList; + } + + public ScatterScanResult() { + } + + public void setResultFrom(long resultFrom) { + this.resultFrom = resultFrom; + } + + public void setResultTo(long resultTo) { + this.resultTo = resultTo; + } + + public void setScatter(List scatter) { + this.scatter = scatter; + } + + @JsonProperty("resultFrom") + public long getResultFrom() { + return resultFrom; + } + + @JsonProperty("resultTo") + public long getResultTo() { + return resultTo; + } + + @JsonProperty("scatterIndex") + public ScatterIndex getScatterIndex() { + return scatterIndex; + } + + @JsonProperty("scatter") + public List getScatter() { + return scatter; + } +} diff --git a/web/src/main/java/com/nhncorp/lucy/spring/db/mybatis/plugin/BindingLogPlugin32.java b/web/src/main/java/com/nhncorp/lucy/spring/db/mybatis/plugin/BindingLogPlugin32.java index 05d819d02df6..ac85bf511c48 100644 --- a/web/src/main/java/com/nhncorp/lucy/spring/db/mybatis/plugin/BindingLogPlugin32.java +++ b/web/src/main/java/com/nhncorp/lucy/spring/db/mybatis/plugin/BindingLogPlugin32.java @@ -1,141 +1,141 @@ -package com.nhncorp.lucy.spring.db.mybatis.plugin; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.List; -import java.util.Properties; - -import org.apache.ibatis.cache.CacheKey; -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.executor.parameter.ParameterHandler; -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.logging.LogFactory; -import org.apache.ibatis.mapping.BoundSql; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.mapping.StatementType; -import org.apache.ibatis.plugin.Interceptor; -import org.apache.ibatis.plugin.Intercepts; -import org.apache.ibatis.plugin.Invocation; -import org.apache.ibatis.plugin.Plugin; -import org.apache.ibatis.plugin.Signature; -import org.apache.ibatis.scripting.defaults.DefaultParameterHandler; -import org.apache.ibatis.session.ResultHandler; -import org.apache.ibatis.session.RowBounds; -import org.springframework.util.Assert; - -import com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter; -import com.nhncorp.lucy.spring.db.mybatis.plugin.util.PreparedStatementParameterLogger; - -/** - * Binding Log 출력 Plugin - *

- * {@link java.sql.PreparedStatement}, {@link java.sql.CallableStatement} 의 바인딩 변수를 Query와 같이 출력해 주는 plugin. - *

- * Query문의 format을 {@link BindLogFormatter}을 통해 변경할 수 있다. - * 기본구현체는 {@link com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter} 이다. - * 공백 제거 옵션인 removeWhitespace옵션이 지원된다. - * - * @author Web Platform Development Lab - * @author emeroad - * @see Interceptor - * @see BindLogFormatter - * @see com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter - * @since 1.7.4 - */ -@Intercepts({ - @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), - @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}), - @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})} -) -public class BindingLogPlugin32 implements Interceptor { - - private static final Log pLogger = LogFactory.getLog(PreparedStatement.class); - private static final Log internalLogger = LogFactory.getLog(BindingLogPlugin32.class); - - private BindLogFormatter bindLogFormatter; - - public BindingLogPlugin32() { - this.bindLogFormatter = new DefaultBindingLogFormatter(); - } - - public BindingLogPlugin32(BindLogFormatter bindLogFormatter) { - Assert.notNull(bindLogFormatter, "bindLogFormatter must no be null"); - this.bindLogFormatter = bindLogFormatter; - } - - - @Override - public Object intercept(Invocation invocation) throws Throwable { - if (internalLogger.isTraceEnabled()) { - internalLogger.trace("target:" + invocation.getTarget() - + " method:" + invocation.getMethod() + " args:" + Arrays.toString(invocation.getArgs())); - } - try { - return invocation.proceed(); - } finally { - bindingLog(invocation); - } - } - - private void bindingLog(Invocation invocation) throws SQLException { - - Object[] args = invocation.getArgs(); - MappedStatement ms = (MappedStatement) args[0]; - Object parameterObject = args[1]; - StatementType statementType = ms.getStatementType(); - if (StatementType.PREPARED == statementType || StatementType.CALLABLE == statementType) { - Log statementLog = ms.getStatementLog(); - if (isDebugEnable(statementLog)) { - BoundSql boundSql = ms.getBoundSql(parameterObject); - - String sql = boundSql.getSql(); - List parameterList = getParameters(ms, parameterObject, boundSql); - debug(statementLog, "==> BindingLog: " + bindLogFormatter.format(sql, parameterList)); - } - } - } - - public boolean isDebugEnable(Log statementLogger) { - return statementLogger.isDebugEnabled() || pLogger.isDebugEnabled(); - } - - public void debug(Log statementLogger, String msg) { - if (statementLogger.isDebugEnabled()) { - statementLogger.debug(msg); - } else { - pLogger.debug(msg); - } - } - - private List getParameters(MappedStatement ms, Object parameterObject, BoundSql boundSql) throws SQLException { - // 현재 parameterHandler의 구현체는 DefaultParameterHandler가 유일함 추후 변경될수 있음 - // 이경우 구현체를 탐색하는 추가 코드가 필요함. - ParameterHandler parameterHandler = new DefaultParameterHandler(ms, parameterObject, boundSql); - PreparedStatementParameterLogger parameterLogger = new PreparedStatementParameterLogger(); - parameterHandler.setParameters(parameterLogger); - return parameterLogger.getParameters(); - } - - - @Override - public Object plugin(Object target) { - return Plugin.wrap(target, this); - } - - /** - * {@link BindLogFormatter}의 구현체인 {@link com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter} 는 removeWhitespace 옵션을 지원한다. - * removeWhitespace : query 포멧을 한줄로 출력되도록 설정한다. - * - * @param properties 옵션 properties - */ - @Override - public void setProperties(Properties properties) { - bindLogFormatter.setProperties(properties); - } - - public void setBindLogFormatter(BindLogFormatter bindLogFormatter) { - Assert.notNull(bindLogFormatter, "bindLogFormatter must no be null"); - this.bindLogFormatter = bindLogFormatter; - } +package com.nhncorp.lucy.spring.db.mybatis.plugin; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import org.apache.ibatis.cache.CacheKey; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.StatementType; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Plugin; +import org.apache.ibatis.plugin.Signature; +import org.apache.ibatis.scripting.defaults.DefaultParameterHandler; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.springframework.util.Assert; + +import com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter; +import com.nhncorp.lucy.spring.db.mybatis.plugin.util.PreparedStatementParameterLogger; + +/** + * Binding Log 출력 Plugin + *

+ * {@link java.sql.PreparedStatement}, {@link java.sql.CallableStatement} 의 바인딩 변수를 Query와 같이 출력해 주는 plugin. + *

+ * Query문의 format을 {@link BindLogFormatter}을 통해 변경할 수 있다. + * 기본구현체는 {@link com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter} 이다. + * 공백 제거 옵션인 removeWhitespace옵션이 지원된다. + * + * @author Web Platform Development Lab + * @author emeroad + * @see Interceptor + * @see BindLogFormatter + * @see com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter + * @since 1.7.4 + */ +@Intercepts({ + @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), + @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}), + @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})} +) +public class BindingLogPlugin32 implements Interceptor { + + private static final Log pLogger = LogFactory.getLog(PreparedStatement.class); + private static final Log internalLogger = LogFactory.getLog(BindingLogPlugin32.class); + + private BindLogFormatter bindLogFormatter; + + public BindingLogPlugin32() { + this.bindLogFormatter = new DefaultBindingLogFormatter(); + } + + public BindingLogPlugin32(BindLogFormatter bindLogFormatter) { + Assert.notNull(bindLogFormatter, "bindLogFormatter must no be null"); + this.bindLogFormatter = bindLogFormatter; + } + + + @Override + public Object intercept(Invocation invocation) throws Throwable { + if (internalLogger.isTraceEnabled()) { + internalLogger.trace("target:" + invocation.getTarget() + + " method:" + invocation.getMethod() + " args:" + Arrays.toString(invocation.getArgs())); + } + try { + return invocation.proceed(); + } finally { + bindingLog(invocation); + } + } + + private void bindingLog(Invocation invocation) throws SQLException { + + Object[] args = invocation.getArgs(); + MappedStatement ms = (MappedStatement) args[0]; + Object parameterObject = args[1]; + StatementType statementType = ms.getStatementType(); + if (StatementType.PREPARED == statementType || StatementType.CALLABLE == statementType) { + Log statementLog = ms.getStatementLog(); + if (isDebugEnable(statementLog)) { + BoundSql boundSql = ms.getBoundSql(parameterObject); + + String sql = boundSql.getSql(); + List parameterList = getParameters(ms, parameterObject, boundSql); + debug(statementLog, "==> BindingLog: " + bindLogFormatter.format(sql, parameterList)); + } + } + } + + public boolean isDebugEnable(Log statementLogger) { + return statementLogger.isDebugEnabled() || pLogger.isDebugEnabled(); + } + + public void debug(Log statementLogger, String msg) { + if (statementLogger.isDebugEnabled()) { + statementLogger.debug(msg); + } else { + pLogger.debug(msg); + } + } + + private List getParameters(MappedStatement ms, Object parameterObject, BoundSql boundSql) throws SQLException { + // 현재 parameterHandler의 구현체는 DefaultParameterHandler가 유일함 추후 변경될수 있음 + // 이경우 구현체를 탐색하는 추가 코드가 필요함. + ParameterHandler parameterHandler = new DefaultParameterHandler(ms, parameterObject, boundSql); + PreparedStatementParameterLogger parameterLogger = new PreparedStatementParameterLogger(); + parameterHandler.setParameters(parameterLogger); + return parameterLogger.getParameters(); + } + + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + /** + * {@link BindLogFormatter}의 구현체인 {@link com.nhncorp.lucy.spring.db.mybatis.plugin.util.DefaultBindingLogFormatter} 는 removeWhitespace 옵션을 지원한다. + * removeWhitespace : query 포멧을 한줄로 출력되도록 설정한다. + * + * @param properties 옵션 properties + */ + @Override + public void setProperties(Properties properties) { + bindLogFormatter.setProperties(properties); + } + + public void setBindLogFormatter(BindLogFormatter bindLogFormatter) { + Assert.notNull(bindLogFormatter, "bindLogFormatter must no be null"); + this.bindLogFormatter = bindLogFormatter; + } } \ No newline at end of file diff --git a/web/src/main/resources-dev/data.properties b/web/src/main/resources-dev/data.properties index cbd17457d4c1..9fdf01c6cff0 100644 --- a/web/src/main/resources-dev/data.properties +++ b/web/src/main/resources-dev/data.properties @@ -1,15 +1,15 @@ -# dev - -pinpoint.url=http://dev.pinpoint.nhncorp.com - -# mex-mt sms -alarm.sms.url=http://alpha.mobile.nhncorp.com:5001/mex-mt-server/SendBO/sendSMS -alarm.sms.serviceId=EMG00058 -alarm.sms.sender.phoneNumber=01086458010 - -# owl email -alarm.mail.subject=[PINPOINT] %s alarm. -alarm.mail.url=common.mail.mailer.class2.2nd/owl#dev -alarm.mail.serviceId=pinpoint -alarm.mail.option=version=1;mimeCharset=utf-8;debugMode=false -alarm.mail.sender.emailAddress= +# dev + +pinpoint.url=http://dev.pinpoint.nhncorp.com + +# mex-mt sms +alarm.sms.url=http://alpha.mobile.nhncorp.com:5001/mex-mt-server/SendBO/sendSMS +alarm.sms.serviceId=EMG00058 +alarm.sms.sender.phoneNumber=01086458010 + +# owl email +alarm.mail.subject=[PINPOINT] %s alarm. +alarm.mail.url=common.mail.mailer.class2.2nd/owl#dev +alarm.mail.serviceId=pinpoint +alarm.mail.option=version=1;mimeCharset=utf-8;debugMode=false +alarm.mail.sender.emailAddress= diff --git a/web/src/main/resources-dev/hbase.properties b/web/src/main/resources-dev/hbase.properties index 363b45c29453..c78889a045da 100644 --- a/web/src/main/resources-dev/hbase.properties +++ b/web/src/main/resources-dev/hbase.properties @@ -1,3 +1,3 @@ -hbase.client.host=dev.zk.pinpoint.navercorp.com -hbase.client.port=2181 +hbase.client.host=dev.zk.pinpoint.navercorp.com +hbase.client.port=2181 hbase.htable.threads.max=64 \ No newline at end of file diff --git a/web/src/main/resources-dev/jdbc.properties b/web/src/main/resources-dev/jdbc.properties index fdd674607849..6e2f88a48e73 100644 --- a/web/src/main/resources-dev/jdbc.properties +++ b/web/src/main/resources-dev/jdbc.properties @@ -1,4 +1,4 @@ -jdbc.driverClassName=com.mysql.jdbc.Driver -jdbc.url=jdbc:mysql://10.101.28.112:13306/pinpoint?characterEncoding=UTF-8 -jdbc.username=admin +jdbc.driverClassName=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://10.101.28.112:13306/pinpoint?characterEncoding=UTF-8 +jdbc.username=admin jdbc.password=admin \ No newline at end of file diff --git a/web/src/main/resources-local/data.properties b/web/src/main/resources-local/data.properties index e652973197e0..3ef55f28c2b8 100644 --- a/web/src/main/resources-local/data.properties +++ b/web/src/main/resources-local/data.properties @@ -1,15 +1,15 @@ -# local - -pinpoint.url=http://dev.pinpoint.nhncorp.com - -# mex-mt sms -alarm.sms.url=http://alpha.mobile.nhncorp.com:5001/mex-mt-server/SendBO/sendSMS -alarm.sms.serviceId=EMG00058 -alarm.sms.sender.phoneNumber=01086458010 - -# owl email -alarm.mail.subject=[PINPOINT] %s alarm. -alarm.mail.url=common.mail.mailer.class2.2nd/owl#dev -alarm.mail.serviceId=pinpoint -alarm.mail.option=version=1;mimeCharset=utf-8;debugMode=false -alarm.mail.sender.emailAddress= +# local + +pinpoint.url=http://dev.pinpoint.nhncorp.com + +# mex-mt sms +alarm.sms.url=http://alpha.mobile.nhncorp.com:5001/mex-mt-server/SendBO/sendSMS +alarm.sms.serviceId=EMG00058 +alarm.sms.sender.phoneNumber=01086458010 + +# owl email +alarm.mail.subject=[PINPOINT] %s alarm. +alarm.mail.url=common.mail.mailer.class2.2nd/owl#dev +alarm.mail.serviceId=pinpoint +alarm.mail.option=version=1;mimeCharset=utf-8;debugMode=false +alarm.mail.sender.emailAddress= diff --git a/web/src/main/resources-local/hbase.properties b/web/src/main/resources-local/hbase.properties index 9f1f3d92c7f7..286867a44d0b 100644 --- a/web/src/main/resources-local/hbase.properties +++ b/web/src/main/resources-local/hbase.properties @@ -1,10 +1,10 @@ -# local -#hbase.client.host=localhost -# dev -#hbase.client.host=dev.zk.pinpoint.navercorp.com -# local-dev -hbase.client.host=10.101.17.108 -# ?? -#hbase.client.host=10.25.149.61 -hbase.client.port=2181 +# local +#hbase.client.host=localhost +# dev +#hbase.client.host=dev.zk.pinpoint.navercorp.com +# local-dev +hbase.client.host=10.101.17.108 +# ?? +#hbase.client.host=10.25.149.61 +hbase.client.port=2181 hbase.htable.threads.max=128 \ No newline at end of file diff --git a/web/src/main/resources-local/jdbc.properties b/web/src/main/resources-local/jdbc.properties index fdd674607849..6e2f88a48e73 100644 --- a/web/src/main/resources-local/jdbc.properties +++ b/web/src/main/resources-local/jdbc.properties @@ -1,4 +1,4 @@ -jdbc.driverClassName=com.mysql.jdbc.Driver -jdbc.url=jdbc:mysql://10.101.28.112:13306/pinpoint?characterEncoding=UTF-8 -jdbc.username=admin +jdbc.driverClassName=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://10.101.28.112:13306/pinpoint?characterEncoding=UTF-8 +jdbc.username=admin jdbc.password=admin \ No newline at end of file diff --git a/web/src/main/resources-release/hbase.properties b/web/src/main/resources-release/hbase.properties index b781fc122d94..80003e54f12f 100644 --- a/web/src/main/resources-release/hbase.properties +++ b/web/src/main/resources-release/hbase.properties @@ -1,3 +1,3 @@ -hbase.client.host=zk.pinpoint.nhncorp.com -hbase.client.port=2181 +hbase.client.host=zk.pinpoint.nhncorp.com +hbase.client.port=2181 hbase.htable.threads.max=128 \ No newline at end of file diff --git a/web/src/main/resources-test/data.properties b/web/src/main/resources-test/data.properties index e652973197e0..3ef55f28c2b8 100644 --- a/web/src/main/resources-test/data.properties +++ b/web/src/main/resources-test/data.properties @@ -1,15 +1,15 @@ -# local - -pinpoint.url=http://dev.pinpoint.nhncorp.com - -# mex-mt sms -alarm.sms.url=http://alpha.mobile.nhncorp.com:5001/mex-mt-server/SendBO/sendSMS -alarm.sms.serviceId=EMG00058 -alarm.sms.sender.phoneNumber=01086458010 - -# owl email -alarm.mail.subject=[PINPOINT] %s alarm. -alarm.mail.url=common.mail.mailer.class2.2nd/owl#dev -alarm.mail.serviceId=pinpoint -alarm.mail.option=version=1;mimeCharset=utf-8;debugMode=false -alarm.mail.sender.emailAddress= +# local + +pinpoint.url=http://dev.pinpoint.nhncorp.com + +# mex-mt sms +alarm.sms.url=http://alpha.mobile.nhncorp.com:5001/mex-mt-server/SendBO/sendSMS +alarm.sms.serviceId=EMG00058 +alarm.sms.sender.phoneNumber=01086458010 + +# owl email +alarm.mail.subject=[PINPOINT] %s alarm. +alarm.mail.url=common.mail.mailer.class2.2nd/owl#dev +alarm.mail.serviceId=pinpoint +alarm.mail.option=version=1;mimeCharset=utf-8;debugMode=false +alarm.mail.sender.emailAddress= diff --git a/web/src/main/resources-test/hbase.properties b/web/src/main/resources-test/hbase.properties index 18968059e98d..fd27fd21fef3 100644 --- a/web/src/main/resources-test/hbase.properties +++ b/web/src/main/resources-test/hbase.properties @@ -1,4 +1,4 @@ -#hbase.client.host=test.collector.pinpoint.navercorp.com -hbase.client.host=10.101.17.108 -hbase.client.port=2181 +#hbase.client.host=test.collector.pinpoint.navercorp.com +hbase.client.host=10.101.17.108 +hbase.client.port=2181 hbase.htable.threads.max=128 \ No newline at end of file diff --git a/web/src/main/resources-test/jdbc.properties b/web/src/main/resources-test/jdbc.properties index fdd674607849..6e2f88a48e73 100644 --- a/web/src/main/resources-test/jdbc.properties +++ b/web/src/main/resources-test/jdbc.properties @@ -1,4 +1,4 @@ -jdbc.driverClassName=com.mysql.jdbc.Driver -jdbc.url=jdbc:mysql://10.101.28.112:13306/pinpoint?characterEncoding=UTF-8 -jdbc.username=admin +jdbc.driverClassName=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://10.101.28.112:13306/pinpoint?characterEncoding=UTF-8 +jdbc.username=admin jdbc.password=admin \ No newline at end of file diff --git a/web/src/main/resources/applicationContext-dao-config.xml b/web/src/main/resources/applicationContext-dao-config.xml index 249ad5b6e1d5..b6eae1278757 100644 --- a/web/src/main/resources/applicationContext-dao-config.xml +++ b/web/src/main/resources/applicationContext-dao-config.xml @@ -1,79 +1,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/src/main/resources/applicationContext-datasource.xml b/web/src/main/resources/applicationContext-datasource.xml index c1b1dcaa11a1..8f400d622a51 100644 --- a/web/src/main/resources/applicationContext-datasource.xml +++ b/web/src/main/resources/applicationContext-datasource.xml @@ -1,33 +1,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/src/main/resources/applicationContext-hbase.xml b/web/src/main/resources/applicationContext-hbase.xml index 4724563f638d..53b8014b2573 100644 --- a/web/src/main/resources/applicationContext-hbase.xml +++ b/web/src/main/resources/applicationContext-hbase.xml @@ -1,82 +1,82 @@ - - - - - - - ${hbase.client.host} - ${hbase.client.port} - ${hbase.htable.threads.max} - - - - - - - - - - - - - - - 32 - - - - - - - - - - 64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + ${hbase.client.host} + ${hbase.client.port} + ${hbase.htable.threads.max} + + + + + + + + + + + + + + + 32 + + + + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/src/main/resources/applicationContext-scheduler.xml b/web/src/main/resources/applicationContext-scheduler.xml index 954c70ba5a78..24ad5ba43208 100644 --- a/web/src/main/resources/applicationContext-scheduler.xml +++ b/web/src/main/resources/applicationContext-scheduler.xml @@ -1,25 +1,25 @@ - - - - Spring Batch infrastructure beans. - - - - - - - - - - + + + + Spring Batch infrastructure beans. + + + + + + + + + + \ No newline at end of file diff --git a/web/src/main/resources/applicationContext.xml b/web/src/main/resources/applicationContext-web.xml similarity index 100% rename from web/src/main/resources/applicationContext.xml rename to web/src/main/resources/applicationContext-web.xml diff --git a/web/src/main/resources/mapper/AlarmMapper.xml b/web/src/main/resources/mapper/AlarmMapper.xml index 82c067b9283a..7884dd5bc8b3 100644 --- a/web/src/main/resources/mapper/AlarmMapper.xml +++ b/web/src/main/resources/mapper/AlarmMapper.xml @@ -1,162 +1,162 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERT INTO alrm_cntt_info ( - alrm_cntt_grp_id, - phn_no, - mail_addr - ) VALUES ( - #{alarmContactGroupId}, - #{phoneNum}, - #{emailAddress} - ) - - - - UPDATE alrm_cntt_info - SET alrm_cntt_grp_id = #{alarmContactGroupId}, - phn_no = #{phoneNum}, - mail_addr = #{emailAddress} - WHERE id = #{id} - - - - DELETE FROM alrm_cntt_info - WHERE id = #{id} - - - - INSERT INTO alrm_cntt_grp ( - alrm_cntt_grp_nm, - alrm_cntt_grp_desc, - reg_ymd, - reg_emp_no, - mod_ymd, - mod_emp_no - ) VALUES ( - #{alarmContactGroupName}, - #{alarmContactGroupDescrption}, - now(), - #{registerEmployeeNumber}, - now(), - #{modifyEmployeeNumber} - ) - - - - UPDATE alrm_cntt_grp - SET alrm_cntt_grp_nm = #{alarmContactGroupName}, - alrm_cntt_grp_desc = #{alarmContactGroupDescrption}, - mod_ymd = CURRENT_DATETIME, - mod_emp_no = #{modifyEmployeeNumber} - WHERE id = #{id} - - - - DELETE FROM alrm_cntt_grp - WHERE id = #{id} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO alrm_cntt_info ( + alrm_cntt_grp_id, + phn_no, + mail_addr + ) VALUES ( + #{alarmContactGroupId}, + #{phoneNum}, + #{emailAddress} + ) + + + + UPDATE alrm_cntt_info + SET alrm_cntt_grp_id = #{alarmContactGroupId}, + phn_no = #{phoneNum}, + mail_addr = #{emailAddress} + WHERE id = #{id} + + + + DELETE FROM alrm_cntt_info + WHERE id = #{id} + + + + INSERT INTO alrm_cntt_grp ( + alrm_cntt_grp_nm, + alrm_cntt_grp_desc, + reg_ymd, + reg_emp_no, + mod_ymd, + mod_emp_no + ) VALUES ( + #{alarmContactGroupName}, + #{alarmContactGroupDescrption}, + now(), + #{registerEmployeeNumber}, + now(), + #{modifyEmployeeNumber} + ) + + + + UPDATE alrm_cntt_grp + SET alrm_cntt_grp_nm = #{alarmContactGroupName}, + alrm_cntt_grp_desc = #{alarmContactGroupDescrption}, + mod_ymd = CURRENT_DATETIME, + mod_emp_no = #{modifyEmployeeNumber} + WHERE id = #{id} + + + + DELETE FROM alrm_cntt_grp + WHERE id = #{id} + + + diff --git a/web/src/main/resources/mybatis-config.xml b/web/src/main/resources/mybatis-config.xml index 0748e0bd6176..9d1578dec121 100644 --- a/web/src/main/resources/mybatis-config.xml +++ b/web/src/main/resources/mybatis-config.xml @@ -1,24 +1,24 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/main/webapp/WEB-INF/views/linkStatistics.jsp b/web/src/main/webapp/WEB-INF/views/linkStatistics.jsp index b49d61586477..7d33ad42a88d 100644 --- a/web/src/main/webapp/WEB-INF/views/linkStatistics.jsp +++ b/web/src/main/webapp/WEB-INF/views/linkStatistics.jsp @@ -1,17 +1,17 @@ -<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -{ - "resultFrom" : ${resultFrom}, - "resultTo" : ${resultTo}, - "sourceApplicationName" : "${sourceApplication.name}", - "targetApplicationName" : "${targetApplication.name}", - "sourceApplicationType" : "${sourceApplication.serviceType.desc}", - "targetApplicationType" : "${targetApplication.serviceType.desc}", - "sourceApplicationTypeCode" : "${sourceApplication.serviceTypeCode}", - "targetApplicationTypeCode" : "${targetApplication.serviceTypeCode}", - "from" : ${range.from}, - "to" : ${range.to}, - "failedCount" : ${linkStatistics.errorCount}, - "successCount" : ${linkStatistics.successCount}, - "timeSeriesHistogram" : ${timeSeriesHistogram} +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +{ + "resultFrom" : ${resultFrom}, + "resultTo" : ${resultTo}, + "sourceApplicationName" : "${sourceApplication.name}", + "targetApplicationName" : "${targetApplication.name}", + "sourceApplicationType" : "${sourceApplication.serviceType.desc}", + "targetApplicationType" : "${targetApplication.serviceType.desc}", + "sourceApplicationTypeCode" : "${sourceApplication.serviceTypeCode}", + "targetApplicationTypeCode" : "${targetApplication.serviceTypeCode}", + "from" : ${range.from}, + "to" : ${range.to}, + "failedCount" : ${linkStatistics.errorCount}, + "successCount" : ${linkStatistics.successCount}, + "timeSeriesHistogram" : ${timeSeriesHistogram} } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/scatter.jsp b/web/src/main/webapp/WEB-INF/views/scatter.jsp index b00e7de5fc96..2669c93c67dd 100644 --- a/web/src/main/webapp/WEB-INF/views/scatter.jsp +++ b/web/src/main/webapp/WEB-INF/views/scatter.jsp @@ -1,17 +1,17 @@ -<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ - "scatter" : [ - - - { - "traceId" : "${dot.transactionId}", - "timestamp" : ${dot.acceptedTime}, - "executionTime" : ${dot.elapsedTime}, - "resultCode" : ${dot.exceptionCode} - } - , - - ] +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +{ + "scatter" : [ + + + { + "traceId" : "${dot.transactionId}", + "timestamp" : ${dot.acceptedTime}, + "executionTime" : ${dot.elapsedTime}, + "resultCode" : ${dot.exceptionCode} + } + , + + ] } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/scatterPopup.jsp b/web/src/main/webapp/WEB-INF/views/scatterPopup.jsp index 00baa90f478d..be44bb9917c8 100644 --- a/web/src/main/webapp/WEB-INF/views/scatterPopup.jsp +++ b/web/src/main/webapp/WEB-INF/views/scatterPopup.jsp @@ -1,60 +1,60 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> -<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> - - - - PINPOINT - ${applicationName} response scatter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'${applicationName}' response scatter
-
-
- - +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> + + + + PINPOINT - ${applicationName} response scatter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
'${applicationName}' response scatter
+
+
+ + \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/scatterRealtime.jsp b/web/src/main/webapp/WEB-INF/views/scatterRealtime.jsp index e6a082ba8bc0..fdbd12cbbbfe 100644 --- a/web/src/main/webapp/WEB-INF/views/scatterRealtime.jsp +++ b/web/src/main/webapp/WEB-INF/views/scatterRealtime.jsp @@ -1,20 +1,20 @@ -<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ - "scatter" : [ - - - { - "traceId" : "${dot.transactionId}", - "timestamp" : ${dot.acceptedTime}, - "executionTime" : ${dot.elapsedTime}, - "resultCode" : ${dot.exceptionCode} - } - , - - ], - "queryFrom" : ${queryFrom}, - "queryTo" : ${queryTo}, - "limit" : ${limit} +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +{ + "scatter" : [ + + + { + "traceId" : "${dot.transactionId}", + "timestamp" : ${dot.acceptedTime}, + "executionTime" : ${dot.elapsedTime}, + "resultCode" : ${dot.exceptionCode} + } + , + + ], + "queryFrom" : ${queryFrom}, + "queryTo" : ${queryTo}, + "limit" : ${limit} } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/scatter_json.jsp b/web/src/main/webapp/WEB-INF/views/scatter_json.jsp index d13213c8b38f..ef307ddc4386 100644 --- a/web/src/main/webapp/WEB-INF/views/scatter_json.jsp +++ b/web/src/main/webapp/WEB-INF/views/scatter_json.jsp @@ -1,19 +1,19 @@ -<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ - "resultFrom" : ${resultFrom}, - "resultTo" : ${resultTo}, - "scatter" : [ - - - { - "x" : ${dot.acceptedTime}, - "y" : ${dot.elapsedTime}, - "traceId" : "${dot.transactionId}", - "type" : "Failed""Success" - } - , - - ] +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +{ + "resultFrom" : ${resultFrom}, + "resultTo" : ${resultTo}, + "scatter" : [ + + + { + "x" : ${dot.acceptedTime}, + "y" : ${dot.elapsedTime}, + "traceId" : "${dot.transactionId}", + "type" : "Failed""Success" + } + , + + ] } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/scatter_json2.jsp b/web/src/main/webapp/WEB-INF/views/scatter_json2.jsp index 1ad75a235029..ec7632c90e80 100644 --- a/web/src/main/webapp/WEB-INF/views/scatter_json2.jsp +++ b/web/src/main/webapp/WEB-INF/views/scatter_json2.jsp @@ -1,15 +1,15 @@ -<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ - "resultFrom" : ${resultFrom}, - "resultTo" : ${resultTo}, - "scatterIndex" : { - "x":0, - "y":1, - "transactionId":2, - "type":3 - }, - - "scatter":[[${dot.acceptedTime},${dot.elapsedTime},"${dot.transactionId}",01],] +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +{ + "resultFrom" : ${resultFrom}, + "resultTo" : ${resultTo}, + "scatterIndex" : { + "x":0, + "y":1, + "transactionId":2, + "type":3 + }, + + "scatter":[[${dot.acceptedTime},${dot.elapsedTime},"${dot.transactionId}",01],] } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/scatter_jsonp.jsp b/web/src/main/webapp/WEB-INF/views/scatter_jsonp.jsp index 2057acf20a2e..b64424fec2c2 100644 --- a/web/src/main/webapp/WEB-INF/views/scatter_jsonp.jsp +++ b/web/src/main/webapp/WEB-INF/views/scatter_jsonp.jsp @@ -1,17 +1,17 @@ -<%@ page language="java" contentType="application/javascript; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>${callback}( -{ - "resultFrom" : ${resultFrom}, - "resultTo" : ${resultTo}, - "scatter" : [ - - - { - "x" : ${dot.acceptedTime}, - "y" : ${dot.elapsedTime}, - "traceId" : "${dot.transactionId}", - "type" : "Failed""Success" - } - , - - ] +<%@ page language="java" contentType="application/javascript; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>${callback}( +{ + "resultFrom" : ${resultFrom}, + "resultTo" : ${resultTo}, + "scatter" : [ + + + { + "x" : ${dot.acceptedTime}, + "y" : ${dot.elapsedTime}, + "traceId" : "${dot.transactionId}", + "type" : "Failed""Success" + } + , + + ] }); \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/scatter_jsonp2.jsp b/web/src/main/webapp/WEB-INF/views/scatter_jsonp2.jsp index 32c39159e15d..868267d74e76 100644 --- a/web/src/main/webapp/WEB-INF/views/scatter_jsonp2.jsp +++ b/web/src/main/webapp/WEB-INF/views/scatter_jsonp2.jsp @@ -1,13 +1,13 @@ -<%@ page language="java" contentType="application/javascript; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>${callback}( -{ - "resultFrom" : ${resultFrom}, - "resultTo" : ${resultTo}, - "scatterIndex" : { - "x":0, - "y":1, - "transactionId":2, - "type":3 - }, - - "scatter":[[${dot.acceptedTime},${dot.elapsedTime},"${dot.transactionId}",01],] +<%@ page language="java" contentType="application/javascript; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>${callback}( +{ + "resultFrom" : ${resultFrom}, + "resultTo" : ${resultTo}, + "scatterIndex" : { + "x":0, + "y":1, + "transactionId":2, + "type":3 + }, + + "scatter":[[${dot.acceptedTime},${dot.elapsedTime},"${dot.transactionId}",01],] }); \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/selectedScatter.jsp b/web/src/main/webapp/WEB-INF/views/selectedScatter.jsp index 436ae658a8af..e110ad1cc2c4 100644 --- a/web/src/main/webapp/WEB-INF/views/selectedScatter.jsp +++ b/web/src/main/webapp/WEB-INF/views/selectedScatter.jsp @@ -1,30 +1,30 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> - - - - +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + + + \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/selectedScatterList.jsp b/web/src/main/webapp/WEB-INF/views/selectedScatterList.jsp index d796703cb01d..0f1c9c8c866c 100644 --- a/web/src/main/webapp/WEB-INF/views/selectedScatterList.jsp +++ b/web/src/main/webapp/WEB-INF/views/selectedScatterList.jsp @@ -1,225 +1,225 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> - - - - PINPOINT - - - - - - - - - - - - - - - - - - - - - -
-
fetched
-
- fetch more / - fetch all -
-
- - - - - - - - - - - - - - - - -
#TimeApplicationRes. Time (ms)ExceptionAgentIdClientIPTraceId
- - +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> + + + + PINPOINT + + + + + + + + + + + + + + + + + + + + + +
+
fetched
+
+ fetch more / + fetch all +
+
+ + + + + + + + + + + + + + + + +
#TimeApplicationRes. Time (ms)ExceptionAgentIdClientIPTraceId
+ + \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/transactionInfo.jsp b/web/src/main/webapp/WEB-INF/views/transactionInfo.jsp index 3e899dba8ced..f7ce1c28e532 100644 --- a/web/src/main/webapp/WEB-INF/views/transactionInfo.jsp +++ b/web/src/main/webapp/WEB-INF/views/transactionInfo.jsp @@ -1,582 +1,582 @@ -<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> - - - - Transaction details (${traceId}) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Application : ${applicationName}

- -
TransactionId : ${traceId.formatString}
- -
AgentId : ${recordSet.agentId}    ApplicationId : ${recordSet.applicationId}
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodArgumentExec TimeGapTime[ms]Time[%]ClassApiTypeAgent
- - - ${record.title} - ${record.arguments} - ${pinpoint:longToDateStr(record.begin, "HH:mm:ss SSS")} - - - - - - - - - - -
px; background-color:#69B2E9;padding:0px;"> 
-
-
${record.simpleClassName}${record.apiType}${record.agent}
- -
- -
-
-
- -
- -
- - - - - - - - - - - - -
px; background-color:#69B2E9; margin-left:px; margin-top:3px;" onmouseover="showDetail(${status.count})" onmouseout="hideDetail(${status.count})"> -
${record.service} (${end - begin}ms)
-
- -
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#ActionArgumentsEndPointTotal[ms]ApplicationAgent
${span.depth}${ano.keyName}${ano.value}${sp.endPoint}${sp.elapsed} - <%--${sp.serviceName}--%> -
- [show span] - -
 
${span.depth}${ano.keyName}${ano.value}${subSp.endPoint}${subSp.endElapsed} - <%--${subSp.serviceName}--%> -
- [show sub span] - -
 
- -
-
- -
-
- - - +<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> + + + + Transaction details (${traceId}) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Application : ${applicationName}

+ +
TransactionId : ${traceId.formatString}
+ +
AgentId : ${recordSet.agentId}    ApplicationId : ${recordSet.applicationId}
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodArgumentExec TimeGapTime[ms]Time[%]ClassApiTypeAgent
+ + + ${record.title} + ${record.arguments} + ${pinpoint:longToDateStr(record.begin, "HH:mm:ss SSS")} + + + + + + + + + + +
px; background-color:#69B2E9;padding:0px;"> 
+
+
${record.simpleClassName}${record.apiType}${record.agent}
+ +
+ +
+
+
+ +
+ +
+ + + + + + + + + + + + +
px; background-color:#69B2E9; margin-left:px; margin-top:3px;" onmouseover="showDetail(${status.count})" onmouseout="hideDetail(${status.count})"> +
${record.service} (${end - begin}ms)
+
+ +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#ActionArgumentsEndPointTotal[ms]ApplicationAgent
${span.depth}${ano.keyName}${ano.value}${sp.endPoint}${sp.elapsed} + <%--${sp.serviceName}--%> +
+ [show span] + +
 
${span.depth}${ano.keyName}${ano.value}${subSp.endPoint}${subSp.endElapsed} + <%--${subSp.serviceName}--%> +
+ [show sub span] + +
 
+ +
+
+ +
+
+ + + \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/transactionInfoJson.jsp b/web/src/main/webapp/WEB-INF/views/transactionInfoJson.jsp index 6fa6357840d3..71e7a1ce7a26 100644 --- a/web/src/main/webapp/WEB-INF/views/transactionInfoJson.jsp +++ b/web/src/main/webapp/WEB-INF/views/transactionInfoJson.jsp @@ -1,73 +1,73 @@ -<%@ page language="java" contentType="application/javascript; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> -{ - "applicationName" : "${applicationName}", - "transactionId" : "${traceId.formatString}", - "agentId" : "${recordSet.agentId}", - "applicationId" : "${recordSet.applicationId}", - "callStackStart" : ${callstackStart}, - "callStackEnd" : ${callstackEnd}, - "completeState" : "${completeState}", - "callStackIndex" : { - "depth":0, - "begin":1, - "end":2, - "excludeFromTimeline":3, - "applicationName":4, - "tab":5, - "id":6, - "parentId":7, - "isMethod":8, - "hasChild":9, - "title":10, - "arguments":11, - "executeTime":12, - "gap":13, - "elapsedTime":14, - "barWidth":15, - "simpleClassName":16, - "apiType":17, - "agent":18, - "isFocused":19, - "hasException":20 - }, - "callStack" : [ -[ -"${span.depth}", -${record.begin}, -${record.begin + record.elapsed}, -${record.excludeFromTimeline}, -"${record.applicationName}", -${record.tab}, -"${record.id}", -"${record.parentId}", -${record.method}, -${record.hasChild}, -"${pinpoint:escapeJson(record.title)}", -"${pinpoint:escapeJson(pinpoint:escapeHtml(record.arguments))}", -"${pinpoint:longToDateStr(record.begin, "HH:mm:ss SSS")}", -"", -"", -"", -"${record.simpleClassName}", -"${record.apiType}", -"${record.agent}", -${record.focused}, -${record.hasException} -], -], - "applicationMapData" : { - "nodeDataArray": [ - - ${node.nodeJson} , - - ], - "linkDataArray": [ - - ${link.json} , - - ] - } +<%@ page language="java" contentType="application/javascript; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> +{ + "applicationName" : "${applicationName}", + "transactionId" : "${traceId.formatString}", + "agentId" : "${recordSet.agentId}", + "applicationId" : "${recordSet.applicationId}", + "callStackStart" : ${callstackStart}, + "callStackEnd" : ${callstackEnd}, + "completeState" : "${completeState}", + "callStackIndex" : { + "depth":0, + "begin":1, + "end":2, + "excludeFromTimeline":3, + "applicationName":4, + "tab":5, + "id":6, + "parentId":7, + "isMethod":8, + "hasChild":9, + "title":10, + "arguments":11, + "executeTime":12, + "gap":13, + "elapsedTime":14, + "barWidth":15, + "simpleClassName":16, + "apiType":17, + "agent":18, + "isFocused":19, + "hasException":20 + }, + "callStack" : [ +[ +"${span.depth}", +${record.begin}, +${record.begin + record.elapsed}, +${record.excludeFromTimeline}, +"${record.applicationName}", +${record.tab}, +"${record.id}", +"${record.parentId}", +${record.method}, +${record.hasChild}, +"${pinpoint:escapeJson(record.title)}", +"${pinpoint:escapeJson(pinpoint:escapeHtml(record.arguments))}", +"${pinpoint:longToDateStr(record.begin, "HH:mm:ss SSS")}", +"", +"", +"", +"${record.simpleClassName}", +"${record.apiType}", +"${record.agent}", +${record.focused}, +${record.hasException} +], +], + "applicationMapData" : { + "nodeDataArray": [ + + ${node.nodeJson} , + + ], + "linkDataArray": [ + + ${link.json} , + + ] + } } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/transactionList.jsp b/web/src/main/webapp/WEB-INF/views/transactionList.jsp index df0a5b6ef6b1..fcee2f70bed7 100644 --- a/web/src/main/webapp/WEB-INF/views/transactionList.jsp +++ b/web/src/main/webapp/WEB-INF/views/transactionList.jsp @@ -1,169 +1,169 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> -<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> - - - - PINPOINT - ${applicationName} request list - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

Application : ${applicationName}

-
Time : ~
-
Total URL count :
-
Total request count :
- -
-
fetched
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - -
URLCallsErrorAvg(ms)Min(ms)Max(ms)
${t.rpc}
-
-
-
- - - +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ taglib prefix="pinpoint" uri="http://pinpoint.nhncorp.com/pinpoint" %> + + + + PINPOINT - ${applicationName} request list + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

Application : ${applicationName}

+
Time : ~
+
Total URL count :
+
Total request count :
+ +
+
fetched
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
URLCallsErrorAvg(ms)Min(ms)Max(ms)
${t.rpc}
+
+
+
+ + + \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/transactionmetadata.jsp b/web/src/main/webapp/WEB-INF/views/transactionmetadata.jsp index 2a8402bce41e..bfa3b9a67b25 100644 --- a/web/src/main/webapp/WEB-INF/views/transactionmetadata.jsp +++ b/web/src/main/webapp/WEB-INF/views/transactionmetadata.jsp @@ -1,21 +1,21 @@ -<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ - "metadata" : [ - - { - "traceId" : "${span.transactionId}", - "collectorAcceptTime" : ${span.collectorAcceptTime}, - "startTime" : ${span.startTime}, - "elapsed" : ${span.elapsed}, - "application" : "${span.rpc}", - "agentId" : "${span.agentId}", - "endpoint" : "${span.endPoint}", - "exception" : ${span.errCode}, - "remoteAddr" : "${span.remoteAddr}" - } - , - - ] +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +{ + "metadata" : [ + + { + "traceId" : "${span.transactionId}", + "collectorAcceptTime" : ${span.collectorAcceptTime}, + "startTime" : ${span.startTime}, + "elapsed" : ${span.elapsed}, + "application" : "${span.rpc}", + "agentId" : "${span.agentId}", + "endpoint" : "${span.endPoint}", + "exception" : ${span.errCode}, + "remoteAddr" : "${span.remoteAddr}" + } + , + + ] } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/views/transactionmetadata2.jsp b/web/src/main/webapp/WEB-INF/views/transactionmetadata2.jsp index 2a8402bce41e..bfa3b9a67b25 100644 --- a/web/src/main/webapp/WEB-INF/views/transactionmetadata2.jsp +++ b/web/src/main/webapp/WEB-INF/views/transactionmetadata2.jsp @@ -1,21 +1,21 @@ -<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ - "metadata" : [ - - { - "traceId" : "${span.transactionId}", - "collectorAcceptTime" : ${span.collectorAcceptTime}, - "startTime" : ${span.startTime}, - "elapsed" : ${span.elapsed}, - "application" : "${span.rpc}", - "agentId" : "${span.agentId}", - "endpoint" : "${span.endPoint}", - "exception" : ${span.errCode}, - "remoteAddr" : "${span.remoteAddr}" - } - , - - ] +<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +{ + "metadata" : [ + + { + "traceId" : "${span.transactionId}", + "collectorAcceptTime" : ${span.collectorAcceptTime}, + "startTime" : ${span.startTime}, + "elapsed" : ${span.elapsed}, + "application" : "${span.rpc}", + "agentId" : "${span.agentId}", + "endpoint" : "${span.endPoint}", + "exception" : ${span.errCode}, + "remoteAddr" : "${span.remoteAddr}" + } + , + + ] } \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/web.xml b/web/src/main/webapp/WEB-INF/web.xml index 116445a71f3d..8259d735bc77 100644 --- a/web/src/main/webapp/WEB-INF/web.xml +++ b/web/src/main/webapp/WEB-INF/web.xml @@ -1,79 +1,79 @@ - - - - - log4jConfigLocation - classpath:log4j.xml - - - - - org.springframework.web.context.ContextLoaderListener - - - - - contextConfigLocation - classpath:applicationContext.xml - - - - - pinpoint-web - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - classpath:servlet-context.xml - - 1 - - - - - pinpoint-web - *.pinpoint - - - - encodingFilter - org.springframework.web.filter.CharacterEncodingFilter - - encoding - UTF-8 - - - - - NoCacheFilter - NoCacheFilter - com.nhn.pinpoint.web.servletfilter.NoCacheFilter - - - - encodingFilter - /* - - - - NoCacheFilter - /* - - - - default - *.css - *.js - *.gif - *.png - *.ico - *.swf - *.html - - - - index.html - + + + + + log4jConfigLocation + classpath:log4j.xml + + + + + org.springframework.web.context.ContextLoaderListener + + + + + contextConfigLocation + classpath:applicationContext-web.xml + + + + + pinpoint-web + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + classpath:servlet-context.xml + + 1 + + + + + pinpoint-web + *.pinpoint + + + + encodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + + + NoCacheFilter + NoCacheFilter + com.nhn.pinpoint.web.servletfilter.NoCacheFilter + + + + encodingFilter + /* + + + + NoCacheFilter + /* + + + + default + *.css + *.js + *.gif + *.png + *.ico + *.swf + *.html + + + + index.html + \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/amcharts.js b/web/src/main/webapp/components/amcharts/amcharts.js index 73816c1a5498..2d57cac232a7 100755 --- a/web/src/main/webapp/components/amcharts/amcharts.js +++ b/web/src/main/webapp/components/amcharts/amcharts.js @@ -1,376 +1,376 @@ -if(!AmCharts)var AmCharts={themes:{},maps:{},inheriting:{},charts:[],onReadyArray:[],useUTC:!1,updateRate:40,uid:0,lang:{},translations:{},mapTranslations:{}}; -AmCharts.Class=function(a){var b=function(){arguments[0]!==AmCharts.inheriting&&(this.events={},this.construct.apply(this,arguments))};a.inherits?(b.prototype=new a.inherits(AmCharts.inheriting),b.base=a.inherits.prototype,delete a.inherits):(b.prototype.createEvents=function(){for(var a=0,b=arguments.length;aAmCharts.IEversion&&0");if(10h){l.remove();for(var l=[],p=0;-1<(index=b.indexOf(" ",p));)l.push(index),p=index+1;for(var q=Math.round(b.length/2),r=1E3,s,p=0;pc&&(a=c);return a};AmCharts.isDefined=function(a){return void 0===a?!1:!0};AmCharts.stripNumbers=function(a){return a.replace(/[0-9]+/g,"")};AmCharts.roundTo=function(a,b){if(0>b)return a;var c=Math.pow(10,b);return Math.round(a*c)/c}; -AmCharts.toFixed=function(a,b){var c=String(Math.round(a*Math.pow(10,b)));if(0=g[b].contains){var k=a-Math.floor(a/g[b].contains)*g[b].contains;"ss"==b&&(k=AmCharts.formatNumber(k,f),1==k.split(h)[0].length&&(k="0"+k));("mm"==b||"hh"==b)&&10>k&&(k="0"+k);c=k+""+d[b]+""+c;a=Math.floor(a/g[b].contains);b=g[b].nextInterval;return AmCharts.formatDuration(a,b,c,d,e,f)}"ss"==b&&(a=AmCharts.formatNumber(a,f),1==a.split(h)[0].length&&(a="0"+a));("mm"==b||"hh"==b)&&10>a&&(a="0"+a);c=a+""+ -d[b]+""+c;if(g[e].count>g[b].count)for(a=g[b].count;aa?"-":"";a=Math.abs(a);var h=String(a),k=!1;-1!=h.indexOf("e")&&(k=!0);0<=c&&!k&&(h=AmCharts.toFixed(a,c));var l="";if(k)l=h;else{var h=h.split("."),k=String(h[0]),m;for(m=k.length;0<=m;m-=3)l=m!=k.length?0!==m?k.substring(m-3,m)+b+l:k.substring(m-3,m)+l:k.substring(m-3,m);void 0!==h[1]&&(l=l+f+h[1]);void 0!==c&&0=c.x-5&&a<=c.x+c.width+5&&b>=c.y-5&&b<=c.y+c.height+5?!0:!1};AmCharts.isPercents=function(a){if(-1!=String(a).indexOf("%"))return!0}; -AmCharts.findPosX=function(a){var b=a,c=a.offsetLeft;if(a.offsetParent){for(;a=a.offsetParent;)c+=a.offsetLeft;for(;(b=b.parentNode)&&b!=document.body;)c-=b.scrollLeft||0}return c};AmCharts.findPosY=function(a){var b=a,c=a.offsetTop;if(a.offsetParent){for(;a=a.offsetParent;)c+=a.offsetTop;for(;(b=b.parentNode)&&b!=document.body;)c-=b.scrollTop||0}return c};AmCharts.findIfFixed=function(a){if(a.offsetParent)for(;a=a.offsetParent;)if("fixed"==AmCharts.getStyle(a,"position"))return!0;return!1}; -AmCharts.findIfAuto=function(a){return a.style&&"auto"==AmCharts.getStyle(a,"overflow")?!0:a.parentNode?AmCharts.findIfAuto(a.parentNode):!1};AmCharts.findScrollLeft=function(a,b){a.scrollLeft&&(b+=a.scrollLeft);return a.parentNode?AmCharts.findScrollLeft(a.parentNode,b):b};AmCharts.findScrollTop=function(a,b){a.scrollTop&&(b+=a.scrollTop);return a.parentNode?AmCharts.findScrollTop(a.parentNode,b):b}; -AmCharts.formatValue=function(a,b,c,d,e,f,g,h){if(b){void 0===e&&(e="");var k;for(k=0;ka&&(g="-");a=Math.abs(a);if(1=b[h].number&&(k=a/b[h].number,l=Number(d.precision),1>l&&(l=1),c=AmCharts.roundTo(k,l),l=AmCharts.formatNumber(c,{precision:-1,decimalSeparator:d.decimalSeparator,thousandsSeparator:d.thousandsSeparator}),!e||k==c)){f=g+""+l+""+b[h].prefix;break}}else for(h=0;h"==a&&(a="easeOutSine");"<"==a&&(a="easeInSine");"elastic"==a&&(a="easeOutElastic");return a}; -AmCharts.getObjById=function(a,b){var c,d;for(d=0;d"));return a};AmCharts.fixBrakes=function(a){if(AmCharts.isModern){var b=RegExp("
","g");a&&(a=a.replace(b,"\n"))}else a=AmCharts.fixNewLines(a);return a}; -AmCharts.deleteObject=function(a,b){if(a){if(void 0===b||null===b)b=20;if(0!==b)if("[object Array]"===Object.prototype.toString.call(a))for(var c=0;ca&&(a=3)):a=this.width/this.minHorizontalGap, -this.gridCountR=Math.max(a,1)):this.gridCountR=this.gridCount;this.axisWidth=this.axisLine.axisWidth;this.addTitle()},setOrientation:function(a){this.orientation=a?"H":"V"},addTitle:function(){var a=this.title;if(a){var b=this.chart,c=this.titleColor;void 0===c&&(c=b.color);var d=this.titleFontSize;isNaN(d)&&(d=b.fontSize+1);this.titleLabel=AmCharts.text(b.container,a,c,b.fontFamily,d,this.titleAlign,this.titleBold)}},positionTitle:function(){var a=this.titleLabel;if(a){var b,c,d=this.labelsSet,e= -{};0=this.gridCountR&&(this.gridCountR=1);this.totals=[];this.data=this.chart.chartData;var a=this.chart;"xy"!=a.type&&(this.stackGraphs("smoothedLine"),this.stackGraphs("line"),this.stackGraphs("column"),this.stackGraphs("step"));this.recalculateToPercents&&this.recalculate();this.synchronizationMultiplier&& -this.synchronizeWith?(AmCharts.isString(this.synchronizeWith)&&(this.synchronizeWith=a.getValueAxisById(this.synchronizeWith)),this.synchronizeWith&&(this.synchronizeWithAxis(this.synchronizeWith),this.foundGraphs=!0)):(this.foundGraphs=!1,this.getMinMax())},draw:function(){AmCharts.ValueAxis.base.draw.call(this);var a=this.chart,b=this.set;"duration"==this.type&&(this.duration="ss");!0===this.dataChanged&&(this.updateData(),this.dataChanged=!1);if(this.logarithmic&&(0>=this.getMin(0,this.data.length- -1)||0>=this.minimum))this.fire("logarithmicAxisFailed",{type:"logarithmicAxisFailed",chart:a});else{this.grid0=null;var c,d,e=a.dx,f=a.dy,g=!1,h=this.logarithmic;if(isNaN(this.min)||isNaN(this.max)||!this.foundGraphs||Infinity==this.min||-Infinity==this.max)g=!0;else{var k=this.labelFrequency,l=this.showFirstLabel,m=this.showLastLabel,n=1,p=0,q=Math.round((this.max-this.min)/this.step)+1,r;!0===h?(r=Math.log(this.max)*Math.LOG10E-Math.log(this.minReal)*Math.LOG10E,this.stepWidth=this.axisWidth/r, -r>this.logGridLimit&&(q=Math.ceil(Math.log(this.max)*Math.LOG10E)+1,p=Math.round(Math.log(this.minReal)*Math.LOG10E),q>this.gridCountR&&(n=Math.ceil(q/this.gridCountR)))):this.stepWidth=this.axisWidth/(this.max-this.min);var s=0;1>this.step&&-1this.maxDecCount&&(s=this.maxDecCount);var v=this.precision;isNaN(v)||(s=v);this.max=AmCharts.roundTo(this.max,this.maxDecCount);this.min=AmCharts.roundTo(this.min,this.maxDecCount); -var w={};w.precision=s;w.decimalSeparator=a.nf.decimalSeparator;w.thousandsSeparator=a.nf.thousandsSeparator;this.numberFormatter=w;var t,u=this.guides,y=u.length;if(05*this.min&&(p-=this.min),p=AmCharts.roundTo(p,this.maxDecCount+1),!this.integersOnly||Math.round(p)==p)if(isNaN(v)||Number(AmCharts.toFixed(p,v))==p){!0===h&&(0===p&&(p=this.minReal),r>this.logGridLimit&&(p=Math.pow(10,d)),u=-1!=String(p).indexOf("e")?!0:!1);this.useScientificNotation&&(u=!0);this.usePrefixes&&(u=!1);u?(t=-1==String(p).indexOf("e")?p.toExponential(15):String(p),c=t.split("e"),t=Number(c[0]),c=Number(c[1]),t=AmCharts.roundTo(t,14),10==t&&(t=1,c+= -1),t=t+"e"+c,0===p&&(t="0"),1==p&&(t="1")):(h&&(t=String(p).split("."),t[1]?(w.precision=t[1].length,0>d&&(w.precision=Math.abs(d))):w.precision=-1),t=this.usePrefixes?AmCharts.addPrefix(p,a.prefixesOfBigNumbers,a.prefixesOfSmallNumbers,w,!0):AmCharts.formatNumber(p,w,w.precision));this.duration&&(t=AmCharts.formatDuration(p,this.duration,"",this.durationUnits,this.maxInterval,w));this.recalculateToPercents?t+="%":(c=this.unit)&&(t="left"==this.unitPosition?c+t:t+c);Math.round(d/k)!=d/k&&(t=void 0); -if(0===d&&!l||d==q-1&&!m)t=" ";c=this.getCoordinate(p);this.labelFunction&&(t=this.labelFunction(p,t,this).toString());t=new this.axisItemRenderer(this,c,t,void 0,void 0,void 0,void 0,this.boldLabels);this.pushAxisItem(t);if(p==this.baseValue&&"radar"!=a.type){var F,H,z=this.viW,A=this.viH;t=this.viX;E=this.viY;"H"==this.orientation?0<=c&&c<=z+1&&(F=[c,c,c+e],H=[A,0,f]):0<=c&&c<=A+1&&(F=[0,z,z+e],H=[c,c,c+f]);F&&(c=AmCharts.fitToBounds(2*this.gridAlpha,0,1),c=AmCharts.line(a.container,F,H,this.gridColor, -c,1,this.dashLength),c.translate(t,E),this.grid0=c,a.axesSet.push(c),c.toBack())}if(!isNaN(I)&&0this.baseValue&&this.max>this.baseValue&&(d=this.min);this.minb&&c.shift();for(var d=Math.floor(Math.log(Math.abs(a))* -Math.LOG10E),e=0;ea){if(g=Math.pow(10,-g)*f,g==Math.round(g))return f}else if(f==Math.round(f))return f}},stackGraphs:function(a){var b=this.stackType;"stacked"==b&&(b="regular");"line"==b&&(b="none");"100% stacked"==b&&(b="100%");this.stackType=b;var c=[],d=[],e=[],f=[],g,h=this.chart.graphs,k,l,m,n,p=this.baseValue,q=!1;if("line"==a||"step"==a||"smoothedLine"==a)q=!0;if(q&&("regular"==b||"100%"== -b))for(n=0;ng?(l.values.close=g,isNaN(d[k])?l.values.open=p:(l.values.close+=d[k],l.values.open=d[k]),d[k]=l.values.close):(l.values.close=g,isNaN(e[k])?l.values.open= -p:(l.values.close+=e[k],l.values.open=e[k]),e[k]=l.values.close)))}}for(k=this.start;k<=this.end;k++)for(n=0;nc?(l.values.close=AmCharts.fitToBounds(c+d[k], --100,100),l.values.open=d[k],d[k]=l.values.close):(l.values.close=AmCharts.fitToBounds(c+e[k],-100,100),l.values.open=e[k],e[k]=l.values.close)))))},recalculate:function(){var a=this.chart,b=a.graphs,c;for(c=0;cn&&g++}if(l=a.recalculateFromDate)a.dataDateFormat&&(l=AmCharts.stringToDate(l,a.dataDateFormat)),g=a.getClosestIndex(a.chartData,"time",l.getTime(),!0,0,a.chartData.length),h=a.chartData.length-1;for(l=g;l<=h&&(g=this.data[l].axes[this.id].graphs[d.id],f=g.values[e],isNaN(f));l++);this.recBaseValue=f;for(e=k;e<= -h;e++){g=this.data[e].axes[this.id].graphs[d.id];g.percents={};var k=g.values,p;for(p in k)g.percents[p]="percents"!=p?k[p]/f*100-100:k[p]}}}},getMinMax:function(){var a=!1,b=this.chart,c=b.graphs,d;for(d=0;dthis.max&&(this.max=c.toValue),c.value>this.max&&(this.max=c.value);isNaN(this.minimum)||(this.min=this.minimum);isNaN(this.maximum)||(this.max=this.maximum);this.min>this.max&&(a=this.max,this.max=this.min,this.min= -a);isNaN(this.minTemp)||(this.min=this.minTemp);isNaN(this.maxTemp)||(this.max=this.maxTemp);this.minReal=this.min;this.maxReal=this.max;0===this.min&&0===this.max&&(this.max=9);this.min>this.max&&(this.min=this.max-1);a=this.min;b=this.max;c=this.max-this.min;d=0===c?Math.pow(10,Math.floor(Math.log(Math.abs(this.max))*Math.LOG10E))/10:Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;isNaN(this.maximum)&&isNaN(this.maxTemp)&&(this.max=Math.ceil(this.max/d)*d+d);isNaN(this.minimum)&&isNaN(this.minTemp)&& -(this.min=Math.floor(this.min/d)*d-d);0>this.min&&0<=a&&(this.min=0);0=b&&(this.max=0);"100%"==this.stackType&&(this.min=0>this.min?-100:0,this.max=0>this.max?0:100);c=this.max-this.min;d=Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;this.step=Math.ceil(c/this.gridCountR/d)*d;c=Math.pow(10,Math.floor(Math.log(Math.abs(this.step))*Math.LOG10E));c=this.fixStepE(c);d=Math.ceil(this.step/c);5=d&&2c?(this.maxDecCount= -Math.abs(Math.log(Math.abs(c))*Math.LOG10E),this.maxDecCount=Math.round(this.maxDecCount),this.step=AmCharts.roundTo(this.step,this.maxDecCount+1)):this.maxDecCount=0;this.min=this.step*Math.floor(this.min/this.step);this.max=this.step*Math.ceil(this.max/this.step);0>this.min&&0<=a&&(this.min=0);0=b&&(this.max=0);1b?Math.abs(b)-1:Math.abs(b);var e;for(e=0;eb?Number("0."+c+String(a)):Number(String(a)+c)},getMin:function(a,b){var c,d;for(d=a;d<=b;d++){var e=this.data[d].axes[this.id].graphs,f;for(f in e)if(e.hasOwnProperty(f)){var g=this.chart.getGraphById(f);if(g.includeInMinMax&& -(!g.hidden||this.includeHidden)){isNaN(c)&&(c=Infinity);this.foundGraphs=!0;g=e[f].values;this.recalculateToPercents&&(g=e[f].percents);var h;if(this.minMaxField)h=g[this.minMaxField],ha&&(a=f);else for(var g in e)e.hasOwnProperty(g)&&"percents"!=g&&"total"!=g&&(f=e[g],f>a&&(a=f))}}}return a},dispatchZoomEvent:function(a,b){var c={type:"axisZoomed",startValue:a,endValue:b,target:this,chart:this.chart};this.fire(c.type,c)},zoomToValues:function(a,b){if(bthis.max&&(b=this.max);c={type:"axisSelfZoomed"}; -c.chart=this.chart;c.valueAxis=this;c.multiplier=this.axisWidth/Math.abs(this.getCoordinate(b)-this.getCoordinate(a));c.position="V"==this.orientation?this.reversed?this.getCoordinate(a):this.getCoordinate(b):this.reversed?this.getCoordinate(b):this.getCoordinate(a);this.fire(c.type,c)},coordinateToValue:function(a){if(isNaN(a))return NaN;var b=this.axisWidth,c=this.stepWidth,d=this.reversed,e=this.rotate,f=this.min,g=this.minReal;return!0===this.logarithmic?Math.pow(10,(e?!0===d?(b-a)/c:a/c:!0=== -d?a/c:(b-a)/c)+Math.log(g)*Math.LOG10E):!0===d?e?f-(a-b)/c:a/c+f:e?a/c+f:f-(a-b)/c},getCoordinate:function(a){if(isNaN(a))return NaN;var b=this.rotate,c=this.reversed,d=this.axisWidth,e=this.stepWidth,f=this.min,g=this.minReal;!0===this.logarithmic?(a=Math.log(a)*Math.LOG10E-Math.log(g)*Math.LOG10E,b=b?!0===c?d-e*a:e*a:!0===c?e*a:d-e*a):b=!0===c?b?d-e*(a-f):e*(a-f):b?e*(a-f):d-e*(a-f);b=this.rotate?b+(this.x-this.viX):b+(this.y-this.viY);1E7m?(B=V+ca*Math.sin(Y)-u-3+2,G+=-ca*Math.cos(Y)-ja*Math.sin(Y)-4):B-=u+p+3+3,B-=ha):(0m?(B=V+u+3-ca/2*Math.sin(Y)+2,G+=ca/2*Math.cos(Y)):B+=u+v+3+3,B+=ha)):(B+=$+p/2-Z,G+=ba,L?(0X+2||0>f))x.remove(),x=null}else{0<=b&&b<=V+1&&(0V+1||Bc&&"object"==typeof d&&(d=d.join(",").split(",").reverse());"V"==g?(a=AmCharts.rect(k,a.width,c,d,l),a.translate(e,b-h+f)):(a=AmCharts.rect(k, -c,a.height,d,l),a.translate(b-h+e,f));this.set=k.set([a])},graphics:function(){return this.set},getLabel:function(){}});AmCharts.AmChart=AmCharts.Class({construct:function(a){this.theme=a;this.version="3.10.0C";AmCharts.addChart(this);this.createEvents("dataUpdated","init","rendered","drawn");this.height=this.width="100%";this.dataChanged=!0;this.chartCreated=!1;this.previousWidth=this.previousHeight=0;this.backgroundColor="#FFFFFF";this.borderAlpha=this.backgroundAlpha=0;this.color=this.borderColor="#000000";this.fontFamily="Verdana";this.fontSize=11;this.usePrefixes=!1;this.precision=-1;this.percentPrecision=2;this.decimalSeparator= -".";this.thousandsSeparator=",";this.labels=[];this.allLabels=[];this.titles=[];this.marginRight=this.marginLeft=this.autoMarginOffset=0;this.timeOuts=[];this.creditsPosition="top-left";var b=document.createElement("div"),c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.chartDiv=b;b=document.createElement("div");c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.legendDiv=b;this.titleHeight=0;this.hideBalloonTime=150;this.handDrawScatter=2;this.handDrawThickness= -1;this.prefixesOfBigNumbers=[{number:1E3,prefix:"k"},{number:1E6,prefix:"M"},{number:1E9,prefix:"G"},{number:1E12,prefix:"T"},{number:1E15,prefix:"P"},{number:1E18,prefix:"E"},{number:1E21,prefix:"Z"},{number:1E24,prefix:"Y"}];this.prefixesOfSmallNumbers=[{number:1E-24,prefix:"y"},{number:1E-21,prefix:"z"},{number:1E-18,prefix:"a"},{number:1E-15,prefix:"f"},{number:1E-12,prefix:"p"},{number:1E-9,prefix:"n"},{number:1E-6,prefix:"\u03bc"},{number:.001,prefix:"m"}];this.panEventsEnabled=!0;AmCharts.bezierX= -3;AmCharts.bezierY=6;this.product="amcharts";this.animations=[];this.balloon=new AmCharts.AmBalloon(this.theme);this.balloon.chart=this;AmCharts.applyTheme(this,a,"AmChart")},drawChart:function(){this.drawBackground();this.redrawLabels();this.drawTitles();this.brr()},drawBackground:function(){AmCharts.remove(this.background);var a=this.container,b=this.backgroundColor,c=this.backgroundAlpha,d=this.set;AmCharts.isModern||0!==c||(c=.001);var e=this.updateWidth();this.realWidth=e;var f=this.updateHeight(); -this.realHeight=f;this.background=b=AmCharts.polygon(a,[0,e-1,e-1,0],[0,0,f-1,f-1],b,c,1,this.borderColor,this.borderAlpha);d.push(b);if(b=this.backgroundImage)this.path&&(b=this.path+b),this.bgImg=a=a.image(b,0,0,e,f),d.push(a)},drawTitles:function(){var a=this.titles;if(AmCharts.ifArray(a)){var b=20,c;for(c=0;ca||isNaN(a))a=0;this.chartDiv.style.height=a+"px"}}return a},updateWidth:function(){var a=this.divRealWidth,b=this.divRealHeight,c=this.legend;if(c){var d=this.legendDiv, -e=d.offsetWidth;isNaN(c.width)||(e=c.width);var f=d.offsetHeight,d=d.style,g=this.chartDiv.style,c=c.position;if("right"==c||"left"==c){a-=e;if(0>a||isNaN(a))a=0;g.width=a+"px";"left"==c?g.left=e+"px":d.left=a+"px";d.top=(b-f)/2+"px"}}return a},getTitleHeight:function(){var a=0,b=this.titles;if(0a.valueAxis.minMaxMultiplier&&a.positiveClip(a.set));break;case "radar":a.createRadarGraph();break;case "xy":a.createXYGraph(),a.positiveClip(a.set)}a.playedTO=setTimeout(function(){a.setAnimationPlayed.call(a)},500*a.chart.startDuration)}},setAnimationPlayed:function(){this.animationPlayed= -!0},createXYGraph:function(){var a=[],b=[],c=this.xAxis,d=this.yAxis;this.pmh=d.viH+1;this.pmw=c.viW+1;this.pmy=this.pmx=0;var e;for(e=this.start;e<=this.end;e++){var f=this.data[e].axes[c.id].graphs[this.id],g=f.values,h=g.x,k=g.y,g=c.getCoordinate(h),l=d.getCoordinate(k);!isNaN(h)&&!isNaN(k)&&(a.push(g),b.push(l),(h=this.createBullet(f,g,l,e))||(h=0),k=this.labelText)&&(f=this.createLabel(f,g,l,k),this.allBullets.push(f),this.positionLabel(g,l,f,this.labelPosition,h))}this.drawLineGraph(a,b);this.launchAnimation()}, -createRadarGraph:function(){var a=this.valueAxis.stackType,b=[],c=[],d,e,f;for(f=this.start;f<=this.end;f++){var g=this.data[f].axes[this.valueAxis.id].graphs[this.id],h;h="none"==a||"3d"==a?g.values.value:g.values.close;if(isNaN(h))this.drawLineGraph(b,c),b=[],c=[];else{var k=this.y-(this.valueAxis.getCoordinate(h)-this.height),l=180-360/(this.end-this.start+1)*f;h=k*Math.sin(l/180*Math.PI);k*=Math.cos(l/180*Math.PI);b.push(h);c.push(k);(l=this.createBullet(g,h,k,f))||(l=0);var m=this.labelText; -m&&(g=this.createLabel(g,h,k,m),this.allBullets.push(g),this.positionLabel(h,k,g,this.labelPosition,l));isNaN(d)&&(d=h);isNaN(e)&&(e=k)}}b.push(d);c.push(e);this.drawLineGraph(b,c);this.launchAnimation()},positionLabel:function(a,b,c,d,e){var f=c.getBBox();switch(d){case "left":a-=(f.width+e)/2+2;break;case "top":b-=(e+f.height)/2+1;break;case "right":a+=(f.width+e)/2+2;break;case "bottom":b+=(e+f.height)/2+1}c.translate(a,b)},getGradRotation:function(){var a=270;"horizontal"==this.gradientOrientation&& -(a=0);return this.gradientRotation=a},createSerialGraph:function(){this.dashLengthSwitched=this.fillColorsSwitched=this.lineColorSwitched=void 0;var a=this.chart,b=this.id,c=this.index,d=this.data,e=this.chart.container,f=this.valueAxis,g=this.type,h=this.columnWidthReal,k=this.showBulletsAt;isNaN(this.columnWidth)||(h=this.columnWidth);isNaN(h)&&(h=.8);var l=this.useNegativeColorIfDown,m=this.width,n=this.height,p=this.y,q=this.rotate,r=this.columnCount,s=AmCharts.toCoordinate(this.cornerRadiusTop, -h/2),v=this.connect,w=[],t=[],u,y,E,A,z=this.chart.graphs.length,K,I=this.dx/this.tcc,F=this.dy/this.tcc;var H=f.stackType,L=this.labelPosition,ha=this.start,ba=this.end,$=this.scrollbar,Ra=this.categoryAxis,na=this.baseCoord,ta=this.negativeBase,V=this.columnIndex,X=this.lineThickness,Z=this.lineAlpha,oa=this.lineColorR,R=this.dashLength,Y=this.set,qa=L,G=this.getGradRotation(),B=this.chart.columnSpacing,W=Ra.cellWidth,ca=(W*h-r)/r;B>ca&&(B=ca);var ja,x,ab,jb=n+1,kb=m+1,bb= -0,lb=0,mb,nb,cb,db,ob=this.fillColorsR,Da=this.negativeFillColors,wa=this.negativeLineColor,Sa=this.fillAlphas,Ta=this.negativeFillAlphas;"object"==typeof Sa&&(Sa=Sa[0]);"object"==typeof Ta&&(Ta=Ta[0]);var eb=f.getCoordinate(f.min);f.logarithmic&&(eb=f.getCoordinate(f.minReal));this.minCoord=eb;this.resetBullet&&(this.bullet="none");if(!($||"line"!=g&&"smoothedLine"!=g&&"step"!=g||(1==d.length&&"step"!=g&&"none"==this.bullet&&(this.bullet="round",this.resetBullet=!0),!Da&&void 0==wa||l))){var La= -ta;La>f.max&&(La=f.max);Lah&&(h=1);var J;if("line"==g||"step"==g||"smoothedLine"==g){if(0U?!0:!1);if(!$)switch(this.showBalloonAt){case "close":x.y=C; -break;case "open":x.y=M;break;case "high":x.y=ya;break;case "low":x.y=xa}var la=ja.x[Ra.id],Oa=this.periodSpan-1,ma=Math.floor(W/2)+Math.floor(Oa*W/2),za=ma,Hb=0;"left"==this.stepDirection&&(Hb=(2*W+Oa*W)/2,la-=Hb);"start"==this.pointPosition&&(la-=W/2+Math.floor(Oa*W/2),ma=0,za=Math.floor(W)+Math.floor(Oa*W));"end"==this.pointPosition&&(la+=W/2+Math.floor(Oa*W/2),ma=Math.floor(W)+Math.floor(Oa*W),za=0);if(Gb){var sb=this.columnWidth;isNaN(sb)||(ma*=sb,za*=sb)}$||(x.x=la);-1E5>la&&(la=-1E5);la>m+ -1E5&&(la=m+1E5);q?(D=C,N=M,M=C=la,isNaN(ka)&&!this.fillToGraph&&(N=na),Fa=xa,Ga=ya):(N=D=la,isNaN(ka)&&!this.fillToGraph&&(M=na));UNa?(Ma&&(Ua=!0),Ma=!1):(Ma||(Ua=!0),Ma=!0):x.isNegative=U=hb||Math.abs(C-gb)>=hb)w.push(D),t.push(C),fb=D,gb=C;aa=D;ia=C;ea=D;fa=C;!Ea||isNaN(M)||isNaN(N)||(O.push(N), -P.push(M));if(Ua||void 0!=x.lineColor||void 0!=x.fillColors||!isNaN(x.dashLength))this.drawLineGraph(w,t,O,P),w=[D],t=[C],O=[],P=[],!Ea||isNaN(M)||isNaN(N)||(O.push(N),P.push(M)),l?Ma?(this.lineColorSwitched=oa,this.fillColorsSwitched=ob):(this.lineColorSwitched=wa,this.fillColorsSwitched=Da):(this.lineColorSwitched=x.lineColor,this.fillColorsSwitched=x.fillColors),this.dashLengthSwitched=x.dashLength;x.gap&&(this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[])}break;case "smoothedLine":if(isNaN(U))v|| -(this.drawSmoothedGraph(w,t,O,P),w=[],t=[],O=[],P=[]);else{if(Math.abs(D-fb)>=hb||Math.abs(C-gb)>=hb)w.push(D),t.push(C),fb=D,gb=C;aa=D;ia=C;ea=D;fa=C;!Ea||isNaN(M)||isNaN(N)||(O.push(N),P.push(M));void 0==x.lineColor&&void 0==x.fillColors&&isNaN(x.dashLength)||(this.drawSmoothedGraph(w,t,O,P),w=[D],t=[C],O=[],P=[],!Ea||isNaN(M)||isNaN(N)||(O.push(N),P.push(M)),this.lineColorSwitched=x.lineColor,this.fillColorsSwitched=x.fillColors,this.dashLengthSwitched=x.dashLength);x.gap&&(this.drawSmoothedGraph(w, -t,O,P),w=[],t=[],O=[],P=[])}break;case "step":if(!isNaN(U)){if(void 0==x.lineColor&&void 0==x.fillColors&&isNaN(x.dashLength)||(this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[],this.lineColorSwitched=x.lineColor,this.fillColorsSwitched=x.fillColors,this.dashLengthSwitched=x.dashLength),q?(isNaN(u)||(w.push(u),t.push(C-ma)),t.push(C-ma),w.push(D),t.push(C+za),w.push(D),!Ea||isNaN(M)||isNaN(N)||(O.push(E),P.push(M-ma),O.push(N),P.push(M-ma),O.push(N),P.push(M+za))):(isNaN(y)||(t.push(y),w.push(u),t.push(y), -w.push(D-ma)),w.push(D-ma),t.push(C),w.push(D+za),t.push(C),!Ea||isNaN(M)||isNaN(N)||(O.push(N-ma),P.push(A),O.push(N-ma),P.push(M),O.push(N+za),P.push(M))),u=D,y=C,E=N,A=M,aa=D,ia=C,ea=D,fa=C,Ua&&(this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[],l&&(Ma?(this.lineColorSwitched=oa,this.fillColorsSwitched=ob):(this.lineColorSwitched=wa,this.fillColorsSwitched=Da))),Gb||x.gap)u=y=NaN,this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[]}else if(!v){if(1>=this.periodSpan||1ma+za)u=y=NaN; -this.drawLineGraph(w,t,O,P);w=[];t=[];O=[];P=[]}break;case "column":pa=ua;void 0!=x.lineColor&&(pa=x.lineColor);if(!isNaN(U)){l||(x.isNegative=UJb&&ka>Jb))if(q){"3d"==H?(T=C-(r/2-this.depthCount+1)*(h+B)+B/2+F*V,S=N+I*V):(T=Math.floor(C-(r/2-V)*(h+B)+B/2),S=N);Q=h;aa=D;ia=T+h/2;ea=D;fa=T+h/2;T+Q>n&&(Q=n-T);0>T&&(Q+=T,T=0);da=D-N;var Vb=S;S=AmCharts.fitToBounds(S,0,m);da+=Vb-S;da=AmCharts.fitToBounds(da, --S,m-S+I*V);TU&&(L=f.reversed?"right":"left")),"regular"==H||"100%"==H)&&(aa+=this.dx)}else{"3d"==H?(S=D-(r/2-this.depthCount+1)*(h+B)+B/2+I*V,T=M+F*V):(S=D-(r/2-V)*(h+B)+B/2,T=M);Q=h;aa=S+h/2;ia=C;ea=S+h/2;fa=C;S+Q>m+V*I&&(Q=m-S+V*I);0>S&&(Q+=S,S=0);da=C-M;var Wb=T;T=AmCharts.fitToBounds(T,this.dy,n);da+=Wb-T;da=AmCharts.fitToBounds(da,-T+F*V,n-T); -if(SU&&"middle"!=L&&"inside"!=L)L="bottom";else if(L=qa,"regular"==H||"100%"==H)ia+=this.dy}if(ra&&(sa=ra.set,x.columnGraphics=sa,sa.translate(S,T),this.columnsSet.push(sa),(x.url||this.showHandOnHover)&&sa.setAttr("cursor","pointer"),!$)){"none"==H&&(K=q?(this.end+1-J)*z-c:z*J+c);"3d"==H&&(q?(K=(this.end+1-J)*z-c-1E3*this.depthCount,aa+=I*this.columnIndex,ea+=I*this.columnIndex,x.y+=I*this.columnIndex): -(K=(z-c)*(J+1)+1E3*this.depthCount,aa+=3,ia+=F*this.columnIndex+7,fa+=F*this.columnIndex,x.y+=F*this.columnIndex));if("regular"==H||"100%"==H)"inside"!=L&&(L="middle"),K=q?0n&&(Q=n-T),0>T&&(Q+=T,T=0),Tka?(ub=[D,Ga],vb=[N,Fa]):(ub=[N,Ga],vb=[D,Fa]);!isNaN(Ga)&&!isNaN(Fa)&&Cm&&(Q=m-S),0>S&&(Q+=S,S=0),da=C-M,Ska?(wb=[C,ya],xb=[M,xa]):(wb=[M,ya],xb=[C,xa]);!isNaN(ya)&&!isNaN(xa)&& -DU||0da?Pa/2+6:-Pa/2-6):Ja=0>da?Ka:-Ka}if(ga){if(isNaN(ia)||isNaN(aa))ga.remove(),ga=null;else if(aa+=Ia,ia+=Ja,ga.translate(aa,ia),q){if(0>ia||ia>n)ga.remove(),ga=null}else{var Pb=0;"3d"==H&&(Pb=I*V);if(0>aa||aa>m+Pb)ga.remove(),ga=null}ga&&this.allBullets.push(ga)}}if("regular"==H||"100%"==H){var Qb=f.totalText;if(Qb){var Qa=this.createLabel(x,0,0,Qb,f.totalTextColor);this.allBullets.push(Qa);var Rb=Qa.getBBox(),Sb=Rb.width, -Tb=Rb.height,Ya,Za,Ub=f.totals[J];Ub&&Ub.remove();var $a=0;"column"!=g&&($a=Ha);q?(Za=C,Ya=0>U?D-Sb/2-2-$a:D+Sb/2+3+$a):(Ya=D,Za=0>U?C+Tb/2+$a:C-Tb/2-3-$a);Qa.translate(Ya,Za);f.totals[J]=Qa;q?(0>Za||Za>n)&&Qa.remove():(0>Ya||Ya>m)&&Qa.remove()}}}}}}if("line"==g||"step"==g||"smoothedLine"==g)"smoothedLine"==g?this.drawSmoothedGraph(w,t,O,P):this.drawLineGraph(w,t,O,P),$||this.launchAnimation();this.bulletsHidden&&this.hideBullets()},animateColumns:function(a,b,c,d,e,f){var g=this;c=g.chart.startDuration; -0a&&(a=this.fillAlphas),0===a&&(a=this.bulletAlpha),0===a&&(a=1));return a},createBullet:function(a,b,c,d){d=this.container;var e=this.bulletOffset,f= -this.bulletSize;isNaN(a.bulletSize)||(f=a.bulletSize);var g=a.values.value,h=this.maxValue,k=this.minValue,l=this.maxBulletSize,m=this.minBulletSize;isNaN(h)||(isNaN(g)||(f=(g-k)/(h-k)*(l-m)+m),k==h&&(f=l));h=f;this.bulletAxis&&(f=a.values.error,isNaN(f)||(g=f),f=this.bulletAxis.stepWidth*g);fb-0||b-0>this.width||c<-f/2||c-0>this.height)&&(n.remove(),n=null),n&&(this.bulletSet.push(n),n.translate(b,c),this.addListeners(n,a),this.allBullets.push(n)),a.bx=b,a.by=c);a.bulletGraphics=n;return f},showBullets:function(){var a=this.allBullets,b;this.bulletsHidden=!1;for(b=0;ba&&(a=0),a>c&&(a=c)):(a=a.mouseX-this.x-1,0>a&&(a=0),a>b&&(a=b));return a},updateCrosshair:function(){var a=this.chart,b=a.mouseX-this.x,c=a.mouseY-this.y,d=this.vLine,e=this.hLine,b=AmCharts.fitToBounds(b, -0,this.width),c=AmCharts.fitToBounds(c,0,this.height);0a&&(e=a,g=c-a),cb&&(f=b,h=d-b),dy&&(e=y-c),z+e=this.data.length||0>l+e||(h.start=l+e,h.end=H+e,this.fire(h.type,h)))}else{"start"==E?r-=g.cellWidth/2:"mouse"==E&&(c.mouseIsOver?r=s?f-2:e-2:isNaN(this.tempPosition)||(r=this.tempPosition-2));if(s){if(0>r)if(z)r=0;else{this.hideCursor();return}if(r>p+1)if(z)r=p+1;else{this.hideCursor();return}}else{if(0>r)if(z)r= -0;else{this.hideCursor();return}if(r>n)if(z)r=n;else{this.hideCursor();return}}if(0r||r>p)v=!1}else if(k=r,r=t,0>k||k>n+h+1)v=!1;v&&(1!=this.graphBulletSize&&AmCharts.isModern&&(v=y.bulletGraphics)&&(v.getBBox(),v.translate(y.bx,y.by,this.graphBulletSize),this.resizedBullets.push(y),A=this.graphBulletAlpha,isNaN(A)||(v.setAttr("fill-opacity",A),v.setAttr("stroke-opacity",A))),v=u.valueBalloon,A=c.getBalloonColor(u,y),v.setBounds(l,m,l+n,m+p),v.pointerOrientation="H", -F=this.balloonPointerOrientation,"vertical"==F&&(v.pointerOrientation="V"),"horizontal"==F&&(v.pointerOrientation="H"),v.changeColor(A),void 0!==u.balloonAlpha&&(v.fillAlpha=u.balloonAlpha),void 0!==u.balloonTextColor&&(v.color=u.balloonTextColor),v.setPosition(k+l,r+m),k=c.formatString(u.balloonText,y,!0),(r=u.balloonFunction)&&(k=r(y,u).toString()),""!==k&&(s?v.showBalloon(k):(v.text=k,v.show=!0),w.push({yy:t,balloon:v})),!s&&v.set&&(v.set.hide(),u=v.textDiv)&&(u.style.visibility="hidden"))}}this.avoidBalloonOverlapping&& -this.arrangeBalloons()}b?(h={type:"changed"},h.index=a,h.chart=this.chart,h.zooming=z,h.mostCloseGraph=H,h.position=s?f:e,h.target=this,c.fire("changed",h),this.fire("changed",h),this.skipZoomDispatch=!1):(this.skipZoomDispatch=!0,c.updateLegendValues(a));this.previousIndex=a;this.previousMostCloseGraph=H}}}else this.hideCursor()},enableDrawing:function(a){this.enabled=!a;this.hideCursor();this.rolledOver=!1;this.drawing=a},isZooming:function(a){a&&a!=this.zooming&&this.handleMouseDown("fake");a|| -a==this.zooming||this.handleMouseUp()},handleMouseOut:function(){if(this.enabled)if(this.zooming)this.setPosition();else{this.index=void 0;var a={type:"changed",index:void 0,target:this};a.chart=this.chart;this.fire("changed",a);this.hideCursor()}},handleReleaseOutside:function(){this.handleMouseUp()},handleMouseUp:function(){var a=this.chart,b=this.data,c;if(a){var d=a.mouseX-this.x,e=a.mouseY-this.y;if(this.drawingNow){this.drawingNow=!1;AmCharts.remove(this.drawingLine);c=this.drawStartX;var f= -this.drawStartY;if(2Math.abs(e-this.initialMouse)&&this.fromIndex==this.index||(this.indexMath.abs(d-g)&&3>Math.abs(e-h)||(b=Math.min(g,d),f=Math.min(h,e),d=Math.abs(g-d),e=Math.abs(h-e),a.hideXScrollbar&&(b=0,d=this.width),a.hideYScrollbar&&(f=0,e=this.height),c.selectionHeight=e,c.selectionWidth=d,c.selectionY= -f,c.selectionX=b,this.skipZoomDispatch||this.fire(c.type,c))}this.selectWithoutZooming||AmCharts.remove(this.selection)}this.panning=this.zooming=this.skipZoomDispatch=!1}}},showCursorAt:function(a){var b=this.chart.categoryAxis;a=b.parseDates?b.dateToCoordinate(a):b.categoryToCoordinate(a);this.previousMousePosition=NaN;this.forceShow=!0;this.setPosition(a,!1)},clearSelection:function(){AmCharts.remove(this.selection)},handleMouseDown:function(a){if(this.zoomable||this.pan||this.drawing){var b=this.rotate, -c=this.chart,d=c.mouseX-this.x,e=c.mouseY-this.y;if(0document.documentMode&&(this.updateOnReleaseOnly=!0);this.dragIconWidth=18;this.dragIconHeight=25;AmCharts.applyTheme(this,a,"SimpleChartScrollbar")},draw:function(){var a= -this;a.destroy();a.interval=setInterval(function(){a.updateScrollbar.call(a)},40);var b=a.chart.container,c=a.rotate,d=a.chart,e=b.set();a.set=e;d.scrollbarsSet.push(e);var f,g;c?(f=a.scrollbarHeight,g=d.plotAreaHeight):(g=a.scrollbarHeight,f=d.plotAreaWidth);a.width=f;if((a.height=g)&&f){var h=AmCharts.rect(b,f,g,a.backgroundColor,a.backgroundAlpha,1,a.backgroundColor,a.backgroundAlpha);a.bg=h;e.push(h);h=AmCharts.rect(b,f,g,"#000",.005);e.push(h);a.invisibleBg=h;h.click(function(){a.handleBgClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()}).touchend(function(){a.handleBgClick()}); -h=AmCharts.rect(b,f,g,a.selectedBackgroundColor,a.selectedBackgroundAlpha);a.selectedBG=h;e.push(h);f=AmCharts.rect(b,f,g,"#000",.005);a.dragger=f;e.push(f);f.mousedown(function(b){a.handleDragStart(b)}).mouseup(function(){a.handleDragStop()}).mouseover(function(){a.handleDraggerOver()}).mouseout(function(){a.handleMouseOut()}).touchstart(function(b){a.handleDragStart(b)}).touchend(function(){a.handleDragStop()});f=d.pathToImages;c?(h=f+"dragIconH.gif",f=a.dragIconWidth,c=a.dragIconHeight):(h=f+"dragIcon.gif", -c=a.dragIconWidth,f=a.dragIconHeight);g=b.image(h,0,0,c,f);var h=b.image(h,0,0,c,f),k=10,l=20;d.panEventsEnabled&&(k=25,l=a.scrollbarHeight);var m=AmCharts.rect(b,k,l,"#000",.005),n=AmCharts.rect(b,k,l,"#000",.005);n.translate(-(k-c)/2,-(l-f)/2);m.translate(-(k-c)/2,-(l-f)/2);c=b.set([g,n]);b=b.set([h,m]);a.iconLeft=c;a.iconRight=b;c.mousedown(function(){a.leftDragStart()}).mouseup(function(){a.leftDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(b){a.leftDragStart()}).touchend(function(){a.leftDragStop()}); -b.mousedown(function(){a.rightDragStart()}).mouseup(function(){a.rightDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(b){a.rightDragStart()}).touchend(function(){a.rightDragStop()});AmCharts.ifArray(d.chartData)?e.show():e.hide();a.hideDragIcons();a.clipDragger(!1)}e.translate(a.x,a.y)},updateScrollbarSize:function(a,b){var c=this.dragger,d,e,f,g;this.rotate?(d=0,e=a,f=this.width+1,g=b-a,c.setAttr("height",b-a),c.setAttr("y",e)):(d=a, -e=0,f=b-a,g=this.height+1,c.setAttr("width",b-a),c.setAttr("x",d));this.clipAndUpdate(d,e,f,g)},updateScrollbar:function(){var a,b=!1,c,d,e=this.x,f=this.y,g=this.dragger,h=this.getDBox();c=h.x+e;d=h.y+f;var k=h.width,h=h.height,l=this.rotate,m=this.chart,n=this.width,p=this.height,q=m.mouseX,r=m.mouseY;a=this.initialMouse;m.mouseIsOver&&(this.dragging&&(m=this.initialCoord,l?(a=m+(r-a),0>a&&(a=0),m=p-h,a>m&&(a=m),g.setAttr("y",a)):(a=m+(q-a),0>a&&(a=0),m=n-k,a>m&&(a=m),g.setAttr("x",a))),this.resizingRight&& -(l?(a=r-d,a+d>p+f&&(a=p-d+f),0>a?(this.resizingRight=!1,b=this.resizingLeft=!0):(0===a&&(a=.1),g.setAttr("height",a))):(a=q-c,a+c>n+e&&(a=n-c+e),0>a?(this.resizingRight=!1,b=this.resizingLeft=!0):(0===a&&(a=.1),g.setAttr("width",a)))),this.resizingLeft&&(l?(c=d,d=r,dp+f&&(d=p+f),a=!0===b?c-d:h+c-d,0>a?(this.resizingRight=!0,this.resizingLeft=!1,g.setAttr("y",c+h-f)):(0===a&&(a=.1),g.setAttr("y",d-f),g.setAttr("height",a))):(d=q,dn+e&&(d=n+e),a=!0===b?c-d:k+c-d,0>a?(this.resizingRight= -!0,this.resizingLeft=!1,g.setAttr("x",c+k-e)):(0===a&&(a=.1),g.setAttr("x",d-e),g.setAttr("width",a)))),this.clipDragger(!0))},clipDragger:function(a){var b=this.getDBox();if(b){var c=b.x,d=b.y,e=b.width,b=b.height,f=!1;if(this.rotate){if(c=0,e=this.width+1,this.clipY!=d||this.clipH!=b)f=!0}else if(d=0,b=this.height+1,this.clipX!=c||this.clipW!=e)f=!0;f&&(this.clipAndUpdate(c,d,e,b),a&&(this.updateOnReleaseOnly||this.dispatchScrollbarEvent()))}},maskGraphs:function(){},clipAndUpdate:function(a,b, -c,d){this.clipX=a;this.clipY=b;this.clipW=c;this.clipH=d;this.selectedBG.clipRect(a,b,c,d);this.updateDragIconPositions();this.maskGraphs(a,b,c,d)},dispatchScrollbarEvent:function(){if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart;a.hideBalloon();var b=this.getDBox(),c=b.x,d=b.y,e=b.width,b=b.height;this.rotate?(c=d,e=this.height/b):e=this.width/e;a={type:"zoomed",position:c,chart:a,target:this,multiplier:e};this.fire(a.type,a)}},updateDragIconPositions:function(){var a=this.getDBox(),b= -a.x,c=a.y,d=this.iconLeft,e=this.iconRight,f,g,h=this.scrollbarHeight;this.rotate?(f=this.dragIconWidth,g=this.dragIconHeight,d.translate(this.x+(h-g)/2,this.y+c-f/2),e.translate(this.x+(h-g)/2,this.y+c+a.height-f/2)):(f=this.dragIconHeight,g=this.dragIconWidth,d.translate(this.x+b-g/2,this.y+(h-f)/2),e.translate(this.x+b-g/2+a.width,this.y+(h-f)/2))},showDragIcons:function(){this.resizeEnabled&&(this.iconLeft.show(),this.iconRight.show())},hideDragIcons:function(){if(!this.resizingLeft&&!this.resizingRight&& -!this.dragging){if(this.hideResizeGrips||!this.resizeEnabled)this.iconLeft.hide(),this.iconRight.hide();this.removeCursors()}},removeCursors:function(){this.chart.setMouseCursor("auto")},relativeZoom:function(a,b){this.dragger.stop();this.multiplier=a;this.position=b;this.updateScrollbarSize(b,this.rotate?b+this.height/a:b+this.width/a)},destroy:function(){this.clear();AmCharts.remove(this.set);AmCharts.remove(this.iconRight);AmCharts.remove(this.iconLeft)},clear:function(){clearInterval(this.interval)}, -handleDragStart:function(){var a=this.chart;this.dragger.stop();this.removeCursors();this.dragging=!0;var b=this.getDBox();this.rotate?(this.initialCoord=b.y,this.initialMouse=a.mouseY):(this.initialCoord=b.x,this.initialMouse=a.mouseX)},handleDragStop:function(){this.updateOnReleaseOnly&&(this.updateScrollbar(),this.skipEvent=!1,this.dispatchScrollbarEvent());this.dragging=!1;this.mouseIsOver&&this.removeCursors();this.updateScrollbar()},handleDraggerOver:function(){this.handleMouseOver()},leftDragStart:function(){this.dragger.stop(); -this.resizingLeft=!0},leftDragStop:function(){this.resizingLeft=!1;this.mouseIsOver||this.removeCursors();this.updateOnRelease()},rightDragStart:function(){this.dragger.stop();this.resizingRight=!0},rightDragStop:function(){this.resizingRight=!1;this.mouseIsOver||this.removeCursors();this.updateOnRelease()},iconRollOut:function(){this.removeCursors()},iconRollOver:function(){this.rotate?this.chart.setMouseCursor("n-resize"):this.chart.setMouseCursor("e-resize");this.handleMouseOver()},getDBox:function(){if(this.dragger)return this.dragger.getBBox()}, -handleBgClick:function(){if(!this.resizingRight&&!this.resizingLeft){this.zooming=!0;var a,b,c=this.scrollDuration,d=this.dragger;a=this.getDBox();var e=a.height,f=a.width;b=this.chart;var g=this.y,h=this.x,k=this.rotate;k?(a="y",b=b.mouseY-e/2-g,b=AmCharts.fitToBounds(b,0,this.height-e)):(a="x",b=b.mouseX-f/2-h,b=AmCharts.fitToBounds(b,0,this.width-f));this.updateOnReleaseOnly?(this.skipEvent=!1,d.setAttr(a,b),this.dispatchScrollbarEvent(),this.clipDragger()):(b=Math.round(b),k?d.animate({y:b},c, -">"):d.animate({x:b},c,">"))}},updateOnRelease:function(){this.updateOnReleaseOnly&&(this.updateScrollbar(),this.skipEvent=!1,this.dispatchScrollbarEvent())},handleReleaseOutside:function(){if(this.set){if(this.resizingLeft||this.resizingRight||this.dragging)this.updateOnRelease(),this.removeCursors();this.mouseIsOver=this.dragging=this.resizingRight=this.resizingLeft=!1;this.hideDragIcons();this.updateScrollbar()}},handleMouseOver:function(){this.mouseIsOver=!0;this.showDragIcons()},handleMouseOut:function(){this.mouseIsOver= -!1;this.hideDragIcons()}});AmCharts.ChartScrollbar=AmCharts.Class({inherits:AmCharts.SimpleChartScrollbar,construct:function(a){this.cname="ChartScrollbar";AmCharts.ChartScrollbar.base.construct.call(this,a);this.graphLineColor="#BBBBBB";this.graphLineAlpha=0;this.graphFillColor="#BBBBBB";this.graphFillAlpha=1;this.selectedGraphLineColor="#888888";this.selectedGraphLineAlpha=0;this.selectedGraphFillColor="#888888";this.selectedGraphFillAlpha=1;this.gridCount=0;this.gridColor="#FFFFFF";this.gridAlpha=.7;this.skipEvent=this.autoGridCount= -!1;this.color="#FFFFFF";this.scrollbarCreated=!1;this.offset=0;AmCharts.applyTheme(this,a,this.cname)},init:function(){var a=this.categoryAxis,b=this.chart;a||(this.categoryAxis=a=new AmCharts.CategoryAxis);a.chart=b;a.id="scrollbar";a.dateFormats=b.categoryAxis.dateFormats;a.markPeriodChange=b.categoryAxis.markPeriodChange;a.boldPeriodBeginning=b.categoryAxis.boldPeriodBeginning;a.axisItemRenderer=AmCharts.RecItem;a.axisRenderer=AmCharts.RecAxis;a.guideFillRenderer=AmCharts.RecFill;a.inside=!0;a.fontSize= -this.fontSize;a.tickLength=0;a.axisAlpha=0;AmCharts.isString(this.graph)&&(this.graph=AmCharts.getObjById(b.graphs,this.graph));if(a=this.graph){var c=this.valueAxis;c||(this.valueAxis=c=new AmCharts.ValueAxis,c.visible=!1,c.scrollbar=!0,c.axisItemRenderer=AmCharts.RecItem,c.axisRenderer=AmCharts.RecAxis,c.guideFillRenderer=AmCharts.RecFill,c.labelsEnabled=!1,c.chart=b);b=this.unselectedGraph;b||(b=new AmCharts.AmGraph,b.scrollbar=!0,this.unselectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers= -a.noStepRisers);b=this.selectedGraph;b||(b=new AmCharts.AmGraph,b.scrollbar=!0,this.selectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers=a.noStepRisers)}this.scrollbarCreated=!0},draw:function(){var a=this;AmCharts.ChartScrollbar.base.draw.call(a);a.scrollbarCreated||a.init();var b=a.chart,c=b.chartData,d=a.categoryAxis,e=a.rotate,f=a.x,g=a.y,h=a.width,k=a.height,l=b.categoryAxis,m=a.set;d.setOrientation(!e);d.parseDates=l.parseDates;d.rotate=e;d.equalSpacing=l.equalSpacing;d.minPeriod=l.minPeriod; -d.startOnAxis=l.startOnAxis;d.viW=h;d.viH=k;d.width=h;d.height=k;d.gridCount=a.gridCount;d.gridColor=a.gridColor;d.gridAlpha=a.gridAlpha;d.color=a.color;d.tickLength=0;d.axisAlpha=0;d.autoGridCount=a.autoGridCount;d.parseDates&&!d.equalSpacing&&d.timeZoom(b.firstTime,b.lastTime);d.zoom(0,c.length-1);if(l=a.graph){var n=a.valueAxis,p=l.valueAxis;n.id=p.id;n.rotate=e;n.setOrientation(e);n.width=h;n.height=k;n.viW=h;n.viH=k;n.dataProvider=c;n.reversed=p.reversed;n.logarithmic=p.logarithmic;n.gridAlpha= -0;n.axisAlpha=0;m.push(n.set);e?(n.y=g,n.x=0):(n.x=f,n.y=0);var f=Infinity,g=-Infinity,q;for(q=0;qg&&(g=v)}}Infinity!=f&&(n.minimum=f);-Infinity!=g&&(n.maximum=g+.1*(g-f));f==g&&(n.minimum-=1,n.maximum+=1);void 0!==a.minimum&&(n.minimum=a.minimum);void 0!==a.maximum&&(n.maximum=a.maximum);n.zoom(0,c.length-1);s=a.unselectedGraph;s.id=l.id;s.rotate=e;s.chart= -b;s.data=c;s.valueAxis=n;s.chart=l.chart;s.categoryAxis=a.categoryAxis;s.periodSpan=l.periodSpan;s.valueField=l.valueField;s.openField=l.openField;s.closeField=l.closeField;s.highField=l.highField;s.lowField=l.lowField;s.lineAlpha=a.graphLineAlpha;s.lineColorR=a.graphLineColor;s.fillAlphas=a.graphFillAlpha;s.fillColorsR=a.graphFillColor;s.connect=l.connect;s.hidden=l.hidden;s.width=h;s.height=k;s.pointPosition=l.pointPosition;s.stepDirection=l.stepDirection;s.periodSpan=l.periodSpan;p=a.selectedGraph; -p.id=l.id;p.rotate=e;p.chart=b;p.data=c;p.valueAxis=n;p.chart=l.chart;p.categoryAxis=d;p.periodSpan=l.periodSpan;p.valueField=l.valueField;p.openField=l.openField;p.closeField=l.closeField;p.highField=l.highField;p.lowField=l.lowField;p.lineAlpha=a.selectedGraphLineAlpha;p.lineColorR=a.selectedGraphLineColor;p.fillAlphas=a.selectedGraphFillAlpha;p.fillColorsR=a.selectedGraphFillColor;p.connect=l.connect;p.hidden=l.hidden;p.width=h;p.height=k;p.pointPosition=l.pointPosition;p.stepDirection=l.stepDirection; -p.periodSpan=l.periodSpan;b=a.graphType;b||(b=l.type);s.type=b;p.type=b;c=c.length-1;s.zoom(0,c);p.zoom(0,c);p.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});s.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});m.push(s.set);m.push(p.set)}m.push(d.set);m.push(d.labelsSet);a.bg.toBack();a.invisibleBg.toFront();a.dragger.toFront();a.iconLeft.toFront(); -a.iconRight.toFront()},timeZoom:function(a,b,c){this.startTime=a;this.endTime=b;this.timeDifference=b-a;this.skipEvent=!AmCharts.toBoolean(c);this.zoomScrollbar();this.skipEvent||this.dispatchScrollbarEvent()},zoom:function(a,b){this.start=a;this.end=b;this.skipEvent=!0;this.zoomScrollbar()},dispatchScrollbarEvent:function(){if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart.chartData,b,c,d=this.dragger.getBBox();b=d.x;var e=d.y,f=d.width;c=d.height;d=this.chart;this.rotate?b=e:c=f;f={type:"zoomed", -target:this};f.chart=d;var g=this.categoryAxis,h=this.stepWidth,e=d.minSelectedTime;if(g.parseDates&&!g.equalSpacing){if(a=d.lastTime,d=d.firstTime,g.minDuration(),g=Math.round(b/h)+d,b=this.dragging?g+this.timeDifference:Math.round((b+c)/h)+d,g>b&&(g=b),0a&&(b=a),b-eb&&(b=g+e),g!=this.startTime||b!=this.endTime)this.startTime=g,this.endTime=b,f.start=g,f.end=b,f.startDate=new Date(g),f.endDate=new Date(b), -this.fire(f.type,f)}else if(g.startOnAxis||(b+=h/2),c-=this.stepWidth/2,e=g.xToIndex(b),b=g.xToIndex(b+c),e!=this.start||this.end!=b)g.startOnAxis&&(this.resizingRight&&e==b&&b++,this.resizingLeft&&e==b&&(0this.timeDifference&&(this.timeDifference=0)},handleBackgroundClick:function(){AmCharts.ChartScrollbar.base.handleBackgroundClick.call(this);this.dragging||(this.difference=this.end-this.start,this.timeDifference=this.endTime-this.startTime,0>this.timeDifference&&(this.timeDifference=0))}});AmCharts.AmBalloon=AmCharts.Class({construct:function(a){this.cname="AmBalloon";this.enabled=!0;this.fillColor="#FFFFFF";this.fillAlpha=.8;this.borderThickness=2;this.borderColor="#FFFFFF";this.borderAlpha=1;this.cornerRadius=0;this.maximumWidth=220;this.horizontalPadding=8;this.verticalPadding=4;this.pointerWidth=6;this.pointerOrientation="V";this.color="#000000";this.adjustBorderColor=!0;this.show=this.follow=this.showBullet=!1;this.bulletSize=3;this.shadowAlpha=.4;this.shadowColor="#000000";this.fadeOutDuration= -this.animationDuration=.3;this.fixedPosition=!1;this.offsetY=6;this.offsetX=1;this.textAlign="center";AmCharts.isModern||(this.offsetY*=1.5);AmCharts.applyTheme(this,a,this.cname)},draw:function(){var a=this.pointToX,b=this.pointToY;this.deltaSignX=this.deltaSignY=1;var c=this.chart;AmCharts.VML&&(this.fadeOutDuration=0);this.xAnim&&c.stopAnim(this.xAnim);this.yAnim&&c.stopAnim(this.yAnim);if(!isNaN(a)){var d=this.follow,e=c.container,f=this.set;AmCharts.remove(f);this.removeDiv();f=e.set();f.node.style.pointerEvents= -"none";this.set=f;c.balloonsSet.push(f);if(this.show){var g=this.l,h=this.t,k=this.r,l=this.b,m=this.balloonColor,n=this.fillColor,p=this.borderColor,q=n;void 0!=m&&(this.adjustBorderColor?q=p=m:n=m);var r=this.horizontalPadding,s=this.verticalPadding,v=this.pointerWidth,w=this.pointerOrientation,t=this.cornerRadius,u=c.fontFamily,y=this.fontSize;void 0==y&&(y=c.fontSize);var m=document.createElement("div"),E=m.style;E.pointerEvents="none";E.position="absolute";var A=this.minWidth,z="";isNaN(A)|| -(z="min-width:"+(A-2*r)+"px; ");m.innerHTML='
'+this.text+"
";c.chartDiv.appendChild(m);this.textDiv=m;y=m.offsetWidth;u=m.offsetHeight;m.clientHeight&&(y=m.clientWidth,u=m.clientHeight);u+=2*s;z=y+2*r;!isNaN(A)&&zu&&(v=u/2),y=b-u/2,a=l&&(y=l-u);yk&&(A=k-z);var h=y+s,l=A+r,s=this.shadowAlpha,I=this.shadowColor,r=this.borderThickness,F=this.bulletSize,H;0z-v&&(g=z-v),gu-v&&(q=u-v),qa?z:a-A,z,z,0,0,z]),0this.r-d.width&&(a=this.r-d.width);e1.1*q&&(w[K].gap=!0);this.processFields(b,F,H);F.category=t.category;F.serialDataItem=t;F.graph=b;t.axes[A].graphs[K]=F}p[K]=t.time;w[K]= -F}}this.chartData[s]=t}}for(c=0;cb?this.colors[b]:AmCharts.randomColor();a.lineColorR=c}a.fillColorsR=a.fillColors?a.fillColors:a.lineColorR;a.bulletBorderColorR=a.bulletBorderColor?a.bulletBorderColor:a.useLineColorForBulletBorder?a.lineColorR:a.bulletColor;a.bulletColorR=a.bulletColor?a.bulletColor:a.lineColorR;if(c= -this.patterns)a.pattern=c[b]},handleLegendEvent:function(a){var b=a.type;a=a.dataItem;if(!this.legend.data&&a){var c=a.hidden,d=a.showBalloon;switch(b){case "clickMarker":this.textClickEnabled&&(d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a));break;case "clickLabel":d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a);break;case "rollOverItem":c||this.highlightGraph(a);break;case "rollOutItem":c||this.unhighlightGraph();break;case "hideItem":this.hideGraph(a);break;case "showItem":this.showGraph(a)}}}, -highlightGraph:function(a){var b=this.graphs,c,d=.2;this.legend&&(d=this.legend.rollOverGraphAlpha);if(1!=d)for(c=0;cthis.hoverAlpha&&a.wedge&&a.wedge.attr({opacity:this.hoverAlpha});var d=a.balloonX,e=a.balloonY;a.pulled&&(d+=a.pullX,e+=a.pullY);var f=this.formatString(this.balloonText,a,!0),g=this.balloonFunction;g&&(f=g(a,f));g=AmCharts.adjustLuminosity(a.color, --.15);this.showBalloon(f,g,b,d,e);a={type:"rollOverSlice",dataItem:a,chart:this,event:c};this.fire(a.type,a)}},rollOutSlice:function(a,b){isNaN(a)||(a=this.chartData[a]);a.wedge&&a.wedge.attr({opacity:1});this.hideBalloon();var c={type:"rollOutSlice",dataItem:a,chart:this,event:b};this.fire(c.type,c)},clickSlice:function(a,b){isNaN(a)||(a=this.chartData[a]);a.pulled?this.pullSlice(a,0):this.pullSlice(a,1);AmCharts.getURL(a.url,this.urlTarget);var c={type:"clickSlice",dataItem:a,chart:this,event:b}; -this.fire(c.type,c)},handleRightClick:function(a,b){isNaN(a)||(a=this.chartData[a]);var c={type:"rightClickSlice",dataItem:a,chart:this,event:b};this.fire(c.type,c)},drawTicks:function(){var a=this.chartData,b;for(b=0;bb&&(b=e);d.remove()}return b}});AmCharts.AmRectangularChart=AmCharts.Class({inherits:AmCharts.AmCoordinateChart,construct:function(a){AmCharts.AmRectangularChart.base.construct.call(this,a);this.theme=a;this.createEvents("zoomed");this.marginRight=this.marginBottom=this.marginTop=this.marginLeft=20;this.verticalPosition=this.horizontalPosition=this.depth3D=this.angle=0;this.heightMultiplier=this.widthMultiplier=1;this.plotAreaFillColors="#FFFFFF";this.plotAreaFillAlphas=0;this.plotAreaBorderColor="#000000";this.plotAreaBorderAlpha= -0;this.zoomOutButtonImageSize=17;this.zoomOutButtonImage="lens.png";this.zoomOutText="Show all";this.zoomOutButtonColor="#e5e5e5";this.zoomOutButtonAlpha=0;this.zoomOutButtonRollOverAlpha=1;this.zoomOutButtonPadding=8;this.trendLines=[];this.autoMargins=!0;this.marginsUpdated=!1;this.autoMarginOffset=10;AmCharts.applyTheme(this,a,"AmRectangularChart")},initChart:function(){AmCharts.AmRectangularChart.base.initChart.call(this);this.updateDxy();var a=!0;!this.marginsUpdated&&this.autoMargins&&(this.resetMargins(), -a=!1);this.processScrollbars();this.updateMargins();this.updatePlotArea();this.updateScrollbars();this.updateTrendLines();this.updateChartCursor();this.updateValueAxes();a&&(this.scrollbarOnly||this.updateGraphs())},drawChart:function(){AmCharts.AmRectangularChart.base.drawChart.call(this);this.drawPlotArea();if(AmCharts.ifArray(this.chartData)){var a=this.chartCursor;a&&a.draw();a=this.zoomOutText;""!==a&&a&&this.drawZoomOutButton()}},resetMargins:function(){var a={},b;if("serial"==this.type){var c= -this.valueAxes;for(b=0;b=e-c&&(this.marginRight=Math.round(k-e+c));d.top&&hf-c&&(this.marginBottom=Math.round(this.marginBottom+b-f+c));this.initChart()},getAxisBounds:function(a,b,c,d,e){if(!a.ignoreAxisWidth){var f=a.labelsSet,g=a.tickLength;a.inside&&(g=0);if(f)switch(f=a.getBBox(),a.position){case "top":a=f.y; -d>a&&(d=a);break;case "bottom":a=f.y+f.height;ea&&(b=a)}}return{l:b,t:d,r:c,b:e}},drawZoomOutButton:function(){var a=this,b=a.container.set();a.zoomButtonSet.push(b);var c=a.color,d=a.fontSize,e=a.zoomOutButtonImageSize,f=a.zoomOutButtonImage,g=AmCharts.lang.zoomOutText||a.zoomOutText,h=a.zoomOutButtonColor,k=a.zoomOutButtonAlpha,l=a.zoomOutButtonFontSize,m=a.zoomOutButtonPadding;isNaN(l)||(d=l);(l=a.zoomOutButtonFontColor)&& -(c=l);var l=a.zoomOutButton,n;l&&(l.fontSize&&(d=l.fontSize),l.color&&(c=l.color),l.backgroundColor&&(h=l.backgroundColor),isNaN(l.backgroundAlpha)||(a.zoomOutButtonRollOverAlpha=l.backgroundAlpha));var p=l=0;void 0!==a.pathToImages&&f&&(n=a.container.image(a.pathToImages+f,0,0,e,e),b.push(n),n=n.getBBox(),l=n.width+5);void 0!==g&&(c=AmCharts.text(a.container,g,c,a.fontFamily,d,"start"),d=c.getBBox(),p=n?n.height/2-3:d.height/2,c.translate(l,p),b.push(c));n=b.getBBox();c=1;AmCharts.isModern||(c=0); -h=AmCharts.rect(a.container,n.width+2*m+5,n.height+2*m-2,h,1,1,h,c);h.setAttr("opacity",k);h.translate(-m,-m);b.push(h);h.toBack();a.zbBG=h;n=h.getBBox();b.translate(a.marginLeftReal+a.plotAreaWidth-n.width+m,a.marginTopReal+m);b.hide();b.mouseover(function(){a.rollOverZB()}).mouseout(function(){a.rollOutZB()}).click(function(){a.clickZB()}).touchstart(function(){a.rollOverZB()}).touchend(function(){a.rollOutZB();a.clickZB()});for(k=0;ka&&(a=1);1>b&&(b=1);this.plotAreaWidth=Math.round(a);this.plotAreaHeight=Math.round(b)},updateDxy:function(){this.dx=Math.round(this.depth3D*Math.cos(this.angle*Math.PI/180));this.dy=Math.round(-this.depth3D*Math.sin(this.angle*Math.PI/180));this.d3x= -Math.round(this.columnSpacing3D*Math.cos(this.angle*Math.PI/180));this.d3y=Math.round(-this.columnSpacing3D*Math.sin(this.angle*Math.PI/180))},updateMargins:function(){var a=this.getTitleHeight();this.titleHeight=a;this.marginTopReal=this.marginTop-this.dy+a;this.marginBottomReal=this.marginBottom;this.marginLeftReal=this.marginLeft;this.marginRightReal=this.marginRight},updateValueAxes:function(){var a=this.valueAxes,b=this.marginLeftReal,c=this.marginTopReal,d=this.plotAreaHeight,e=this.plotAreaWidth, -f;for(f=0;fb&&(b=Math.abs(b),q=-b);0>c&&(c=Math.abs(c),r=-c);q+=AmCharts.dx;r+=AmCharts.dy;e={fill:n,stroke:g,"fill-opacity":e,"stroke-opacity":h};void 0!==m&&0=s&&(e=s);var v=1/180*Math.PI,s=b+Math.sin(d*v)*h,w=c-Math.cos(d*v)*q,t=b+Math.sin(d*v)*f,u=c-Math.cos(d*v)*g,y=b+Math.sin((d+e)*v)*f,E=c-Math.cos((d+e)*v)*g,A=b+Math.sin((d+e)*v)*h,v=c-Math.cos((d+e)*v)*q,z={fill:AmCharts.adjustLuminosity(l.fill,-.2),"stroke-opacity":0,"fill-opacity":l["fill-opacity"]},K=0;180Math.abs(e)&&1>=Math.abs(y-t)&&1>=Math.abs(E-u)&&(I=!0));e="";var F;n&&(z["fill-opacity"]=0,z["stroke-opacity"]=l["stroke-opacity"]/2,z.stroke=l.stroke);0a.length&&(a=String(a[0])+String(a[0])+String(a[1])+String(a[1])+String(a[2])+String(a[2]));b=b||0;var c="#",d,e;for(e=0;3>e;e++)d=parseInt(a.substr(2*e,2),16),d=Math.round(Math.min(Math.max(0,d+d*b),255)).toString(16),c+=("00"+d).substr(d.length);return c};AmCharts.Bezier=AmCharts.Class({construct:function(a,b,c,d,e,f,g,h,k,l){"object"==typeof g&&(g=g[0]);"object"==typeof h&&(h=h[0]);f={fill:g,"fill-opacity":h,"stroke-width":f};void 0!==k&&0c&&(h=c);b.push({x:k.x-h/e,y:k.y-d/f});b.push({x:k.x,y:k.y});b.push({x:k.x+h/e,y:k.y+d/f})}d=a[a.length-1].y-a[a.length-2].y;c=a[a.length-1].x-a[a.length-2].x;b.push({x:a[a.length-1].x- -c/e,y:a[a.length-1].y-d/f});b.push({x:a[a.length-1].x,y:a[a.length-1].y});return b},drawBeziers:function(a){var b="",c;for(c=0;c<(a.length-1)/3;c++)b+=this.drawBezierMidpoint(a[3*c],a[3*c+1],a[3*c+2],a[3*c+3]);return b},drawBezierMidpoint:function(a,b,c,d){var e=Math.round,f=this.getPointOnSegment(a,b,.75),g=this.getPointOnSegment(d,c,.75),h=(d.x-a.x)/16,k=(d.y-a.y)/16,l=this.getPointOnSegment(a,b,.375);a=this.getPointOnSegment(f,g,.375);a.x-=h;a.y-=k;b=this.getPointOnSegment(g,f,.375);b.x+=h;b.y+= -k;c=this.getPointOnSegment(d,c,.375);h=this.getMiddle(l,a);f=this.getMiddle(f,g);g=this.getMiddle(b,c);l=" Q"+e(l.x)+","+e(l.y)+","+e(h.x)+","+e(h.y);l+=" Q"+e(a.x)+","+e(a.y)+","+e(f.x)+","+e(f.y);l+=" Q"+e(b.x)+","+e(b.y)+","+e(g.x)+","+e(g.y);return l+=" Q"+e(c.x)+","+e(c.y)+","+e(d.x)+","+e(d.y)},getMiddle:function(a,b){return{x:(a.x+b.x)/2,y:(a.y+b.y)/2}},getPointOnSegment:function(a,b,c){return{x:a.x+(b.x-a.x)*c,y:a.y+(b.y-a.y)*c}}});AmCharts.AmDraw=AmCharts.Class({construct:function(a,b,c,d){AmCharts.SVG_NS="http://www.w3.org/2000/svg";AmCharts.SVG_XLINK="http://www.w3.org/1999/xlink";AmCharts.hasSVG=!!document.createElementNS&&!!document.createElementNS(AmCharts.SVG_NS,"svg").createSVGRect;1>b&&(b=10);1>c&&(c=10);this.div=a;this.width=b;this.height=c;this.rBin=document.createElement("div");if(AmCharts.hasSVG){AmCharts.SVG=!0;var e=this.createSvgElement("svg");e.style.position="absolute";e.style.width=b+"px";e.style.height=c+ -"px";b=this.createSvgElement("desc");b.appendChild(document.createTextNode("JavaScript chart by amCharts "+d.version));e.appendChild(b);AmCharts.rtl&&(e.setAttribute("direction","rtl"),e.style.left="auto",e.style.right="0px");e.setAttribute("version","1.1");a.appendChild(e);this.container=e;this.R=new AmCharts.SVGRenderer(this)}else AmCharts.isIE&&AmCharts.VMLRenderer&&(AmCharts.VML=!0,AmCharts.vmlStyleSheet||(document.namespaces.add("amvml","urn:schemas-microsoft-com:vml"),31>document.styleSheets.length? -(e=document.createStyleSheet(),e.addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true"),AmCharts.vmlStyleSheet=e):document.styleSheets[0].addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true")),this.container=a,this.R=new AmCharts.VMLRenderer(this,d),this.R.disableSelection(a))},createSvgElement:function(a){return document.createElementNS(AmCharts.SVG_NS,a)},circle:function(a,b,c,d){var e=new AmCharts.AmDObject("circle",this);e.attr({r:c, -cx:a,cy:b});this.addToContainer(e.node,d);return e},setSize:function(a,b){0c&&(c=1);1>d&&(d=1);h.attr({x:a,y:b,width:c,height:d,rx:e,ry:e,"stroke-width":f});this.addToContainer(h.node,g);return h},image:function(a,b,c,d,e,f){var g=new AmCharts.AmDObject("image", -this);g.attr({x:b,y:c,width:d,height:e});this.R.path(g,a);this.addToContainer(g.node,f);return g},addToContainer:function(a,b){b||(b=this.container);b.appendChild(a)},text:function(a,b,c){return this.R.text(a,b,c)},path:function(a,b,c,d){var e=new AmCharts.AmDObject("path",this);d||(d="100,100");e.attr({cs:d});c?e.attr({dd:a}):e.attr({d:a});this.addToContainer(e.node,b);return e},set:function(a){return this.R.set(a)},remove:function(a){if(a){var b=this.rBin;b.appendChild(a);b.innerHTML=""}},renderFix:function(){var a= -this.container,b=a.style,c;try{c=a.getScreenCTM()||a.createSVGMatrix()}catch(d){c=a.createSVGMatrix()}a=1-c.e%1;c=1-c.f%1;.5c&&(g="dot"), -3<=c&&6>=c&&(g="dash"),6g&&(b+=g);0>h&&(c+=h)}return{x:b,y:c,width:d, -height:e}},setText:function(a,b){var c=a.node;c&&(c.innerHTML=b);this.setAttr(a,"text-anchor",a.anchor)},addListener:function(a,b,c){a.node["on"+b]=c},move:function(a,b,c){var d=a.node,e=d.style;"text"==a.type&&(c-=AmCharts.removePx(e.fontSize)/2-1);"oval"==a.shapeType&&(b-=AmCharts.removePx(e.width)/2,c-=AmCharts.removePx(e.height)/2);a=a.bw;isNaN(a)||(b-=a,c-=a);isNaN(b)||isNaN(c)||(d.style.left=b+"px",d.style.top=c+"px")},svgPathToVml:function(a){var b=a.split(" ");a="";var c,d=Math.round,e;for(e= -0;ethis.fontSize&&(this.ly=e/2-1);0p&&(p=u);w=w.height;w>q&&(q=w)}var u=q=0,y=f,E=0,A=0;for(t=0;tA&&(A=w.height);K+w.width>n&&0=k&& -(u=0,q++,E=E+A+l,A=0);r.push(z)}w=r.getBBox();k=w.height+2*l-1;"left"==a||"right"==a?(h=w.width+2*f,g.style.width=h+b+c+"px"):h=h-b-c-1;c=AmCharts.polygon(this.container,[0,h,h,0],[0,0,k,k],this.backgroundColor,this.backgroundAlpha,1,this.borderColor,this.borderAlpha);s.push(c);s.translate(b,d);c.toBack();b=f;if("top"==a||"bottom"==a||"absolute"==a||"outside"==a)"center"==this.align?b=f+(h-w.width)/2:"right"==this.align&&(b=f+h-w.width);r.translate(b,l+1);this.titleHeight>k&&(k=this.titleHeight); -a=k+d+e+1;0>a&&(a=0);g.style.height=Math.round(a)+"px"},createEntry:function(a){if(!1!==a.visibleInLegend){var b=this.chart,c=a.markerType;c||(c=this.markerType);var d=a.color,e=a.alpha;a.legendKeyColor&&(d=a.legendKeyColor());a.legendKeyAlpha&&(e=a.legendKeyAlpha());var f;!0===a.hidden&&(f=d=this.markerDisabledColor);var g=a.pattern,h=a.customMarker;h||(h=this.customMarker);var k=this.container,l=this.markerSize,m=0,n=0,p=l/2;if(this.useGraphSettings)if(m=a.type,this.switchType=void 0,"line"==m|| -"step"==m||"smoothedLine"==m||"ohlc"==m)g=k.set(),a.hidden||(d=a.lineColorR,f=a.bulletBorderColorR),n=AmCharts.line(k,[0,2*l],[l/2,l/2],d,a.lineAlpha,a.lineThickness,a.dashLength),g.push(n),a.bullet&&(a.hidden||(d=a.bulletColorR),n=AmCharts.bullet(k,a.bullet,a.bulletSize,d,a.bulletAlpha,a.bulletBorderThickness,f,a.bulletBorderAlpha))&&(n.translate(l+1,l/2),g.push(n)),p=0,m=l,n=l/3;else{var q;a.getGradRotation&&(q=a.getGradRotation());m=a.fillColorsR;!0===a.hidden&&(m=d);if(g=this.createMarker("rectangle", -m,a.fillAlphas,a.lineThickness,d,a.lineAlpha,q,g))p=l,g.translate(p,l/2);m=l}else h?(b.path&&(h=b.path+h),g=k.image(h,0,0,l,l)):(g=this.createMarker(c,d,e,void 0,void 0,void 0,void 0,g))&&g.translate(l/2,l/2);this.addListeners(g,a);k=k.set([g]);this.switchable&&a.switchable&&k.setAttr("cursor","pointer");(f=this.switchType)&&"none"!=f&&("x"==f?(q=this.createX(),q.translate(l/2,l/2)):q=this.createV(),q.dItem=a,!0!==a.hidden?"x"==f?q.hide():q.show():"x"!=f&&q.hide(),this.switchable||q.hide(),this.addListeners(q, -a),a.legendSwitch=q,k.push(q));f=this.color;a.showBalloon&&this.textClickEnabled&&void 0!==this.selectedColor&&(f=this.selectedColor);this.useMarkerColorForLabels&&(f=d);!0===a.hidden&&(f=this.markerDisabledColor);d=AmCharts.massReplace(this.labelText,{"[[title]]":a.title});q=this.fontSize;g&&l<=q&&g.translate(p,l/2+this.ly-q/2+(q+2-l)/2-n);var r;d&&(d=AmCharts.fixBrakes(d),a.legendTextReal=d,r=this.labelWidth,r=isNaN(r)?AmCharts.text(this.container,d,f,b.fontFamily,q,"start"):AmCharts.wrappedText(this.container, -d,f,b.fontFamily,q,"start",!1,r,0),r.translate(this.lx+m,this.ly),k.push(r),b=r.getBBox().width,this.maxLabelWidthc&&(d="00"+c);10<=c&&100>c&&(d="0"+c);a=a.replace(/fff/g,d)}return a};AmCharts.extractPeriod=function(a){var b=AmCharts.stripNumbers(a),c=1;b!=a&&(c=Number(a.slice(0,a.indexOf(b))));return{period:b,count:c}}; -AmCharts.newDate=function(a,b){return date="fff"==b?AmCharts.useUTC?new Date(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate(),a.getUTCHours(),a.getUTCMinutes(),a.getUTCSeconds(),a.getUTCMilliseconds()):new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes(),a.getSeconds(),a.getMilliseconds()):new Date(a)}; -AmCharts.resetDateToMin=function(a,b,c,d){void 0===d&&(d=1);var e,f,g,h,k,l,m;AmCharts.useUTC?(e=a.getUTCFullYear(),f=a.getUTCMonth(),g=a.getUTCDate(),h=a.getUTCHours(),k=a.getUTCMinutes(),l=a.getUTCSeconds(),m=a.getUTCMilliseconds(),a=a.getUTCDay()):(e=a.getFullYear(),f=a.getMonth(),g=a.getDate(),h=a.getHours(),k=a.getMinutes(),l=a.getSeconds(),m=a.getMilliseconds(),a=a.getDay());switch(b){case "YYYY":e=Math.floor(e/c)*c;f=0;g=1;m=l=k=h=0;break;case "MM":f=Math.floor(f/c)*c;g=1;m=l=k=h=0;break;case "WW":0=== -a&&0=c[b].contains?(a=Math.round(a/c[b].contains),b=c[b].nextInterval,AmCharts.getMaxInterval(a,b)):"ss"==b?c[b].nextInterval:b};AmCharts.dayNames="Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" ");AmCharts.shortDayNames="Sun Mon Tue Wed Thu Fri Sat".split(" ");AmCharts.monthNames="January February March April May June July August September October November December".split(" ");AmCharts.shortMonthNames="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "); -AmCharts.getWeekNumber=function(a){a=new Date(a);a.setHours(0,0,0);a.setDate(a.getDate()+4-(a.getDay()||7));var b=new Date(a.getFullYear(),0,1);return Math.ceil(((a-b)/864E5+1)/7)}; -AmCharts.stringToDate=function(a,b){var c={},d=[{pattern:"YYYY",period:"year"},{pattern:"YY",period:"year"},{pattern:"MM",period:"month"},{pattern:"M",period:"month"},{pattern:"DD",period:"date"},{pattern:"D",period:"date"},{pattern:"JJ",period:"hours"},{pattern:"J",period:"hours"},{pattern:"HH",period:"hours"},{pattern:"H",period:"hours"},{pattern:"KK",period:"hours"},{pattern:"K",period:"hours"},{pattern:"LL",period:"hours"},{pattern:"L",period:"hours"},{pattern:"NN",period:"minutes"},{pattern:"N", -period:"minutes"},{pattern:"SS",period:"seconds"},{pattern:"S",period:"seconds"},{pattern:"QQQ",period:"milliseconds"},{pattern:"QQ",period:"milliseconds"},{pattern:"Q",period:"milliseconds"}],e=!0,f=b.indexOf("AA");-1!=f&&(a.substr(f,2),"pm"==a.toLowerCase&&(e=!1));var f=b,g,h,k;for(k=0;kd&&(p="0"+p);var q="0"+f;b=b.replace(/W/g,m);m=g;24==m&&(m=0);var r=m;10>r&&(r= -"0"+r);b=b.replace(/JJ/g,r);b=b.replace(/J/g,m);r=g;0===r&&(r=24,-1!=b.indexOf("H")&&e--);m=e;10>e&&(m="0"+e);var s=r;10>s&&(s="0"+s);b=b.replace(/HH/g,s);b=b.replace(/H/g,r);r=g;11s&&(s="0"+s);b=b.replace(/KK/g,s);b=b.replace(/K/g,r);r=g;0===r&&(r=12);12s&&(s="0"+s);b=b.replace(/LL/g,s);b=b.replace(/L/g,r);r=h;10>r&&(r="0"+r);b=b.replace(/NN/g,r);b=b.replace(/N/g,h);h=k;10>h&&(h="0"+h);b=b.replace(/SS/g,h);b=b.replace(/S/g,k);k=l;10>k&&(k="00"+k);100>k&&(k="0"+ -k);h=l;10>h&&(h="00"+h);b=b.replace(/QQQ/g,k);b=b.replace(/QQ/g,h);b=b.replace(/Q/g,l);b=12>g?b.replace(/A/g,"am"):b.replace(/A/g,"pm");b=b.replace(/YYYY/g,"@IIII@");b=b.replace(/YY/g,"@II@");b=b.replace(/MMMM/g,"@XXXX@");b=b.replace(/MMM/g,"@XXX@");b=b.replace(/MM/g,"@XX@");b=b.replace(/M/g,"@X@");b=b.replace(/DD/g,"@RR@");b=b.replace(/D/g,"@R@");b=b.replace(/EEEE/g,"@PPPP@");b=b.replace(/EEE/g,"@PPP@");b=b.replace(/EE/g,"@PP@");b=b.replace(/E/g,"@P@");b=b.replace(/@IIII@/g,c);b=b.replace(/@II@/g, -n);b=b.replace(/@XXXX@/g,AmCharts.monthNames[d]);b=b.replace(/@XXX@/g,AmCharts.shortMonthNames[d]);b=b.replace(/@XX@/g,p);b=b.replace(/@X@/g,d+1);b=b.replace(/@RR@/g,m);b=b.replace(/@R@/g,e);b=b.replace(/@PPPP@/g,AmCharts.dayNames[f]);b=b.replace(/@PPP@/g,AmCharts.shortDayNames[f]);b=b.replace(/@PP@/g,q);return b=b.replace(/@P@/g,f)}; -AmCharts.changeDate=function(a,b,c,d,e){var f=-1;void 0===d&&(d=!0);void 0===e&&(e=!1);!0===d&&(f=1);switch(b){case "YYYY":a.setFullYear(a.getFullYear()+c*f);d||e||a.setDate(a.getDate()+1);break;case "MM":b=a.getMonth();a.setMonth(a.getMonth()+c*f);a.getMonth()>b+c*f&&a.setDate(a.getDate()-1);d||e||a.setDate(a.getDate()+1);break;case "DD":a.setDate(a.getDate()+c*f);break;case "WW":a.setDate(a.getDate()+c*f*7);break;case "hh":a.setHours(a.getHours()+c*f);break;case "mm":a.setMinutes(a.getMinutes()+ +if(!AmCharts)var AmCharts={themes:{},maps:{},inheriting:{},charts:[],onReadyArray:[],useUTC:!1,updateRate:40,uid:0,lang:{},translations:{},mapTranslations:{}}; +AmCharts.Class=function(a){var b=function(){arguments[0]!==AmCharts.inheriting&&(this.events={},this.construct.apply(this,arguments))};a.inherits?(b.prototype=new a.inherits(AmCharts.inheriting),b.base=a.inherits.prototype,delete a.inherits):(b.prototype.createEvents=function(){for(var a=0,b=arguments.length;aAmCharts.IEversion&&0");if(10h){l.remove();for(var l=[],p=0;-1<(index=b.indexOf(" ",p));)l.push(index),p=index+1;for(var q=Math.round(b.length/2),r=1E3,s,p=0;pc&&(a=c);return a};AmCharts.isDefined=function(a){return void 0===a?!1:!0};AmCharts.stripNumbers=function(a){return a.replace(/[0-9]+/g,"")};AmCharts.roundTo=function(a,b){if(0>b)return a;var c=Math.pow(10,b);return Math.round(a*c)/c}; +AmCharts.toFixed=function(a,b){var c=String(Math.round(a*Math.pow(10,b)));if(0=g[b].contains){var k=a-Math.floor(a/g[b].contains)*g[b].contains;"ss"==b&&(k=AmCharts.formatNumber(k,f),1==k.split(h)[0].length&&(k="0"+k));("mm"==b||"hh"==b)&&10>k&&(k="0"+k);c=k+""+d[b]+""+c;a=Math.floor(a/g[b].contains);b=g[b].nextInterval;return AmCharts.formatDuration(a,b,c,d,e,f)}"ss"==b&&(a=AmCharts.formatNumber(a,f),1==a.split(h)[0].length&&(a="0"+a));("mm"==b||"hh"==b)&&10>a&&(a="0"+a);c=a+""+ +d[b]+""+c;if(g[e].count>g[b].count)for(a=g[b].count;aa?"-":"";a=Math.abs(a);var h=String(a),k=!1;-1!=h.indexOf("e")&&(k=!0);0<=c&&!k&&(h=AmCharts.toFixed(a,c));var l="";if(k)l=h;else{var h=h.split("."),k=String(h[0]),m;for(m=k.length;0<=m;m-=3)l=m!=k.length?0!==m?k.substring(m-3,m)+b+l:k.substring(m-3,m)+l:k.substring(m-3,m);void 0!==h[1]&&(l=l+f+h[1]);void 0!==c&&0=c.x-5&&a<=c.x+c.width+5&&b>=c.y-5&&b<=c.y+c.height+5?!0:!1};AmCharts.isPercents=function(a){if(-1!=String(a).indexOf("%"))return!0}; +AmCharts.findPosX=function(a){var b=a,c=a.offsetLeft;if(a.offsetParent){for(;a=a.offsetParent;)c+=a.offsetLeft;for(;(b=b.parentNode)&&b!=document.body;)c-=b.scrollLeft||0}return c};AmCharts.findPosY=function(a){var b=a,c=a.offsetTop;if(a.offsetParent){for(;a=a.offsetParent;)c+=a.offsetTop;for(;(b=b.parentNode)&&b!=document.body;)c-=b.scrollTop||0}return c};AmCharts.findIfFixed=function(a){if(a.offsetParent)for(;a=a.offsetParent;)if("fixed"==AmCharts.getStyle(a,"position"))return!0;return!1}; +AmCharts.findIfAuto=function(a){return a.style&&"auto"==AmCharts.getStyle(a,"overflow")?!0:a.parentNode?AmCharts.findIfAuto(a.parentNode):!1};AmCharts.findScrollLeft=function(a,b){a.scrollLeft&&(b+=a.scrollLeft);return a.parentNode?AmCharts.findScrollLeft(a.parentNode,b):b};AmCharts.findScrollTop=function(a,b){a.scrollTop&&(b+=a.scrollTop);return a.parentNode?AmCharts.findScrollTop(a.parentNode,b):b}; +AmCharts.formatValue=function(a,b,c,d,e,f,g,h){if(b){void 0===e&&(e="");var k;for(k=0;ka&&(g="-");a=Math.abs(a);if(1=b[h].number&&(k=a/b[h].number,l=Number(d.precision),1>l&&(l=1),c=AmCharts.roundTo(k,l),l=AmCharts.formatNumber(c,{precision:-1,decimalSeparator:d.decimalSeparator,thousandsSeparator:d.thousandsSeparator}),!e||k==c)){f=g+""+l+""+b[h].prefix;break}}else for(h=0;h"==a&&(a="easeOutSine");"<"==a&&(a="easeInSine");"elastic"==a&&(a="easeOutElastic");return a}; +AmCharts.getObjById=function(a,b){var c,d;for(d=0;d"));return a};AmCharts.fixBrakes=function(a){if(AmCharts.isModern){var b=RegExp("
","g");a&&(a=a.replace(b,"\n"))}else a=AmCharts.fixNewLines(a);return a}; +AmCharts.deleteObject=function(a,b){if(a){if(void 0===b||null===b)b=20;if(0!==b)if("[object Array]"===Object.prototype.toString.call(a))for(var c=0;ca&&(a=3)):a=this.width/this.minHorizontalGap, +this.gridCountR=Math.max(a,1)):this.gridCountR=this.gridCount;this.axisWidth=this.axisLine.axisWidth;this.addTitle()},setOrientation:function(a){this.orientation=a?"H":"V"},addTitle:function(){var a=this.title;if(a){var b=this.chart,c=this.titleColor;void 0===c&&(c=b.color);var d=this.titleFontSize;isNaN(d)&&(d=b.fontSize+1);this.titleLabel=AmCharts.text(b.container,a,c,b.fontFamily,d,this.titleAlign,this.titleBold)}},positionTitle:function(){var a=this.titleLabel;if(a){var b,c,d=this.labelsSet,e= +{};0=this.gridCountR&&(this.gridCountR=1);this.totals=[];this.data=this.chart.chartData;var a=this.chart;"xy"!=a.type&&(this.stackGraphs("smoothedLine"),this.stackGraphs("line"),this.stackGraphs("column"),this.stackGraphs("step"));this.recalculateToPercents&&this.recalculate();this.synchronizationMultiplier&& +this.synchronizeWith?(AmCharts.isString(this.synchronizeWith)&&(this.synchronizeWith=a.getValueAxisById(this.synchronizeWith)),this.synchronizeWith&&(this.synchronizeWithAxis(this.synchronizeWith),this.foundGraphs=!0)):(this.foundGraphs=!1,this.getMinMax())},draw:function(){AmCharts.ValueAxis.base.draw.call(this);var a=this.chart,b=this.set;"duration"==this.type&&(this.duration="ss");!0===this.dataChanged&&(this.updateData(),this.dataChanged=!1);if(this.logarithmic&&(0>=this.getMin(0,this.data.length- +1)||0>=this.minimum))this.fire("logarithmicAxisFailed",{type:"logarithmicAxisFailed",chart:a});else{this.grid0=null;var c,d,e=a.dx,f=a.dy,g=!1,h=this.logarithmic;if(isNaN(this.min)||isNaN(this.max)||!this.foundGraphs||Infinity==this.min||-Infinity==this.max)g=!0;else{var k=this.labelFrequency,l=this.showFirstLabel,m=this.showLastLabel,n=1,p=0,q=Math.round((this.max-this.min)/this.step)+1,r;!0===h?(r=Math.log(this.max)*Math.LOG10E-Math.log(this.minReal)*Math.LOG10E,this.stepWidth=this.axisWidth/r, +r>this.logGridLimit&&(q=Math.ceil(Math.log(this.max)*Math.LOG10E)+1,p=Math.round(Math.log(this.minReal)*Math.LOG10E),q>this.gridCountR&&(n=Math.ceil(q/this.gridCountR)))):this.stepWidth=this.axisWidth/(this.max-this.min);var s=0;1>this.step&&-1this.maxDecCount&&(s=this.maxDecCount);var v=this.precision;isNaN(v)||(s=v);this.max=AmCharts.roundTo(this.max,this.maxDecCount);this.min=AmCharts.roundTo(this.min,this.maxDecCount); +var w={};w.precision=s;w.decimalSeparator=a.nf.decimalSeparator;w.thousandsSeparator=a.nf.thousandsSeparator;this.numberFormatter=w;var t,u=this.guides,y=u.length;if(05*this.min&&(p-=this.min),p=AmCharts.roundTo(p,this.maxDecCount+1),!this.integersOnly||Math.round(p)==p)if(isNaN(v)||Number(AmCharts.toFixed(p,v))==p){!0===h&&(0===p&&(p=this.minReal),r>this.logGridLimit&&(p=Math.pow(10,d)),u=-1!=String(p).indexOf("e")?!0:!1);this.useScientificNotation&&(u=!0);this.usePrefixes&&(u=!1);u?(t=-1==String(p).indexOf("e")?p.toExponential(15):String(p),c=t.split("e"),t=Number(c[0]),c=Number(c[1]),t=AmCharts.roundTo(t,14),10==t&&(t=1,c+= +1),t=t+"e"+c,0===p&&(t="0"),1==p&&(t="1")):(h&&(t=String(p).split("."),t[1]?(w.precision=t[1].length,0>d&&(w.precision=Math.abs(d))):w.precision=-1),t=this.usePrefixes?AmCharts.addPrefix(p,a.prefixesOfBigNumbers,a.prefixesOfSmallNumbers,w,!0):AmCharts.formatNumber(p,w,w.precision));this.duration&&(t=AmCharts.formatDuration(p,this.duration,"",this.durationUnits,this.maxInterval,w));this.recalculateToPercents?t+="%":(c=this.unit)&&(t="left"==this.unitPosition?c+t:t+c);Math.round(d/k)!=d/k&&(t=void 0); +if(0===d&&!l||d==q-1&&!m)t=" ";c=this.getCoordinate(p);this.labelFunction&&(t=this.labelFunction(p,t,this).toString());t=new this.axisItemRenderer(this,c,t,void 0,void 0,void 0,void 0,this.boldLabels);this.pushAxisItem(t);if(p==this.baseValue&&"radar"!=a.type){var F,H,z=this.viW,A=this.viH;t=this.viX;E=this.viY;"H"==this.orientation?0<=c&&c<=z+1&&(F=[c,c,c+e],H=[A,0,f]):0<=c&&c<=A+1&&(F=[0,z,z+e],H=[c,c,c+f]);F&&(c=AmCharts.fitToBounds(2*this.gridAlpha,0,1),c=AmCharts.line(a.container,F,H,this.gridColor, +c,1,this.dashLength),c.translate(t,E),this.grid0=c,a.axesSet.push(c),c.toBack())}if(!isNaN(I)&&0this.baseValue&&this.max>this.baseValue&&(d=this.min);this.minb&&c.shift();for(var d=Math.floor(Math.log(Math.abs(a))* +Math.LOG10E),e=0;ea){if(g=Math.pow(10,-g)*f,g==Math.round(g))return f}else if(f==Math.round(f))return f}},stackGraphs:function(a){var b=this.stackType;"stacked"==b&&(b="regular");"line"==b&&(b="none");"100% stacked"==b&&(b="100%");this.stackType=b;var c=[],d=[],e=[],f=[],g,h=this.chart.graphs,k,l,m,n,p=this.baseValue,q=!1;if("line"==a||"step"==a||"smoothedLine"==a)q=!0;if(q&&("regular"==b||"100%"== +b))for(n=0;ng?(l.values.close=g,isNaN(d[k])?l.values.open=p:(l.values.close+=d[k],l.values.open=d[k]),d[k]=l.values.close):(l.values.close=g,isNaN(e[k])?l.values.open= +p:(l.values.close+=e[k],l.values.open=e[k]),e[k]=l.values.close)))}}for(k=this.start;k<=this.end;k++)for(n=0;nc?(l.values.close=AmCharts.fitToBounds(c+d[k], +-100,100),l.values.open=d[k],d[k]=l.values.close):(l.values.close=AmCharts.fitToBounds(c+e[k],-100,100),l.values.open=e[k],e[k]=l.values.close)))))},recalculate:function(){var a=this.chart,b=a.graphs,c;for(c=0;cn&&g++}if(l=a.recalculateFromDate)a.dataDateFormat&&(l=AmCharts.stringToDate(l,a.dataDateFormat)),g=a.getClosestIndex(a.chartData,"time",l.getTime(),!0,0,a.chartData.length),h=a.chartData.length-1;for(l=g;l<=h&&(g=this.data[l].axes[this.id].graphs[d.id],f=g.values[e],isNaN(f));l++);this.recBaseValue=f;for(e=k;e<= +h;e++){g=this.data[e].axes[this.id].graphs[d.id];g.percents={};var k=g.values,p;for(p in k)g.percents[p]="percents"!=p?k[p]/f*100-100:k[p]}}}},getMinMax:function(){var a=!1,b=this.chart,c=b.graphs,d;for(d=0;dthis.max&&(this.max=c.toValue),c.value>this.max&&(this.max=c.value);isNaN(this.minimum)||(this.min=this.minimum);isNaN(this.maximum)||(this.max=this.maximum);this.min>this.max&&(a=this.max,this.max=this.min,this.min= +a);isNaN(this.minTemp)||(this.min=this.minTemp);isNaN(this.maxTemp)||(this.max=this.maxTemp);this.minReal=this.min;this.maxReal=this.max;0===this.min&&0===this.max&&(this.max=9);this.min>this.max&&(this.min=this.max-1);a=this.min;b=this.max;c=this.max-this.min;d=0===c?Math.pow(10,Math.floor(Math.log(Math.abs(this.max))*Math.LOG10E))/10:Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;isNaN(this.maximum)&&isNaN(this.maxTemp)&&(this.max=Math.ceil(this.max/d)*d+d);isNaN(this.minimum)&&isNaN(this.minTemp)&& +(this.min=Math.floor(this.min/d)*d-d);0>this.min&&0<=a&&(this.min=0);0=b&&(this.max=0);"100%"==this.stackType&&(this.min=0>this.min?-100:0,this.max=0>this.max?0:100);c=this.max-this.min;d=Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;this.step=Math.ceil(c/this.gridCountR/d)*d;c=Math.pow(10,Math.floor(Math.log(Math.abs(this.step))*Math.LOG10E));c=this.fixStepE(c);d=Math.ceil(this.step/c);5=d&&2c?(this.maxDecCount= +Math.abs(Math.log(Math.abs(c))*Math.LOG10E),this.maxDecCount=Math.round(this.maxDecCount),this.step=AmCharts.roundTo(this.step,this.maxDecCount+1)):this.maxDecCount=0;this.min=this.step*Math.floor(this.min/this.step);this.max=this.step*Math.ceil(this.max/this.step);0>this.min&&0<=a&&(this.min=0);0=b&&(this.max=0);1b?Math.abs(b)-1:Math.abs(b);var e;for(e=0;eb?Number("0."+c+String(a)):Number(String(a)+c)},getMin:function(a,b){var c,d;for(d=a;d<=b;d++){var e=this.data[d].axes[this.id].graphs,f;for(f in e)if(e.hasOwnProperty(f)){var g=this.chart.getGraphById(f);if(g.includeInMinMax&& +(!g.hidden||this.includeHidden)){isNaN(c)&&(c=Infinity);this.foundGraphs=!0;g=e[f].values;this.recalculateToPercents&&(g=e[f].percents);var h;if(this.minMaxField)h=g[this.minMaxField],ha&&(a=f);else for(var g in e)e.hasOwnProperty(g)&&"percents"!=g&&"total"!=g&&(f=e[g],f>a&&(a=f))}}}return a},dispatchZoomEvent:function(a,b){var c={type:"axisZoomed",startValue:a,endValue:b,target:this,chart:this.chart};this.fire(c.type,c)},zoomToValues:function(a,b){if(bthis.max&&(b=this.max);c={type:"axisSelfZoomed"}; +c.chart=this.chart;c.valueAxis=this;c.multiplier=this.axisWidth/Math.abs(this.getCoordinate(b)-this.getCoordinate(a));c.position="V"==this.orientation?this.reversed?this.getCoordinate(a):this.getCoordinate(b):this.reversed?this.getCoordinate(b):this.getCoordinate(a);this.fire(c.type,c)},coordinateToValue:function(a){if(isNaN(a))return NaN;var b=this.axisWidth,c=this.stepWidth,d=this.reversed,e=this.rotate,f=this.min,g=this.minReal;return!0===this.logarithmic?Math.pow(10,(e?!0===d?(b-a)/c:a/c:!0=== +d?a/c:(b-a)/c)+Math.log(g)*Math.LOG10E):!0===d?e?f-(a-b)/c:a/c+f:e?a/c+f:f-(a-b)/c},getCoordinate:function(a){if(isNaN(a))return NaN;var b=this.rotate,c=this.reversed,d=this.axisWidth,e=this.stepWidth,f=this.min,g=this.minReal;!0===this.logarithmic?(a=Math.log(a)*Math.LOG10E-Math.log(g)*Math.LOG10E,b=b?!0===c?d-e*a:e*a:!0===c?e*a:d-e*a):b=!0===c?b?d-e*(a-f):e*(a-f):b?e*(a-f):d-e*(a-f);b=this.rotate?b+(this.x-this.viX):b+(this.y-this.viY);1E7m?(B=V+ca*Math.sin(Y)-u-3+2,G+=-ca*Math.cos(Y)-ja*Math.sin(Y)-4):B-=u+p+3+3,B-=ha):(0m?(B=V+u+3-ca/2*Math.sin(Y)+2,G+=ca/2*Math.cos(Y)):B+=u+v+3+3,B+=ha)):(B+=$+p/2-Z,G+=ba,L?(0X+2||0>f))x.remove(),x=null}else{0<=b&&b<=V+1&&(0V+1||Bc&&"object"==typeof d&&(d=d.join(",").split(",").reverse());"V"==g?(a=AmCharts.rect(k,a.width,c,d,l),a.translate(e,b-h+f)):(a=AmCharts.rect(k, +c,a.height,d,l),a.translate(b-h+e,f));this.set=k.set([a])},graphics:function(){return this.set},getLabel:function(){}});AmCharts.AmChart=AmCharts.Class({construct:function(a){this.theme=a;this.version="3.10.0C";AmCharts.addChart(this);this.createEvents("dataUpdated","init","rendered","drawn");this.height=this.width="100%";this.dataChanged=!0;this.chartCreated=!1;this.previousWidth=this.previousHeight=0;this.backgroundColor="#FFFFFF";this.borderAlpha=this.backgroundAlpha=0;this.color=this.borderColor="#000000";this.fontFamily="Verdana";this.fontSize=11;this.usePrefixes=!1;this.precision=-1;this.percentPrecision=2;this.decimalSeparator= +".";this.thousandsSeparator=",";this.labels=[];this.allLabels=[];this.titles=[];this.marginRight=this.marginLeft=this.autoMarginOffset=0;this.timeOuts=[];this.creditsPosition="top-left";var b=document.createElement("div"),c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.chartDiv=b;b=document.createElement("div");c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.legendDiv=b;this.titleHeight=0;this.hideBalloonTime=150;this.handDrawScatter=2;this.handDrawThickness= +1;this.prefixesOfBigNumbers=[{number:1E3,prefix:"k"},{number:1E6,prefix:"M"},{number:1E9,prefix:"G"},{number:1E12,prefix:"T"},{number:1E15,prefix:"P"},{number:1E18,prefix:"E"},{number:1E21,prefix:"Z"},{number:1E24,prefix:"Y"}];this.prefixesOfSmallNumbers=[{number:1E-24,prefix:"y"},{number:1E-21,prefix:"z"},{number:1E-18,prefix:"a"},{number:1E-15,prefix:"f"},{number:1E-12,prefix:"p"},{number:1E-9,prefix:"n"},{number:1E-6,prefix:"\u03bc"},{number:.001,prefix:"m"}];this.panEventsEnabled=!0;AmCharts.bezierX= +3;AmCharts.bezierY=6;this.product="amcharts";this.animations=[];this.balloon=new AmCharts.AmBalloon(this.theme);this.balloon.chart=this;AmCharts.applyTheme(this,a,"AmChart")},drawChart:function(){this.drawBackground();this.redrawLabels();this.drawTitles();this.brr()},drawBackground:function(){AmCharts.remove(this.background);var a=this.container,b=this.backgroundColor,c=this.backgroundAlpha,d=this.set;AmCharts.isModern||0!==c||(c=.001);var e=this.updateWidth();this.realWidth=e;var f=this.updateHeight(); +this.realHeight=f;this.background=b=AmCharts.polygon(a,[0,e-1,e-1,0],[0,0,f-1,f-1],b,c,1,this.borderColor,this.borderAlpha);d.push(b);if(b=this.backgroundImage)this.path&&(b=this.path+b),this.bgImg=a=a.image(b,0,0,e,f),d.push(a)},drawTitles:function(){var a=this.titles;if(AmCharts.ifArray(a)){var b=20,c;for(c=0;ca||isNaN(a))a=0;this.chartDiv.style.height=a+"px"}}return a},updateWidth:function(){var a=this.divRealWidth,b=this.divRealHeight,c=this.legend;if(c){var d=this.legendDiv, +e=d.offsetWidth;isNaN(c.width)||(e=c.width);var f=d.offsetHeight,d=d.style,g=this.chartDiv.style,c=c.position;if("right"==c||"left"==c){a-=e;if(0>a||isNaN(a))a=0;g.width=a+"px";"left"==c?g.left=e+"px":d.left=a+"px";d.top=(b-f)/2+"px"}}return a},getTitleHeight:function(){var a=0,b=this.titles;if(0a.valueAxis.minMaxMultiplier&&a.positiveClip(a.set));break;case "radar":a.createRadarGraph();break;case "xy":a.createXYGraph(),a.positiveClip(a.set)}a.playedTO=setTimeout(function(){a.setAnimationPlayed.call(a)},500*a.chart.startDuration)}},setAnimationPlayed:function(){this.animationPlayed= +!0},createXYGraph:function(){var a=[],b=[],c=this.xAxis,d=this.yAxis;this.pmh=d.viH+1;this.pmw=c.viW+1;this.pmy=this.pmx=0;var e;for(e=this.start;e<=this.end;e++){var f=this.data[e].axes[c.id].graphs[this.id],g=f.values,h=g.x,k=g.y,g=c.getCoordinate(h),l=d.getCoordinate(k);!isNaN(h)&&!isNaN(k)&&(a.push(g),b.push(l),(h=this.createBullet(f,g,l,e))||(h=0),k=this.labelText)&&(f=this.createLabel(f,g,l,k),this.allBullets.push(f),this.positionLabel(g,l,f,this.labelPosition,h))}this.drawLineGraph(a,b);this.launchAnimation()}, +createRadarGraph:function(){var a=this.valueAxis.stackType,b=[],c=[],d,e,f;for(f=this.start;f<=this.end;f++){var g=this.data[f].axes[this.valueAxis.id].graphs[this.id],h;h="none"==a||"3d"==a?g.values.value:g.values.close;if(isNaN(h))this.drawLineGraph(b,c),b=[],c=[];else{var k=this.y-(this.valueAxis.getCoordinate(h)-this.height),l=180-360/(this.end-this.start+1)*f;h=k*Math.sin(l/180*Math.PI);k*=Math.cos(l/180*Math.PI);b.push(h);c.push(k);(l=this.createBullet(g,h,k,f))||(l=0);var m=this.labelText; +m&&(g=this.createLabel(g,h,k,m),this.allBullets.push(g),this.positionLabel(h,k,g,this.labelPosition,l));isNaN(d)&&(d=h);isNaN(e)&&(e=k)}}b.push(d);c.push(e);this.drawLineGraph(b,c);this.launchAnimation()},positionLabel:function(a,b,c,d,e){var f=c.getBBox();switch(d){case "left":a-=(f.width+e)/2+2;break;case "top":b-=(e+f.height)/2+1;break;case "right":a+=(f.width+e)/2+2;break;case "bottom":b+=(e+f.height)/2+1}c.translate(a,b)},getGradRotation:function(){var a=270;"horizontal"==this.gradientOrientation&& +(a=0);return this.gradientRotation=a},createSerialGraph:function(){this.dashLengthSwitched=this.fillColorsSwitched=this.lineColorSwitched=void 0;var a=this.chart,b=this.id,c=this.index,d=this.data,e=this.chart.container,f=this.valueAxis,g=this.type,h=this.columnWidthReal,k=this.showBulletsAt;isNaN(this.columnWidth)||(h=this.columnWidth);isNaN(h)&&(h=.8);var l=this.useNegativeColorIfDown,m=this.width,n=this.height,p=this.y,q=this.rotate,r=this.columnCount,s=AmCharts.toCoordinate(this.cornerRadiusTop, +h/2),v=this.connect,w=[],t=[],u,y,E,A,z=this.chart.graphs.length,K,I=this.dx/this.tcc,F=this.dy/this.tcc;var H=f.stackType,L=this.labelPosition,ha=this.start,ba=this.end,$=this.scrollbar,Ra=this.categoryAxis,na=this.baseCoord,ta=this.negativeBase,V=this.columnIndex,X=this.lineThickness,Z=this.lineAlpha,oa=this.lineColorR,R=this.dashLength,Y=this.set,qa=L,G=this.getGradRotation(),B=this.chart.columnSpacing,W=Ra.cellWidth,ca=(W*h-r)/r;B>ca&&(B=ca);var ja,x,ab,jb=n+1,kb=m+1,bb= +0,lb=0,mb,nb,cb,db,ob=this.fillColorsR,Da=this.negativeFillColors,wa=this.negativeLineColor,Sa=this.fillAlphas,Ta=this.negativeFillAlphas;"object"==typeof Sa&&(Sa=Sa[0]);"object"==typeof Ta&&(Ta=Ta[0]);var eb=f.getCoordinate(f.min);f.logarithmic&&(eb=f.getCoordinate(f.minReal));this.minCoord=eb;this.resetBullet&&(this.bullet="none");if(!($||"line"!=g&&"smoothedLine"!=g&&"step"!=g||(1==d.length&&"step"!=g&&"none"==this.bullet&&(this.bullet="round",this.resetBullet=!0),!Da&&void 0==wa||l))){var La= +ta;La>f.max&&(La=f.max);Lah&&(h=1);var J;if("line"==g||"step"==g||"smoothedLine"==g){if(0U?!0:!1);if(!$)switch(this.showBalloonAt){case "close":x.y=C; +break;case "open":x.y=M;break;case "high":x.y=ya;break;case "low":x.y=xa}var la=ja.x[Ra.id],Oa=this.periodSpan-1,ma=Math.floor(W/2)+Math.floor(Oa*W/2),za=ma,Hb=0;"left"==this.stepDirection&&(Hb=(2*W+Oa*W)/2,la-=Hb);"start"==this.pointPosition&&(la-=W/2+Math.floor(Oa*W/2),ma=0,za=Math.floor(W)+Math.floor(Oa*W));"end"==this.pointPosition&&(la+=W/2+Math.floor(Oa*W/2),ma=Math.floor(W)+Math.floor(Oa*W),za=0);if(Gb){var sb=this.columnWidth;isNaN(sb)||(ma*=sb,za*=sb)}$||(x.x=la);-1E5>la&&(la=-1E5);la>m+ +1E5&&(la=m+1E5);q?(D=C,N=M,M=C=la,isNaN(ka)&&!this.fillToGraph&&(N=na),Fa=xa,Ga=ya):(N=D=la,isNaN(ka)&&!this.fillToGraph&&(M=na));UNa?(Ma&&(Ua=!0),Ma=!1):(Ma||(Ua=!0),Ma=!0):x.isNegative=U=hb||Math.abs(C-gb)>=hb)w.push(D),t.push(C),fb=D,gb=C;aa=D;ia=C;ea=D;fa=C;!Ea||isNaN(M)||isNaN(N)||(O.push(N), +P.push(M));if(Ua||void 0!=x.lineColor||void 0!=x.fillColors||!isNaN(x.dashLength))this.drawLineGraph(w,t,O,P),w=[D],t=[C],O=[],P=[],!Ea||isNaN(M)||isNaN(N)||(O.push(N),P.push(M)),l?Ma?(this.lineColorSwitched=oa,this.fillColorsSwitched=ob):(this.lineColorSwitched=wa,this.fillColorsSwitched=Da):(this.lineColorSwitched=x.lineColor,this.fillColorsSwitched=x.fillColors),this.dashLengthSwitched=x.dashLength;x.gap&&(this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[])}break;case "smoothedLine":if(isNaN(U))v|| +(this.drawSmoothedGraph(w,t,O,P),w=[],t=[],O=[],P=[]);else{if(Math.abs(D-fb)>=hb||Math.abs(C-gb)>=hb)w.push(D),t.push(C),fb=D,gb=C;aa=D;ia=C;ea=D;fa=C;!Ea||isNaN(M)||isNaN(N)||(O.push(N),P.push(M));void 0==x.lineColor&&void 0==x.fillColors&&isNaN(x.dashLength)||(this.drawSmoothedGraph(w,t,O,P),w=[D],t=[C],O=[],P=[],!Ea||isNaN(M)||isNaN(N)||(O.push(N),P.push(M)),this.lineColorSwitched=x.lineColor,this.fillColorsSwitched=x.fillColors,this.dashLengthSwitched=x.dashLength);x.gap&&(this.drawSmoothedGraph(w, +t,O,P),w=[],t=[],O=[],P=[])}break;case "step":if(!isNaN(U)){if(void 0==x.lineColor&&void 0==x.fillColors&&isNaN(x.dashLength)||(this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[],this.lineColorSwitched=x.lineColor,this.fillColorsSwitched=x.fillColors,this.dashLengthSwitched=x.dashLength),q?(isNaN(u)||(w.push(u),t.push(C-ma)),t.push(C-ma),w.push(D),t.push(C+za),w.push(D),!Ea||isNaN(M)||isNaN(N)||(O.push(E),P.push(M-ma),O.push(N),P.push(M-ma),O.push(N),P.push(M+za))):(isNaN(y)||(t.push(y),w.push(u),t.push(y), +w.push(D-ma)),w.push(D-ma),t.push(C),w.push(D+za),t.push(C),!Ea||isNaN(M)||isNaN(N)||(O.push(N-ma),P.push(A),O.push(N-ma),P.push(M),O.push(N+za),P.push(M))),u=D,y=C,E=N,A=M,aa=D,ia=C,ea=D,fa=C,Ua&&(this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[],l&&(Ma?(this.lineColorSwitched=oa,this.fillColorsSwitched=ob):(this.lineColorSwitched=wa,this.fillColorsSwitched=Da))),Gb||x.gap)u=y=NaN,this.drawLineGraph(w,t,O,P),w=[],t=[],O=[],P=[]}else if(!v){if(1>=this.periodSpan||1ma+za)u=y=NaN; +this.drawLineGraph(w,t,O,P);w=[];t=[];O=[];P=[]}break;case "column":pa=ua;void 0!=x.lineColor&&(pa=x.lineColor);if(!isNaN(U)){l||(x.isNegative=UJb&&ka>Jb))if(q){"3d"==H?(T=C-(r/2-this.depthCount+1)*(h+B)+B/2+F*V,S=N+I*V):(T=Math.floor(C-(r/2-V)*(h+B)+B/2),S=N);Q=h;aa=D;ia=T+h/2;ea=D;fa=T+h/2;T+Q>n&&(Q=n-T);0>T&&(Q+=T,T=0);da=D-N;var Vb=S;S=AmCharts.fitToBounds(S,0,m);da+=Vb-S;da=AmCharts.fitToBounds(da, +-S,m-S+I*V);TU&&(L=f.reversed?"right":"left")),"regular"==H||"100%"==H)&&(aa+=this.dx)}else{"3d"==H?(S=D-(r/2-this.depthCount+1)*(h+B)+B/2+I*V,T=M+F*V):(S=D-(r/2-V)*(h+B)+B/2,T=M);Q=h;aa=S+h/2;ia=C;ea=S+h/2;fa=C;S+Q>m+V*I&&(Q=m-S+V*I);0>S&&(Q+=S,S=0);da=C-M;var Wb=T;T=AmCharts.fitToBounds(T,this.dy,n);da+=Wb-T;da=AmCharts.fitToBounds(da,-T+F*V,n-T); +if(SU&&"middle"!=L&&"inside"!=L)L="bottom";else if(L=qa,"regular"==H||"100%"==H)ia+=this.dy}if(ra&&(sa=ra.set,x.columnGraphics=sa,sa.translate(S,T),this.columnsSet.push(sa),(x.url||this.showHandOnHover)&&sa.setAttr("cursor","pointer"),!$)){"none"==H&&(K=q?(this.end+1-J)*z-c:z*J+c);"3d"==H&&(q?(K=(this.end+1-J)*z-c-1E3*this.depthCount,aa+=I*this.columnIndex,ea+=I*this.columnIndex,x.y+=I*this.columnIndex): +(K=(z-c)*(J+1)+1E3*this.depthCount,aa+=3,ia+=F*this.columnIndex+7,fa+=F*this.columnIndex,x.y+=F*this.columnIndex));if("regular"==H||"100%"==H)"inside"!=L&&(L="middle"),K=q?0n&&(Q=n-T),0>T&&(Q+=T,T=0),Tka?(ub=[D,Ga],vb=[N,Fa]):(ub=[N,Ga],vb=[D,Fa]);!isNaN(Ga)&&!isNaN(Fa)&&Cm&&(Q=m-S),0>S&&(Q+=S,S=0),da=C-M,Ska?(wb=[C,ya],xb=[M,xa]):(wb=[M,ya],xb=[C,xa]);!isNaN(ya)&&!isNaN(xa)&& +DU||0da?Pa/2+6:-Pa/2-6):Ja=0>da?Ka:-Ka}if(ga){if(isNaN(ia)||isNaN(aa))ga.remove(),ga=null;else if(aa+=Ia,ia+=Ja,ga.translate(aa,ia),q){if(0>ia||ia>n)ga.remove(),ga=null}else{var Pb=0;"3d"==H&&(Pb=I*V);if(0>aa||aa>m+Pb)ga.remove(),ga=null}ga&&this.allBullets.push(ga)}}if("regular"==H||"100%"==H){var Qb=f.totalText;if(Qb){var Qa=this.createLabel(x,0,0,Qb,f.totalTextColor);this.allBullets.push(Qa);var Rb=Qa.getBBox(),Sb=Rb.width, +Tb=Rb.height,Ya,Za,Ub=f.totals[J];Ub&&Ub.remove();var $a=0;"column"!=g&&($a=Ha);q?(Za=C,Ya=0>U?D-Sb/2-2-$a:D+Sb/2+3+$a):(Ya=D,Za=0>U?C+Tb/2+$a:C-Tb/2-3-$a);Qa.translate(Ya,Za);f.totals[J]=Qa;q?(0>Za||Za>n)&&Qa.remove():(0>Ya||Ya>m)&&Qa.remove()}}}}}}if("line"==g||"step"==g||"smoothedLine"==g)"smoothedLine"==g?this.drawSmoothedGraph(w,t,O,P):this.drawLineGraph(w,t,O,P),$||this.launchAnimation();this.bulletsHidden&&this.hideBullets()},animateColumns:function(a,b,c,d,e,f){var g=this;c=g.chart.startDuration; +0a&&(a=this.fillAlphas),0===a&&(a=this.bulletAlpha),0===a&&(a=1));return a},createBullet:function(a,b,c,d){d=this.container;var e=this.bulletOffset,f= +this.bulletSize;isNaN(a.bulletSize)||(f=a.bulletSize);var g=a.values.value,h=this.maxValue,k=this.minValue,l=this.maxBulletSize,m=this.minBulletSize;isNaN(h)||(isNaN(g)||(f=(g-k)/(h-k)*(l-m)+m),k==h&&(f=l));h=f;this.bulletAxis&&(f=a.values.error,isNaN(f)||(g=f),f=this.bulletAxis.stepWidth*g);fb-0||b-0>this.width||c<-f/2||c-0>this.height)&&(n.remove(),n=null),n&&(this.bulletSet.push(n),n.translate(b,c),this.addListeners(n,a),this.allBullets.push(n)),a.bx=b,a.by=c);a.bulletGraphics=n;return f},showBullets:function(){var a=this.allBullets,b;this.bulletsHidden=!1;for(b=0;ba&&(a=0),a>c&&(a=c)):(a=a.mouseX-this.x-1,0>a&&(a=0),a>b&&(a=b));return a},updateCrosshair:function(){var a=this.chart,b=a.mouseX-this.x,c=a.mouseY-this.y,d=this.vLine,e=this.hLine,b=AmCharts.fitToBounds(b, +0,this.width),c=AmCharts.fitToBounds(c,0,this.height);0a&&(e=a,g=c-a),cb&&(f=b,h=d-b),dy&&(e=y-c),z+e=this.data.length||0>l+e||(h.start=l+e,h.end=H+e,this.fire(h.type,h)))}else{"start"==E?r-=g.cellWidth/2:"mouse"==E&&(c.mouseIsOver?r=s?f-2:e-2:isNaN(this.tempPosition)||(r=this.tempPosition-2));if(s){if(0>r)if(z)r=0;else{this.hideCursor();return}if(r>p+1)if(z)r=p+1;else{this.hideCursor();return}}else{if(0>r)if(z)r= +0;else{this.hideCursor();return}if(r>n)if(z)r=n;else{this.hideCursor();return}}if(0r||r>p)v=!1}else if(k=r,r=t,0>k||k>n+h+1)v=!1;v&&(1!=this.graphBulletSize&&AmCharts.isModern&&(v=y.bulletGraphics)&&(v.getBBox(),v.translate(y.bx,y.by,this.graphBulletSize),this.resizedBullets.push(y),A=this.graphBulletAlpha,isNaN(A)||(v.setAttr("fill-opacity",A),v.setAttr("stroke-opacity",A))),v=u.valueBalloon,A=c.getBalloonColor(u,y),v.setBounds(l,m,l+n,m+p),v.pointerOrientation="H", +F=this.balloonPointerOrientation,"vertical"==F&&(v.pointerOrientation="V"),"horizontal"==F&&(v.pointerOrientation="H"),v.changeColor(A),void 0!==u.balloonAlpha&&(v.fillAlpha=u.balloonAlpha),void 0!==u.balloonTextColor&&(v.color=u.balloonTextColor),v.setPosition(k+l,r+m),k=c.formatString(u.balloonText,y,!0),(r=u.balloonFunction)&&(k=r(y,u).toString()),""!==k&&(s?v.showBalloon(k):(v.text=k,v.show=!0),w.push({yy:t,balloon:v})),!s&&v.set&&(v.set.hide(),u=v.textDiv)&&(u.style.visibility="hidden"))}}this.avoidBalloonOverlapping&& +this.arrangeBalloons()}b?(h={type:"changed"},h.index=a,h.chart=this.chart,h.zooming=z,h.mostCloseGraph=H,h.position=s?f:e,h.target=this,c.fire("changed",h),this.fire("changed",h),this.skipZoomDispatch=!1):(this.skipZoomDispatch=!0,c.updateLegendValues(a));this.previousIndex=a;this.previousMostCloseGraph=H}}}else this.hideCursor()},enableDrawing:function(a){this.enabled=!a;this.hideCursor();this.rolledOver=!1;this.drawing=a},isZooming:function(a){a&&a!=this.zooming&&this.handleMouseDown("fake");a|| +a==this.zooming||this.handleMouseUp()},handleMouseOut:function(){if(this.enabled)if(this.zooming)this.setPosition();else{this.index=void 0;var a={type:"changed",index:void 0,target:this};a.chart=this.chart;this.fire("changed",a);this.hideCursor()}},handleReleaseOutside:function(){this.handleMouseUp()},handleMouseUp:function(){var a=this.chart,b=this.data,c;if(a){var d=a.mouseX-this.x,e=a.mouseY-this.y;if(this.drawingNow){this.drawingNow=!1;AmCharts.remove(this.drawingLine);c=this.drawStartX;var f= +this.drawStartY;if(2Math.abs(e-this.initialMouse)&&this.fromIndex==this.index||(this.indexMath.abs(d-g)&&3>Math.abs(e-h)||(b=Math.min(g,d),f=Math.min(h,e),d=Math.abs(g-d),e=Math.abs(h-e),a.hideXScrollbar&&(b=0,d=this.width),a.hideYScrollbar&&(f=0,e=this.height),c.selectionHeight=e,c.selectionWidth=d,c.selectionY= +f,c.selectionX=b,this.skipZoomDispatch||this.fire(c.type,c))}this.selectWithoutZooming||AmCharts.remove(this.selection)}this.panning=this.zooming=this.skipZoomDispatch=!1}}},showCursorAt:function(a){var b=this.chart.categoryAxis;a=b.parseDates?b.dateToCoordinate(a):b.categoryToCoordinate(a);this.previousMousePosition=NaN;this.forceShow=!0;this.setPosition(a,!1)},clearSelection:function(){AmCharts.remove(this.selection)},handleMouseDown:function(a){if(this.zoomable||this.pan||this.drawing){var b=this.rotate, +c=this.chart,d=c.mouseX-this.x,e=c.mouseY-this.y;if(0document.documentMode&&(this.updateOnReleaseOnly=!0);this.dragIconWidth=18;this.dragIconHeight=25;AmCharts.applyTheme(this,a,"SimpleChartScrollbar")},draw:function(){var a= +this;a.destroy();a.interval=setInterval(function(){a.updateScrollbar.call(a)},40);var b=a.chart.container,c=a.rotate,d=a.chart,e=b.set();a.set=e;d.scrollbarsSet.push(e);var f,g;c?(f=a.scrollbarHeight,g=d.plotAreaHeight):(g=a.scrollbarHeight,f=d.plotAreaWidth);a.width=f;if((a.height=g)&&f){var h=AmCharts.rect(b,f,g,a.backgroundColor,a.backgroundAlpha,1,a.backgroundColor,a.backgroundAlpha);a.bg=h;e.push(h);h=AmCharts.rect(b,f,g,"#000",.005);e.push(h);a.invisibleBg=h;h.click(function(){a.handleBgClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()}).touchend(function(){a.handleBgClick()}); +h=AmCharts.rect(b,f,g,a.selectedBackgroundColor,a.selectedBackgroundAlpha);a.selectedBG=h;e.push(h);f=AmCharts.rect(b,f,g,"#000",.005);a.dragger=f;e.push(f);f.mousedown(function(b){a.handleDragStart(b)}).mouseup(function(){a.handleDragStop()}).mouseover(function(){a.handleDraggerOver()}).mouseout(function(){a.handleMouseOut()}).touchstart(function(b){a.handleDragStart(b)}).touchend(function(){a.handleDragStop()});f=d.pathToImages;c?(h=f+"dragIconH.gif",f=a.dragIconWidth,c=a.dragIconHeight):(h=f+"dragIcon.gif", +c=a.dragIconWidth,f=a.dragIconHeight);g=b.image(h,0,0,c,f);var h=b.image(h,0,0,c,f),k=10,l=20;d.panEventsEnabled&&(k=25,l=a.scrollbarHeight);var m=AmCharts.rect(b,k,l,"#000",.005),n=AmCharts.rect(b,k,l,"#000",.005);n.translate(-(k-c)/2,-(l-f)/2);m.translate(-(k-c)/2,-(l-f)/2);c=b.set([g,n]);b=b.set([h,m]);a.iconLeft=c;a.iconRight=b;c.mousedown(function(){a.leftDragStart()}).mouseup(function(){a.leftDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(b){a.leftDragStart()}).touchend(function(){a.leftDragStop()}); +b.mousedown(function(){a.rightDragStart()}).mouseup(function(){a.rightDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(b){a.rightDragStart()}).touchend(function(){a.rightDragStop()});AmCharts.ifArray(d.chartData)?e.show():e.hide();a.hideDragIcons();a.clipDragger(!1)}e.translate(a.x,a.y)},updateScrollbarSize:function(a,b){var c=this.dragger,d,e,f,g;this.rotate?(d=0,e=a,f=this.width+1,g=b-a,c.setAttr("height",b-a),c.setAttr("y",e)):(d=a, +e=0,f=b-a,g=this.height+1,c.setAttr("width",b-a),c.setAttr("x",d));this.clipAndUpdate(d,e,f,g)},updateScrollbar:function(){var a,b=!1,c,d,e=this.x,f=this.y,g=this.dragger,h=this.getDBox();c=h.x+e;d=h.y+f;var k=h.width,h=h.height,l=this.rotate,m=this.chart,n=this.width,p=this.height,q=m.mouseX,r=m.mouseY;a=this.initialMouse;m.mouseIsOver&&(this.dragging&&(m=this.initialCoord,l?(a=m+(r-a),0>a&&(a=0),m=p-h,a>m&&(a=m),g.setAttr("y",a)):(a=m+(q-a),0>a&&(a=0),m=n-k,a>m&&(a=m),g.setAttr("x",a))),this.resizingRight&& +(l?(a=r-d,a+d>p+f&&(a=p-d+f),0>a?(this.resizingRight=!1,b=this.resizingLeft=!0):(0===a&&(a=.1),g.setAttr("height",a))):(a=q-c,a+c>n+e&&(a=n-c+e),0>a?(this.resizingRight=!1,b=this.resizingLeft=!0):(0===a&&(a=.1),g.setAttr("width",a)))),this.resizingLeft&&(l?(c=d,d=r,dp+f&&(d=p+f),a=!0===b?c-d:h+c-d,0>a?(this.resizingRight=!0,this.resizingLeft=!1,g.setAttr("y",c+h-f)):(0===a&&(a=.1),g.setAttr("y",d-f),g.setAttr("height",a))):(d=q,dn+e&&(d=n+e),a=!0===b?c-d:k+c-d,0>a?(this.resizingRight= +!0,this.resizingLeft=!1,g.setAttr("x",c+k-e)):(0===a&&(a=.1),g.setAttr("x",d-e),g.setAttr("width",a)))),this.clipDragger(!0))},clipDragger:function(a){var b=this.getDBox();if(b){var c=b.x,d=b.y,e=b.width,b=b.height,f=!1;if(this.rotate){if(c=0,e=this.width+1,this.clipY!=d||this.clipH!=b)f=!0}else if(d=0,b=this.height+1,this.clipX!=c||this.clipW!=e)f=!0;f&&(this.clipAndUpdate(c,d,e,b),a&&(this.updateOnReleaseOnly||this.dispatchScrollbarEvent()))}},maskGraphs:function(){},clipAndUpdate:function(a,b, +c,d){this.clipX=a;this.clipY=b;this.clipW=c;this.clipH=d;this.selectedBG.clipRect(a,b,c,d);this.updateDragIconPositions();this.maskGraphs(a,b,c,d)},dispatchScrollbarEvent:function(){if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart;a.hideBalloon();var b=this.getDBox(),c=b.x,d=b.y,e=b.width,b=b.height;this.rotate?(c=d,e=this.height/b):e=this.width/e;a={type:"zoomed",position:c,chart:a,target:this,multiplier:e};this.fire(a.type,a)}},updateDragIconPositions:function(){var a=this.getDBox(),b= +a.x,c=a.y,d=this.iconLeft,e=this.iconRight,f,g,h=this.scrollbarHeight;this.rotate?(f=this.dragIconWidth,g=this.dragIconHeight,d.translate(this.x+(h-g)/2,this.y+c-f/2),e.translate(this.x+(h-g)/2,this.y+c+a.height-f/2)):(f=this.dragIconHeight,g=this.dragIconWidth,d.translate(this.x+b-g/2,this.y+(h-f)/2),e.translate(this.x+b-g/2+a.width,this.y+(h-f)/2))},showDragIcons:function(){this.resizeEnabled&&(this.iconLeft.show(),this.iconRight.show())},hideDragIcons:function(){if(!this.resizingLeft&&!this.resizingRight&& +!this.dragging){if(this.hideResizeGrips||!this.resizeEnabled)this.iconLeft.hide(),this.iconRight.hide();this.removeCursors()}},removeCursors:function(){this.chart.setMouseCursor("auto")},relativeZoom:function(a,b){this.dragger.stop();this.multiplier=a;this.position=b;this.updateScrollbarSize(b,this.rotate?b+this.height/a:b+this.width/a)},destroy:function(){this.clear();AmCharts.remove(this.set);AmCharts.remove(this.iconRight);AmCharts.remove(this.iconLeft)},clear:function(){clearInterval(this.interval)}, +handleDragStart:function(){var a=this.chart;this.dragger.stop();this.removeCursors();this.dragging=!0;var b=this.getDBox();this.rotate?(this.initialCoord=b.y,this.initialMouse=a.mouseY):(this.initialCoord=b.x,this.initialMouse=a.mouseX)},handleDragStop:function(){this.updateOnReleaseOnly&&(this.updateScrollbar(),this.skipEvent=!1,this.dispatchScrollbarEvent());this.dragging=!1;this.mouseIsOver&&this.removeCursors();this.updateScrollbar()},handleDraggerOver:function(){this.handleMouseOver()},leftDragStart:function(){this.dragger.stop(); +this.resizingLeft=!0},leftDragStop:function(){this.resizingLeft=!1;this.mouseIsOver||this.removeCursors();this.updateOnRelease()},rightDragStart:function(){this.dragger.stop();this.resizingRight=!0},rightDragStop:function(){this.resizingRight=!1;this.mouseIsOver||this.removeCursors();this.updateOnRelease()},iconRollOut:function(){this.removeCursors()},iconRollOver:function(){this.rotate?this.chart.setMouseCursor("n-resize"):this.chart.setMouseCursor("e-resize");this.handleMouseOver()},getDBox:function(){if(this.dragger)return this.dragger.getBBox()}, +handleBgClick:function(){if(!this.resizingRight&&!this.resizingLeft){this.zooming=!0;var a,b,c=this.scrollDuration,d=this.dragger;a=this.getDBox();var e=a.height,f=a.width;b=this.chart;var g=this.y,h=this.x,k=this.rotate;k?(a="y",b=b.mouseY-e/2-g,b=AmCharts.fitToBounds(b,0,this.height-e)):(a="x",b=b.mouseX-f/2-h,b=AmCharts.fitToBounds(b,0,this.width-f));this.updateOnReleaseOnly?(this.skipEvent=!1,d.setAttr(a,b),this.dispatchScrollbarEvent(),this.clipDragger()):(b=Math.round(b),k?d.animate({y:b},c, +">"):d.animate({x:b},c,">"))}},updateOnRelease:function(){this.updateOnReleaseOnly&&(this.updateScrollbar(),this.skipEvent=!1,this.dispatchScrollbarEvent())},handleReleaseOutside:function(){if(this.set){if(this.resizingLeft||this.resizingRight||this.dragging)this.updateOnRelease(),this.removeCursors();this.mouseIsOver=this.dragging=this.resizingRight=this.resizingLeft=!1;this.hideDragIcons();this.updateScrollbar()}},handleMouseOver:function(){this.mouseIsOver=!0;this.showDragIcons()},handleMouseOut:function(){this.mouseIsOver= +!1;this.hideDragIcons()}});AmCharts.ChartScrollbar=AmCharts.Class({inherits:AmCharts.SimpleChartScrollbar,construct:function(a){this.cname="ChartScrollbar";AmCharts.ChartScrollbar.base.construct.call(this,a);this.graphLineColor="#BBBBBB";this.graphLineAlpha=0;this.graphFillColor="#BBBBBB";this.graphFillAlpha=1;this.selectedGraphLineColor="#888888";this.selectedGraphLineAlpha=0;this.selectedGraphFillColor="#888888";this.selectedGraphFillAlpha=1;this.gridCount=0;this.gridColor="#FFFFFF";this.gridAlpha=.7;this.skipEvent=this.autoGridCount= +!1;this.color="#FFFFFF";this.scrollbarCreated=!1;this.offset=0;AmCharts.applyTheme(this,a,this.cname)},init:function(){var a=this.categoryAxis,b=this.chart;a||(this.categoryAxis=a=new AmCharts.CategoryAxis);a.chart=b;a.id="scrollbar";a.dateFormats=b.categoryAxis.dateFormats;a.markPeriodChange=b.categoryAxis.markPeriodChange;a.boldPeriodBeginning=b.categoryAxis.boldPeriodBeginning;a.axisItemRenderer=AmCharts.RecItem;a.axisRenderer=AmCharts.RecAxis;a.guideFillRenderer=AmCharts.RecFill;a.inside=!0;a.fontSize= +this.fontSize;a.tickLength=0;a.axisAlpha=0;AmCharts.isString(this.graph)&&(this.graph=AmCharts.getObjById(b.graphs,this.graph));if(a=this.graph){var c=this.valueAxis;c||(this.valueAxis=c=new AmCharts.ValueAxis,c.visible=!1,c.scrollbar=!0,c.axisItemRenderer=AmCharts.RecItem,c.axisRenderer=AmCharts.RecAxis,c.guideFillRenderer=AmCharts.RecFill,c.labelsEnabled=!1,c.chart=b);b=this.unselectedGraph;b||(b=new AmCharts.AmGraph,b.scrollbar=!0,this.unselectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers= +a.noStepRisers);b=this.selectedGraph;b||(b=new AmCharts.AmGraph,b.scrollbar=!0,this.selectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers=a.noStepRisers)}this.scrollbarCreated=!0},draw:function(){var a=this;AmCharts.ChartScrollbar.base.draw.call(a);a.scrollbarCreated||a.init();var b=a.chart,c=b.chartData,d=a.categoryAxis,e=a.rotate,f=a.x,g=a.y,h=a.width,k=a.height,l=b.categoryAxis,m=a.set;d.setOrientation(!e);d.parseDates=l.parseDates;d.rotate=e;d.equalSpacing=l.equalSpacing;d.minPeriod=l.minPeriod; +d.startOnAxis=l.startOnAxis;d.viW=h;d.viH=k;d.width=h;d.height=k;d.gridCount=a.gridCount;d.gridColor=a.gridColor;d.gridAlpha=a.gridAlpha;d.color=a.color;d.tickLength=0;d.axisAlpha=0;d.autoGridCount=a.autoGridCount;d.parseDates&&!d.equalSpacing&&d.timeZoom(b.firstTime,b.lastTime);d.zoom(0,c.length-1);if(l=a.graph){var n=a.valueAxis,p=l.valueAxis;n.id=p.id;n.rotate=e;n.setOrientation(e);n.width=h;n.height=k;n.viW=h;n.viH=k;n.dataProvider=c;n.reversed=p.reversed;n.logarithmic=p.logarithmic;n.gridAlpha= +0;n.axisAlpha=0;m.push(n.set);e?(n.y=g,n.x=0):(n.x=f,n.y=0);var f=Infinity,g=-Infinity,q;for(q=0;qg&&(g=v)}}Infinity!=f&&(n.minimum=f);-Infinity!=g&&(n.maximum=g+.1*(g-f));f==g&&(n.minimum-=1,n.maximum+=1);void 0!==a.minimum&&(n.minimum=a.minimum);void 0!==a.maximum&&(n.maximum=a.maximum);n.zoom(0,c.length-1);s=a.unselectedGraph;s.id=l.id;s.rotate=e;s.chart= +b;s.data=c;s.valueAxis=n;s.chart=l.chart;s.categoryAxis=a.categoryAxis;s.periodSpan=l.periodSpan;s.valueField=l.valueField;s.openField=l.openField;s.closeField=l.closeField;s.highField=l.highField;s.lowField=l.lowField;s.lineAlpha=a.graphLineAlpha;s.lineColorR=a.graphLineColor;s.fillAlphas=a.graphFillAlpha;s.fillColorsR=a.graphFillColor;s.connect=l.connect;s.hidden=l.hidden;s.width=h;s.height=k;s.pointPosition=l.pointPosition;s.stepDirection=l.stepDirection;s.periodSpan=l.periodSpan;p=a.selectedGraph; +p.id=l.id;p.rotate=e;p.chart=b;p.data=c;p.valueAxis=n;p.chart=l.chart;p.categoryAxis=d;p.periodSpan=l.periodSpan;p.valueField=l.valueField;p.openField=l.openField;p.closeField=l.closeField;p.highField=l.highField;p.lowField=l.lowField;p.lineAlpha=a.selectedGraphLineAlpha;p.lineColorR=a.selectedGraphLineColor;p.fillAlphas=a.selectedGraphFillAlpha;p.fillColorsR=a.selectedGraphFillColor;p.connect=l.connect;p.hidden=l.hidden;p.width=h;p.height=k;p.pointPosition=l.pointPosition;p.stepDirection=l.stepDirection; +p.periodSpan=l.periodSpan;b=a.graphType;b||(b=l.type);s.type=b;p.type=b;c=c.length-1;s.zoom(0,c);p.zoom(0,c);p.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});s.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});m.push(s.set);m.push(p.set)}m.push(d.set);m.push(d.labelsSet);a.bg.toBack();a.invisibleBg.toFront();a.dragger.toFront();a.iconLeft.toFront(); +a.iconRight.toFront()},timeZoom:function(a,b,c){this.startTime=a;this.endTime=b;this.timeDifference=b-a;this.skipEvent=!AmCharts.toBoolean(c);this.zoomScrollbar();this.skipEvent||this.dispatchScrollbarEvent()},zoom:function(a,b){this.start=a;this.end=b;this.skipEvent=!0;this.zoomScrollbar()},dispatchScrollbarEvent:function(){if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart.chartData,b,c,d=this.dragger.getBBox();b=d.x;var e=d.y,f=d.width;c=d.height;d=this.chart;this.rotate?b=e:c=f;f={type:"zoomed", +target:this};f.chart=d;var g=this.categoryAxis,h=this.stepWidth,e=d.minSelectedTime;if(g.parseDates&&!g.equalSpacing){if(a=d.lastTime,d=d.firstTime,g.minDuration(),g=Math.round(b/h)+d,b=this.dragging?g+this.timeDifference:Math.round((b+c)/h)+d,g>b&&(g=b),0a&&(b=a),b-eb&&(b=g+e),g!=this.startTime||b!=this.endTime)this.startTime=g,this.endTime=b,f.start=g,f.end=b,f.startDate=new Date(g),f.endDate=new Date(b), +this.fire(f.type,f)}else if(g.startOnAxis||(b+=h/2),c-=this.stepWidth/2,e=g.xToIndex(b),b=g.xToIndex(b+c),e!=this.start||this.end!=b)g.startOnAxis&&(this.resizingRight&&e==b&&b++,this.resizingLeft&&e==b&&(0this.timeDifference&&(this.timeDifference=0)},handleBackgroundClick:function(){AmCharts.ChartScrollbar.base.handleBackgroundClick.call(this);this.dragging||(this.difference=this.end-this.start,this.timeDifference=this.endTime-this.startTime,0>this.timeDifference&&(this.timeDifference=0))}});AmCharts.AmBalloon=AmCharts.Class({construct:function(a){this.cname="AmBalloon";this.enabled=!0;this.fillColor="#FFFFFF";this.fillAlpha=.8;this.borderThickness=2;this.borderColor="#FFFFFF";this.borderAlpha=1;this.cornerRadius=0;this.maximumWidth=220;this.horizontalPadding=8;this.verticalPadding=4;this.pointerWidth=6;this.pointerOrientation="V";this.color="#000000";this.adjustBorderColor=!0;this.show=this.follow=this.showBullet=!1;this.bulletSize=3;this.shadowAlpha=.4;this.shadowColor="#000000";this.fadeOutDuration= +this.animationDuration=.3;this.fixedPosition=!1;this.offsetY=6;this.offsetX=1;this.textAlign="center";AmCharts.isModern||(this.offsetY*=1.5);AmCharts.applyTheme(this,a,this.cname)},draw:function(){var a=this.pointToX,b=this.pointToY;this.deltaSignX=this.deltaSignY=1;var c=this.chart;AmCharts.VML&&(this.fadeOutDuration=0);this.xAnim&&c.stopAnim(this.xAnim);this.yAnim&&c.stopAnim(this.yAnim);if(!isNaN(a)){var d=this.follow,e=c.container,f=this.set;AmCharts.remove(f);this.removeDiv();f=e.set();f.node.style.pointerEvents= +"none";this.set=f;c.balloonsSet.push(f);if(this.show){var g=this.l,h=this.t,k=this.r,l=this.b,m=this.balloonColor,n=this.fillColor,p=this.borderColor,q=n;void 0!=m&&(this.adjustBorderColor?q=p=m:n=m);var r=this.horizontalPadding,s=this.verticalPadding,v=this.pointerWidth,w=this.pointerOrientation,t=this.cornerRadius,u=c.fontFamily,y=this.fontSize;void 0==y&&(y=c.fontSize);var m=document.createElement("div"),E=m.style;E.pointerEvents="none";E.position="absolute";var A=this.minWidth,z="";isNaN(A)|| +(z="min-width:"+(A-2*r)+"px; ");m.innerHTML='
'+this.text+"
";c.chartDiv.appendChild(m);this.textDiv=m;y=m.offsetWidth;u=m.offsetHeight;m.clientHeight&&(y=m.clientWidth,u=m.clientHeight);u+=2*s;z=y+2*r;!isNaN(A)&&zu&&(v=u/2),y=b-u/2,a=l&&(y=l-u);yk&&(A=k-z);var h=y+s,l=A+r,s=this.shadowAlpha,I=this.shadowColor,r=this.borderThickness,F=this.bulletSize,H;0z-v&&(g=z-v),gu-v&&(q=u-v),qa?z:a-A,z,z,0,0,z]),0this.r-d.width&&(a=this.r-d.width);e1.1*q&&(w[K].gap=!0);this.processFields(b,F,H);F.category=t.category;F.serialDataItem=t;F.graph=b;t.axes[A].graphs[K]=F}p[K]=t.time;w[K]= +F}}this.chartData[s]=t}}for(c=0;cb?this.colors[b]:AmCharts.randomColor();a.lineColorR=c}a.fillColorsR=a.fillColors?a.fillColors:a.lineColorR;a.bulletBorderColorR=a.bulletBorderColor?a.bulletBorderColor:a.useLineColorForBulletBorder?a.lineColorR:a.bulletColor;a.bulletColorR=a.bulletColor?a.bulletColor:a.lineColorR;if(c= +this.patterns)a.pattern=c[b]},handleLegendEvent:function(a){var b=a.type;a=a.dataItem;if(!this.legend.data&&a){var c=a.hidden,d=a.showBalloon;switch(b){case "clickMarker":this.textClickEnabled&&(d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a));break;case "clickLabel":d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a);break;case "rollOverItem":c||this.highlightGraph(a);break;case "rollOutItem":c||this.unhighlightGraph();break;case "hideItem":this.hideGraph(a);break;case "showItem":this.showGraph(a)}}}, +highlightGraph:function(a){var b=this.graphs,c,d=.2;this.legend&&(d=this.legend.rollOverGraphAlpha);if(1!=d)for(c=0;cthis.hoverAlpha&&a.wedge&&a.wedge.attr({opacity:this.hoverAlpha});var d=a.balloonX,e=a.balloonY;a.pulled&&(d+=a.pullX,e+=a.pullY);var f=this.formatString(this.balloonText,a,!0),g=this.balloonFunction;g&&(f=g(a,f));g=AmCharts.adjustLuminosity(a.color, +-.15);this.showBalloon(f,g,b,d,e);a={type:"rollOverSlice",dataItem:a,chart:this,event:c};this.fire(a.type,a)}},rollOutSlice:function(a,b){isNaN(a)||(a=this.chartData[a]);a.wedge&&a.wedge.attr({opacity:1});this.hideBalloon();var c={type:"rollOutSlice",dataItem:a,chart:this,event:b};this.fire(c.type,c)},clickSlice:function(a,b){isNaN(a)||(a=this.chartData[a]);a.pulled?this.pullSlice(a,0):this.pullSlice(a,1);AmCharts.getURL(a.url,this.urlTarget);var c={type:"clickSlice",dataItem:a,chart:this,event:b}; +this.fire(c.type,c)},handleRightClick:function(a,b){isNaN(a)||(a=this.chartData[a]);var c={type:"rightClickSlice",dataItem:a,chart:this,event:b};this.fire(c.type,c)},drawTicks:function(){var a=this.chartData,b;for(b=0;bb&&(b=e);d.remove()}return b}});AmCharts.AmRectangularChart=AmCharts.Class({inherits:AmCharts.AmCoordinateChart,construct:function(a){AmCharts.AmRectangularChart.base.construct.call(this,a);this.theme=a;this.createEvents("zoomed");this.marginRight=this.marginBottom=this.marginTop=this.marginLeft=20;this.verticalPosition=this.horizontalPosition=this.depth3D=this.angle=0;this.heightMultiplier=this.widthMultiplier=1;this.plotAreaFillColors="#FFFFFF";this.plotAreaFillAlphas=0;this.plotAreaBorderColor="#000000";this.plotAreaBorderAlpha= +0;this.zoomOutButtonImageSize=17;this.zoomOutButtonImage="lens.png";this.zoomOutText="Show all";this.zoomOutButtonColor="#e5e5e5";this.zoomOutButtonAlpha=0;this.zoomOutButtonRollOverAlpha=1;this.zoomOutButtonPadding=8;this.trendLines=[];this.autoMargins=!0;this.marginsUpdated=!1;this.autoMarginOffset=10;AmCharts.applyTheme(this,a,"AmRectangularChart")},initChart:function(){AmCharts.AmRectangularChart.base.initChart.call(this);this.updateDxy();var a=!0;!this.marginsUpdated&&this.autoMargins&&(this.resetMargins(), +a=!1);this.processScrollbars();this.updateMargins();this.updatePlotArea();this.updateScrollbars();this.updateTrendLines();this.updateChartCursor();this.updateValueAxes();a&&(this.scrollbarOnly||this.updateGraphs())},drawChart:function(){AmCharts.AmRectangularChart.base.drawChart.call(this);this.drawPlotArea();if(AmCharts.ifArray(this.chartData)){var a=this.chartCursor;a&&a.draw();a=this.zoomOutText;""!==a&&a&&this.drawZoomOutButton()}},resetMargins:function(){var a={},b;if("serial"==this.type){var c= +this.valueAxes;for(b=0;b=e-c&&(this.marginRight=Math.round(k-e+c));d.top&&hf-c&&(this.marginBottom=Math.round(this.marginBottom+b-f+c));this.initChart()},getAxisBounds:function(a,b,c,d,e){if(!a.ignoreAxisWidth){var f=a.labelsSet,g=a.tickLength;a.inside&&(g=0);if(f)switch(f=a.getBBox(),a.position){case "top":a=f.y; +d>a&&(d=a);break;case "bottom":a=f.y+f.height;ea&&(b=a)}}return{l:b,t:d,r:c,b:e}},drawZoomOutButton:function(){var a=this,b=a.container.set();a.zoomButtonSet.push(b);var c=a.color,d=a.fontSize,e=a.zoomOutButtonImageSize,f=a.zoomOutButtonImage,g=AmCharts.lang.zoomOutText||a.zoomOutText,h=a.zoomOutButtonColor,k=a.zoomOutButtonAlpha,l=a.zoomOutButtonFontSize,m=a.zoomOutButtonPadding;isNaN(l)||(d=l);(l=a.zoomOutButtonFontColor)&& +(c=l);var l=a.zoomOutButton,n;l&&(l.fontSize&&(d=l.fontSize),l.color&&(c=l.color),l.backgroundColor&&(h=l.backgroundColor),isNaN(l.backgroundAlpha)||(a.zoomOutButtonRollOverAlpha=l.backgroundAlpha));var p=l=0;void 0!==a.pathToImages&&f&&(n=a.container.image(a.pathToImages+f,0,0,e,e),b.push(n),n=n.getBBox(),l=n.width+5);void 0!==g&&(c=AmCharts.text(a.container,g,c,a.fontFamily,d,"start"),d=c.getBBox(),p=n?n.height/2-3:d.height/2,c.translate(l,p),b.push(c));n=b.getBBox();c=1;AmCharts.isModern||(c=0); +h=AmCharts.rect(a.container,n.width+2*m+5,n.height+2*m-2,h,1,1,h,c);h.setAttr("opacity",k);h.translate(-m,-m);b.push(h);h.toBack();a.zbBG=h;n=h.getBBox();b.translate(a.marginLeftReal+a.plotAreaWidth-n.width+m,a.marginTopReal+m);b.hide();b.mouseover(function(){a.rollOverZB()}).mouseout(function(){a.rollOutZB()}).click(function(){a.clickZB()}).touchstart(function(){a.rollOverZB()}).touchend(function(){a.rollOutZB();a.clickZB()});for(k=0;ka&&(a=1);1>b&&(b=1);this.plotAreaWidth=Math.round(a);this.plotAreaHeight=Math.round(b)},updateDxy:function(){this.dx=Math.round(this.depth3D*Math.cos(this.angle*Math.PI/180));this.dy=Math.round(-this.depth3D*Math.sin(this.angle*Math.PI/180));this.d3x= +Math.round(this.columnSpacing3D*Math.cos(this.angle*Math.PI/180));this.d3y=Math.round(-this.columnSpacing3D*Math.sin(this.angle*Math.PI/180))},updateMargins:function(){var a=this.getTitleHeight();this.titleHeight=a;this.marginTopReal=this.marginTop-this.dy+a;this.marginBottomReal=this.marginBottom;this.marginLeftReal=this.marginLeft;this.marginRightReal=this.marginRight},updateValueAxes:function(){var a=this.valueAxes,b=this.marginLeftReal,c=this.marginTopReal,d=this.plotAreaHeight,e=this.plotAreaWidth, +f;for(f=0;fb&&(b=Math.abs(b),q=-b);0>c&&(c=Math.abs(c),r=-c);q+=AmCharts.dx;r+=AmCharts.dy;e={fill:n,stroke:g,"fill-opacity":e,"stroke-opacity":h};void 0!==m&&0=s&&(e=s);var v=1/180*Math.PI,s=b+Math.sin(d*v)*h,w=c-Math.cos(d*v)*q,t=b+Math.sin(d*v)*f,u=c-Math.cos(d*v)*g,y=b+Math.sin((d+e)*v)*f,E=c-Math.cos((d+e)*v)*g,A=b+Math.sin((d+e)*v)*h,v=c-Math.cos((d+e)*v)*q,z={fill:AmCharts.adjustLuminosity(l.fill,-.2),"stroke-opacity":0,"fill-opacity":l["fill-opacity"]},K=0;180Math.abs(e)&&1>=Math.abs(y-t)&&1>=Math.abs(E-u)&&(I=!0));e="";var F;n&&(z["fill-opacity"]=0,z["stroke-opacity"]=l["stroke-opacity"]/2,z.stroke=l.stroke);0a.length&&(a=String(a[0])+String(a[0])+String(a[1])+String(a[1])+String(a[2])+String(a[2]));b=b||0;var c="#",d,e;for(e=0;3>e;e++)d=parseInt(a.substr(2*e,2),16),d=Math.round(Math.min(Math.max(0,d+d*b),255)).toString(16),c+=("00"+d).substr(d.length);return c};AmCharts.Bezier=AmCharts.Class({construct:function(a,b,c,d,e,f,g,h,k,l){"object"==typeof g&&(g=g[0]);"object"==typeof h&&(h=h[0]);f={fill:g,"fill-opacity":h,"stroke-width":f};void 0!==k&&0c&&(h=c);b.push({x:k.x-h/e,y:k.y-d/f});b.push({x:k.x,y:k.y});b.push({x:k.x+h/e,y:k.y+d/f})}d=a[a.length-1].y-a[a.length-2].y;c=a[a.length-1].x-a[a.length-2].x;b.push({x:a[a.length-1].x- +c/e,y:a[a.length-1].y-d/f});b.push({x:a[a.length-1].x,y:a[a.length-1].y});return b},drawBeziers:function(a){var b="",c;for(c=0;c<(a.length-1)/3;c++)b+=this.drawBezierMidpoint(a[3*c],a[3*c+1],a[3*c+2],a[3*c+3]);return b},drawBezierMidpoint:function(a,b,c,d){var e=Math.round,f=this.getPointOnSegment(a,b,.75),g=this.getPointOnSegment(d,c,.75),h=(d.x-a.x)/16,k=(d.y-a.y)/16,l=this.getPointOnSegment(a,b,.375);a=this.getPointOnSegment(f,g,.375);a.x-=h;a.y-=k;b=this.getPointOnSegment(g,f,.375);b.x+=h;b.y+= +k;c=this.getPointOnSegment(d,c,.375);h=this.getMiddle(l,a);f=this.getMiddle(f,g);g=this.getMiddle(b,c);l=" Q"+e(l.x)+","+e(l.y)+","+e(h.x)+","+e(h.y);l+=" Q"+e(a.x)+","+e(a.y)+","+e(f.x)+","+e(f.y);l+=" Q"+e(b.x)+","+e(b.y)+","+e(g.x)+","+e(g.y);return l+=" Q"+e(c.x)+","+e(c.y)+","+e(d.x)+","+e(d.y)},getMiddle:function(a,b){return{x:(a.x+b.x)/2,y:(a.y+b.y)/2}},getPointOnSegment:function(a,b,c){return{x:a.x+(b.x-a.x)*c,y:a.y+(b.y-a.y)*c}}});AmCharts.AmDraw=AmCharts.Class({construct:function(a,b,c,d){AmCharts.SVG_NS="http://www.w3.org/2000/svg";AmCharts.SVG_XLINK="http://www.w3.org/1999/xlink";AmCharts.hasSVG=!!document.createElementNS&&!!document.createElementNS(AmCharts.SVG_NS,"svg").createSVGRect;1>b&&(b=10);1>c&&(c=10);this.div=a;this.width=b;this.height=c;this.rBin=document.createElement("div");if(AmCharts.hasSVG){AmCharts.SVG=!0;var e=this.createSvgElement("svg");e.style.position="absolute";e.style.width=b+"px";e.style.height=c+ +"px";b=this.createSvgElement("desc");b.appendChild(document.createTextNode("JavaScript chart by amCharts "+d.version));e.appendChild(b);AmCharts.rtl&&(e.setAttribute("direction","rtl"),e.style.left="auto",e.style.right="0px");e.setAttribute("version","1.1");a.appendChild(e);this.container=e;this.R=new AmCharts.SVGRenderer(this)}else AmCharts.isIE&&AmCharts.VMLRenderer&&(AmCharts.VML=!0,AmCharts.vmlStyleSheet||(document.namespaces.add("amvml","urn:schemas-microsoft-com:vml"),31>document.styleSheets.length? +(e=document.createStyleSheet(),e.addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true"),AmCharts.vmlStyleSheet=e):document.styleSheets[0].addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true")),this.container=a,this.R=new AmCharts.VMLRenderer(this,d),this.R.disableSelection(a))},createSvgElement:function(a){return document.createElementNS(AmCharts.SVG_NS,a)},circle:function(a,b,c,d){var e=new AmCharts.AmDObject("circle",this);e.attr({r:c, +cx:a,cy:b});this.addToContainer(e.node,d);return e},setSize:function(a,b){0c&&(c=1);1>d&&(d=1);h.attr({x:a,y:b,width:c,height:d,rx:e,ry:e,"stroke-width":f});this.addToContainer(h.node,g);return h},image:function(a,b,c,d,e,f){var g=new AmCharts.AmDObject("image", +this);g.attr({x:b,y:c,width:d,height:e});this.R.path(g,a);this.addToContainer(g.node,f);return g},addToContainer:function(a,b){b||(b=this.container);b.appendChild(a)},text:function(a,b,c){return this.R.text(a,b,c)},path:function(a,b,c,d){var e=new AmCharts.AmDObject("path",this);d||(d="100,100");e.attr({cs:d});c?e.attr({dd:a}):e.attr({d:a});this.addToContainer(e.node,b);return e},set:function(a){return this.R.set(a)},remove:function(a){if(a){var b=this.rBin;b.appendChild(a);b.innerHTML=""}},renderFix:function(){var a= +this.container,b=a.style,c;try{c=a.getScreenCTM()||a.createSVGMatrix()}catch(d){c=a.createSVGMatrix()}a=1-c.e%1;c=1-c.f%1;.5c&&(g="dot"), +3<=c&&6>=c&&(g="dash"),6g&&(b+=g);0>h&&(c+=h)}return{x:b,y:c,width:d, +height:e}},setText:function(a,b){var c=a.node;c&&(c.innerHTML=b);this.setAttr(a,"text-anchor",a.anchor)},addListener:function(a,b,c){a.node["on"+b]=c},move:function(a,b,c){var d=a.node,e=d.style;"text"==a.type&&(c-=AmCharts.removePx(e.fontSize)/2-1);"oval"==a.shapeType&&(b-=AmCharts.removePx(e.width)/2,c-=AmCharts.removePx(e.height)/2);a=a.bw;isNaN(a)||(b-=a,c-=a);isNaN(b)||isNaN(c)||(d.style.left=b+"px",d.style.top=c+"px")},svgPathToVml:function(a){var b=a.split(" ");a="";var c,d=Math.round,e;for(e= +0;ethis.fontSize&&(this.ly=e/2-1);0p&&(p=u);w=w.height;w>q&&(q=w)}var u=q=0,y=f,E=0,A=0;for(t=0;tA&&(A=w.height);K+w.width>n&&0=k&& +(u=0,q++,E=E+A+l,A=0);r.push(z)}w=r.getBBox();k=w.height+2*l-1;"left"==a||"right"==a?(h=w.width+2*f,g.style.width=h+b+c+"px"):h=h-b-c-1;c=AmCharts.polygon(this.container,[0,h,h,0],[0,0,k,k],this.backgroundColor,this.backgroundAlpha,1,this.borderColor,this.borderAlpha);s.push(c);s.translate(b,d);c.toBack();b=f;if("top"==a||"bottom"==a||"absolute"==a||"outside"==a)"center"==this.align?b=f+(h-w.width)/2:"right"==this.align&&(b=f+h-w.width);r.translate(b,l+1);this.titleHeight>k&&(k=this.titleHeight); +a=k+d+e+1;0>a&&(a=0);g.style.height=Math.round(a)+"px"},createEntry:function(a){if(!1!==a.visibleInLegend){var b=this.chart,c=a.markerType;c||(c=this.markerType);var d=a.color,e=a.alpha;a.legendKeyColor&&(d=a.legendKeyColor());a.legendKeyAlpha&&(e=a.legendKeyAlpha());var f;!0===a.hidden&&(f=d=this.markerDisabledColor);var g=a.pattern,h=a.customMarker;h||(h=this.customMarker);var k=this.container,l=this.markerSize,m=0,n=0,p=l/2;if(this.useGraphSettings)if(m=a.type,this.switchType=void 0,"line"==m|| +"step"==m||"smoothedLine"==m||"ohlc"==m)g=k.set(),a.hidden||(d=a.lineColorR,f=a.bulletBorderColorR),n=AmCharts.line(k,[0,2*l],[l/2,l/2],d,a.lineAlpha,a.lineThickness,a.dashLength),g.push(n),a.bullet&&(a.hidden||(d=a.bulletColorR),n=AmCharts.bullet(k,a.bullet,a.bulletSize,d,a.bulletAlpha,a.bulletBorderThickness,f,a.bulletBorderAlpha))&&(n.translate(l+1,l/2),g.push(n)),p=0,m=l,n=l/3;else{var q;a.getGradRotation&&(q=a.getGradRotation());m=a.fillColorsR;!0===a.hidden&&(m=d);if(g=this.createMarker("rectangle", +m,a.fillAlphas,a.lineThickness,d,a.lineAlpha,q,g))p=l,g.translate(p,l/2);m=l}else h?(b.path&&(h=b.path+h),g=k.image(h,0,0,l,l)):(g=this.createMarker(c,d,e,void 0,void 0,void 0,void 0,g))&&g.translate(l/2,l/2);this.addListeners(g,a);k=k.set([g]);this.switchable&&a.switchable&&k.setAttr("cursor","pointer");(f=this.switchType)&&"none"!=f&&("x"==f?(q=this.createX(),q.translate(l/2,l/2)):q=this.createV(),q.dItem=a,!0!==a.hidden?"x"==f?q.hide():q.show():"x"!=f&&q.hide(),this.switchable||q.hide(),this.addListeners(q, +a),a.legendSwitch=q,k.push(q));f=this.color;a.showBalloon&&this.textClickEnabled&&void 0!==this.selectedColor&&(f=this.selectedColor);this.useMarkerColorForLabels&&(f=d);!0===a.hidden&&(f=this.markerDisabledColor);d=AmCharts.massReplace(this.labelText,{"[[title]]":a.title});q=this.fontSize;g&&l<=q&&g.translate(p,l/2+this.ly-q/2+(q+2-l)/2-n);var r;d&&(d=AmCharts.fixBrakes(d),a.legendTextReal=d,r=this.labelWidth,r=isNaN(r)?AmCharts.text(this.container,d,f,b.fontFamily,q,"start"):AmCharts.wrappedText(this.container, +d,f,b.fontFamily,q,"start",!1,r,0),r.translate(this.lx+m,this.ly),k.push(r),b=r.getBBox().width,this.maxLabelWidthc&&(d="00"+c);10<=c&&100>c&&(d="0"+c);a=a.replace(/fff/g,d)}return a};AmCharts.extractPeriod=function(a){var b=AmCharts.stripNumbers(a),c=1;b!=a&&(c=Number(a.slice(0,a.indexOf(b))));return{period:b,count:c}}; +AmCharts.newDate=function(a,b){return date="fff"==b?AmCharts.useUTC?new Date(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate(),a.getUTCHours(),a.getUTCMinutes(),a.getUTCSeconds(),a.getUTCMilliseconds()):new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes(),a.getSeconds(),a.getMilliseconds()):new Date(a)}; +AmCharts.resetDateToMin=function(a,b,c,d){void 0===d&&(d=1);var e,f,g,h,k,l,m;AmCharts.useUTC?(e=a.getUTCFullYear(),f=a.getUTCMonth(),g=a.getUTCDate(),h=a.getUTCHours(),k=a.getUTCMinutes(),l=a.getUTCSeconds(),m=a.getUTCMilliseconds(),a=a.getUTCDay()):(e=a.getFullYear(),f=a.getMonth(),g=a.getDate(),h=a.getHours(),k=a.getMinutes(),l=a.getSeconds(),m=a.getMilliseconds(),a=a.getDay());switch(b){case "YYYY":e=Math.floor(e/c)*c;f=0;g=1;m=l=k=h=0;break;case "MM":f=Math.floor(f/c)*c;g=1;m=l=k=h=0;break;case "WW":0=== +a&&0=c[b].contains?(a=Math.round(a/c[b].contains),b=c[b].nextInterval,AmCharts.getMaxInterval(a,b)):"ss"==b?c[b].nextInterval:b};AmCharts.dayNames="Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" ");AmCharts.shortDayNames="Sun Mon Tue Wed Thu Fri Sat".split(" ");AmCharts.monthNames="January February March April May June July August September October November December".split(" ");AmCharts.shortMonthNames="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "); +AmCharts.getWeekNumber=function(a){a=new Date(a);a.setHours(0,0,0);a.setDate(a.getDate()+4-(a.getDay()||7));var b=new Date(a.getFullYear(),0,1);return Math.ceil(((a-b)/864E5+1)/7)}; +AmCharts.stringToDate=function(a,b){var c={},d=[{pattern:"YYYY",period:"year"},{pattern:"YY",period:"year"},{pattern:"MM",period:"month"},{pattern:"M",period:"month"},{pattern:"DD",period:"date"},{pattern:"D",period:"date"},{pattern:"JJ",period:"hours"},{pattern:"J",period:"hours"},{pattern:"HH",period:"hours"},{pattern:"H",period:"hours"},{pattern:"KK",period:"hours"},{pattern:"K",period:"hours"},{pattern:"LL",period:"hours"},{pattern:"L",period:"hours"},{pattern:"NN",period:"minutes"},{pattern:"N", +period:"minutes"},{pattern:"SS",period:"seconds"},{pattern:"S",period:"seconds"},{pattern:"QQQ",period:"milliseconds"},{pattern:"QQ",period:"milliseconds"},{pattern:"Q",period:"milliseconds"}],e=!0,f=b.indexOf("AA");-1!=f&&(a.substr(f,2),"pm"==a.toLowerCase&&(e=!1));var f=b,g,h,k;for(k=0;kd&&(p="0"+p);var q="0"+f;b=b.replace(/W/g,m);m=g;24==m&&(m=0);var r=m;10>r&&(r= +"0"+r);b=b.replace(/JJ/g,r);b=b.replace(/J/g,m);r=g;0===r&&(r=24,-1!=b.indexOf("H")&&e--);m=e;10>e&&(m="0"+e);var s=r;10>s&&(s="0"+s);b=b.replace(/HH/g,s);b=b.replace(/H/g,r);r=g;11s&&(s="0"+s);b=b.replace(/KK/g,s);b=b.replace(/K/g,r);r=g;0===r&&(r=12);12s&&(s="0"+s);b=b.replace(/LL/g,s);b=b.replace(/L/g,r);r=h;10>r&&(r="0"+r);b=b.replace(/NN/g,r);b=b.replace(/N/g,h);h=k;10>h&&(h="0"+h);b=b.replace(/SS/g,h);b=b.replace(/S/g,k);k=l;10>k&&(k="00"+k);100>k&&(k="0"+ +k);h=l;10>h&&(h="00"+h);b=b.replace(/QQQ/g,k);b=b.replace(/QQ/g,h);b=b.replace(/Q/g,l);b=12>g?b.replace(/A/g,"am"):b.replace(/A/g,"pm");b=b.replace(/YYYY/g,"@IIII@");b=b.replace(/YY/g,"@II@");b=b.replace(/MMMM/g,"@XXXX@");b=b.replace(/MMM/g,"@XXX@");b=b.replace(/MM/g,"@XX@");b=b.replace(/M/g,"@X@");b=b.replace(/DD/g,"@RR@");b=b.replace(/D/g,"@R@");b=b.replace(/EEEE/g,"@PPPP@");b=b.replace(/EEE/g,"@PPP@");b=b.replace(/EE/g,"@PP@");b=b.replace(/E/g,"@P@");b=b.replace(/@IIII@/g,c);b=b.replace(/@II@/g, +n);b=b.replace(/@XXXX@/g,AmCharts.monthNames[d]);b=b.replace(/@XXX@/g,AmCharts.shortMonthNames[d]);b=b.replace(/@XX@/g,p);b=b.replace(/@X@/g,d+1);b=b.replace(/@RR@/g,m);b=b.replace(/@R@/g,e);b=b.replace(/@PPPP@/g,AmCharts.dayNames[f]);b=b.replace(/@PPP@/g,AmCharts.shortDayNames[f]);b=b.replace(/@PP@/g,q);return b=b.replace(/@P@/g,f)}; +AmCharts.changeDate=function(a,b,c,d,e){var f=-1;void 0===d&&(d=!0);void 0===e&&(e=!1);!0===d&&(f=1);switch(b){case "YYYY":a.setFullYear(a.getFullYear()+c*f);d||e||a.setDate(a.getDate()+1);break;case "MM":b=a.getMonth();a.setMonth(a.getMonth()+c*f);a.getMonth()>b+c*f&&a.setDate(a.getDate()-1);d||e||a.setDate(a.getDate()+1);break;case "DD":a.setDate(a.getDate()+c*f);break;case "WW":a.setDate(a.getDate()+c*f*7);break;case "hh":a.setHours(a.getHours()+c*f);break;case "mm":a.setMinutes(a.getMinutes()+ c*f);break;case "ss":a.setSeconds(a.getSeconds()+c*f);break;case "fff":a.setMilliseconds(a.getMilliseconds()+c*f)}return a}; \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/exporting/amexport.js b/web/src/main/webapp/components/amcharts/exporting/amexport.js index 00e631119223..9c349272b517 100755 --- a/web/src/main/webapp/components/amcharts/exporting/amexport.js +++ b/web/src/main/webapp/components/amcharts/exporting/amexport.js @@ -1,793 +1,793 @@ -AmCharts.AmExport = AmCharts.Class({ - construct: function(chart, cfg, init ) { - var _this = this; - _this.DEBUG = false; - _this.chart = chart; - _this.canvas = null; - _this.svgs = []; - _this.userCFG = cfg; - - _this.buttonIcon = 'export.png'; - _this.exportPNG = true; - _this.exportPDF = false; - _this.exportJPG = false; - _this.exportSVG = false; - //_this.left; - _this.right = 0; - //_this.bottom; - _this.top = 0; - //_this.color; - _this.buttonRollOverColor = "#EFEFEF"; - //_this.buttonColor = "#FFFFFF"; - //_this.buttonRollOverAlpha = 0.5; - _this.textRollOverColor = "#CC0000"; - _this.buttonTitle = "Save chart as an image"; - _this.buttonAlpha = 0.75; - _this.imageFileName = "amChart"; - _this.imageBackgroundColor = "#FFFFFF"; - - if (init) { - _this.init(); - } - }, - - toCoordinate:function(value){ - if(value === undefined){ - return "auto"; - } - if(String(value).indexOf("%") != -1){ - return value; - } - else{ - return value + "px"; - } - }, - - init: function(){ - var _this = this; - - var formats = []; - if (_this.exportPNG) { - formats.push("png"); - } - if (_this.exportPDF) { - formats.push("pdf"); - } - if (_this.exportJPG) { - formats.push("jpg"); - } - if (_this.exportSVG) { - formats.push("svg"); - } - - var menuItems = []; - if(formats.length == 1){ - var format = formats[0]; - menuItems.push({format:format, iconTitle:_this.buttonTitle, icon:_this.chart.pathToImages + _this.buttonIcon}) - } - else if(formats.length > 1){ - var subItems = []; - for(var i = 0; i < formats.length; i++){ - subItems.push({format:formats[i], title:formats[i].toUpperCase()}); - } - menuItems.push({onclick: function() {}, icon:_this.chart.pathToImages + _this.buttonIcon, items:subItems}) - } - - - var color = _this.color; - if(color === undefined){ - color = _this.chart.color; - } - - var buttonColor = _this.buttonColor; - if(buttonColor === undefined){ - buttonColor = "transparent"; - } - - - _this.cfg = { - menuTop : _this.toCoordinate(_this.top), - menuLeft : _this.toCoordinate(_this.left), - menuRight : _this.toCoordinate(_this.right), - menuBottom : _this.toCoordinate(_this.bottom), - menuItems : menuItems, - menuItemStyle: { - backgroundColor : buttonColor, - opacity :_this.buttonAlpha, - rollOverBackgroundColor : _this.buttonRollOverColor, - color : color, - rollOverColor : _this.textRollOverColor, - paddingTop : '6px', - paddingRight : '6px', - paddingBottom : '6px', - paddingLeft : '6px', - marginTop : '0px', - marginRight : '0px', - marginBottom : '0px', - marginLeft : '0px', - textAlign : 'left', - textDecoration : 'none', - fontFamily : _this.chart.fontFamily, - fontSize : _this.chart.fontSize + 'px' - }, - menuItemOutput: { - backgroundColor : _this.imageBackgroundColor, - fileName : _this.imageFileName, - format : 'png', - output : 'dataurlnewwindow', - render : 'browser', - dpi : 90, - onclick : function(instance, config, event) { - event.preventDefault(); - if(_this.chart.prepareForExport){ - _this.chart.prepareForExport(); - } - instance.output(config); - } - }, - removeImagery: true - }; - - _this.processing = { - buffer: [], - drawn: 0, - timer: 0 - }; - - // Config dependency adaption - if (typeof(window.canvg) != 'undefined' && typeof(window.RGBColor) != 'undefined') { - _this.cfg.menuItemOutput.render = 'canvg'; - } - if (typeof(window.saveAs) != 'undefined') { - _this.cfg.menuItemOutput.output = 'save'; - } - if (AmCharts.isIE && AmCharts.IEversion < 10) { - _this.cfg.menuItemOutput.output = 'dataurlnewwindow'; - } - - // Merge given configs - var cfg = _this.userCFG; - if (cfg) { - cfg.menuItemOutput = AmCharts.extend(_this.cfg.menuItemOutput, cfg.menuItemOutput || {}); - cfg.menuItemStyle = AmCharts.extend(_this.cfg.menuItemStyle, cfg.menuItemStyle || {}); - _this.cfg = AmCharts.extend(_this.cfg, cfg); - } - - // Add reference to chart - _this.chart.AmExport = _this; - - // Listen to the drawer - _this.chart.addListener('rendered', function() { - _this.setup(); - }); - - // DEBUG; Public reference - if (_this.DEBUG) { - window.AmExport = _this; - } - }, - - - /* - Simple log function for internal purpose - @param **args - */ - log: function() { - console.log('AmExport: ', arguments); - }, - - /* PUBLIC - Prepares everything to get exported - @param none - */ - setup: function() { - var _this = this; - - if (_this.DEBUG == 10) { - _this.log('SETUP START'); - } // DEBUG - - - if (!AmCharts.isIE || (AmCharts.isIE && AmCharts.IEversion > 9)) { - // Build Buttons - _this.generateButtons(); - if (_this.DEBUG == 10) { - _this.log('SETUP END'); - } // DEBUG - } else { - if (_this.DEBUG == 10) { - _this.log('< IE10 NOT SUPPORTED'); - } // DEBUG - } - }, - - /* PUBLIC - Decodes base64 string to binary array - @param base64_string - @copyright Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr - */ - generateBinaryArray: function(base64_string) { - var - len = base64_string.length, - buffer = new Uint8Array(len / 4 * 3 | 0), - i = 0, - outptr = 0, - last = [0, 0], - state = 0, - save = 0, - rank, code, undef, base64_ranks = new Uint8Array([ - 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 - ]); - while (len--) { - code = base64_string.charCodeAt(i++); - rank = base64_ranks[code - 43]; - if (rank !== 255 && rank !== undef) { - last[1] = last[0]; - last[0] = code; - save = (save << 6) | rank; - state++; - if (state === 4) { - buffer[outptr++] = save >>> 16; - if (last[1] !== 61 /* padding character */ ) { - buffer[outptr++] = save >>> 8; - } - if (last[0] !== 61 /* padding character */ ) { - buffer[outptr++] = save; - } - state = 0; - } - } - } - // 2/3 chance there's going to be some null bytes at the end, but that - // doesn't really matter with most image formats. - // If it somehow matters for you, truncate the buffer up outptr. - return buffer; - }, - - /* - Creates blob object - @param base64_datastring string - @param type string - */ - generateBlob: function(datastring, type) { - var _this = this, - header_end = type!='image/svg+xml'?datastring.indexOf(',') + 1:0, - header = datastring.substring(0, header_end), - data = datastring, - blob = new Blob(); - - if (header.indexOf('base64') != -1) { - data = _this.generateBinaryArray(datastring.substring(header_end)); - } - - // Fake blob for IE - if (AmCharts.isIE && AmCharts.IEversion < 10) { - blob.data = data; - blob.size = data.length; - blob.type = type; - blob.encoding = 'base64'; - } else { - blob = new Blob([data], { - type: type - }); - } - return blob; - }, - - /* - Creates PDF object - @param config object - */ - generatePDF: function(cfg) { - var _this = this, - pdf = { - output: function() { - return ''; - } - }, - data = _this.canvas.toDataURL('image/jpeg'), // JSPDF ONLY SUPPORTS JPG - width = (_this.canvas.width * 25.4) / cfg.dpi, - height = (_this.canvas.height * 25.4) / cfg.dpi; - - // Check - if (window.jsPDF) { - pdf = new jsPDF(); - if (pdf.addImage) { - pdf.addImage(data, 'JPEG', 0, 0, width, height); - } else { - alert("Missing jsPDF plugin; Please add the 'addImage' plugin."); - } - } else { - alert("Missing jsPDF lib; Don't forget to add the addImage plugin."); - } - - return pdf; - }, - - /* - Creates the CANVAS to receive the image data - @param format void() - @param callback; given callback function which returns the blob or datastring of the configured ouput type - */ - output: function(cfg, externalCallback) { - var _this = this; - cfg = AmCharts.extend(AmCharts.extend({}, _this.cfg.menuItemOutput), cfg || {}); - - /* PRIVATE - Callback function which gets called after the drawing process is done - @param none - */ - function internalCallback() { - var data = null; - var blob; - if (_this.DEBUG == 10) { - _this.log('OUTPUT', cfg.format); - } // DEBUG - - // SVG - if (cfg.format == 'image/svg+xml' || cfg.format == 'svg') { - data = _this.generateSVG(); - blob = _this.generateBlob(data, 'image/svg+xml'); - - if (cfg.output == 'save') { - saveAs(blob, cfg.fileName + '.svg'); - } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { - blob = 'data:image/svg+xml;base64,' + btoa(data); - } else if (cfg.output == 'dataurlnewwindow') { - window.open('data:image/svg+xml;base64,' + btoa(data)); - } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { - location.href = 'data:image/svg+xml;base64,' + btoa(data); - } else if (cfg.output == 'datastream') { - location.href = 'data:image/octet-stream;base64,' + data; - } - - if (externalCallback) - externalCallback.apply(_this, [blob]); - - // PDF - } else if (cfg.format == 'application/pdf' || cfg.format == 'pdf') { - data = _this.generatePDF(cfg).output('dataurlstring'); - blob = _this.generateBlob(data, 'application/pdf'); - - if (cfg.output == 'save') { - saveAs(blob, cfg.fileName + '.pdf'); - } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { - blob = data; - } else if (cfg.output == 'dataurlnewwindow') { - window.open(data); - } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { - location.href = data; - } else if (cfg.output == 'datastream') { - location.href = data.replace('application/pdf', 'application/octet-stream'); - } - - if (externalCallback) - externalCallback.apply(_this, [blob]); - - // PNG - } else if (cfg.format == 'image/png' || cfg.format == 'png') { - data = _this.canvas.toDataURL('image/png'); - blob = _this.generateBlob(data, 'image/png'); - - if (cfg.output == 'save') { - saveAs(blob, cfg.fileName + '.png'); - } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { - blob = data; - } else if (cfg.output == 'dataurlnewwindow') { - window.open(data); - } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { - location.href = data; - } else if (cfg.output == 'datastream') { - location.href = data.replace('image/png', 'image/octet-stream'); - } - - if (externalCallback) - externalCallback.apply(_this, [blob]); - - // JPG - } else if (cfg.format == 'image/jpeg' || cfg.format == 'jpeg' || cfg.format == 'jpg') { - data = _this.canvas.toDataURL('image/jpeg'); - blob = _this.generateBlob(data, 'image/jpeg'); - - if (cfg.output == 'save') { - saveAs(blob, cfg.fileName + '.jpg'); - } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { - blob = data; - } else if (cfg.output == 'dataurlnewwindow') { - window.open(data); - } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { - location.href = data; - } else if (cfg.output == 'datastream') { - location.href = data.replace('image/jpeg', 'image/octet-stream'); - } - - if (externalCallback) - externalCallback.apply(_this, [blob]); - } - - } - - return _this.generateOutput(cfg, internalCallback); - }, - - /* PUBLIC - Polifies missing attributes to the SVG and replaces images to embedded base64 images - @param none - */ - polifySVG: function(svg) { - var _this = this; - - // Recursive function to force the attributes - function recursiveChange(svg, tag) { - var items = svg.getElementsByTagName(tag); - var i = items.length; - - while(i--) { - if (_this.cfg.removeImagery) { - items[i].parentNode.removeChild(items[i]); - - } else { - var image = document.createElement('img'); - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - - canvas.width = items[i].getAttribute('width'); - canvas.height = items[i].getAttribute('height'); - image.src = items[i].getAttribute('xlink:href'); - image.width = items[i].getAttribute('width'); - image.height = items[i].getAttribute('height'); - - try { - ctx.drawImage(image, 0, 0, image.width, image.height); - datastring = canvas.toDataURL(); // image.src; // canvas.toDataURL(); // - } catch (err) { - datastring = image.src; // image.src; // canvas.toDataURL(); // - - _this.log('Tainted canvas, reached browser CORS security; origin from imagery must be equal to the server!'); - throw new Error(err); - } - - items[i].setAttribute('xlink:href', datastring); - } - - if (_this.DEBUG == 10) { - _this.log('POLIFIED', items[i]); - } // DEBUG - } - } - - // Put some attrs to it; fixed 20/03/14 xmlns is required to produce a valid svg file - if (AmCharts.IEversion == 0) { - svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); - if ( !_this.cfg.removeImagery ) { - svg.setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); - } - } - - // DEBUG - if (_this.DEBUG == 10) { - _this.log('POLIFIED', svg); - } - - // Force link adaption - recursiveChange(svg, 'pattern'); - recursiveChange(svg, 'image'); - - _this.svgs.push(svg); - - return svg; - }, - - - /* PUBLIC - Stacks multiple SVGs into one - @param none - */ - generateSVG: function() { - var _this = this; - var context = document.createElement('svg'); - context.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); - context.setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); - - for (var i = 0; i < _this.processing.buffer.length; i++) { - var group = document.createElement('g'), - data = _this.processing.buffer[i]; - - data[0].setAttribute('xmlns', 'http://www.w3.org/2000/svg'); - data[0].setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); - - group.setAttribute('transform', 'translate('+data[1].x+','+data[1].y+')'); - group.appendChild(data[0]); - context.appendChild(group); - } - - return new XMLSerializer().serializeToString(context); - }, - - /* PUBLIC - Generates the canvas with the given SVGs and configured renderer - @param callback; function(); gets called after drawing process on the canvas has been finished - */ - generateOutput: function(cfg, callback) { - var _this = this, - svgs = _this.chart.div.getElementsByTagName('svg'), - canvas = document.createElement('canvas'), - context = canvas.getContext('2d'), - offset = { - y: 0, - x: 0 - }, - tmp = {}; - - // Reset - _this.processing.buffer = []; - _this.processing.drawn = 0; - _this.canvas = canvas; - _this.svgs = []; - - // Walkthroug SVGs - if (_this.DEBUG == 10) { - _this.log('START EXPORT'); - } // DEBUG - if (_this.DEBUG == 10) { - _this.log('START BUFFERING'); - } // DEBUG - for (var i = 0; i < svgs.length; i++) { - var parent = svgs[i].parentNode, - svgX = Number(parent.style.left.slice(0, -2)), - svgY = Number(parent.style.top.slice(0, -2)), - svgClone = _this.polifySVG(svgs[i].cloneNode(true)), - tmp = AmCharts.extend({}, offset); - - // Overtake parent position if given; fixed 20/03/14 distinguish between relativ and others - if (parent.style.position == 'relative') { - offset.x = svgX ? svgX : offset.x; - offset.y = svgY ? svgY : offset.y; - } else { - offset.x = svgX; - offset.y = svgY; - } - - _this.processing.buffer.push([svgClone, AmCharts.extend({}, offset)]); - - // Put back from "cache" - if (svgY && svgX) { - offset = tmp; - - // New offset for next one - } else { - offset.y += svgY ? 0 : parent.offsetHeight; - } - - if (_this.DEBUG == 10) { - _this.log('BUFFERED', svgs[i], offset); - } // DEBUG - } - if (_this.DEBUG == 10) { - _this.log('END BUFFERING'); - } // DEBUG - - // Apply background - if (_this.DEBUG == 10) { - _this.log('START DRAWING', cfg.render); - } // DEBUG - if (_this.DEBUG == 10) { - _this.log('FILL BACKGROUND'); - } // DEBUG - canvas.id = AmCharts.getUniqueId(); - canvas.width = _this.chart.divRealWidth; - canvas.height = _this.chart.divRealHeight; - - - // Stockchart exception - var adapted = { - width: false, - height: false - }; - if ( _this.chart.periodSelector ) { - if ( ['left','right'].indexOf(_this.chart.periodSelector.position) != -1 ) { - canvas.width -= _this.chart.periodSelector.div.offsetWidth + 16; - adapted.width = true; - } else { - canvas.height -= _this.chart.periodSelector.div.offsetHeight; - adapted.height = true; - } - } - - if ( _this.chart.dataSetSelector ) { - if ( ['left','right'].indexOf(_this.chart.dataSetSelector.position) != -1 ) { - if ( !adapted.width ) { - canvas.width -= _this.chart.dataSetSelector.div.offsetWidth + 16; - } - } else { - canvas.height -= _this.chart.dataSetSelector.div.offsetHeight; - } - } - - // Set given background; jpeg default - if (cfg.backgroundColor || cfg.format == 'image/jpeg') { - context.fillStyle = cfg.backgroundColor || '#FFFFFF'; - context.fillRect(0, 0, canvas.width, canvas.height); - } - - /* PRIVATE - Recursive function to draw the images to the canvas; - @param none; - */ - function drawItWhenItsLoaded() { - var img, buffer, offset, source; - - // DRAWING PROCESS DONE - if (_this.processing.buffer.length == _this.processing.drawn || cfg.format == 'svg' ) { - if (_this.DEBUG == 10) { - _this.log('END DRAWING'); - } // DEBUG - return callback(); - - // LOOPING LUI - } else { - if (_this.DEBUG == 10) { - _this.log('DRAW', _this.processing.drawn + 1, 'OF', _this.processing.buffer.length); - } // DEBUG - - buffer = _this.processing.buffer[_this.processing.drawn]; - source = new XMLSerializer().serializeToString(buffer[0]); //source = 'data:image/svg+xml;base64,' + btoa(); - offset = buffer[1]; - - if (_this.DEBUG == 10) { - _this.log('SOURCE', source); - } // DEBUG - - // NATIVE - if (cfg.render == 'browser') { - img = new Image(); - img.id = AmCharts.getUniqueId(); - source = 'data:image/svg+xml;base64,' + btoa(source); - - //img.crossOrigin = "Anonymous"; - img.onload = function() { - context.drawImage(this, buffer[1].x, buffer[1].y); - _this.processing.drawn++; - - if (_this.DEBUG == 10) { - _this.log('ONLOAD', this); - } // DEBUG - drawItWhenItsLoaded(); - }; - img.onerror = function() { - if (_this.DEBUG == 10) { - _this.log('ONERROR', this); - } // DEBUG - context.drawImage(this, buffer[1].x, buffer[1].y); - _this.processing.drawn++; - drawItWhenItsLoaded(); - }; - img.src = source; - - if (_this.DEBUG == 10) { - _this.log('ADD', img); - } // DEBUG - if (img.complete || typeof(img.complete) == 'undefined' || img.complete === undefined) { - if (_this.DEBUG == 10) { - _this.log('FORCE ONLOAD', img); - } // DEBUG - img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; - img.src = source; - } - - // CANVG - } else if (cfg.render == 'canvg') { - canvg(canvas, source, { - offsetX: offset.x, - offsetY: offset.y, - ignoreMouse: true, - ignoreAnimation: true, - ignoreDimensions: true, - ignoreClear: true, - renderCallback: function() { - _this.processing.drawn++; - drawItWhenItsLoaded(); - } - }); - } - } - } - return drawItWhenItsLoaded(); - }, - - /* - Generates the export menu to trigger the exportation - @param none; - */ - generateButtons: function() { - var _this = this, - div = document.createElement('div'), - lvl = 0; - - // Push sublings - function createList(items) { - var ul = document.createElement('ul'); - - ul.setAttribute('style', 'list-style: none; margin: 0; padding: 0;'); - - // Walkthrough items - for (var i = 0; i < items.length; i++) { - var li = document.createElement('li'), - img = document.createElement('img'), - a = document.createElement('a'), - item = items[i], - children = null, - itemStyle = AmCharts.extend(AmCharts.extend({}, _this.cfg.menuItemStyle), items[i]); - - // MERGE CFG - item = AmCharts.extend(AmCharts.extend({}, _this.cfg.menuItemOutput), item); - - // ICON - if (item['icon']) { - img.alt = ''; - img.src = item['icon']; - img.setAttribute('style', 'margin: 0 auto;border: none;outline: none'); - if (item['iconTitle']) { - img.title = item['iconTitle']; - } - a.appendChild(img); - } - - // TITLE; STYLING - a.href = '#'; - if (item['title']) { - img.setAttribute('style', 'margin-right: 5px;'); - a.innerHTML += item.title; - } - a.setAttribute('style', 'display: block;'); - AmCharts.extend(a.style, itemStyle); - - // ONCLICK - a.onclick = item.onclick.bind(a, _this, item); - li.appendChild(a); - - // APPEND SIBLINGS - if (item.items) { - children = createList(item.items); - li.appendChild(children); - - li.onmouseover = function() { - children.style.display = 'block'; - }; - li.onmouseout = function() { - children.style.display = 'none'; - }; - children.style.display = 'none'; - } - - // Append to parent - ul.appendChild(li); - - // Apply hover - a.onmouseover = function() { - this.style.backgroundColor = itemStyle.rollOverBackgroundColor; - this.style.color = itemStyle.rollOverColor; - this.style.borderColor = itemStyle.rollOverBorderColor; - }; - a.onmouseout = function() { - this.style.backgroundColor = itemStyle.backgroundColor; - this.style.color = itemStyle.color; - this.style.borderColor = itemStyle.borderColor; - }; - } - lvl++; - - if (_this.DEBUG == 10) { - _this.log('MENU', ul); - } // DEBUG - - return ul; - } - - // Style wrapper; Push into chart div - div.setAttribute('style', 'width:39px; height:28px; position: absolute;top:' + _this.cfg.menuTop + ';right:' + _this.cfg.menuRight + ';bottom:' + _this.cfg.menuBottom + ';left:' + _this.cfg.menuLeft + ';box-shadow:0px 0px 1px 0px rgba(0,0,0,0);'); - div.setAttribute('class', 'amExportButton'); - div.appendChild(createList(_this.cfg.menuItems)); - _this.chart.containerDiv.appendChild(div); - } +AmCharts.AmExport = AmCharts.Class({ + construct: function(chart, cfg, init ) { + var _this = this; + _this.DEBUG = false; + _this.chart = chart; + _this.canvas = null; + _this.svgs = []; + _this.userCFG = cfg; + + _this.buttonIcon = 'export.png'; + _this.exportPNG = true; + _this.exportPDF = false; + _this.exportJPG = false; + _this.exportSVG = false; + //_this.left; + _this.right = 0; + //_this.bottom; + _this.top = 0; + //_this.color; + _this.buttonRollOverColor = "#EFEFEF"; + //_this.buttonColor = "#FFFFFF"; + //_this.buttonRollOverAlpha = 0.5; + _this.textRollOverColor = "#CC0000"; + _this.buttonTitle = "Save chart as an image"; + _this.buttonAlpha = 0.75; + _this.imageFileName = "amChart"; + _this.imageBackgroundColor = "#FFFFFF"; + + if (init) { + _this.init(); + } + }, + + toCoordinate:function(value){ + if(value === undefined){ + return "auto"; + } + if(String(value).indexOf("%") != -1){ + return value; + } + else{ + return value + "px"; + } + }, + + init: function(){ + var _this = this; + + var formats = []; + if (_this.exportPNG) { + formats.push("png"); + } + if (_this.exportPDF) { + formats.push("pdf"); + } + if (_this.exportJPG) { + formats.push("jpg"); + } + if (_this.exportSVG) { + formats.push("svg"); + } + + var menuItems = []; + if(formats.length == 1){ + var format = formats[0]; + menuItems.push({format:format, iconTitle:_this.buttonTitle, icon:_this.chart.pathToImages + _this.buttonIcon}) + } + else if(formats.length > 1){ + var subItems = []; + for(var i = 0; i < formats.length; i++){ + subItems.push({format:formats[i], title:formats[i].toUpperCase()}); + } + menuItems.push({onclick: function() {}, icon:_this.chart.pathToImages + _this.buttonIcon, items:subItems}) + } + + + var color = _this.color; + if(color === undefined){ + color = _this.chart.color; + } + + var buttonColor = _this.buttonColor; + if(buttonColor === undefined){ + buttonColor = "transparent"; + } + + + _this.cfg = { + menuTop : _this.toCoordinate(_this.top), + menuLeft : _this.toCoordinate(_this.left), + menuRight : _this.toCoordinate(_this.right), + menuBottom : _this.toCoordinate(_this.bottom), + menuItems : menuItems, + menuItemStyle: { + backgroundColor : buttonColor, + opacity :_this.buttonAlpha, + rollOverBackgroundColor : _this.buttonRollOverColor, + color : color, + rollOverColor : _this.textRollOverColor, + paddingTop : '6px', + paddingRight : '6px', + paddingBottom : '6px', + paddingLeft : '6px', + marginTop : '0px', + marginRight : '0px', + marginBottom : '0px', + marginLeft : '0px', + textAlign : 'left', + textDecoration : 'none', + fontFamily : _this.chart.fontFamily, + fontSize : _this.chart.fontSize + 'px' + }, + menuItemOutput: { + backgroundColor : _this.imageBackgroundColor, + fileName : _this.imageFileName, + format : 'png', + output : 'dataurlnewwindow', + render : 'browser', + dpi : 90, + onclick : function(instance, config, event) { + event.preventDefault(); + if(_this.chart.prepareForExport){ + _this.chart.prepareForExport(); + } + instance.output(config); + } + }, + removeImagery: true + }; + + _this.processing = { + buffer: [], + drawn: 0, + timer: 0 + }; + + // Config dependency adaption + if (typeof(window.canvg) != 'undefined' && typeof(window.RGBColor) != 'undefined') { + _this.cfg.menuItemOutput.render = 'canvg'; + } + if (typeof(window.saveAs) != 'undefined') { + _this.cfg.menuItemOutput.output = 'save'; + } + if (AmCharts.isIE && AmCharts.IEversion < 10) { + _this.cfg.menuItemOutput.output = 'dataurlnewwindow'; + } + + // Merge given configs + var cfg = _this.userCFG; + if (cfg) { + cfg.menuItemOutput = AmCharts.extend(_this.cfg.menuItemOutput, cfg.menuItemOutput || {}); + cfg.menuItemStyle = AmCharts.extend(_this.cfg.menuItemStyle, cfg.menuItemStyle || {}); + _this.cfg = AmCharts.extend(_this.cfg, cfg); + } + + // Add reference to chart + _this.chart.AmExport = _this; + + // Listen to the drawer + _this.chart.addListener('rendered', function() { + _this.setup(); + }); + + // DEBUG; Public reference + if (_this.DEBUG) { + window.AmExport = _this; + } + }, + + + /* + Simple log function for internal purpose + @param **args + */ + log: function() { + console.log('AmExport: ', arguments); + }, + + /* PUBLIC + Prepares everything to get exported + @param none + */ + setup: function() { + var _this = this; + + if (_this.DEBUG == 10) { + _this.log('SETUP START'); + } // DEBUG + + + if (!AmCharts.isIE || (AmCharts.isIE && AmCharts.IEversion > 9)) { + // Build Buttons + _this.generateButtons(); + if (_this.DEBUG == 10) { + _this.log('SETUP END'); + } // DEBUG + } else { + if (_this.DEBUG == 10) { + _this.log('< IE10 NOT SUPPORTED'); + } // DEBUG + } + }, + + /* PUBLIC + Decodes base64 string to binary array + @param base64_string + @copyright Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr + */ + generateBinaryArray: function(base64_string) { + var + len = base64_string.length, + buffer = new Uint8Array(len / 4 * 3 | 0), + i = 0, + outptr = 0, + last = [0, 0], + state = 0, + save = 0, + rank, code, undef, base64_ranks = new Uint8Array([ + 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + ]); + while (len--) { + code = base64_string.charCodeAt(i++); + rank = base64_ranks[code - 43]; + if (rank !== 255 && rank !== undef) { + last[1] = last[0]; + last[0] = code; + save = (save << 6) | rank; + state++; + if (state === 4) { + buffer[outptr++] = save >>> 16; + if (last[1] !== 61 /* padding character */ ) { + buffer[outptr++] = save >>> 8; + } + if (last[0] !== 61 /* padding character */ ) { + buffer[outptr++] = save; + } + state = 0; + } + } + } + // 2/3 chance there's going to be some null bytes at the end, but that + // doesn't really matter with most image formats. + // If it somehow matters for you, truncate the buffer up outptr. + return buffer; + }, + + /* + Creates blob object + @param base64_datastring string + @param type string + */ + generateBlob: function(datastring, type) { + var _this = this, + header_end = type!='image/svg+xml'?datastring.indexOf(',') + 1:0, + header = datastring.substring(0, header_end), + data = datastring, + blob = new Blob(); + + if (header.indexOf('base64') != -1) { + data = _this.generateBinaryArray(datastring.substring(header_end)); + } + + // Fake blob for IE + if (AmCharts.isIE && AmCharts.IEversion < 10) { + blob.data = data; + blob.size = data.length; + blob.type = type; + blob.encoding = 'base64'; + } else { + blob = new Blob([data], { + type: type + }); + } + return blob; + }, + + /* + Creates PDF object + @param config object + */ + generatePDF: function(cfg) { + var _this = this, + pdf = { + output: function() { + return ''; + } + }, + data = _this.canvas.toDataURL('image/jpeg'), // JSPDF ONLY SUPPORTS JPG + width = (_this.canvas.width * 25.4) / cfg.dpi, + height = (_this.canvas.height * 25.4) / cfg.dpi; + + // Check + if (window.jsPDF) { + pdf = new jsPDF(); + if (pdf.addImage) { + pdf.addImage(data, 'JPEG', 0, 0, width, height); + } else { + alert("Missing jsPDF plugin; Please add the 'addImage' plugin."); + } + } else { + alert("Missing jsPDF lib; Don't forget to add the addImage plugin."); + } + + return pdf; + }, + + /* + Creates the CANVAS to receive the image data + @param format void() + @param callback; given callback function which returns the blob or datastring of the configured ouput type + */ + output: function(cfg, externalCallback) { + var _this = this; + cfg = AmCharts.extend(AmCharts.extend({}, _this.cfg.menuItemOutput), cfg || {}); + + /* PRIVATE + Callback function which gets called after the drawing process is done + @param none + */ + function internalCallback() { + var data = null; + var blob; + if (_this.DEBUG == 10) { + _this.log('OUTPUT', cfg.format); + } // DEBUG + + // SVG + if (cfg.format == 'image/svg+xml' || cfg.format == 'svg') { + data = _this.generateSVG(); + blob = _this.generateBlob(data, 'image/svg+xml'); + + if (cfg.output == 'save') { + saveAs(blob, cfg.fileName + '.svg'); + } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { + blob = 'data:image/svg+xml;base64,' + btoa(data); + } else if (cfg.output == 'dataurlnewwindow') { + window.open('data:image/svg+xml;base64,' + btoa(data)); + } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { + location.href = 'data:image/svg+xml;base64,' + btoa(data); + } else if (cfg.output == 'datastream') { + location.href = 'data:image/octet-stream;base64,' + data; + } + + if (externalCallback) + externalCallback.apply(_this, [blob]); + + // PDF + } else if (cfg.format == 'application/pdf' || cfg.format == 'pdf') { + data = _this.generatePDF(cfg).output('dataurlstring'); + blob = _this.generateBlob(data, 'application/pdf'); + + if (cfg.output == 'save') { + saveAs(blob, cfg.fileName + '.pdf'); + } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { + blob = data; + } else if (cfg.output == 'dataurlnewwindow') { + window.open(data); + } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { + location.href = data; + } else if (cfg.output == 'datastream') { + location.href = data.replace('application/pdf', 'application/octet-stream'); + } + + if (externalCallback) + externalCallback.apply(_this, [blob]); + + // PNG + } else if (cfg.format == 'image/png' || cfg.format == 'png') { + data = _this.canvas.toDataURL('image/png'); + blob = _this.generateBlob(data, 'image/png'); + + if (cfg.output == 'save') { + saveAs(blob, cfg.fileName + '.png'); + } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { + blob = data; + } else if (cfg.output == 'dataurlnewwindow') { + window.open(data); + } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { + location.href = data; + } else if (cfg.output == 'datastream') { + location.href = data.replace('image/png', 'image/octet-stream'); + } + + if (externalCallback) + externalCallback.apply(_this, [blob]); + + // JPG + } else if (cfg.format == 'image/jpeg' || cfg.format == 'jpeg' || cfg.format == 'jpg') { + data = _this.canvas.toDataURL('image/jpeg'); + blob = _this.generateBlob(data, 'image/jpeg'); + + if (cfg.output == 'save') { + saveAs(blob, cfg.fileName + '.jpg'); + } else if (cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring') { + blob = data; + } else if (cfg.output == 'dataurlnewwindow') { + window.open(data); + } else if (cfg.output == 'datauri' || cfg.output == 'dataurl') { + location.href = data; + } else if (cfg.output == 'datastream') { + location.href = data.replace('image/jpeg', 'image/octet-stream'); + } + + if (externalCallback) + externalCallback.apply(_this, [blob]); + } + + } + + return _this.generateOutput(cfg, internalCallback); + }, + + /* PUBLIC + Polifies missing attributes to the SVG and replaces images to embedded base64 images + @param none + */ + polifySVG: function(svg) { + var _this = this; + + // Recursive function to force the attributes + function recursiveChange(svg, tag) { + var items = svg.getElementsByTagName(tag); + var i = items.length; + + while(i--) { + if (_this.cfg.removeImagery) { + items[i].parentNode.removeChild(items[i]); + + } else { + var image = document.createElement('img'); + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext('2d'); + + canvas.width = items[i].getAttribute('width'); + canvas.height = items[i].getAttribute('height'); + image.src = items[i].getAttribute('xlink:href'); + image.width = items[i].getAttribute('width'); + image.height = items[i].getAttribute('height'); + + try { + ctx.drawImage(image, 0, 0, image.width, image.height); + datastring = canvas.toDataURL(); // image.src; // canvas.toDataURL(); // + } catch (err) { + datastring = image.src; // image.src; // canvas.toDataURL(); // + + _this.log('Tainted canvas, reached browser CORS security; origin from imagery must be equal to the server!'); + throw new Error(err); + } + + items[i].setAttribute('xlink:href', datastring); + } + + if (_this.DEBUG == 10) { + _this.log('POLIFIED', items[i]); + } // DEBUG + } + } + + // Put some attrs to it; fixed 20/03/14 xmlns is required to produce a valid svg file + if (AmCharts.IEversion == 0) { + svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + if ( !_this.cfg.removeImagery ) { + svg.setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); + } + } + + // DEBUG + if (_this.DEBUG == 10) { + _this.log('POLIFIED', svg); + } + + // Force link adaption + recursiveChange(svg, 'pattern'); + recursiveChange(svg, 'image'); + + _this.svgs.push(svg); + + return svg; + }, + + + /* PUBLIC + Stacks multiple SVGs into one + @param none + */ + generateSVG: function() { + var _this = this; + var context = document.createElement('svg'); + context.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + context.setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); + + for (var i = 0; i < _this.processing.buffer.length; i++) { + var group = document.createElement('g'), + data = _this.processing.buffer[i]; + + data[0].setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + data[0].setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); + + group.setAttribute('transform', 'translate('+data[1].x+','+data[1].y+')'); + group.appendChild(data[0]); + context.appendChild(group); + } + + return new XMLSerializer().serializeToString(context); + }, + + /* PUBLIC + Generates the canvas with the given SVGs and configured renderer + @param callback; function(); gets called after drawing process on the canvas has been finished + */ + generateOutput: function(cfg, callback) { + var _this = this, + svgs = _this.chart.div.getElementsByTagName('svg'), + canvas = document.createElement('canvas'), + context = canvas.getContext('2d'), + offset = { + y: 0, + x: 0 + }, + tmp = {}; + + // Reset + _this.processing.buffer = []; + _this.processing.drawn = 0; + _this.canvas = canvas; + _this.svgs = []; + + // Walkthroug SVGs + if (_this.DEBUG == 10) { + _this.log('START EXPORT'); + } // DEBUG + if (_this.DEBUG == 10) { + _this.log('START BUFFERING'); + } // DEBUG + for (var i = 0; i < svgs.length; i++) { + var parent = svgs[i].parentNode, + svgX = Number(parent.style.left.slice(0, -2)), + svgY = Number(parent.style.top.slice(0, -2)), + svgClone = _this.polifySVG(svgs[i].cloneNode(true)), + tmp = AmCharts.extend({}, offset); + + // Overtake parent position if given; fixed 20/03/14 distinguish between relativ and others + if (parent.style.position == 'relative') { + offset.x = svgX ? svgX : offset.x; + offset.y = svgY ? svgY : offset.y; + } else { + offset.x = svgX; + offset.y = svgY; + } + + _this.processing.buffer.push([svgClone, AmCharts.extend({}, offset)]); + + // Put back from "cache" + if (svgY && svgX) { + offset = tmp; + + // New offset for next one + } else { + offset.y += svgY ? 0 : parent.offsetHeight; + } + + if (_this.DEBUG == 10) { + _this.log('BUFFERED', svgs[i], offset); + } // DEBUG + } + if (_this.DEBUG == 10) { + _this.log('END BUFFERING'); + } // DEBUG + + // Apply background + if (_this.DEBUG == 10) { + _this.log('START DRAWING', cfg.render); + } // DEBUG + if (_this.DEBUG == 10) { + _this.log('FILL BACKGROUND'); + } // DEBUG + canvas.id = AmCharts.getUniqueId(); + canvas.width = _this.chart.divRealWidth; + canvas.height = _this.chart.divRealHeight; + + + // Stockchart exception + var adapted = { + width: false, + height: false + }; + if ( _this.chart.periodSelector ) { + if ( ['left','right'].indexOf(_this.chart.periodSelector.position) != -1 ) { + canvas.width -= _this.chart.periodSelector.div.offsetWidth + 16; + adapted.width = true; + } else { + canvas.height -= _this.chart.periodSelector.div.offsetHeight; + adapted.height = true; + } + } + + if ( _this.chart.dataSetSelector ) { + if ( ['left','right'].indexOf(_this.chart.dataSetSelector.position) != -1 ) { + if ( !adapted.width ) { + canvas.width -= _this.chart.dataSetSelector.div.offsetWidth + 16; + } + } else { + canvas.height -= _this.chart.dataSetSelector.div.offsetHeight; + } + } + + // Set given background; jpeg default + if (cfg.backgroundColor || cfg.format == 'image/jpeg') { + context.fillStyle = cfg.backgroundColor || '#FFFFFF'; + context.fillRect(0, 0, canvas.width, canvas.height); + } + + /* PRIVATE + Recursive function to draw the images to the canvas; + @param none; + */ + function drawItWhenItsLoaded() { + var img, buffer, offset, source; + + // DRAWING PROCESS DONE + if (_this.processing.buffer.length == _this.processing.drawn || cfg.format == 'svg' ) { + if (_this.DEBUG == 10) { + _this.log('END DRAWING'); + } // DEBUG + return callback(); + + // LOOPING LUI + } else { + if (_this.DEBUG == 10) { + _this.log('DRAW', _this.processing.drawn + 1, 'OF', _this.processing.buffer.length); + } // DEBUG + + buffer = _this.processing.buffer[_this.processing.drawn]; + source = new XMLSerializer().serializeToString(buffer[0]); //source = 'data:image/svg+xml;base64,' + btoa(); + offset = buffer[1]; + + if (_this.DEBUG == 10) { + _this.log('SOURCE', source); + } // DEBUG + + // NATIVE + if (cfg.render == 'browser') { + img = new Image(); + img.id = AmCharts.getUniqueId(); + source = 'data:image/svg+xml;base64,' + btoa(source); + + //img.crossOrigin = "Anonymous"; + img.onload = function() { + context.drawImage(this, buffer[1].x, buffer[1].y); + _this.processing.drawn++; + + if (_this.DEBUG == 10) { + _this.log('ONLOAD', this); + } // DEBUG + drawItWhenItsLoaded(); + }; + img.onerror = function() { + if (_this.DEBUG == 10) { + _this.log('ONERROR', this); + } // DEBUG + context.drawImage(this, buffer[1].x, buffer[1].y); + _this.processing.drawn++; + drawItWhenItsLoaded(); + }; + img.src = source; + + if (_this.DEBUG == 10) { + _this.log('ADD', img); + } // DEBUG + if (img.complete || typeof(img.complete) == 'undefined' || img.complete === undefined) { + if (_this.DEBUG == 10) { + _this.log('FORCE ONLOAD', img); + } // DEBUG + img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; + img.src = source; + } + + // CANVG + } else if (cfg.render == 'canvg') { + canvg(canvas, source, { + offsetX: offset.x, + offsetY: offset.y, + ignoreMouse: true, + ignoreAnimation: true, + ignoreDimensions: true, + ignoreClear: true, + renderCallback: function() { + _this.processing.drawn++; + drawItWhenItsLoaded(); + } + }); + } + } + } + return drawItWhenItsLoaded(); + }, + + /* + Generates the export menu to trigger the exportation + @param none; + */ + generateButtons: function() { + var _this = this, + div = document.createElement('div'), + lvl = 0; + + // Push sublings + function createList(items) { + var ul = document.createElement('ul'); + + ul.setAttribute('style', 'list-style: none; margin: 0; padding: 0;'); + + // Walkthrough items + for (var i = 0; i < items.length; i++) { + var li = document.createElement('li'), + img = document.createElement('img'), + a = document.createElement('a'), + item = items[i], + children = null, + itemStyle = AmCharts.extend(AmCharts.extend({}, _this.cfg.menuItemStyle), items[i]); + + // MERGE CFG + item = AmCharts.extend(AmCharts.extend({}, _this.cfg.menuItemOutput), item); + + // ICON + if (item['icon']) { + img.alt = ''; + img.src = item['icon']; + img.setAttribute('style', 'margin: 0 auto;border: none;outline: none'); + if (item['iconTitle']) { + img.title = item['iconTitle']; + } + a.appendChild(img); + } + + // TITLE; STYLING + a.href = '#'; + if (item['title']) { + img.setAttribute('style', 'margin-right: 5px;'); + a.innerHTML += item.title; + } + a.setAttribute('style', 'display: block;'); + AmCharts.extend(a.style, itemStyle); + + // ONCLICK + a.onclick = item.onclick.bind(a, _this, item); + li.appendChild(a); + + // APPEND SIBLINGS + if (item.items) { + children = createList(item.items); + li.appendChild(children); + + li.onmouseover = function() { + children.style.display = 'block'; + }; + li.onmouseout = function() { + children.style.display = 'none'; + }; + children.style.display = 'none'; + } + + // Append to parent + ul.appendChild(li); + + // Apply hover + a.onmouseover = function() { + this.style.backgroundColor = itemStyle.rollOverBackgroundColor; + this.style.color = itemStyle.rollOverColor; + this.style.borderColor = itemStyle.rollOverBorderColor; + }; + a.onmouseout = function() { + this.style.backgroundColor = itemStyle.backgroundColor; + this.style.color = itemStyle.color; + this.style.borderColor = itemStyle.borderColor; + }; + } + lvl++; + + if (_this.DEBUG == 10) { + _this.log('MENU', ul); + } // DEBUG + + return ul; + } + + // Style wrapper; Push into chart div + div.setAttribute('style', 'width:39px; height:28px; position: absolute;top:' + _this.cfg.menuTop + ';right:' + _this.cfg.menuRight + ';bottom:' + _this.cfg.menuBottom + ';left:' + _this.cfg.menuLeft + ';box-shadow:0px 0px 1px 0px rgba(0,0,0,0);'); + div.setAttribute('class', 'amExportButton'); + div.appendChild(createList(_this.cfg.menuItems)); + _this.chart.containerDiv.appendChild(div); + } }); \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/exporting/canvg.js b/web/src/main/webapp/components/amcharts/exporting/canvg.js index e9f35e07a0f0..4f4199395701 100755 --- a/web/src/main/webapp/components/amcharts/exporting/canvg.js +++ b/web/src/main/webapp/components/amcharts/exporting/canvg.js @@ -1,2842 +1,2842 @@ -/* - * canvg.js - Javascript SVG parser and renderer on Canvas - * MIT Licensed - * Gabe Lerner (gabelerner@gmail.com) - * http://code.google.com/p/canvg/ - * - * Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/ - */ -(function(){ - // canvg(target, s) - // empty parameters: replace all 'svg' elements on page with 'canvas' elements - // target: canvas element or the id of a canvas element - // s: svg string, url to svg file, or xml document - // opts: optional hash of options - // ignoreMouse: true => ignore mouse events - // ignoreAnimation: true => ignore animations - // ignoreDimensions: true => does not try to resize canvas - // ignoreClear: true => does not clear canvas - // offsetX: int => draws at a x offset - // offsetY: int => draws at a y offset - // scaleWidth: int => scales horizontally to width - // scaleHeight: int => scales vertically to height - // renderCallback: function => will call the function after the first render is completed - // forceRedraw: function => will call the function on every frame, if it returns true, will redraw - this.canvg = function (target, s, opts) { - // no parameters - if (target == null && s == null && opts == null) { - var svgTags = document.getElementsByTagName('svg'); - for (var i=0; i]*>/, ''); - var xmlDoc = new ActiveXObject('Microsoft.XMLDOM'); - xmlDoc.async = 'false'; - xmlDoc.loadXML(xml); - return xmlDoc; - } - } - - svg.Property = function(name, value) { - this.name = name; - this.value = value; - } - svg.Property.prototype.getValue = function() { - return this.value; - } - - svg.Property.prototype.hasValue = function() { - return (this.value != null && this.value !== ''); - } - - // return the numerical value of the property - svg.Property.prototype.numValue = function() { - if (!this.hasValue()) return 0; - - var n = parseFloat(this.value); - if ((this.value + '').match(/%$/)) { - n = n / 100.0; - } - return n; - } - - svg.Property.prototype.valueOrDefault = function(def) { - if (this.hasValue()) return this.value; - return def; - } - - svg.Property.prototype.numValueOrDefault = function(def) { - if (this.hasValue()) return this.numValue(); - return def; - } - - // color extensions - // augment the current color value with the opacity - svg.Property.prototype.addOpacity = function(opacity) { - var newValue = this.value; - if (opacity != null && opacity != '' && typeof(this.value)=='string') { // can only add opacity to colors, not patterns - var color = new RGBColor(this.value); - if (color.ok) { - newValue = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + opacity + ')'; - } - } - return new svg.Property(this.name, newValue); - } - - // definition extensions - // get the definition from the definitions table - svg.Property.prototype.getDefinition = function() { - var name = this.value.match(/#([^\)'"]+)/); - if (name) { name = name[1]; } - if (!name) { name = this.value; } - return svg.Definitions[name]; - } - - svg.Property.prototype.isUrlDefinition = function() { - return this.value.indexOf('url(') == 0 - } - - svg.Property.prototype.getFillStyleDefinition = function(e, opacityProp) { - var def = this.getDefinition(); - - // gradient - if (def != null && def.createGradient) { - return def.createGradient(svg.ctx, e, opacityProp); - } - - // pattern - if (def != null && def.createPattern) { - if (def.getHrefAttribute().hasValue()) { - var pt = def.attribute('patternTransform'); - def = def.getHrefAttribute().getDefinition(); - if (pt.hasValue()) { def.attribute('patternTransform', true).value = pt.value; } - } - return def.createPattern(svg.ctx, e); - } - - return null; - } - - // length extensions - svg.Property.prototype.getDPI = function(viewPort) { - return 96.0; // TODO: compute? - } - - svg.Property.prototype.getEM = function(viewPort) { - var em = 12; - - var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize); - if (fontSize.hasValue()) em = fontSize.toPixels(viewPort); - - return em; - } - - svg.Property.prototype.getUnits = function() { - var s = this.value+''; - return s.replace(/[0-9\.\-]/g,''); - } - - // get the length as pixels - svg.Property.prototype.toPixels = function(viewPort, processPercent) { - if (!this.hasValue()) return 0; - var s = this.value+''; - if (s.match(/em$/)) return this.numValue() * this.getEM(viewPort); - if (s.match(/ex$/)) return this.numValue() * this.getEM(viewPort) / 2.0; - if (s.match(/px$/)) return this.numValue(); - if (s.match(/pt$/)) return this.numValue() * this.getDPI(viewPort) * (1.0 / 72.0); - if (s.match(/pc$/)) return this.numValue() * 15; - if (s.match(/cm$/)) return this.numValue() * this.getDPI(viewPort) / 2.54; - if (s.match(/mm$/)) return this.numValue() * this.getDPI(viewPort) / 25.4; - if (s.match(/in$/)) return this.numValue() * this.getDPI(viewPort); - if (s.match(/%$/)) return this.numValue() * svg.ViewPort.ComputeSize(viewPort); - var n = this.numValue(); - if (processPercent && n < 1.0) return n * svg.ViewPort.ComputeSize(viewPort); - return n; - } - - // time extensions - // get the time as milliseconds - svg.Property.prototype.toMilliseconds = function() { - if (!this.hasValue()) return 0; - var s = this.value+''; - if (s.match(/s$/)) return this.numValue() * 1000; - if (s.match(/ms$/)) return this.numValue(); - return this.numValue(); - } - - // angle extensions - // get the angle as radians - svg.Property.prototype.toRadians = function() { - if (!this.hasValue()) return 0; - var s = this.value+''; - if (s.match(/deg$/)) return this.numValue() * (Math.PI / 180.0); - if (s.match(/grad$/)) return this.numValue() * (Math.PI / 200.0); - if (s.match(/rad$/)) return this.numValue(); - return this.numValue() * (Math.PI / 180.0); - } - - // fonts - svg.Font = new (function() { - this.Styles = 'normal|italic|oblique|inherit'; - this.Variants = 'normal|small-caps|inherit'; - this.Weights = 'normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900|inherit'; - - this.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) { - var f = inherit != null ? this.Parse(inherit) : this.CreateFont('', '', '', '', '', svg.ctx.font); - return { - fontFamily: fontFamily || f.fontFamily, - fontSize: fontSize || f.fontSize, - fontStyle: fontStyle || f.fontStyle, - fontWeight: fontWeight || f.fontWeight, - fontVariant: fontVariant || f.fontVariant, - toString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') } - } - } - - var that = this; - this.Parse = function(s) { - var f = {}; - var d = svg.trim(svg.compressSpaces(s || '')).split(' '); - var set = { fontSize: false, fontStyle: false, fontWeight: false, fontVariant: false } - var ff = ''; - for (var i=0; i this.x2) this.x2 = x; - } - - if (y != null) { - if (isNaN(this.y1) || isNaN(this.y2)) { - this.y1 = y; - this.y2 = y; - } - if (y < this.y1) this.y1 = y; - if (y > this.y2) this.y2 = y; - } - } - this.addX = function(x) { this.addPoint(x, null); } - this.addY = function(y) { this.addPoint(null, y); } - - this.addBoundingBox = function(bb) { - this.addPoint(bb.x1, bb.y1); - this.addPoint(bb.x2, bb.y2); - } - - this.addQuadraticCurve = function(p0x, p0y, p1x, p1y, p2x, p2y) { - var cp1x = p0x + 2/3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0) - var cp1y = p0y + 2/3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0) - var cp2x = cp1x + 1/3 * (p2x - p0x); // CP2 = CP1 + 1/3 *(QP2-QP0) - var cp2y = cp1y + 1/3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0) - this.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y, cp2y, p2x, p2y); - } - - this.addBezierCurve = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) { - // from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html - var p0 = [p0x, p0y], p1 = [p1x, p1y], p2 = [p2x, p2y], p3 = [p3x, p3y]; - this.addPoint(p0[0], p0[1]); - this.addPoint(p3[0], p3[1]); - - for (i=0; i<=1; i++) { - var f = function(t) { - return Math.pow(1-t, 3) * p0[i] - + 3 * Math.pow(1-t, 2) * t * p1[i] - + 3 * (1-t) * Math.pow(t, 2) * p2[i] - + Math.pow(t, 3) * p3[i]; - } - - var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i]; - var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i]; - var c = 3 * p1[i] - 3 * p0[i]; - - if (a == 0) { - if (b == 0) continue; - var t = -c / b; - if (0 < t && t < 1) { - if (i == 0) this.addX(f(t)); - if (i == 1) this.addY(f(t)); - } - continue; - } - - var b2ac = Math.pow(b, 2) - 4 * c * a; - if (b2ac < 0) continue; - var t1 = (-b + Math.sqrt(b2ac)) / (2 * a); - if (0 < t1 && t1 < 1) { - if (i == 0) this.addX(f(t1)); - if (i == 1) this.addY(f(t1)); - } - var t2 = (-b - Math.sqrt(b2ac)) / (2 * a); - if (0 < t2 && t2 < 1) { - if (i == 0) this.addX(f(t2)); - if (i == 1) this.addY(f(t2)); - } - } - } - - this.isPointInBox = function(x, y) { - return (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2); - } - - this.addPoint(x1, y1); - this.addPoint(x2, y2); - } - - // transforms - svg.Transform = function(v) { - var that = this; - this.Type = {} - - // translate - this.Type.translate = function(s) { - this.p = svg.CreatePoint(s); - this.apply = function(ctx) { - ctx.translate(this.p.x || 0.0, this.p.y || 0.0); - } - this.unapply = function(ctx) { - ctx.translate(-1.0 * this.p.x || 0.0, -1.0 * this.p.y || 0.0); - } - this.applyToPoint = function(p) { - p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); - } - } - - // rotate - this.Type.rotate = function(s) { - var a = svg.ToNumberArray(s); - this.angle = new svg.Property('angle', a[0]); - this.cx = a[1] || 0; - this.cy = a[2] || 0; - this.apply = function(ctx) { - ctx.translate(this.cx, this.cy); - ctx.rotate(this.angle.toRadians()); - ctx.translate(-this.cx, -this.cy); - } - this.unapply = function(ctx) { - ctx.translate(this.cx, this.cy); - ctx.rotate(-1.0 * this.angle.toRadians()); - ctx.translate(-this.cx, -this.cy); - } - this.applyToPoint = function(p) { - var a = this.angle.toRadians(); - p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); - p.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]); - p.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]); - } - } - - this.Type.scale = function(s) { - this.p = svg.CreatePoint(s); - this.apply = function(ctx) { - ctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0); - } - this.unapply = function(ctx) { - ctx.scale(1.0 / this.p.x || 1.0, 1.0 / this.p.y || this.p.x || 1.0); - } - this.applyToPoint = function(p) { - p.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]); - } - } - - this.Type.matrix = function(s) { - this.m = svg.ToNumberArray(s); - this.apply = function(ctx) { - ctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]); - } - this.applyToPoint = function(p) { - p.applyTransform(this.m); - } - } - - this.Type.SkewBase = function(s) { - this.base = that.Type.matrix; - this.base(s); - this.angle = new svg.Property('angle', s); - } - this.Type.SkewBase.prototype = new this.Type.matrix; - - this.Type.skewX = function(s) { - this.base = that.Type.SkewBase; - this.base(s); - this.m = [1, 0, Math.tan(this.angle.toRadians()), 1, 0, 0]; - } - this.Type.skewX.prototype = new this.Type.SkewBase; - - this.Type.skewY = function(s) { - this.base = that.Type.SkewBase; - this.base(s); - this.m = [1, Math.tan(this.angle.toRadians()), 0, 1, 0, 0]; - } - this.Type.skewY.prototype = new this.Type.SkewBase; - - this.transforms = []; - - this.apply = function(ctx) { - for (var i=0; i=0; i--) { - this.transforms[i].unapply(ctx); - } - } - - this.applyToPoint = function(p) { - for (var i=0; i= this.tokens.length - 1; - } - - this.isCommandOrEnd = function() { - if (this.isEnd()) return true; - return this.tokens[this.i + 1].match(/^[A-Za-z]$/) != null; - } - - this.isRelativeCommand = function() { - switch(this.command) - { - case 'm': - case 'l': - case 'h': - case 'v': - case 'c': - case 's': - case 'q': - case 't': - case 'a': - case 'z': - return true; - break; - } - return false; - } - - this.getToken = function() { - this.i++; - return this.tokens[this.i]; - } - - this.getScalar = function() { - return parseFloat(this.getToken()); - } - - this.nextCommand = function() { - this.previousCommand = this.command; - this.command = this.getToken(); - } - - this.getPoint = function() { - var p = new svg.Point(this.getScalar(), this.getScalar()); - return this.makeAbsolute(p); - } - - this.getAsControlPoint = function() { - var p = this.getPoint(); - this.control = p; - return p; - } - - this.getAsCurrentPoint = function() { - var p = this.getPoint(); - this.current = p; - return p; - } - - this.getReflectedControlPoint = function() { - if (this.previousCommand.toLowerCase() != 'c' && - this.previousCommand.toLowerCase() != 's' && - this.previousCommand.toLowerCase() != 'q' && - this.previousCommand.toLowerCase() != 't' ){ - return this.current; - } - - // reflect point - var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y); - return p; - } - - this.makeAbsolute = function(p) { - if (this.isRelativeCommand()) { - p.x += this.current.x; - p.y += this.current.y; - } - return p; - } - - this.addMarker = function(p, from, priorTo) { - // if the last angle isn't filled in because we didn't have this point yet ... - if (priorTo != null && this.angles.length > 0 && this.angles[this.angles.length-1] == null) { - this.angles[this.angles.length-1] = this.points[this.points.length-1].angleTo(priorTo); - } - this.addMarkerAngle(p, from == null ? null : from.angleTo(p)); - } - - this.addMarkerAngle = function(p, a) { - this.points.push(p); - this.angles.push(a); - } - - this.getMarkerPoints = function() { return this.points; } - this.getMarkerAngles = function() { - for (var i=0; i 1) { - rx *= Math.sqrt(l); - ry *= Math.sqrt(l); - } - // cx', cy' - var s = (largeArcFlag == sweepFlag ? -1 : 1) * Math.sqrt( - ((Math.pow(rx,2)*Math.pow(ry,2))-(Math.pow(rx,2)*Math.pow(currp.y,2))-(Math.pow(ry,2)*Math.pow(currp.x,2))) / - (Math.pow(rx,2)*Math.pow(currp.y,2)+Math.pow(ry,2)*Math.pow(currp.x,2)) - ); - if (isNaN(s)) s = 0; - var cpp = new svg.Point(s * rx * currp.y / ry, s * -ry * currp.x / rx); - // cx, cy - var centp = new svg.Point( - (curr.x + cp.x) / 2.0 + Math.cos(xAxisRotation) * cpp.x - Math.sin(xAxisRotation) * cpp.y, - (curr.y + cp.y) / 2.0 + Math.sin(xAxisRotation) * cpp.x + Math.cos(xAxisRotation) * cpp.y - ); - // vector magnitude - var m = function(v) { return Math.sqrt(Math.pow(v[0],2) + Math.pow(v[1],2)); } - // ratio between two vectors - var r = function(u, v) { return (u[0]*v[0]+u[1]*v[1]) / (m(u)*m(v)) } - // angle between two vectors - var a = function(u, v) { return (u[0]*v[1] < u[1]*v[0] ? -1 : 1) * Math.acos(r(u,v)); } - // initial angle - var a1 = a([1,0], [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]); - // angle delta - var u = [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]; - var v = [(-currp.x-cpp.x)/rx,(-currp.y-cpp.y)/ry]; - var ad = a(u, v); - if (r(u,v) <= -1) ad = Math.PI; - if (r(u,v) >= 1) ad = 0; - - // for markers - var dir = 1 - sweepFlag ? 1.0 : -1.0; - var ah = a1 + dir * (ad / 2.0); - var halfWay = new svg.Point( - centp.x + rx * Math.cos(ah), - centp.y + ry * Math.sin(ah) - ); - pp.addMarkerAngle(halfWay, ah - dir * Math.PI / 2); - pp.addMarkerAngle(cp, ah - dir * Math.PI); - - bb.addPoint(cp.x, cp.y); // TODO: this is too naive, make it better - if (ctx != null) { - var r = rx > ry ? rx : ry; - var sx = rx > ry ? 1 : rx / ry; - var sy = rx > ry ? ry / rx : 1; - - ctx.translate(centp.x, centp.y); - ctx.rotate(xAxisRotation); - ctx.scale(sx, sy); - ctx.arc(0, 0, r, a1, a1 + ad, 1 - sweepFlag); - ctx.scale(1/sx, 1/sy); - ctx.rotate(-xAxisRotation); - ctx.translate(-centp.x, -centp.y); - } - } - break; - case 'Z': - case 'z': - if (ctx != null) ctx.closePath(); - pp.current = pp.start; - } - } - - return bb; - } - - this.getMarkers = function() { - var points = this.PathParser.getMarkerPoints(); - var angles = this.PathParser.getMarkerAngles(); - - var markers = []; - for (var i=0; i 1) this.offset = 1; - - var stopColor = this.style('stop-color'); - if (this.style('stop-opacity').hasValue()) stopColor = stopColor.addOpacity(this.style('stop-opacity').value); - this.color = stopColor.value; - } - svg.Element.stop.prototype = new svg.Element.ElementBase; - - // animation base element - svg.Element.AnimateBase = function(node) { - this.base = svg.Element.ElementBase; - this.base(node); - - svg.Animations.push(this); - - this.duration = 0.0; - this.begin = this.attribute('begin').toMilliseconds(); - this.maxDuration = this.begin + this.attribute('dur').toMilliseconds(); - - this.getProperty = function() { - var attributeType = this.attribute('attributeType').value; - var attributeName = this.attribute('attributeName').value; - - if (attributeType == 'CSS') { - return this.parent.style(attributeName, true); - } - return this.parent.attribute(attributeName, true); - }; - - this.initialValue = null; - this.initialUnits = ''; - this.removed = false; - - this.calcValue = function() { - // OVERRIDE ME! - return ''; - } - - this.update = function(delta) { - // set initial value - if (this.initialValue == null) { - this.initialValue = this.getProperty().value; - this.initialUnits = this.getProperty().getUnits(); - } - - // if we're past the end time - if (this.duration > this.maxDuration) { - // loop for indefinitely repeating animations - if (this.attribute('repeatCount').value == 'indefinite' - || this.attribute('repeatDur').value == 'indefinite') { - this.duration = 0.0 - } - else if (this.attribute('fill').valueOrDefault('remove') == 'remove' && !this.removed) { - this.removed = true; - this.getProperty().value = this.initialValue; - return true; - } - else { - return false; // no updates made - } - } - this.duration = this.duration + delta; - - // if we're past the begin time - var updated = false; - if (this.begin < this.duration) { - var newValue = this.calcValue(); // tween - - if (this.attribute('type').hasValue()) { - // for transform, etc. - var type = this.attribute('type').value; - newValue = type + '(' + newValue + ')'; - } - - this.getProperty().value = newValue; - updated = true; - } - - return updated; - } - - this.from = this.attribute('from'); - this.to = this.attribute('to'); - this.values = this.attribute('values'); - if (this.values.hasValue()) this.values.value = this.values.value.split(';'); - - // fraction of duration we've covered - this.progress = function() { - var ret = { progress: (this.duration - this.begin) / (this.maxDuration - this.begin) }; - if (this.values.hasValue()) { - var p = ret.progress * (this.values.value.length - 1); - var lb = Math.floor(p), ub = Math.ceil(p); - ret.from = new svg.Property('from', parseFloat(this.values.value[lb])); - ret.to = new svg.Property('to', parseFloat(this.values.value[ub])); - ret.progress = (p - lb) / (ub - lb); - } - else { - ret.from = this.from; - ret.to = this.to; - } - return ret; - } - } - svg.Element.AnimateBase.prototype = new svg.Element.ElementBase; - - // animate element - svg.Element.animate = function(node) { - this.base = svg.Element.AnimateBase; - this.base(node); - - this.calcValue = function() { - var p = this.progress(); - - // tween value linearly - var newValue = p.from.numValue() + (p.to.numValue() - p.from.numValue()) * p.progress; - return newValue + this.initialUnits; - }; - } - svg.Element.animate.prototype = new svg.Element.AnimateBase; - - // animate color element - svg.Element.animateColor = function(node) { - this.base = svg.Element.AnimateBase; - this.base(node); - - this.calcValue = function() { - var p = this.progress(); - var from = new RGBColor(p.from.value); - var to = new RGBColor(p.to.value); - - if (from.ok && to.ok) { - // tween color linearly - var r = from.r + (to.r - from.r) * p.progress; - var g = from.g + (to.g - from.g) * p.progress; - var b = from.b + (to.b - from.b) * p.progress; - return 'rgb('+parseInt(r,10)+','+parseInt(g,10)+','+parseInt(b,10)+')'; - } - return this.attribute('from').value; - }; - } - svg.Element.animateColor.prototype = new svg.Element.AnimateBase; - - // animate transform element - svg.Element.animateTransform = function(node) { - this.base = svg.Element.AnimateBase; - this.base(node); - - this.calcValue = function() { - var p = this.progress(); - - // tween value linearly - var from = svg.ToNumberArray(p.from.value); - var to = svg.ToNumberArray(p.to.value); - var newValue = ''; - for (var i=0; i startI && child.attribute('x').hasValue()) break; // new group - width += child.measureTextRecursive(ctx); - } - return -1 * (textAnchor == 'end' ? width : width / 2.0); - } - return 0; - } - - this.renderChild = function(ctx, parent, i) { - var child = parent.children[i]; - if (child.attribute('x').hasValue()) { - child.x = child.attribute('x').toPixels('x') + this.getAnchorDelta(ctx, parent, i); - } - else { - if (this.attribute('dx').hasValue()) this.x += this.attribute('dx').toPixels('x'); - if (child.attribute('dx').hasValue()) this.x += child.attribute('dx').toPixels('x'); - child.x = this.x; - } - this.x = child.x + child.measureText(ctx); - - if (child.attribute('y').hasValue()) { - child.y = child.attribute('y').toPixels('y'); - } - else { - if (this.attribute('dy').hasValue()) this.y += this.attribute('dy').toPixels('y'); - if (child.attribute('dy').hasValue()) this.y += child.attribute('dy').toPixels('y'); - child.y = this.y; - } - this.y = child.y; - - child.render(ctx); - - for (var i=0; i0 && text[i-1]!=' ' && i0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial'; - if (typeof(font.glyphs[c]) != 'undefined') { - glyph = font.glyphs[c][arabicForm]; - if (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c]; - } - } - else { - glyph = font.glyphs[c]; - } - if (glyph == null) glyph = font.missingGlyph; - return glyph; - } - - this.renderChildren = function(ctx) { - var customFont = this.parent.style('font-family').getDefinition(); - if (customFont != null) { - var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize); - var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle); - var text = this.getText(); - if (customFont.isRTL) text = text.split("").reverse().join(""); - - var dx = svg.ToNumberArray(this.parent.attribute('dx').value); - for (var i=0; i 0) { - var urlStart = srcs[s].indexOf('url'); - var urlEnd = srcs[s].indexOf(')', urlStart); - var url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6); - var doc = svg.parseXml(svg.ajax(url)); - var fonts = doc.getElementsByTagName('font'); - for (var f=0; f ignore mouse events + // ignoreAnimation: true => ignore animations + // ignoreDimensions: true => does not try to resize canvas + // ignoreClear: true => does not clear canvas + // offsetX: int => draws at a x offset + // offsetY: int => draws at a y offset + // scaleWidth: int => scales horizontally to width + // scaleHeight: int => scales vertically to height + // renderCallback: function => will call the function after the first render is completed + // forceRedraw: function => will call the function on every frame, if it returns true, will redraw + this.canvg = function (target, s, opts) { + // no parameters + if (target == null && s == null && opts == null) { + var svgTags = document.getElementsByTagName('svg'); + for (var i=0; i]*>/, ''); + var xmlDoc = new ActiveXObject('Microsoft.XMLDOM'); + xmlDoc.async = 'false'; + xmlDoc.loadXML(xml); + return xmlDoc; + } + } + + svg.Property = function(name, value) { + this.name = name; + this.value = value; + } + svg.Property.prototype.getValue = function() { + return this.value; + } + + svg.Property.prototype.hasValue = function() { + return (this.value != null && this.value !== ''); + } + + // return the numerical value of the property + svg.Property.prototype.numValue = function() { + if (!this.hasValue()) return 0; + + var n = parseFloat(this.value); + if ((this.value + '').match(/%$/)) { + n = n / 100.0; + } + return n; + } + + svg.Property.prototype.valueOrDefault = function(def) { + if (this.hasValue()) return this.value; + return def; + } + + svg.Property.prototype.numValueOrDefault = function(def) { + if (this.hasValue()) return this.numValue(); + return def; + } + + // color extensions + // augment the current color value with the opacity + svg.Property.prototype.addOpacity = function(opacity) { + var newValue = this.value; + if (opacity != null && opacity != '' && typeof(this.value)=='string') { // can only add opacity to colors, not patterns + var color = new RGBColor(this.value); + if (color.ok) { + newValue = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + opacity + ')'; + } + } + return new svg.Property(this.name, newValue); + } + + // definition extensions + // get the definition from the definitions table + svg.Property.prototype.getDefinition = function() { + var name = this.value.match(/#([^\)'"]+)/); + if (name) { name = name[1]; } + if (!name) { name = this.value; } + return svg.Definitions[name]; + } + + svg.Property.prototype.isUrlDefinition = function() { + return this.value.indexOf('url(') == 0 + } + + svg.Property.prototype.getFillStyleDefinition = function(e, opacityProp) { + var def = this.getDefinition(); + + // gradient + if (def != null && def.createGradient) { + return def.createGradient(svg.ctx, e, opacityProp); + } + + // pattern + if (def != null && def.createPattern) { + if (def.getHrefAttribute().hasValue()) { + var pt = def.attribute('patternTransform'); + def = def.getHrefAttribute().getDefinition(); + if (pt.hasValue()) { def.attribute('patternTransform', true).value = pt.value; } + } + return def.createPattern(svg.ctx, e); + } + + return null; + } + + // length extensions + svg.Property.prototype.getDPI = function(viewPort) { + return 96.0; // TODO: compute? + } + + svg.Property.prototype.getEM = function(viewPort) { + var em = 12; + + var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize); + if (fontSize.hasValue()) em = fontSize.toPixels(viewPort); + + return em; + } + + svg.Property.prototype.getUnits = function() { + var s = this.value+''; + return s.replace(/[0-9\.\-]/g,''); + } + + // get the length as pixels + svg.Property.prototype.toPixels = function(viewPort, processPercent) { + if (!this.hasValue()) return 0; + var s = this.value+''; + if (s.match(/em$/)) return this.numValue() * this.getEM(viewPort); + if (s.match(/ex$/)) return this.numValue() * this.getEM(viewPort) / 2.0; + if (s.match(/px$/)) return this.numValue(); + if (s.match(/pt$/)) return this.numValue() * this.getDPI(viewPort) * (1.0 / 72.0); + if (s.match(/pc$/)) return this.numValue() * 15; + if (s.match(/cm$/)) return this.numValue() * this.getDPI(viewPort) / 2.54; + if (s.match(/mm$/)) return this.numValue() * this.getDPI(viewPort) / 25.4; + if (s.match(/in$/)) return this.numValue() * this.getDPI(viewPort); + if (s.match(/%$/)) return this.numValue() * svg.ViewPort.ComputeSize(viewPort); + var n = this.numValue(); + if (processPercent && n < 1.0) return n * svg.ViewPort.ComputeSize(viewPort); + return n; + } + + // time extensions + // get the time as milliseconds + svg.Property.prototype.toMilliseconds = function() { + if (!this.hasValue()) return 0; + var s = this.value+''; + if (s.match(/s$/)) return this.numValue() * 1000; + if (s.match(/ms$/)) return this.numValue(); + return this.numValue(); + } + + // angle extensions + // get the angle as radians + svg.Property.prototype.toRadians = function() { + if (!this.hasValue()) return 0; + var s = this.value+''; + if (s.match(/deg$/)) return this.numValue() * (Math.PI / 180.0); + if (s.match(/grad$/)) return this.numValue() * (Math.PI / 200.0); + if (s.match(/rad$/)) return this.numValue(); + return this.numValue() * (Math.PI / 180.0); + } + + // fonts + svg.Font = new (function() { + this.Styles = 'normal|italic|oblique|inherit'; + this.Variants = 'normal|small-caps|inherit'; + this.Weights = 'normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900|inherit'; + + this.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) { + var f = inherit != null ? this.Parse(inherit) : this.CreateFont('', '', '', '', '', svg.ctx.font); + return { + fontFamily: fontFamily || f.fontFamily, + fontSize: fontSize || f.fontSize, + fontStyle: fontStyle || f.fontStyle, + fontWeight: fontWeight || f.fontWeight, + fontVariant: fontVariant || f.fontVariant, + toString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') } + } + } + + var that = this; + this.Parse = function(s) { + var f = {}; + var d = svg.trim(svg.compressSpaces(s || '')).split(' '); + var set = { fontSize: false, fontStyle: false, fontWeight: false, fontVariant: false } + var ff = ''; + for (var i=0; i this.x2) this.x2 = x; + } + + if (y != null) { + if (isNaN(this.y1) || isNaN(this.y2)) { + this.y1 = y; + this.y2 = y; + } + if (y < this.y1) this.y1 = y; + if (y > this.y2) this.y2 = y; + } + } + this.addX = function(x) { this.addPoint(x, null); } + this.addY = function(y) { this.addPoint(null, y); } + + this.addBoundingBox = function(bb) { + this.addPoint(bb.x1, bb.y1); + this.addPoint(bb.x2, bb.y2); + } + + this.addQuadraticCurve = function(p0x, p0y, p1x, p1y, p2x, p2y) { + var cp1x = p0x + 2/3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0) + var cp1y = p0y + 2/3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0) + var cp2x = cp1x + 1/3 * (p2x - p0x); // CP2 = CP1 + 1/3 *(QP2-QP0) + var cp2y = cp1y + 1/3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0) + this.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y, cp2y, p2x, p2y); + } + + this.addBezierCurve = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) { + // from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html + var p0 = [p0x, p0y], p1 = [p1x, p1y], p2 = [p2x, p2y], p3 = [p3x, p3y]; + this.addPoint(p0[0], p0[1]); + this.addPoint(p3[0], p3[1]); + + for (i=0; i<=1; i++) { + var f = function(t) { + return Math.pow(1-t, 3) * p0[i] + + 3 * Math.pow(1-t, 2) * t * p1[i] + + 3 * (1-t) * Math.pow(t, 2) * p2[i] + + Math.pow(t, 3) * p3[i]; + } + + var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i]; + var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i]; + var c = 3 * p1[i] - 3 * p0[i]; + + if (a == 0) { + if (b == 0) continue; + var t = -c / b; + if (0 < t && t < 1) { + if (i == 0) this.addX(f(t)); + if (i == 1) this.addY(f(t)); + } + continue; + } + + var b2ac = Math.pow(b, 2) - 4 * c * a; + if (b2ac < 0) continue; + var t1 = (-b + Math.sqrt(b2ac)) / (2 * a); + if (0 < t1 && t1 < 1) { + if (i == 0) this.addX(f(t1)); + if (i == 1) this.addY(f(t1)); + } + var t2 = (-b - Math.sqrt(b2ac)) / (2 * a); + if (0 < t2 && t2 < 1) { + if (i == 0) this.addX(f(t2)); + if (i == 1) this.addY(f(t2)); + } + } + } + + this.isPointInBox = function(x, y) { + return (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2); + } + + this.addPoint(x1, y1); + this.addPoint(x2, y2); + } + + // transforms + svg.Transform = function(v) { + var that = this; + this.Type = {} + + // translate + this.Type.translate = function(s) { + this.p = svg.CreatePoint(s); + this.apply = function(ctx) { + ctx.translate(this.p.x || 0.0, this.p.y || 0.0); + } + this.unapply = function(ctx) { + ctx.translate(-1.0 * this.p.x || 0.0, -1.0 * this.p.y || 0.0); + } + this.applyToPoint = function(p) { + p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); + } + } + + // rotate + this.Type.rotate = function(s) { + var a = svg.ToNumberArray(s); + this.angle = new svg.Property('angle', a[0]); + this.cx = a[1] || 0; + this.cy = a[2] || 0; + this.apply = function(ctx) { + ctx.translate(this.cx, this.cy); + ctx.rotate(this.angle.toRadians()); + ctx.translate(-this.cx, -this.cy); + } + this.unapply = function(ctx) { + ctx.translate(this.cx, this.cy); + ctx.rotate(-1.0 * this.angle.toRadians()); + ctx.translate(-this.cx, -this.cy); + } + this.applyToPoint = function(p) { + var a = this.angle.toRadians(); + p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); + p.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]); + p.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]); + } + } + + this.Type.scale = function(s) { + this.p = svg.CreatePoint(s); + this.apply = function(ctx) { + ctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0); + } + this.unapply = function(ctx) { + ctx.scale(1.0 / this.p.x || 1.0, 1.0 / this.p.y || this.p.x || 1.0); + } + this.applyToPoint = function(p) { + p.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]); + } + } + + this.Type.matrix = function(s) { + this.m = svg.ToNumberArray(s); + this.apply = function(ctx) { + ctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]); + } + this.applyToPoint = function(p) { + p.applyTransform(this.m); + } + } + + this.Type.SkewBase = function(s) { + this.base = that.Type.matrix; + this.base(s); + this.angle = new svg.Property('angle', s); + } + this.Type.SkewBase.prototype = new this.Type.matrix; + + this.Type.skewX = function(s) { + this.base = that.Type.SkewBase; + this.base(s); + this.m = [1, 0, Math.tan(this.angle.toRadians()), 1, 0, 0]; + } + this.Type.skewX.prototype = new this.Type.SkewBase; + + this.Type.skewY = function(s) { + this.base = that.Type.SkewBase; + this.base(s); + this.m = [1, Math.tan(this.angle.toRadians()), 0, 1, 0, 0]; + } + this.Type.skewY.prototype = new this.Type.SkewBase; + + this.transforms = []; + + this.apply = function(ctx) { + for (var i=0; i=0; i--) { + this.transforms[i].unapply(ctx); + } + } + + this.applyToPoint = function(p) { + for (var i=0; i= this.tokens.length - 1; + } + + this.isCommandOrEnd = function() { + if (this.isEnd()) return true; + return this.tokens[this.i + 1].match(/^[A-Za-z]$/) != null; + } + + this.isRelativeCommand = function() { + switch(this.command) + { + case 'm': + case 'l': + case 'h': + case 'v': + case 'c': + case 's': + case 'q': + case 't': + case 'a': + case 'z': + return true; + break; + } + return false; + } + + this.getToken = function() { + this.i++; + return this.tokens[this.i]; + } + + this.getScalar = function() { + return parseFloat(this.getToken()); + } + + this.nextCommand = function() { + this.previousCommand = this.command; + this.command = this.getToken(); + } + + this.getPoint = function() { + var p = new svg.Point(this.getScalar(), this.getScalar()); + return this.makeAbsolute(p); + } + + this.getAsControlPoint = function() { + var p = this.getPoint(); + this.control = p; + return p; + } + + this.getAsCurrentPoint = function() { + var p = this.getPoint(); + this.current = p; + return p; + } + + this.getReflectedControlPoint = function() { + if (this.previousCommand.toLowerCase() != 'c' && + this.previousCommand.toLowerCase() != 's' && + this.previousCommand.toLowerCase() != 'q' && + this.previousCommand.toLowerCase() != 't' ){ + return this.current; + } + + // reflect point + var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y); + return p; + } + + this.makeAbsolute = function(p) { + if (this.isRelativeCommand()) { + p.x += this.current.x; + p.y += this.current.y; + } + return p; + } + + this.addMarker = function(p, from, priorTo) { + // if the last angle isn't filled in because we didn't have this point yet ... + if (priorTo != null && this.angles.length > 0 && this.angles[this.angles.length-1] == null) { + this.angles[this.angles.length-1] = this.points[this.points.length-1].angleTo(priorTo); + } + this.addMarkerAngle(p, from == null ? null : from.angleTo(p)); + } + + this.addMarkerAngle = function(p, a) { + this.points.push(p); + this.angles.push(a); + } + + this.getMarkerPoints = function() { return this.points; } + this.getMarkerAngles = function() { + for (var i=0; i 1) { + rx *= Math.sqrt(l); + ry *= Math.sqrt(l); + } + // cx', cy' + var s = (largeArcFlag == sweepFlag ? -1 : 1) * Math.sqrt( + ((Math.pow(rx,2)*Math.pow(ry,2))-(Math.pow(rx,2)*Math.pow(currp.y,2))-(Math.pow(ry,2)*Math.pow(currp.x,2))) / + (Math.pow(rx,2)*Math.pow(currp.y,2)+Math.pow(ry,2)*Math.pow(currp.x,2)) + ); + if (isNaN(s)) s = 0; + var cpp = new svg.Point(s * rx * currp.y / ry, s * -ry * currp.x / rx); + // cx, cy + var centp = new svg.Point( + (curr.x + cp.x) / 2.0 + Math.cos(xAxisRotation) * cpp.x - Math.sin(xAxisRotation) * cpp.y, + (curr.y + cp.y) / 2.0 + Math.sin(xAxisRotation) * cpp.x + Math.cos(xAxisRotation) * cpp.y + ); + // vector magnitude + var m = function(v) { return Math.sqrt(Math.pow(v[0],2) + Math.pow(v[1],2)); } + // ratio between two vectors + var r = function(u, v) { return (u[0]*v[0]+u[1]*v[1]) / (m(u)*m(v)) } + // angle between two vectors + var a = function(u, v) { return (u[0]*v[1] < u[1]*v[0] ? -1 : 1) * Math.acos(r(u,v)); } + // initial angle + var a1 = a([1,0], [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]); + // angle delta + var u = [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]; + var v = [(-currp.x-cpp.x)/rx,(-currp.y-cpp.y)/ry]; + var ad = a(u, v); + if (r(u,v) <= -1) ad = Math.PI; + if (r(u,v) >= 1) ad = 0; + + // for markers + var dir = 1 - sweepFlag ? 1.0 : -1.0; + var ah = a1 + dir * (ad / 2.0); + var halfWay = new svg.Point( + centp.x + rx * Math.cos(ah), + centp.y + ry * Math.sin(ah) + ); + pp.addMarkerAngle(halfWay, ah - dir * Math.PI / 2); + pp.addMarkerAngle(cp, ah - dir * Math.PI); + + bb.addPoint(cp.x, cp.y); // TODO: this is too naive, make it better + if (ctx != null) { + var r = rx > ry ? rx : ry; + var sx = rx > ry ? 1 : rx / ry; + var sy = rx > ry ? ry / rx : 1; + + ctx.translate(centp.x, centp.y); + ctx.rotate(xAxisRotation); + ctx.scale(sx, sy); + ctx.arc(0, 0, r, a1, a1 + ad, 1 - sweepFlag); + ctx.scale(1/sx, 1/sy); + ctx.rotate(-xAxisRotation); + ctx.translate(-centp.x, -centp.y); + } + } + break; + case 'Z': + case 'z': + if (ctx != null) ctx.closePath(); + pp.current = pp.start; + } + } + + return bb; + } + + this.getMarkers = function() { + var points = this.PathParser.getMarkerPoints(); + var angles = this.PathParser.getMarkerAngles(); + + var markers = []; + for (var i=0; i 1) this.offset = 1; + + var stopColor = this.style('stop-color'); + if (this.style('stop-opacity').hasValue()) stopColor = stopColor.addOpacity(this.style('stop-opacity').value); + this.color = stopColor.value; + } + svg.Element.stop.prototype = new svg.Element.ElementBase; + + // animation base element + svg.Element.AnimateBase = function(node) { + this.base = svg.Element.ElementBase; + this.base(node); + + svg.Animations.push(this); + + this.duration = 0.0; + this.begin = this.attribute('begin').toMilliseconds(); + this.maxDuration = this.begin + this.attribute('dur').toMilliseconds(); + + this.getProperty = function() { + var attributeType = this.attribute('attributeType').value; + var attributeName = this.attribute('attributeName').value; + + if (attributeType == 'CSS') { + return this.parent.style(attributeName, true); + } + return this.parent.attribute(attributeName, true); + }; + + this.initialValue = null; + this.initialUnits = ''; + this.removed = false; + + this.calcValue = function() { + // OVERRIDE ME! + return ''; + } + + this.update = function(delta) { + // set initial value + if (this.initialValue == null) { + this.initialValue = this.getProperty().value; + this.initialUnits = this.getProperty().getUnits(); + } + + // if we're past the end time + if (this.duration > this.maxDuration) { + // loop for indefinitely repeating animations + if (this.attribute('repeatCount').value == 'indefinite' + || this.attribute('repeatDur').value == 'indefinite') { + this.duration = 0.0 + } + else if (this.attribute('fill').valueOrDefault('remove') == 'remove' && !this.removed) { + this.removed = true; + this.getProperty().value = this.initialValue; + return true; + } + else { + return false; // no updates made + } + } + this.duration = this.duration + delta; + + // if we're past the begin time + var updated = false; + if (this.begin < this.duration) { + var newValue = this.calcValue(); // tween + + if (this.attribute('type').hasValue()) { + // for transform, etc. + var type = this.attribute('type').value; + newValue = type + '(' + newValue + ')'; + } + + this.getProperty().value = newValue; + updated = true; + } + + return updated; + } + + this.from = this.attribute('from'); + this.to = this.attribute('to'); + this.values = this.attribute('values'); + if (this.values.hasValue()) this.values.value = this.values.value.split(';'); + + // fraction of duration we've covered + this.progress = function() { + var ret = { progress: (this.duration - this.begin) / (this.maxDuration - this.begin) }; + if (this.values.hasValue()) { + var p = ret.progress * (this.values.value.length - 1); + var lb = Math.floor(p), ub = Math.ceil(p); + ret.from = new svg.Property('from', parseFloat(this.values.value[lb])); + ret.to = new svg.Property('to', parseFloat(this.values.value[ub])); + ret.progress = (p - lb) / (ub - lb); + } + else { + ret.from = this.from; + ret.to = this.to; + } + return ret; + } + } + svg.Element.AnimateBase.prototype = new svg.Element.ElementBase; + + // animate element + svg.Element.animate = function(node) { + this.base = svg.Element.AnimateBase; + this.base(node); + + this.calcValue = function() { + var p = this.progress(); + + // tween value linearly + var newValue = p.from.numValue() + (p.to.numValue() - p.from.numValue()) * p.progress; + return newValue + this.initialUnits; + }; + } + svg.Element.animate.prototype = new svg.Element.AnimateBase; + + // animate color element + svg.Element.animateColor = function(node) { + this.base = svg.Element.AnimateBase; + this.base(node); + + this.calcValue = function() { + var p = this.progress(); + var from = new RGBColor(p.from.value); + var to = new RGBColor(p.to.value); + + if (from.ok && to.ok) { + // tween color linearly + var r = from.r + (to.r - from.r) * p.progress; + var g = from.g + (to.g - from.g) * p.progress; + var b = from.b + (to.b - from.b) * p.progress; + return 'rgb('+parseInt(r,10)+','+parseInt(g,10)+','+parseInt(b,10)+')'; + } + return this.attribute('from').value; + }; + } + svg.Element.animateColor.prototype = new svg.Element.AnimateBase; + + // animate transform element + svg.Element.animateTransform = function(node) { + this.base = svg.Element.AnimateBase; + this.base(node); + + this.calcValue = function() { + var p = this.progress(); + + // tween value linearly + var from = svg.ToNumberArray(p.from.value); + var to = svg.ToNumberArray(p.to.value); + var newValue = ''; + for (var i=0; i startI && child.attribute('x').hasValue()) break; // new group + width += child.measureTextRecursive(ctx); + } + return -1 * (textAnchor == 'end' ? width : width / 2.0); + } + return 0; + } + + this.renderChild = function(ctx, parent, i) { + var child = parent.children[i]; + if (child.attribute('x').hasValue()) { + child.x = child.attribute('x').toPixels('x') + this.getAnchorDelta(ctx, parent, i); + } + else { + if (this.attribute('dx').hasValue()) this.x += this.attribute('dx').toPixels('x'); + if (child.attribute('dx').hasValue()) this.x += child.attribute('dx').toPixels('x'); + child.x = this.x; + } + this.x = child.x + child.measureText(ctx); + + if (child.attribute('y').hasValue()) { + child.y = child.attribute('y').toPixels('y'); + } + else { + if (this.attribute('dy').hasValue()) this.y += this.attribute('dy').toPixels('y'); + if (child.attribute('dy').hasValue()) this.y += child.attribute('dy').toPixels('y'); + child.y = this.y; + } + this.y = child.y; + + child.render(ctx); + + for (var i=0; i0 && text[i-1]!=' ' && i0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial'; + if (typeof(font.glyphs[c]) != 'undefined') { + glyph = font.glyphs[c][arabicForm]; + if (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c]; + } + } + else { + glyph = font.glyphs[c]; + } + if (glyph == null) glyph = font.missingGlyph; + return glyph; + } + + this.renderChildren = function(ctx) { + var customFont = this.parent.style('font-family').getDefinition(); + if (customFont != null) { + var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize); + var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle); + var text = this.getText(); + if (customFont.isRTL) text = text.split("").reverse().join(""); + + var dx = svg.ToNumberArray(this.parent.attribute('dx').value); + for (var i=0; i 0) { + var urlStart = srcs[s].indexOf('url'); + var urlEnd = srcs[s].indexOf(')', urlStart); + var url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6); + var doc = svg.parseXml(svg.ajax(url)); + var fonts = doc.getElementsByTagName('font'); + for (var f=0; f - * @link http://www.phpied.com/rgb-color-parser-in-javascript/ - * @license Use it if you like it - */ -function RGBColor(color_string) -{ - this.ok = false; - - // strip any leading # - if (color_string.charAt(0) == '#') { // remove # if any - color_string = color_string.substr(1,6); - } - - color_string = color_string.replace(/ /g,''); - color_string = color_string.toLowerCase(); - - // before getting into regexps, try simple matches - // and overwrite the input - var simple_colors = { - aliceblue: 'f0f8ff', - antiquewhite: 'faebd7', - aqua: '00ffff', - aquamarine: '7fffd4', - azure: 'f0ffff', - beige: 'f5f5dc', - bisque: 'ffe4c4', - black: '000000', - blanchedalmond: 'ffebcd', - blue: '0000ff', - blueviolet: '8a2be2', - brown: 'a52a2a', - burlywood: 'deb887', - cadetblue: '5f9ea0', - chartreuse: '7fff00', - chocolate: 'd2691e', - coral: 'ff7f50', - cornflowerblue: '6495ed', - cornsilk: 'fff8dc', - crimson: 'dc143c', - cyan: '00ffff', - darkblue: '00008b', - darkcyan: '008b8b', - darkgoldenrod: 'b8860b', - darkgray: 'a9a9a9', - darkgreen: '006400', - darkkhaki: 'bdb76b', - darkmagenta: '8b008b', - darkolivegreen: '556b2f', - darkorange: 'ff8c00', - darkorchid: '9932cc', - darkred: '8b0000', - darksalmon: 'e9967a', - darkseagreen: '8fbc8f', - darkslateblue: '483d8b', - darkslategray: '2f4f4f', - darkturquoise: '00ced1', - darkviolet: '9400d3', - deeppink: 'ff1493', - deepskyblue: '00bfff', - dimgray: '696969', - dodgerblue: '1e90ff', - feldspar: 'd19275', - firebrick: 'b22222', - floralwhite: 'fffaf0', - forestgreen: '228b22', - fuchsia: 'ff00ff', - gainsboro: 'dcdcdc', - ghostwhite: 'f8f8ff', - gold: 'ffd700', - goldenrod: 'daa520', - gray: '808080', - green: '008000', - greenyellow: 'adff2f', - honeydew: 'f0fff0', - hotpink: 'ff69b4', - indianred : 'cd5c5c', - indigo : '4b0082', - ivory: 'fffff0', - khaki: 'f0e68c', - lavender: 'e6e6fa', - lavenderblush: 'fff0f5', - lawngreen: '7cfc00', - lemonchiffon: 'fffacd', - lightblue: 'add8e6', - lightcoral: 'f08080', - lightcyan: 'e0ffff', - lightgoldenrodyellow: 'fafad2', - lightgrey: 'd3d3d3', - lightgreen: '90ee90', - lightpink: 'ffb6c1', - lightsalmon: 'ffa07a', - lightseagreen: '20b2aa', - lightskyblue: '87cefa', - lightslateblue: '8470ff', - lightslategray: '778899', - lightsteelblue: 'b0c4de', - lightyellow: 'ffffe0', - lime: '00ff00', - limegreen: '32cd32', - linen: 'faf0e6', - magenta: 'ff00ff', - maroon: '800000', - mediumaquamarine: '66cdaa', - mediumblue: '0000cd', - mediumorchid: 'ba55d3', - mediumpurple: '9370d8', - mediumseagreen: '3cb371', - mediumslateblue: '7b68ee', - mediumspringgreen: '00fa9a', - mediumturquoise: '48d1cc', - mediumvioletred: 'c71585', - midnightblue: '191970', - mintcream: 'f5fffa', - mistyrose: 'ffe4e1', - moccasin: 'ffe4b5', - navajowhite: 'ffdead', - navy: '000080', - oldlace: 'fdf5e6', - olive: '808000', - olivedrab: '6b8e23', - orange: 'ffa500', - orangered: 'ff4500', - orchid: 'da70d6', - palegoldenrod: 'eee8aa', - palegreen: '98fb98', - paleturquoise: 'afeeee', - palevioletred: 'd87093', - papayawhip: 'ffefd5', - peachpuff: 'ffdab9', - peru: 'cd853f', - pink: 'ffc0cb', - plum: 'dda0dd', - powderblue: 'b0e0e6', - purple: '800080', - red: 'ff0000', - rosybrown: 'bc8f8f', - royalblue: '4169e1', - saddlebrown: '8b4513', - salmon: 'fa8072', - sandybrown: 'f4a460', - seagreen: '2e8b57', - seashell: 'fff5ee', - sienna: 'a0522d', - silver: 'c0c0c0', - skyblue: '87ceeb', - slateblue: '6a5acd', - slategray: '708090', - snow: 'fffafa', - springgreen: '00ff7f', - steelblue: '4682b4', - tan: 'd2b48c', - teal: '008080', - thistle: 'd8bfd8', - tomato: 'ff6347', - turquoise: '40e0d0', - violet: 'ee82ee', - violetred: 'd02090', - wheat: 'f5deb3', - white: 'ffffff', - whitesmoke: 'f5f5f5', - yellow: 'ffff00', - yellowgreen: '9acd32' - }; - for (var key in simple_colors) { - if (color_string == key) { - color_string = simple_colors[key]; - } - } - // emd of simple type-in colors - - // array of color definition objects - var color_defs = [ - { - re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, - example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'], - process: function (bits){ - return [ - parseInt(bits[1]), - parseInt(bits[2]), - parseInt(bits[3]) - ]; - } - }, - { - re: /^(\w{2})(\w{2})(\w{2})$/, - example: ['#00ff00', '336699'], - process: function (bits){ - return [ - parseInt(bits[1], 16), - parseInt(bits[2], 16), - parseInt(bits[3], 16) - ]; - } - }, - { - re: /^(\w{1})(\w{1})(\w{1})$/, - example: ['#fb0', 'f0f'], - process: function (bits){ - return [ - parseInt(bits[1] + bits[1], 16), - parseInt(bits[2] + bits[2], 16), - parseInt(bits[3] + bits[3], 16) - ]; - } - } - ]; - - // search through the definitions to find a match - for (var i = 0; i < color_defs.length; i++) { - var re = color_defs[i].re; - var processor = color_defs[i].process; - var bits = re.exec(color_string); - if (bits) { - channels = processor(bits); - this.r = channels[0]; - this.g = channels[1]; - this.b = channels[2]; - this.ok = true; - } - - } - - // validate/cleanup values - this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r); - this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g); - this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b); - - // some getters - this.toRGB = function () { - return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')'; - } - this.toHex = function () { - var r = this.r.toString(16); - var g = this.g.toString(16); - var b = this.b.toString(16); - if (r.length == 1) r = '0' + r; - if (g.length == 1) g = '0' + g; - if (b.length == 1) b = '0' + b; - return '#' + r + g + b; - } - - // help - this.getHelpXML = function () { - - var examples = new Array(); - // add regexps - for (var i = 0; i < color_defs.length; i++) { - var example = color_defs[i].example; - for (var j = 0; j < example.length; j++) { - examples[examples.length] = example[j]; - } - } - // add type-in colors - for (var sc in simple_colors) { - examples[examples.length] = sc; - } - - var xml = document.createElement('ul'); - xml.setAttribute('id', 'rgbcolor-examples'); - for (var i = 0; i < examples.length; i++) { - try { - var list_item = document.createElement('li'); - var list_color = new RGBColor(examples[i]); - var example_div = document.createElement('div'); - example_div.style.cssText = - 'margin: 3px; ' - + 'border: 1px solid black; ' - + 'background:' + list_color.toHex() + '; ' - + 'color:' + list_color.toHex() - ; - example_div.appendChild(document.createTextNode('test')); - var list_item_value = document.createTextNode( - ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex() - ); - list_item.appendChild(example_div); - list_item.appendChild(list_item_value); - xml.appendChild(list_item); - - } catch(e){} - } - return xml; - - } - -} - +/** + * A class to parse color values + * @author Stoyan Stefanov + * @link http://www.phpied.com/rgb-color-parser-in-javascript/ + * @license Use it if you like it + */ +function RGBColor(color_string) +{ + this.ok = false; + + // strip any leading # + if (color_string.charAt(0) == '#') { // remove # if any + color_string = color_string.substr(1,6); + } + + color_string = color_string.replace(/ /g,''); + color_string = color_string.toLowerCase(); + + // before getting into regexps, try simple matches + // and overwrite the input + var simple_colors = { + aliceblue: 'f0f8ff', + antiquewhite: 'faebd7', + aqua: '00ffff', + aquamarine: '7fffd4', + azure: 'f0ffff', + beige: 'f5f5dc', + bisque: 'ffe4c4', + black: '000000', + blanchedalmond: 'ffebcd', + blue: '0000ff', + blueviolet: '8a2be2', + brown: 'a52a2a', + burlywood: 'deb887', + cadetblue: '5f9ea0', + chartreuse: '7fff00', + chocolate: 'd2691e', + coral: 'ff7f50', + cornflowerblue: '6495ed', + cornsilk: 'fff8dc', + crimson: 'dc143c', + cyan: '00ffff', + darkblue: '00008b', + darkcyan: '008b8b', + darkgoldenrod: 'b8860b', + darkgray: 'a9a9a9', + darkgreen: '006400', + darkkhaki: 'bdb76b', + darkmagenta: '8b008b', + darkolivegreen: '556b2f', + darkorange: 'ff8c00', + darkorchid: '9932cc', + darkred: '8b0000', + darksalmon: 'e9967a', + darkseagreen: '8fbc8f', + darkslateblue: '483d8b', + darkslategray: '2f4f4f', + darkturquoise: '00ced1', + darkviolet: '9400d3', + deeppink: 'ff1493', + deepskyblue: '00bfff', + dimgray: '696969', + dodgerblue: '1e90ff', + feldspar: 'd19275', + firebrick: 'b22222', + floralwhite: 'fffaf0', + forestgreen: '228b22', + fuchsia: 'ff00ff', + gainsboro: 'dcdcdc', + ghostwhite: 'f8f8ff', + gold: 'ffd700', + goldenrod: 'daa520', + gray: '808080', + green: '008000', + greenyellow: 'adff2f', + honeydew: 'f0fff0', + hotpink: 'ff69b4', + indianred : 'cd5c5c', + indigo : '4b0082', + ivory: 'fffff0', + khaki: 'f0e68c', + lavender: 'e6e6fa', + lavenderblush: 'fff0f5', + lawngreen: '7cfc00', + lemonchiffon: 'fffacd', + lightblue: 'add8e6', + lightcoral: 'f08080', + lightcyan: 'e0ffff', + lightgoldenrodyellow: 'fafad2', + lightgrey: 'd3d3d3', + lightgreen: '90ee90', + lightpink: 'ffb6c1', + lightsalmon: 'ffa07a', + lightseagreen: '20b2aa', + lightskyblue: '87cefa', + lightslateblue: '8470ff', + lightslategray: '778899', + lightsteelblue: 'b0c4de', + lightyellow: 'ffffe0', + lime: '00ff00', + limegreen: '32cd32', + linen: 'faf0e6', + magenta: 'ff00ff', + maroon: '800000', + mediumaquamarine: '66cdaa', + mediumblue: '0000cd', + mediumorchid: 'ba55d3', + mediumpurple: '9370d8', + mediumseagreen: '3cb371', + mediumslateblue: '7b68ee', + mediumspringgreen: '00fa9a', + mediumturquoise: '48d1cc', + mediumvioletred: 'c71585', + midnightblue: '191970', + mintcream: 'f5fffa', + mistyrose: 'ffe4e1', + moccasin: 'ffe4b5', + navajowhite: 'ffdead', + navy: '000080', + oldlace: 'fdf5e6', + olive: '808000', + olivedrab: '6b8e23', + orange: 'ffa500', + orangered: 'ff4500', + orchid: 'da70d6', + palegoldenrod: 'eee8aa', + palegreen: '98fb98', + paleturquoise: 'afeeee', + palevioletred: 'd87093', + papayawhip: 'ffefd5', + peachpuff: 'ffdab9', + peru: 'cd853f', + pink: 'ffc0cb', + plum: 'dda0dd', + powderblue: 'b0e0e6', + purple: '800080', + red: 'ff0000', + rosybrown: 'bc8f8f', + royalblue: '4169e1', + saddlebrown: '8b4513', + salmon: 'fa8072', + sandybrown: 'f4a460', + seagreen: '2e8b57', + seashell: 'fff5ee', + sienna: 'a0522d', + silver: 'c0c0c0', + skyblue: '87ceeb', + slateblue: '6a5acd', + slategray: '708090', + snow: 'fffafa', + springgreen: '00ff7f', + steelblue: '4682b4', + tan: 'd2b48c', + teal: '008080', + thistle: 'd8bfd8', + tomato: 'ff6347', + turquoise: '40e0d0', + violet: 'ee82ee', + violetred: 'd02090', + wheat: 'f5deb3', + white: 'ffffff', + whitesmoke: 'f5f5f5', + yellow: 'ffff00', + yellowgreen: '9acd32' + }; + for (var key in simple_colors) { + if (color_string == key) { + color_string = simple_colors[key]; + } + } + // emd of simple type-in colors + + // array of color definition objects + var color_defs = [ + { + re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, + example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'], + process: function (bits){ + return [ + parseInt(bits[1]), + parseInt(bits[2]), + parseInt(bits[3]) + ]; + } + }, + { + re: /^(\w{2})(\w{2})(\w{2})$/, + example: ['#00ff00', '336699'], + process: function (bits){ + return [ + parseInt(bits[1], 16), + parseInt(bits[2], 16), + parseInt(bits[3], 16) + ]; + } + }, + { + re: /^(\w{1})(\w{1})(\w{1})$/, + example: ['#fb0', 'f0f'], + process: function (bits){ + return [ + parseInt(bits[1] + bits[1], 16), + parseInt(bits[2] + bits[2], 16), + parseInt(bits[3] + bits[3], 16) + ]; + } + } + ]; + + // search through the definitions to find a match + for (var i = 0; i < color_defs.length; i++) { + var re = color_defs[i].re; + var processor = color_defs[i].process; + var bits = re.exec(color_string); + if (bits) { + channels = processor(bits); + this.r = channels[0]; + this.g = channels[1]; + this.b = channels[2]; + this.ok = true; + } + + } + + // validate/cleanup values + this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r); + this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g); + this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b); + + // some getters + this.toRGB = function () { + return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')'; + } + this.toHex = function () { + var r = this.r.toString(16); + var g = this.g.toString(16); + var b = this.b.toString(16); + if (r.length == 1) r = '0' + r; + if (g.length == 1) g = '0' + g; + if (b.length == 1) b = '0' + b; + return '#' + r + g + b; + } + + // help + this.getHelpXML = function () { + + var examples = new Array(); + // add regexps + for (var i = 0; i < color_defs.length; i++) { + var example = color_defs[i].example; + for (var j = 0; j < example.length; j++) { + examples[examples.length] = example[j]; + } + } + // add type-in colors + for (var sc in simple_colors) { + examples[examples.length] = sc; + } + + var xml = document.createElement('ul'); + xml.setAttribute('id', 'rgbcolor-examples'); + for (var i = 0; i < examples.length; i++) { + try { + var list_item = document.createElement('li'); + var list_color = new RGBColor(examples[i]); + var example_div = document.createElement('div'); + example_div.style.cssText = + 'margin: 3px; ' + + 'border: 1px solid black; ' + + 'background:' + list_color.toHex() + '; ' + + 'color:' + list_color.toHex() + ; + example_div.appendChild(document.createTextNode('test')); + var list_item_value = document.createTextNode( + ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex() + ); + list_item.appendChild(example_div); + list_item.appendChild(list_item_value); + xml.appendChild(list_item); + + } catch(e){} + } + return xml; + + } + +} + diff --git a/web/src/main/webapp/components/amcharts/funnel.js b/web/src/main/webapp/components/amcharts/funnel.js index 8ab57cd5518a..41708229dda6 100755 --- a/web/src/main/webapp/components/amcharts/funnel.js +++ b/web/src/main/webapp/components/amcharts/funnel.js @@ -1,8 +1,8 @@ -AmCharts.AmFunnelChart=AmCharts.Class({inherits:AmCharts.AmSlicedChart,construct:function(u){this.type="funnel";AmCharts.AmFunnelChart.base.construct.call(this,u);this.cname="AmFunnelChart";this.startX=this.startY=0;this.baseWidth="100%";this.neckHeight=this.neckWidth=0;this.rotate=!1;this.valueRepresents="height";this.pullDistance=30;this.labelPosition="center";this.labelText="[[title]]: [[value]]";this.balloonText="[[title]]: [[value]]\n[[description]]";AmCharts.applyTheme(this,u,this.cname)},drawChart:function(){AmCharts.AmFunnelChart.base.drawChart.call(this); -var u=this.chartData;if(AmCharts.ifArray(u))if(0b&&(b=0);b=(Math.sqrt(b)-C)/(2*d);if(!k&&a>=r||k&&a<=r)b=2*-p/l;else if(!k&&a+b>r||k&&a-br||k&&a-br&&(d=0),e.push(a,a,a+d,a+b,a+b,a+d,a)),C=!0):(n.push(h-m,h+m,h+p,h-p),k?e.push(a,a,a-b,a-b):e.push(a,a,a+b,a+b));t.set();d=t.set();n=AmCharts.polygon(t,n,e,c.color,c.alpha,this.outlineThickness,this.outlineColor,this.outlineAlpha);d.push(n);this.graphsSet.push(d);c.wedge=d;c.index=w;if(e=this.gradientRatio){var s=[],f;for(f=0;f=this.hideLabelsPercent&&(e=this.formatString(this.labelText,c),(n=this.labelFunction)&&(e=n(c,e)),s=c.labelColor,s||(s=this.color),n=this.labelPosition,f="left","center"==n&&(f="middle"),"left"==n&&(f="right"),e=AmCharts.wrappedText(t,e,s,this.fontFamily,this.fontSize, -f,!1,this.maxLabelWidth),e.node.style.pointerEvents="none",d.push(e),s=h,k?(f=a-b/2,c.ty0=f):(f=a+b/2,c.ty0=f,fg-q&&(f=g-q)),"right"==n&&(s=v+10+A,c.tx0=h+(m-b/2/E),C&&(c.tx0=h+p)),"left"==n&&(c.tx0=h-(m-b/2/E),C&&(c.tx0=h-p),s=A),c.label=e,c.labelX=s,c.labelY=f,c.labelHeight=e.getBBox().height,e.translate(s,f),m=e.getBBox(),B=AmCharts.rect(t,m.width+5,m.height+5,"#ffffff",.005),B.translate(s+m.x,f+m.y),d.push(B),c.hitRect=B,F=e.getBBox().height,B=f);(0===c.alpha||0b&&(b=0);b=(Math.sqrt(b)-C)/(2*d);if(!k&&a>=r||k&&a<=r)b=2*-p/l;else if(!k&&a+b>r||k&&a-br||k&&a-br&&(d=0),e.push(a,a,a+d,a+b,a+b,a+d,a)),C=!0):(n.push(h-m,h+m,h+p,h-p),k?e.push(a,a,a-b,a-b):e.push(a,a,a+b,a+b));t.set();d=t.set();n=AmCharts.polygon(t,n,e,c.color,c.alpha,this.outlineThickness,this.outlineColor,this.outlineAlpha);d.push(n);this.graphsSet.push(d);c.wedge=d;c.index=w;if(e=this.gradientRatio){var s=[],f;for(f=0;f=this.hideLabelsPercent&&(e=this.formatString(this.labelText,c),(n=this.labelFunction)&&(e=n(c,e)),s=c.labelColor,s||(s=this.color),n=this.labelPosition,f="left","center"==n&&(f="middle"),"left"==n&&(f="right"),e=AmCharts.wrappedText(t,e,s,this.fontFamily,this.fontSize, +f,!1,this.maxLabelWidth),e.node.style.pointerEvents="none",d.push(e),s=h,k?(f=a-b/2,c.ty0=f):(f=a+b/2,c.ty0=f,fg-q&&(f=g-q)),"right"==n&&(s=v+10+A,c.tx0=h+(m-b/2/E),C&&(c.tx0=h+p)),"left"==n&&(c.tx0=h-(m-b/2/E),C&&(c.tx0=h-p),s=A),c.label=e,c.labelX=s,c.labelY=f,c.labelHeight=e.getBBox().height,e.translate(s,f),m=e.getBBox(),B=AmCharts.rect(t,m.width+5,m.height+5,"#ffffff",.005),B.translate(s+m.x,f+m.y),d.push(B),c.hitRect=B,F=e.getBBox().height,B=f);(0===c.alpha||0v&&(l=t+D+5):v+y+5>t&&(l=t-5-y);t=l;D=y;if(A){A.translate(a,l);var z=A.getBBox()}g.hitRect.translate(a+z.x,l+z.y);g.labelY=l;g.tx=a;g.ty=l;g.tx2=a}"center"!=this.labelPosition&&this.drawTicks()}}); \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/gauge.js b/web/src/main/webapp/components/amcharts/gauge.js index d03d4ef41959..1f9e9b46d5aa 100755 --- a/web/src/main/webapp/components/amcharts/gauge.js +++ b/web/src/main/webapp/components/amcharts/gauge.js @@ -1,19 +1,19 @@ -AmCharts.GaugeAxis=AmCharts.Class({construct:function(a){this.cname="GaugeAxis";this.radius="95%";this.startAngle=-120;this.endAngle=120;this.startValue=0;this.endValue=200;this.gridCount=5;this.tickLength=10;this.minorTickLength=5;this.tickColor="#555555";this.labelFrequency=this.tickThickness=this.tickAlpha=1;this.inside=!0;this.labelOffset=10;this.showLastLabel=this.showFirstLabel=!0;this.axisThickness=1;this.axisColor="#000000";this.axisAlpha=1;this.gridInside=!0;this.topTextYOffset=0;this.topTextBold= -!0;this.bottomTextYOffset=0;this.bottomTextBold=!0;this.centerY=this.centerX="0%";this.bandOutlineAlpha=this.bandOutlineThickness=0;this.bandOutlineColor="#000000";this.bandAlpha=1;AmCharts.applyTheme(this,a,"GaugeAxis")},value2angle:function(a){return(a-this.startValue)/(this.endValue-this.startValue)*(this.endAngle-this.startAngle)+this.startAngle},setTopText:function(a){if(void 0!==a){this.topText=a;var b=this.chart;if(this.axisCreated){this.topTF&&this.topTF.remove();var c=this.topTextFontSize; -c||(c=b.fontSize);var d=this.topTextColor;d||(d=b.color);a=AmCharts.text(b.container,a,d,b.fontFamily,c,void 0,this.topTextBold);a.translate(this.centerXReal,this.centerYReal-this.radiusReal/2+this.topTextYOffset);this.chart.graphsSet.push(a);this.topTF=a}}},setBottomText:function(a){if(void 0!==a){this.bottomText=a;var b=this.chart;if(this.axisCreated){this.bottomTF&&this.bottomTF.remove();var c=this.bottomTextFontSize;c||(c=b.fontSize);var d=this.bottomTextColor;d||(d=b.color);a=AmCharts.text(b.container, -a,d,b.fontFamily,c,void 0,this.bottomTextBold);a.translate(this.centerXReal,this.centerYReal+this.radiusReal/2+this.bottomTextYOffset);this.bottomTF=a;this.chart.graphsSet.push(a)}}},draw:function(){var a=this.chart,b=a.graphsSet,c=this.startValue,d=this.endValue,f=this.valueInterval;isNaN(f)&&(f=(d-c)/this.gridCount);var m=this.minorTickInterval;isNaN(m)&&(m=f/5);var p=this.startAngle,k=this.endAngle,e=this.tickLength,l=(d-c)/f+1,g=(k-p)/(l-1);this.singleValueAngle=d=g/f;var h=a.container,q=this.tickColor, -u=this.tickAlpha,C=this.tickThickness,D=f/m,F=g/D,m=this.minorTickLength,I=this.labelFrequency,s=this.radiusReal;this.inside||(s-=15);var y=a.centerX+AmCharts.toCoordinate(this.centerX,a.realWidth),z=a.centerY+AmCharts.toCoordinate(this.centerY,a.realHeight);this.centerXReal=y;this.centerYReal=z;var J={fill:this.axisColor,"fill-opacity":this.axisAlpha,"stroke-width":0,"stroke-opacity":0},n,A;this.gridInside?A=n=s:(n=s-e,A=n+m);var r=this.axisThickness/2,k=AmCharts.wedge(h,y,z,p,k-p,n+r,n+r,n-r,0, -J);b.push(k);k=AmCharts.doNothing;AmCharts.isModern||(k=Math.round);J=AmCharts.getDecimals(f);for(n=0;na&&(a=c.width*h);c.height*h>e&&(e=c.height* -h)}(h=this.legend)&&h.invalidateSize();if(this.adjustSize&&!this.chartCreated){g&&(g=g.getBBox(),g.width>a&&(a=g.width),g.height>e&&(e=g.height));g=0;if(l>e||d>a)g=Math.min(l-e,d-a);0= +AmCharts.GaugeAxis=AmCharts.Class({construct:function(a){this.cname="GaugeAxis";this.radius="95%";this.startAngle=-120;this.endAngle=120;this.startValue=0;this.endValue=200;this.gridCount=5;this.tickLength=10;this.minorTickLength=5;this.tickColor="#555555";this.labelFrequency=this.tickThickness=this.tickAlpha=1;this.inside=!0;this.labelOffset=10;this.showLastLabel=this.showFirstLabel=!0;this.axisThickness=1;this.axisColor="#000000";this.axisAlpha=1;this.gridInside=!0;this.topTextYOffset=0;this.topTextBold= +!0;this.bottomTextYOffset=0;this.bottomTextBold=!0;this.centerY=this.centerX="0%";this.bandOutlineAlpha=this.bandOutlineThickness=0;this.bandOutlineColor="#000000";this.bandAlpha=1;AmCharts.applyTheme(this,a,"GaugeAxis")},value2angle:function(a){return(a-this.startValue)/(this.endValue-this.startValue)*(this.endAngle-this.startAngle)+this.startAngle},setTopText:function(a){if(void 0!==a){this.topText=a;var b=this.chart;if(this.axisCreated){this.topTF&&this.topTF.remove();var c=this.topTextFontSize; +c||(c=b.fontSize);var d=this.topTextColor;d||(d=b.color);a=AmCharts.text(b.container,a,d,b.fontFamily,c,void 0,this.topTextBold);a.translate(this.centerXReal,this.centerYReal-this.radiusReal/2+this.topTextYOffset);this.chart.graphsSet.push(a);this.topTF=a}}},setBottomText:function(a){if(void 0!==a){this.bottomText=a;var b=this.chart;if(this.axisCreated){this.bottomTF&&this.bottomTF.remove();var c=this.bottomTextFontSize;c||(c=b.fontSize);var d=this.bottomTextColor;d||(d=b.color);a=AmCharts.text(b.container, +a,d,b.fontFamily,c,void 0,this.bottomTextBold);a.translate(this.centerXReal,this.centerYReal+this.radiusReal/2+this.bottomTextYOffset);this.bottomTF=a;this.chart.graphsSet.push(a)}}},draw:function(){var a=this.chart,b=a.graphsSet,c=this.startValue,d=this.endValue,f=this.valueInterval;isNaN(f)&&(f=(d-c)/this.gridCount);var m=this.minorTickInterval;isNaN(m)&&(m=f/5);var p=this.startAngle,k=this.endAngle,e=this.tickLength,l=(d-c)/f+1,g=(k-p)/(l-1);this.singleValueAngle=d=g/f;var h=a.container,q=this.tickColor, +u=this.tickAlpha,C=this.tickThickness,D=f/m,F=g/D,m=this.minorTickLength,I=this.labelFrequency,s=this.radiusReal;this.inside||(s-=15);var y=a.centerX+AmCharts.toCoordinate(this.centerX,a.realWidth),z=a.centerY+AmCharts.toCoordinate(this.centerY,a.realHeight);this.centerXReal=y;this.centerYReal=z;var J={fill:this.axisColor,"fill-opacity":this.axisAlpha,"stroke-width":0,"stroke-opacity":0},n,A;this.gridInside?A=n=s:(n=s-e,A=n+m);var r=this.axisThickness/2,k=AmCharts.wedge(h,y,z,p,k-p,n+r,n+r,n-r,0, +J);b.push(k);k=AmCharts.doNothing;AmCharts.isModern||(k=Math.round);J=AmCharts.getDecimals(f);for(n=0;na&&(a=c.width*h);c.height*h>e&&(e=c.height* +h)}(h=this.legend)&&h.invalidateSize();if(this.adjustSize&&!this.chartCreated){g&&(g=g.getBBox(),g.width>a&&(a=g.width),g.height>e&&(e=g.height));g=0;if(l>e||d>a)g=Math.min(l-e,d-a);0= this.totalFrames?d=b.value:(b.frame++,b.clockWiseOnly&&b.valuethis.maxLabelWidth&&(q=this.maxLabelWidth);this.labelText&&this.labelsEnabled||(v=q=0);w=void 0===this.pieX?(b-k-a)/2+k:d(this.pieX,this.realWidth);x=void 0===this.pieY?(h-t-m)/2+t:d(this.pieY,h);g=d(this.radius,b,h);g||(b=0<=v?b-k-a-2*q:b-k-a,h=h-t-m,g=Math.min(b,h),hb&&(g=b)),h=AmCharts.toCoordinate(this.pullOutRadius,g),g=(0<=v?g-1.8*(v+h):g-1.8*h)/2);g=g&&(d=g-1);m=AmCharts.fitToBounds(this.startAngle,0,360);0=this.hideLabelsPercent){var l=m+n/2;360=l&&0<=l?(B=0,A="start",u=8):90<=l&&180>l?(B=1, -A="start",u=8):180<=l&&270>l?(B=2,A="end",u=-8):270<=l&&360>l&&(B=3,A="end",u=-8);a.labelQuarter=B}else A="middle";var l=this.formatString(this.labelText,a),s=this.labelFunction;s&&(l=s(a,l));s=a.labelColor;s||(s=this.color);l=AmCharts.wrappedText(c,l,s,this.fontFamily,this.fontSize,A,!1,this.maxLabelWidth);l.translate(n+1.5*u,z);l.node.style.pointerEvents="none";a.tx=n+1.5*u;a.ty=z;0<=r?(r=l.getBBox(),s=AmCharts.rect(c,r.width+5,r.height+5,"#FFFFFF",.005),s.translate(n+1.5*u+r.x,z+r.y),a.hitRect= -s,p.push(l),p.push(s)):this.freeLabelsSet.push(l);a.label=l;a.tx=n;a.tx2=n+u;a.tx0=w+q*g;a.ty0=x+y*g}n=d+(g-d)/2;a.pulled&&(n+=this.pullOutRadiusReal);a.balloonX=q*n+w;a.balloonY=y*n+x;a.startX=Math.round(q*t);a.startY=Math.round(y*t);a.pullX=Math.round(q*h);a.pullY=Math.round(y*h);this.graphsSet.push(p);(0===a.alpha||0c?b.toFront():180<=c&&b.toBack()}},arrangeLabels:function(){var e=this.chartData,f=e.length,c,b;for(b=f-1;0<=b;b--)c=e[b],0!==c.labelQuarter||c.hidden||this.checkOverlapping(b,c,0,!0,0);for(b=0;b +AmCharts.AmPieChart=AmCharts.Class({inherits:AmCharts.AmSlicedChart,construct:function(e){this.type="pie";AmCharts.AmPieChart.base.construct.call(this,e);this.cname="AmPieChart";this.pieBrightnessStep=30;this.minRadius=10;this.depth3D=0;this.startAngle=90;this.angle=this.innerRadius=0;this.startRadius="500%";this.pullOutRadius="20%";this.labelRadius=20;this.labelText="[[title]]: [[percents]]%";this.balloonText="[[title]]: [[percents]]% ([[value]])\n[[description]]";this.previousScale=1;AmCharts.applyTheme(this, +e,this.cname)},drawChart:function(){AmCharts.AmPieChart.base.drawChart.call(this);var e=this.chartData;if(AmCharts.ifArray(e)){if(0this.maxLabelWidth&&(q=this.maxLabelWidth);this.labelText&&this.labelsEnabled||(v=q=0);w=void 0===this.pieX?(b-k-a)/2+k:d(this.pieX,this.realWidth);x=void 0===this.pieY?(h-t-m)/2+t:d(this.pieY,h);g=d(this.radius,b,h);g||(b=0<=v?b-k-a-2*q:b-k-a,h=h-t-m,g=Math.min(b,h),hb&&(g=b)),h=AmCharts.toCoordinate(this.pullOutRadius,g),g=(0<=v?g-1.8*(v+h):g-1.8*h)/2);g=g&&(d=g-1);m=AmCharts.fitToBounds(this.startAngle,0,360);0=this.hideLabelsPercent){var l=m+n/2;360=l&&0<=l?(B=0,A="start",u=8):90<=l&&180>l?(B=1, +A="start",u=8):180<=l&&270>l?(B=2,A="end",u=-8):270<=l&&360>l&&(B=3,A="end",u=-8);a.labelQuarter=B}else A="middle";var l=this.formatString(this.labelText,a),s=this.labelFunction;s&&(l=s(a,l));s=a.labelColor;s||(s=this.color);l=AmCharts.wrappedText(c,l,s,this.fontFamily,this.fontSize,A,!1,this.maxLabelWidth);l.translate(n+1.5*u,z);l.node.style.pointerEvents="none";a.tx=n+1.5*u;a.ty=z;0<=r?(r=l.getBBox(),s=AmCharts.rect(c,r.width+5,r.height+5,"#FFFFFF",.005),s.translate(n+1.5*u+r.x,z+r.y),a.hitRect= +s,p.push(l),p.push(s)):this.freeLabelsSet.push(l);a.label=l;a.tx=n;a.tx2=n+u;a.tx0=w+q*g;a.ty0=x+y*g}n=d+(g-d)/2;a.pulled&&(n+=this.pullOutRadiusReal);a.balloonX=q*n+w;a.balloonY=y*n+x;a.startX=Math.round(q*t);a.startY=Math.round(y*t);a.pullX=Math.round(q*h);a.pullY=Math.round(y*h);this.graphsSet.push(p);(0===a.alpha||0c?b.toFront():180<=c&&b.toBack()}},arrangeLabels:function(){var e=this.chartData,f=e.length,c,b;for(b=f-1;0<=b;b--)c=e[b],0!==c.labelQuarter||c.hidden||this.checkOverlapping(b,c,0,!0,0);for(b=0;b h&&(d=f.ty+3*f.iy,f.ty=d,m.translate(f.tx2,d),f.hitRect&&(m=m.getBBox(),f.hitRect.translate(f.tx2+m.x,d+m.y)),this.checkOverlapping(e,f,c,b,h+1))}},checkOverlappingReal:function(e,f,c){var b=!1,h=e.label,d=f.label;e.labelQuarter!=c||e.hidden||f.hidden||!d||(h=h.getBBox(),c={},c.width=h.width,c.height=h.height,c.y=e.ty,c.x=e.tx,e=d.getBBox(),d={},d.width=e.width,d.height=e.height,d.y=f.ty,d.x=f.tx,AmCharts.hitTest(c,d)&&(b=!0));return b}}); \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/radar.js b/web/src/main/webapp/components/amcharts/radar.js index e44dfe217a6a..aca083dd175e 100755 --- a/web/src/main/webapp/components/amcharts/radar.js +++ b/web/src/main/webapp/components/amcharts/radar.js @@ -1,10 +1,10 @@ -AmCharts.AmRadarChart=AmCharts.Class({inherits:AmCharts.AmCoordinateChart,construct:function(a){this.type="radar";AmCharts.AmRadarChart.base.construct.call(this,a);this.cname="AmRadarChart";this.marginRight=this.marginBottom=this.marginTop=this.marginLeft=0;this.radius="35%";AmCharts.applyTheme(this,a,this.cname)},initChart:function(){AmCharts.AmRadarChart.base.initChart.call(this);this.dataChanged&&(this.updateData(),this.dataChanged=!1,this.dispatchDataUpdated=!0);this.drawChart()},updateData:function(){this.parseData(); -var a=this.graphs,b;for(b=0;bk&&(u="end",h-=10);180==k&&(q-=5);0===k&&(q+=5);k=AmCharts.text(b.container,a[t].category,r,l,g,u);k.translate(h+5,q);this.set.push(k);k.getBBox()}}}}});AmCharts.RadItem=AmCharts.Class({construct:function(a,b,c,d,m,p,e,f){void 0===c&&(c="");var n=a.chart.fontFamily,l=a.fontSize;void 0===l&&(l=a.chart.fontSize);var g=a.color;void 0===g&&(g=a.chart.color);var r=a.chart.container;this.set=d=r.set();var w=a.axisColor,t=a.axisAlpha,k=a.tickLength,h=a.gridAlpha,q=a.gridThickness,u=a.gridColor,A=a.dashLength,B=a.fillColor,y=a.fillAlpha,C=a.labelsEnabled;m=a.counter;var D=a.inside,E=a.gridType,s,H=a.labelOffset;b-=a.height;var x;p=a.x;var F=a.y;e?(C=!0,isNaN(e.tickLength)|| -(k=e.tickLength),void 0!=e.lineColor&&(u=e.lineColor),isNaN(e.lineAlpha)||(h=e.lineAlpha),isNaN(e.dashLength)||(A=e.dashLength),isNaN(e.lineThickness)||(q=e.lineThickness),!0===e.inside&&(D=!0),void 0!==e.boldLabel&&(f=e.boldLabel)):c||(h/=3,k/=2);var G="end",z=-1;D&&(G="start",z=1);var v;C&&(v=AmCharts.text(r,c,g,n,l,G,f),v.translate(p+(k+3+H)*z,b),d.push(v),this.label=v,x=AmCharts.line(r,[p,p+k*z],[b,b],w,t,q),d.push(x));b=Math.round(a.y-b);f=[];n=[];if(0k&&(u="end",h-=10);180==k&&(q-=5);0===k&&(q+=5);k=AmCharts.text(b.container,a[t].category,r,l,g,u);k.translate(h+5,q);this.set.push(k);k.getBBox()}}}}});AmCharts.RadItem=AmCharts.Class({construct:function(a,b,c,d,m,p,e,f){void 0===c&&(c="");var n=a.chart.fontFamily,l=a.fontSize;void 0===l&&(l=a.chart.fontSize);var g=a.color;void 0===g&&(g=a.chart.color);var r=a.chart.container;this.set=d=r.set();var w=a.axisColor,t=a.axisAlpha,k=a.tickLength,h=a.gridAlpha,q=a.gridThickness,u=a.gridColor,A=a.dashLength,B=a.fillColor,y=a.fillAlpha,C=a.labelsEnabled;m=a.counter;var D=a.inside,E=a.gridType,s,H=a.labelOffset;b-=a.height;var x;p=a.x;var F=a.y;e?(C=!0,isNaN(e.tickLength)|| +(k=e.tickLength),void 0!=e.lineColor&&(u=e.lineColor),isNaN(e.lineAlpha)||(h=e.lineAlpha),isNaN(e.dashLength)||(A=e.dashLength),isNaN(e.lineThickness)||(q=e.lineThickness),!0===e.inside&&(D=!0),void 0!==e.boldLabel&&(f=e.boldLabel)):c||(h/=3,k/=2);var G="end",z=-1;D&&(G="start",z=1);var v;C&&(v=AmCharts.text(r,c,g,n,l,G,f),v.translate(p+(k+3+H)*z,b),d.push(v),this.label=v,x=AmCharts.line(r,[p,p+k*z],[b,b],w,t,q),d.push(x));b=Math.round(a.y-b);f=[];n=[];if(0a?d?(d=this.startTime+e*c,c=this.endTime+1*c,this.zoomToDates(new Date(d),new Date(c))):(d=this.start+e,c=this.end+1,this.zoomToIndexes(d,c)):d?(d=this.startTime-e*c,c=this.endTime- -1*c,this.zoomToDates(new Date(d),new Date(c))):(d=this.start-e,c=this.end-1,this.zoomToIndexes(d,c))}},validateData:function(a){this.marginsUpdated=!1;this.zoomOutOnDataUpdate&&!a&&(this.endTime=this.end=this.startTime=this.start=NaN);AmCharts.AmSerialChart.base.validateData.call(this)},drawChart:function(){AmCharts.AmSerialChart.base.drawChart.call(this);var a=this.chartData;if(AmCharts.ifArray(a)){var b=this.chartScrollbar;b&&b.draw();if(0c&&(a=b-c,this.updateScrollbar=!0),a!=this.startTime&&b-a>c&&(b=a+c,this.updateScrollbar=!0));var d=this.minSelectedTime;if(0n&&(a=n);bn&&(b=n);bc&&(a=b-c,this.updateScrollbar=!0),a!=this.start&&b-a>c&&(b=a+c,this.updateScrollbar=!0));if(a!=this.start||b!=this.end){var d=this.chartData.length-1;isNaN(a)&&(a=0,isNaN(c)||(a=d-c));isNaN(b)&&(b=d);bd&&(b=d);a>d&&(a=d-1);0>a&&(a=0);this.start=a;this.end=b;this.categoryAxis.zoom(a,b);this.zoomAxesAndGraphs();this.zoomScrollbar();0!== -a||b!=this.chartData.length-1?this.showZB(!0):this.showZB(!1);this.updateColumnsDepth();this.dispatchIndexZoomEvent()}},updateGraphs:function(){AmCharts.AmSerialChart.base.updateGraphs.call(this);var a=this.graphs,b;for(b=0;bb.depth?1:-1},zoomScrollbar:function(){var a=this.chartScrollbar,b=this.categoryAxis;a&&this.updateScrollbar&& -(b.parseDates&&!b.equalSpacing?a.timeZoom(this.startTime,this.endTime):a.zoom(this.start,this.end),this.updateScrollbar=!0)},updateTrendLines:function(){var a=this.trendLines,b;for(b=0;be&&(e=0);f>a.length-1&&(f=a.length-1);var l=e+Math.round((f-e)/2),n=a[l][b];if(1>=f-e){if(d)return e;d=a[f][b];return Math.abs(a[e][b]-c)a&&(a=0),b>d-1&&(b=d-1),d=this.categoryAxis,d.parseDates&&!d.equalSpacing?this.zoom(c[a].time,this.getEndTime(c[b].time)):this.zoom(a,b))}},zoomToDates:function(a,b){this.updateScrollbar=!0;var c=this.chartData;if(this.categoryAxis.equalSpacing){var d=this.getClosestIndex(c,"time",a.getTime(),!0,0,c.length);b=AmCharts.resetDateToMin(b,this.categoryAxis.minPeriod, -1);c=this.getClosestIndex(c,"time",b.getTime(),!1,0,c.length);this.zoom(d,c)}else this.zoom(a.getTime(),b.getTime())},zoomToCategoryValues:function(a,b){this.updateScrollbar=!0;this.zoom(this.getCategoryIndexByValue(a),this.getCategoryIndexByValue(b))},formatPeriodString:function(a,b){if(b){var c=["value","open","low","high","close"],d="value open low high close average sum count".split(" "),e=b.valueAxis,f=this.chartData,l=b.numberFormatter;l||(l=this.nf);for(var n=0;nA)r=A;if(isNaN(s)||sz)y=z;if(isNaN(w)||wb&&0===h&&(h=180):0>c&&270==h&&(h=90);this.gradientRotation=h;0===d&&0===e&&(this.cornerRadius=m);this.draw()},draw:function(){var a=this.set;a.clear();var b=this.container,c=this.w,d=this.h,e=this.dx,f= -this.dy,l=this.colors,n=this.alpha,k=this.bwidth,g=this.bcolor,h=this.balpha,m=this.gradientRotation,u=this.cornerRadius,r=this.dashLength,s=this.pattern,p=l,v=l;"object"==typeof l&&(p=l[0],v=l[l.length-1]);var q,x,t,y,w,C,B,z,A,D=n;s&&(n=0);if(0Math.abs(d)&&(d=0);1>Math.abs(c)&&(c=0);b=0===d?AmCharts.line(b,[0,c],[0,0],g,h,k,r):0===c?AmCharts.line(b, -[0,0],[0,d],g,h,k,r):0d?[q,A,x,t,y,w,C,B,z,b]:[B,z,x,t,y,w,q,A,C,b];for(q=0;qa&&(this.endTime=a);q=this.minorGridEnabled;var w,a=this.gridAlpha,C;if(this.parseDates&&!this.equalSpacing){this.timeDifference=this.endTime-this.startTime;d=this.choosePeriod(0);e=d.period;u=d.count;r=AmCharts.getPeriodDuration(e,u);rg&&(g=0),l=0,this.end-g+1>=this.autoRotateCount&&(this.labelRotation=this.autoRotateAngle),b=g;b<=this.end+2;b++){p=!1;0<=b&&bthis.end&&"start"==this.tickPosition&&(h=" ");p=new this.axisItemRenderer(this,g,h,x,B,p,void 0,y,tickShift,!1,s.labelColor);p.serialDataItem=s;this.pushAxisItem(p);this.gridAlpha=a}}else if(this.parseDates&&this.equalSpacing){f=this.start; -this.startTime=this.data[this.start].time;this.endTime=this.data[this.end].time;this.timeDifference=this.endTime-this.startTime;d=this.choosePeriod(0);e=d.period;u=d.count;r=AmCharts.getPeriodDuration(e,u);rg&&(g=0);v=this.end+2;v>=this.data.length&&(v=this.data.length);C=!1;C=!n;this.previousPos=-1E3;20=r){g=this.getCoordinate(b-this.start);q=!1;this.nextPeriod[s]&&(q=this.checkPeriodChange(this.nextPeriod[s],1,m,h,s));y=!1;q&&this.markPeriodChange?(q=this.dateFormatsObject[this.nextPeriod[s]],y=!0):q=this.dateFormatsObject[s];h=AmCharts.formatDate(new Date(m),q);if(b==d&&!n||b==l&&!k)h=" ";C?C=!1:(t||(y=!1),g-this.previousPos>this.safeDistance*Math.cos(this.labelRotation*Math.PI/180)&&(this.labelFunction&&(h=this.labelFunction(h,new Date(m),this,e,u,p)),this.boldLabels&&(y=!0),p=new this.axisItemRenderer(this, -g,h,void 0,void 0,void 0,void 0,y),x=p.graphics(),this.pushAxisItem(p),p=x.getBBox().width,AmCharts.isModern||(p-=g),this.previousPos=g+p));p=h=m}else isNaN(w)||(this.checkPeriodChange(e,w,m,B)&&(this.gridAlpha=this.minorGridAlpha,g=this.getCoordinate(b-this.start),q=new this.axisItemRenderer(this,g),this.pushAxisItem(q),B=m),this.gridAlpha=a)}for(b=0;bthis.height+1&&c--:f>this.width+1&&c--;0>f&&c++;return c=AmCharts.fitToBounds(c,0,b.length-1)},dateToCoordinate:function(a){return this.parseDates&&!this.equalSpacing?(a.getTime()- +AmCharts.AmSerialChart=AmCharts.Class({inherits:AmCharts.AmRectangularChart,construct:function(a){this.type="serial";AmCharts.AmSerialChart.base.construct.call(this,a);this.cname="AmSerialChart";this.theme=a;this.createEvents("changed");this.columnSpacing=5;this.columnSpacing3D=0;this.columnWidth=.8;this.updateScrollbar=!0;var b=new AmCharts.CategoryAxis(a);b.chart=this;this.categoryAxis=b;this.zoomOutOnDataUpdate=!0;this.mouseWheelZoomEnabled=this.mouseWheelScrollEnabled=this.rotate=this.skipZoom= +!1;this.minSelectedTime=0;AmCharts.applyTheme(this,a,this.cname)},initChart:function(){AmCharts.AmSerialChart.base.initChart.call(this);this.updateCategoryAxis(this.categoryAxis,this.rotate,"categoryAxis");this.dataChanged&&(this.updateData(),this.dataChanged=!1,this.dispatchDataUpdated=!0);var a=this.chartCursor;a&&(a.updateData(),a.fullWidth&&(a.fullRectSet=this.cursorLineSet));var a=this.countColumns(),b=this.graphs,c;for(c=0;ca?d?(d=this.startTime+e*c,c=this.endTime+1*c,this.zoomToDates(new Date(d),new Date(c))):(d=this.start+e,c=this.end+1,this.zoomToIndexes(d,c)):d?(d=this.startTime-e*c,c=this.endTime- +1*c,this.zoomToDates(new Date(d),new Date(c))):(d=this.start-e,c=this.end-1,this.zoomToIndexes(d,c))}},validateData:function(a){this.marginsUpdated=!1;this.zoomOutOnDataUpdate&&!a&&(this.endTime=this.end=this.startTime=this.start=NaN);AmCharts.AmSerialChart.base.validateData.call(this)},drawChart:function(){AmCharts.AmSerialChart.base.drawChart.call(this);var a=this.chartData;if(AmCharts.ifArray(a)){var b=this.chartScrollbar;b&&b.draw();if(0c&&(a=b-c,this.updateScrollbar=!0),a!=this.startTime&&b-a>c&&(b=a+c,this.updateScrollbar=!0));var d=this.minSelectedTime;if(0n&&(a=n);bn&&(b=n);bc&&(a=b-c,this.updateScrollbar=!0),a!=this.start&&b-a>c&&(b=a+c,this.updateScrollbar=!0));if(a!=this.start||b!=this.end){var d=this.chartData.length-1;isNaN(a)&&(a=0,isNaN(c)||(a=d-c));isNaN(b)&&(b=d);bd&&(b=d);a>d&&(a=d-1);0>a&&(a=0);this.start=a;this.end=b;this.categoryAxis.zoom(a,b);this.zoomAxesAndGraphs();this.zoomScrollbar();0!== +a||b!=this.chartData.length-1?this.showZB(!0):this.showZB(!1);this.updateColumnsDepth();this.dispatchIndexZoomEvent()}},updateGraphs:function(){AmCharts.AmSerialChart.base.updateGraphs.call(this);var a=this.graphs,b;for(b=0;bb.depth?1:-1},zoomScrollbar:function(){var a=this.chartScrollbar,b=this.categoryAxis;a&&this.updateScrollbar&& +(b.parseDates&&!b.equalSpacing?a.timeZoom(this.startTime,this.endTime):a.zoom(this.start,this.end),this.updateScrollbar=!0)},updateTrendLines:function(){var a=this.trendLines,b;for(b=0;be&&(e=0);f>a.length-1&&(f=a.length-1);var l=e+Math.round((f-e)/2),n=a[l][b];if(1>=f-e){if(d)return e;d=a[f][b];return Math.abs(a[e][b]-c)a&&(a=0),b>d-1&&(b=d-1),d=this.categoryAxis,d.parseDates&&!d.equalSpacing?this.zoom(c[a].time,this.getEndTime(c[b].time)):this.zoom(a,b))}},zoomToDates:function(a,b){this.updateScrollbar=!0;var c=this.chartData;if(this.categoryAxis.equalSpacing){var d=this.getClosestIndex(c,"time",a.getTime(),!0,0,c.length);b=AmCharts.resetDateToMin(b,this.categoryAxis.minPeriod, +1);c=this.getClosestIndex(c,"time",b.getTime(),!1,0,c.length);this.zoom(d,c)}else this.zoom(a.getTime(),b.getTime())},zoomToCategoryValues:function(a,b){this.updateScrollbar=!0;this.zoom(this.getCategoryIndexByValue(a),this.getCategoryIndexByValue(b))},formatPeriodString:function(a,b){if(b){var c=["value","open","low","high","close"],d="value open low high close average sum count".split(" "),e=b.valueAxis,f=this.chartData,l=b.numberFormatter;l||(l=this.nf);for(var n=0;nA)r=A;if(isNaN(s)||sz)y=z;if(isNaN(w)||wb&&0===h&&(h=180):0>c&&270==h&&(h=90);this.gradientRotation=h;0===d&&0===e&&(this.cornerRadius=m);this.draw()},draw:function(){var a=this.set;a.clear();var b=this.container,c=this.w,d=this.h,e=this.dx,f= +this.dy,l=this.colors,n=this.alpha,k=this.bwidth,g=this.bcolor,h=this.balpha,m=this.gradientRotation,u=this.cornerRadius,r=this.dashLength,s=this.pattern,p=l,v=l;"object"==typeof l&&(p=l[0],v=l[l.length-1]);var q,x,t,y,w,C,B,z,A,D=n;s&&(n=0);if(0Math.abs(d)&&(d=0);1>Math.abs(c)&&(c=0);b=0===d?AmCharts.line(b,[0,c],[0,0],g,h,k,r):0===c?AmCharts.line(b, +[0,0],[0,d],g,h,k,r):0d?[q,A,x,t,y,w,C,B,z,b]:[B,z,x,t,y,w,q,A,C,b];for(q=0;qa&&(this.endTime=a);q=this.minorGridEnabled;var w,a=this.gridAlpha,C;if(this.parseDates&&!this.equalSpacing){this.timeDifference=this.endTime-this.startTime;d=this.choosePeriod(0);e=d.period;u=d.count;r=AmCharts.getPeriodDuration(e,u);rg&&(g=0),l=0,this.end-g+1>=this.autoRotateCount&&(this.labelRotation=this.autoRotateAngle),b=g;b<=this.end+2;b++){p=!1;0<=b&&bthis.end&&"start"==this.tickPosition&&(h=" ");p=new this.axisItemRenderer(this,g,h,x,B,p,void 0,y,tickShift,!1,s.labelColor);p.serialDataItem=s;this.pushAxisItem(p);this.gridAlpha=a}}else if(this.parseDates&&this.equalSpacing){f=this.start; +this.startTime=this.data[this.start].time;this.endTime=this.data[this.end].time;this.timeDifference=this.endTime-this.startTime;d=this.choosePeriod(0);e=d.period;u=d.count;r=AmCharts.getPeriodDuration(e,u);rg&&(g=0);v=this.end+2;v>=this.data.length&&(v=this.data.length);C=!1;C=!n;this.previousPos=-1E3;20=r){g=this.getCoordinate(b-this.start);q=!1;this.nextPeriod[s]&&(q=this.checkPeriodChange(this.nextPeriod[s],1,m,h,s));y=!1;q&&this.markPeriodChange?(q=this.dateFormatsObject[this.nextPeriod[s]],y=!0):q=this.dateFormatsObject[s];h=AmCharts.formatDate(new Date(m),q);if(b==d&&!n||b==l&&!k)h=" ";C?C=!1:(t||(y=!1),g-this.previousPos>this.safeDistance*Math.cos(this.labelRotation*Math.PI/180)&&(this.labelFunction&&(h=this.labelFunction(h,new Date(m),this,e,u,p)),this.boldLabels&&(y=!0),p=new this.axisItemRenderer(this, +g,h,void 0,void 0,void 0,void 0,y),x=p.graphics(),this.pushAxisItem(p),p=x.getBBox().width,AmCharts.isModern||(p-=g),this.previousPos=g+p));p=h=m}else isNaN(w)||(this.checkPeriodChange(e,w,m,B)&&(this.gridAlpha=this.minorGridAlpha,g=this.getCoordinate(b-this.start),q=new this.axisItemRenderer(this,g),this.pushAxisItem(q),B=m),this.gridAlpha=a)}for(b=0;bthis.height+1&&c--:f>this.width+1&&c--;0>f&&c++;return c=AmCharts.fitToBounds(c,0,b.length-1)},dateToCoordinate:function(a){return this.parseDates&&!this.equalSpacing?(a.getTime()- this.startTime)*this.stepWidth:this.parseDates&&this.equalSpacing?(a=this.chart.getClosestIndex(this.data,"time",a.getTime(),!1,0,this.data.length-1),this.getCoordinate(a-this.start)):NaN},categoryToCoordinate:function(a){return this.chart?(a=this.chart.getCategoryIndexByValue(a),this.getCoordinate(a-this.start)):NaN},coordinateToDate:function(a){return this.equalSpacing?(a=this.xToIndex(a),new Date(this.data[a].time)):new Date(this.startTime+a/this.stepWidth)}}); \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/themes/black.js b/web/src/main/webapp/components/amcharts/themes/black.js index 09c160bda2d9..b604c3408ac9 100755 --- a/web/src/main/webapp/components/amcharts/themes/black.js +++ b/web/src/main/webapp/components/amcharts/themes/black.js @@ -1,206 +1,206 @@ -AmCharts.themes.black = { - - themeName: "black", - - AmChart: { - color: "#e7e7e7", backgroundColor: "#222222" - }, - - AmCoordinateChart: { - colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] - }, - - AmStockChart: { - colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] - }, - - AmSlicedChart: { - outlineAlpha: 1, - outlineThickness: 2, - labelTickColor: "#FFFFFF", - labelTickAlpha: 0.3, - colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] - }, - - AmRectangularChart: { - zoomOutButtonColor: '#FFFFFF', - zoomOutButtonRollOverAlpha: 0.15, - zoomOutButtonImage: "lensWhite.png" - }, - - AxisBase: { - axisColor: "#FFFFFF", - axisAlpha: 0.3, - gridAlpha: 0.1, - gridColor: "#FFFFFF", - dashLength: 3 - }, - - ChartScrollbar: { - backgroundColor: "#000000", - backgroundAlpha: 0.2, - graphFillAlpha: 0.2, - graphLineAlpha: 0, - graphFillColor: "#FFFFFF", - selectedGraphFillColor: "#FFFFFF", - selectedGraphFillAlpha: 0.4, - selectedGraphLineColor: "#FFFFFF", - selectedBackgroundColor: "#FFFFFF", - selectedBackgroundAlpha: 0.09, - gridAlpha: 0.15 - }, - - ChartCursor: { - cursorColor: "#FFFFFF", - color: "#000000", - cursorAlpha: 0.5 - }, - - AmLegend: { - color: "#e7e7e7" - }, - - AmGraph: { - lineAlpha: 0.9 - }, - - - GaugeArrow: { - color: "#FFFFFF", - alpha: 0.8, - nailAlpha: 0, - innerRadius: "40%", - nailRadius: 15, - startWidth: 15, - borderAlpha: 0.8, - nailBorderAlpha: 0 - }, - - GaugeAxis: { - tickColor: "#FFFFFF", - tickAlpha: 1, - tickLength: 15, - minorTickLength: 8, - axisThickness: 3, - axisColor: '#FFFFFF', - axisAlpha: 1, - bandAlpha: 0.8 - }, - - TrendLine: { - lineColor: "#c03246", - lineAlpha: 0.8 - }, - - // ammap - AreasSettings: { - alpha: 0.8, - color: "#FFFFFF", - colorSolid: "#000000", - unlistedAreasAlpha: 0.4, - unlistedAreasColor: "#FFFFFF", - outlineColor: "#000000", - outlineAlpha: 0.5, - outlineThickness: 0.5, - rollOverColor: "#3c5bdc", - rollOverOutlineColor: "#000000", - selectedOutlineColor: "#000000", - selectedColor: "#f15135", - unlistedAreasOutlineColor: "#000000", - unlistedAreasOutlineAlpha: 0.5 - }, - - LinesSettings: { - color: "#FFFFFF", - alpha: 0.8 - }, - - ImagesSettings: { - alpha: 0.8, - labelColor: "#FFFFFF", - color: "#FFFFFF", - labelRollOverColor: "#3c5bdc" - }, - - ZoomControl: { - buttonRollOverColor: "#3c5bdc", - buttonFillColor: "#738f58", - buttonBorderColor: "#738f58", - buttonFillAlpha: 0.8, - gridBackgroundColor: "#FFFFFF", - buttonBorderAlpha:0, - buttonCornerRadius:2, - gridAlpha:0.5, - gridBackgroundColor:"#FFFFFF", - homeIconFile:"homeIconWhite.gif", - buttonIconAlpha:0.6, - gridAlpha: 0.2, - buttonSize:20 - }, - - SmallMap: { - mapColor: "#FFFFFF", - rectangleColor: "#FFFFFF", - backgroundColor: "#000000", - backgroundAlpha: 0.7, - borderThickness: 1, - borderAlpha: 0.8 - }, - - // the defaults below are set using CSS syntax, you can use any existing css property - // if you don't use Stock chart, you can delete lines below - PeriodSelector: { - color: "#e7e7e7" - }, - - PeriodButton: { - color: "#e7e7e7", - background: "transparent", - opacity: 0.7, - border: "1px solid rgba(255, 255, 255, .15)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - boxSizing: "border-box" - }, - - PeriodButtonSelected: { - color: "#e7e7e7", - backgroundColor: "rgba(255, 255, 255, 0.1)", - border: "1px solid rgba(255, 255, 255, .3)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - opacity: 1, - boxSizing: "border-box" - }, - - PeriodInputField: { - color: "#e7e7e7", - background: "transparent", - border: "1px solid rgba(255, 255, 255, .15)", - outline: "none" - }, - - DataSetSelector: { - color: "#e7e7e7", - selectedBackgroundColor: "rgba(255, 255, 255, .25)", - rollOverBackgroundColor: "rgba(255, 255, 255, .15)" - }, - - DataSetCompareList: { - color: "#e7e7e7", - lineHeight: "100%", - boxSizing: "initial", - webkitBoxSizing: "initial", - border: "1px solid rgba(255, 255, 255, .15)" - }, - - DataSetSelect: { - border: "1px solid rgba(255, 255, 255, .15)", - outline: "none" - } - +AmCharts.themes.black = { + + themeName: "black", + + AmChart: { + color: "#e7e7e7", backgroundColor: "#222222" + }, + + AmCoordinateChart: { + colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] + }, + + AmStockChart: { + colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] + }, + + AmSlicedChart: { + outlineAlpha: 1, + outlineThickness: 2, + labelTickColor: "#FFFFFF", + labelTickAlpha: 0.3, + colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] + }, + + AmRectangularChart: { + zoomOutButtonColor: '#FFFFFF', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lensWhite.png" + }, + + AxisBase: { + axisColor: "#FFFFFF", + axisAlpha: 0.3, + gridAlpha: 0.1, + gridColor: "#FFFFFF", + dashLength: 3 + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.2, + graphFillAlpha: 0.2, + graphLineAlpha: 0, + graphFillColor: "#FFFFFF", + selectedGraphFillColor: "#FFFFFF", + selectedGraphFillAlpha: 0.4, + selectedGraphLineColor: "#FFFFFF", + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.09, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#FFFFFF", + color: "#000000", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#e7e7e7" + }, + + AmGraph: { + lineAlpha: 0.9 + }, + + + GaugeArrow: { + color: "#FFFFFF", + alpha: 0.8, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#FFFFFF", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: '#FFFFFF', + axisAlpha: 1, + bandAlpha: 0.8 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#FFFFFF", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#FFFFFF", + outlineColor: "#000000", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#3c5bdc", + rollOverOutlineColor: "#000000", + selectedOutlineColor: "#000000", + selectedColor: "#f15135", + unlistedAreasOutlineColor: "#000000", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#FFFFFF", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#FFFFFF", + color: "#FFFFFF", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonRollOverColor: "#3c5bdc", + buttonFillColor: "#738f58", + buttonBorderColor: "#738f58", + buttonFillAlpha: 0.8, + gridBackgroundColor: "#FFFFFF", + buttonBorderAlpha:0, + buttonCornerRadius:2, + gridAlpha:0.5, + gridBackgroundColor:"#FFFFFF", + homeIconFile:"homeIconWhite.gif", + buttonIconAlpha:0.6, + gridAlpha: 0.2, + buttonSize:20 + }, + + SmallMap: { + mapColor: "#FFFFFF", + rectangleColor: "#FFFFFF", + backgroundColor: "#000000", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#e7e7e7" + }, + + PeriodButton: { + color: "#e7e7e7", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(255, 255, 255, .15)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#e7e7e7", + backgroundColor: "rgba(255, 255, 255, 0.1)", + border: "1px solid rgba(255, 255, 255, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#e7e7e7", + background: "transparent", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + }, + + DataSetSelector: { + color: "#e7e7e7", + selectedBackgroundColor: "rgba(255, 255, 255, .25)", + rollOverBackgroundColor: "rgba(255, 255, 255, .15)" + }, + + DataSetCompareList: { + color: "#e7e7e7", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(255, 255, 255, .15)" + }, + + DataSetSelect: { + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + } + }; \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/themes/chalk.js b/web/src/main/webapp/components/amcharts/themes/chalk.js index a33f392118f8..e383032f343f 100755 --- a/web/src/main/webapp/components/amcharts/themes/chalk.js +++ b/web/src/main/webapp/components/amcharts/themes/chalk.js @@ -1,217 +1,217 @@ -AmCharts.themes.chalk = { - - themeName: "chalk", - - AmChart: { - color: "#e7e7e7", - fontFamily: "Covered By Your Grace", - fontSize: 18, - handDrawn: true, - backgroundColor: "#282828" - }, - - AmCoordinateChart: { - colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] - }, - - AmSlicedChart: { - outlineAlpha: 1, - labelTickColor: "#FFFFFF", - labelTickAlpha: 0.3, - colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] - }, - - AmStockChart: { - colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] - }, - - AmRectangularChart: { - - zoomOutButtonColor: '#FFFFFF', - zoomOutButtonRollOverAlpha: 0.15, - zoomOutButtonImage: "lensWhite.png" - }, - - AxisBase: { - axisColor: "#FFFFFF", - gridColor: "#FFFFFF" - }, - - ChartScrollbar: { - backgroundColor: "#FFFFFF", - backgroundAlpha: 0.2, - graphFillAlpha: 0.5, - graphLineAlpha: 0, - selectedBackgroundColor: "#000000", - selectedBackgroundAlpha: 0.25, - fontSize: 15, - gridAlpha: 0.15 - }, - - ChartCursor: { - cursorColor: "#FFFFFF", - color: "#000000" - }, - - AmLegend: { - color: "#e7e7e7", - markerSize: 20 - }, - - AmGraph: { - lineAlpha: 0.8 - }, - - - GaugeArrow: { - color: "#FFFFFF", - alpha: 0.1, - nailAlpha: 0, - innerRadius: "40%", - nailRadius: 15, - startWidth: 15, - borderAlpha: 0.8, - nailBorderAlpha: 0 - }, - - GaugeAxis: { - tickColor: "#FFFFFF", - tickAlpha: 0.8, - tickLength: 15, - minorTickLength: 8, - axisThickness: 3, - axisColor: '#FFFFFF', - axisAlpha: 0.8, - bandAlpha: 0.4 - }, - - TrendLine: { - lineColor: "#c03246", - lineAlpha: 0.8 - }, - - // ammap - AmMap: { - handDrawn: false - }, - - AreasSettings: { - alpha: 0.8, - color: "#FFFFFF", - colorSolid: "#000000", - unlistedAreasAlpha: 0.4, - unlistedAreasColor: "#FFFFFF", - outlineColor: "#000000", - outlineAlpha: 0.5, - outlineThickness: 0.5, - rollOverColor: "#4d90d6", - rollOverOutlineColor: "#000000", - selectedOutlineColor: "#000000", - selectedColor: "#e384a6", - unlistedAreasOutlineColor: "#000000", - unlistedAreasOutlineAlpha: 0.5 - }, - - LinesSettings: { - color: "#FFFFFF", - alpha: 0.8 - }, - - ImagesSettings: { - alpha: 0.8, - labelFontSize: 16, - labelColor: "#FFFFFF", - color: "#FFFFFF", - labelRollOverColor: "#4d90d6" - }, - - ZoomControl: { - buttonRollOverColor: "#4d90d6", - buttonFillColor: "#e384a6", - buttonFillAlpha: 0.8, - buttonBorderColor: "#FFFFFF", - gridBackgroundColor: "#FFFFFF", - gridAlpha: 0.8 - }, - - SmallMap: { - mapColor: "#FFFFFF", - rectangleColor: "#FFFFFF", - backgroundColor: "#000000", - backgroundAlpha: 0.7, - borderThickness: 1, - borderAlpha: 0.8 - }, - - - // the defaults below are set using CSS syntax, you can use any existing css property - // if you don't use Stock chart, you can delete lines below - PeriodSelector: { - fontFamily: "Covered By Your Grace", - fontSize:"16px", - color: "#e7e7e7" - }, - - PeriodButton: { - fontFamily: "Covered By Your Grace", - fontSize:"16px", - color: "#e7e7e7", - background: "transparent", - opacity: 0.7, - border: "1px solid rgba(255, 255, 255, .15)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - boxSizing: "border-box" - }, - - PeriodButtonSelected: { - fontFamily: "Covered By Your Grace", - fontSize:"16px", - color: "#e7e7e7", - backgroundColor: "rgba(255, 255, 255, 0.1)", - border: "1px solid rgba(255, 255, 255, .3)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - opacity: 1, - boxSizing: "border-box" - }, - - PeriodInputField: { - fontFamily: "Covered By Your Grace", - fontSize:"16px", - color: "#e7e7e7", - background: "transparent", - border: "1px solid rgba(255, 255, 255, .15)", - outline: "none" - }, - - DataSetSelector: { - fontFamily: "Covered By Your Grace", - fontSize:"16px", - color: "#e7e7e7", - selectedBackgroundColor: "rgba(255, 255, 255, .25)", - rollOverBackgroundColor: "rgba(255, 255, 255, .15)" - }, - - DataSetCompareList: { - fontFamily: "Covered By Your Grace", - fontSize:"16px", - color: "#e7e7e7", - lineHeight: "100%", - boxSizing: "initial", - webkitBoxSizing: "initial", - border: "1px solid rgba(255, 255, 255, .15)" - }, - - DataSetSelect: { - fontFamily: "Covered By Your Grace", - fontSize:"16px", - border: "1px solid rgba(255, 255, 255, .15)", - outline: "none" - } - +AmCharts.themes.chalk = { + + themeName: "chalk", + + AmChart: { + color: "#e7e7e7", + fontFamily: "Covered By Your Grace", + fontSize: 18, + handDrawn: true, + backgroundColor: "#282828" + }, + + AmCoordinateChart: { + colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] + }, + + AmSlicedChart: { + outlineAlpha: 1, + labelTickColor: "#FFFFFF", + labelTickAlpha: 0.3, + colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] + }, + + AmStockChart: { + colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] + }, + + AmRectangularChart: { + + zoomOutButtonColor: '#FFFFFF', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lensWhite.png" + }, + + AxisBase: { + axisColor: "#FFFFFF", + gridColor: "#FFFFFF" + }, + + ChartScrollbar: { + backgroundColor: "#FFFFFF", + backgroundAlpha: 0.2, + graphFillAlpha: 0.5, + graphLineAlpha: 0, + selectedBackgroundColor: "#000000", + selectedBackgroundAlpha: 0.25, + fontSize: 15, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#FFFFFF", + color: "#000000" + }, + + AmLegend: { + color: "#e7e7e7", + markerSize: 20 + }, + + AmGraph: { + lineAlpha: 0.8 + }, + + + GaugeArrow: { + color: "#FFFFFF", + alpha: 0.1, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#FFFFFF", + tickAlpha: 0.8, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: '#FFFFFF', + axisAlpha: 0.8, + bandAlpha: 0.4 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AmMap: { + handDrawn: false + }, + + AreasSettings: { + alpha: 0.8, + color: "#FFFFFF", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#FFFFFF", + outlineColor: "#000000", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#4d90d6", + rollOverOutlineColor: "#000000", + selectedOutlineColor: "#000000", + selectedColor: "#e384a6", + unlistedAreasOutlineColor: "#000000", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#FFFFFF", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelFontSize: 16, + labelColor: "#FFFFFF", + color: "#FFFFFF", + labelRollOverColor: "#4d90d6" + }, + + ZoomControl: { + buttonRollOverColor: "#4d90d6", + buttonFillColor: "#e384a6", + buttonFillAlpha: 0.8, + buttonBorderColor: "#FFFFFF", + gridBackgroundColor: "#FFFFFF", + gridAlpha: 0.8 + }, + + SmallMap: { + mapColor: "#FFFFFF", + rectangleColor: "#FFFFFF", + backgroundColor: "#000000", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7" + }, + + PeriodButton: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(255, 255, 255, .15)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + backgroundColor: "rgba(255, 255, 255, 0.1)", + border: "1px solid rgba(255, 255, 255, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + background: "transparent", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + }, + + DataSetSelector: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + selectedBackgroundColor: "rgba(255, 255, 255, .25)", + rollOverBackgroundColor: "rgba(255, 255, 255, .15)" + }, + + DataSetCompareList: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(255, 255, 255, .15)" + }, + + DataSetSelect: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + } + }; \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/themes/dark.js b/web/src/main/webapp/components/amcharts/themes/dark.js index 8367b72f7bd0..37713d086021 100755 --- a/web/src/main/webapp/components/amcharts/themes/dark.js +++ b/web/src/main/webapp/components/amcharts/themes/dark.js @@ -1,205 +1,205 @@ -AmCharts.themes.dark = { - - themeName: "dark", - - AmChart: { - color: "#e7e7e7", backgroundColor: "#282828" - }, - - AmCoordinateChart: { - colors: ["#ae85c9", "#aab9f7", "#b6d2ff", "#c9e6f2", "#c9f0e1", "#e8d685", "#e0ad63", "#d48652", "#d27362", "#495fba", "#7a629b", "#8881cc"] - }, - - AmStockChart: { - colors: ["#639dbd", "#e8d685", "#ae85c9", "#c9f0e1", "#d48652", "#629b6d", "#719dc3", "#719dc3"] - }, - - AmSlicedChart: { - outlineAlpha: 1, - outlineThickness: 2, - labelTickColor: "#FFFFFF", - labelTickAlpha: 0.3, - colors: ["#495fba", "#e8d685", "#ae85c9", "#c9f0e1", "#d48652", "#629b6d", "#719dc3", "#719dc3"] - }, - - AmRectangularChart: { - zoomOutButtonColor: '#FFFFFF', - zoomOutButtonRollOverAlpha: 0.15, - zoomOutButtonImage: "lensWhite.png" - }, - - AxisBase: { - axisColor: "#FFFFFF", - axisAlpha: 0.3, - gridAlpha: 0.1, - gridColor: "#FFFFFF", - dashLength: 3 - }, - - ChartScrollbar: { - backgroundColor: "#000000", - backgroundAlpha: 0.2, - graphFillAlpha: 0.2, - graphLineAlpha: 0, - graphFillColor: "#FFFFFF", - selectedGraphFillColor: "#FFFFFF", - selectedGraphFillAlpha: 0.4, - selectedGraphLineColor: "#FFFFFF", - selectedBackgroundColor: "#FFFFFF", - selectedBackgroundAlpha: 0.09, - gridAlpha: 0.15 - }, - - ChartCursor: { - cursorColor: "#FFFFFF", - color: "#000000", - cursorAlpha: 0.5 - }, - - AmLegend: { - color: "#e7e7e7" - }, - - AmGraph: { - lineAlpha: 0.9 - }, - - - GaugeArrow: { - color: "#FFFFFF", - alpha: 0.8, - nailAlpha: 0, - innerRadius: "40%", - nailRadius: 15, - startWidth: 15, - borderAlpha: 0.8, - nailBorderAlpha: 0 - }, - - GaugeAxis: { - tickColor: "#FFFFFF", - tickAlpha: 1, - tickLength: 15, - minorTickLength: 8, - axisThickness: 3, - axisColor: '#FFFFFF', - axisAlpha: 1, - bandAlpha: 0.8 - }, - - TrendLine: { - lineColor: "#c03246", - lineAlpha: 0.8 - }, - - // ammap - AreasSettings: { - alpha: 0.8, - color: "#FFFFFF", - colorSolid: "#000000", - unlistedAreasAlpha: 0.4, - unlistedAreasColor: "#FFFFFF", - outlineColor: "#000000", - outlineAlpha: 0.5, - outlineThickness: 0.5, - rollOverColor: "#3c5bdc", - rollOverOutlineColor: "#000000", - selectedOutlineColor: "#000000", - selectedColor: "#f15135", - unlistedAreasOutlineColor: "#000000", - unlistedAreasOutlineAlpha: 0.5 - }, - - LinesSettings: { - color: "#FFFFFF", - alpha: 0.8 - }, - - ImagesSettings: { - alpha: 0.8, - labelColor: "#FFFFFF", - color: "#FFFFFF", - labelRollOverColor: "#3c5bdc" - }, - - ZoomControl: { - buttonRollOverColor: "#3c5bdc", - buttonFillColor: "#f15135", - buttonFillAlpha: 0.8, - gridBackgroundColor: "#FFFFFF", - buttonBorderAlpha:0, - buttonCornerRadius:2, - gridAlpha:0.5, - gridBackgroundColor:"#FFFFFF", - homeIconFile:"homeIconWhite.gif", - buttonIconAlpha:0.6, - gridAlpha: 0.2, - buttonSize:20 - }, - - SmallMap: { - mapColor: "#FFFFFF", - rectangleColor: "#FFFFFF", - backgroundColor: "#000000", - backgroundAlpha: 0.7, - borderThickness: 1, - borderAlpha: 0.8 - }, - - // the defaults below are set using CSS syntax, you can use any existing css property - // if you don't use Stock chart, you can delete lines below - PeriodSelector: { - color: "#e7e7e7" - }, - - PeriodButton: { - color: "#e7e7e7", - background: "transparent", - opacity: 0.7, - border: "1px solid rgba(255, 255, 255, .15)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - boxSizing: "border-box" - }, - - PeriodButtonSelected: { - color: "#e7e7e7", - backgroundColor: "rgba(255, 255, 255, 0.1)", - border: "1px solid rgba(255, 255, 255, .3)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - opacity: 1, - boxSizing: "border-box" - }, - - PeriodInputField: { - color: "#e7e7e7", - background: "transparent", - border: "1px solid rgba(255, 255, 255, .15)", - outline: "none" - }, - - DataSetSelector: { - color: "#e7e7e7", - selectedBackgroundColor: "rgba(255, 255, 255, .25)", - rollOverBackgroundColor: "rgba(255, 255, 255, .15)" - }, - - DataSetCompareList: { - color: "#e7e7e7", - lineHeight: "100%", - boxSizing: "initial", - webkitBoxSizing: "initial", - border: "1px solid rgba(255, 255, 255, .15)" - }, - - DataSetSelect: { - border: "1px solid rgba(255, 255, 255, .15)", - outline: "none" - } - +AmCharts.themes.dark = { + + themeName: "dark", + + AmChart: { + color: "#e7e7e7", backgroundColor: "#282828" + }, + + AmCoordinateChart: { + colors: ["#ae85c9", "#aab9f7", "#b6d2ff", "#c9e6f2", "#c9f0e1", "#e8d685", "#e0ad63", "#d48652", "#d27362", "#495fba", "#7a629b", "#8881cc"] + }, + + AmStockChart: { + colors: ["#639dbd", "#e8d685", "#ae85c9", "#c9f0e1", "#d48652", "#629b6d", "#719dc3", "#719dc3"] + }, + + AmSlicedChart: { + outlineAlpha: 1, + outlineThickness: 2, + labelTickColor: "#FFFFFF", + labelTickAlpha: 0.3, + colors: ["#495fba", "#e8d685", "#ae85c9", "#c9f0e1", "#d48652", "#629b6d", "#719dc3", "#719dc3"] + }, + + AmRectangularChart: { + zoomOutButtonColor: '#FFFFFF', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lensWhite.png" + }, + + AxisBase: { + axisColor: "#FFFFFF", + axisAlpha: 0.3, + gridAlpha: 0.1, + gridColor: "#FFFFFF", + dashLength: 3 + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.2, + graphFillAlpha: 0.2, + graphLineAlpha: 0, + graphFillColor: "#FFFFFF", + selectedGraphFillColor: "#FFFFFF", + selectedGraphFillAlpha: 0.4, + selectedGraphLineColor: "#FFFFFF", + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.09, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#FFFFFF", + color: "#000000", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#e7e7e7" + }, + + AmGraph: { + lineAlpha: 0.9 + }, + + + GaugeArrow: { + color: "#FFFFFF", + alpha: 0.8, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#FFFFFF", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: '#FFFFFF', + axisAlpha: 1, + bandAlpha: 0.8 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#FFFFFF", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#FFFFFF", + outlineColor: "#000000", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#3c5bdc", + rollOverOutlineColor: "#000000", + selectedOutlineColor: "#000000", + selectedColor: "#f15135", + unlistedAreasOutlineColor: "#000000", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#FFFFFF", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#FFFFFF", + color: "#FFFFFF", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonRollOverColor: "#3c5bdc", + buttonFillColor: "#f15135", + buttonFillAlpha: 0.8, + gridBackgroundColor: "#FFFFFF", + buttonBorderAlpha:0, + buttonCornerRadius:2, + gridAlpha:0.5, + gridBackgroundColor:"#FFFFFF", + homeIconFile:"homeIconWhite.gif", + buttonIconAlpha:0.6, + gridAlpha: 0.2, + buttonSize:20 + }, + + SmallMap: { + mapColor: "#FFFFFF", + rectangleColor: "#FFFFFF", + backgroundColor: "#000000", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#e7e7e7" + }, + + PeriodButton: { + color: "#e7e7e7", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(255, 255, 255, .15)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#e7e7e7", + backgroundColor: "rgba(255, 255, 255, 0.1)", + border: "1px solid rgba(255, 255, 255, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#e7e7e7", + background: "transparent", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + }, + + DataSetSelector: { + color: "#e7e7e7", + selectedBackgroundColor: "rgba(255, 255, 255, .25)", + rollOverBackgroundColor: "rgba(255, 255, 255, .15)" + }, + + DataSetCompareList: { + color: "#e7e7e7", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(255, 255, 255, .15)" + }, + + DataSetSelect: { + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + } + }; \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/themes/light.js b/web/src/main/webapp/components/amcharts/themes/light.js index 077ddbb96e39..971472196f7f 100755 --- a/web/src/main/webapp/components/amcharts/themes/light.js +++ b/web/src/main/webapp/components/amcharts/themes/light.js @@ -1,199 +1,199 @@ -AmCharts.themes.light = { - - themeName:"light", - - AmChart: { - color: "#000000", backgroundColor: "#FFFFFF" - }, - - AmCoordinateChart: { - colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"] - }, - - AmStockChart: { - colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"] - }, - - AmSlicedChart: { - colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"], - outlineAlpha: 1, - outlineThickness: 2, - labelTickColor: "#000000", - labelTickAlpha: 0.3 - }, - - AmRectangularChart: { - zoomOutButtonColor: '#000000', - zoomOutButtonRollOverAlpha: 0.15, - zoomOutButtonImage: "lens.png" - }, - - AxisBase: { - axisColor: "#000000", - axisAlpha: 0.3, - gridAlpha: 0.1, - gridColor: "#000000" - }, - - ChartScrollbar: { - backgroundColor: "#000000", - backgroundAlpha: 0.12, - graphFillAlpha: 0.5, - graphLineAlpha: 0, - selectedBackgroundColor: "#FFFFFF", - selectedBackgroundAlpha: 0.4, - gridAlpha: 0.15 - }, - - ChartCursor: { - cursorColor: "#000000", - color: "#FFFFFF", - cursorAlpha: 0.5 - }, - - AmLegend: { - color: "#000000" - }, - - AmGraph: { - lineAlpha: 0.9 - }, - GaugeArrow: { - color: "#000000", - alpha: 0.8, - nailAlpha: 0, - innerRadius: "40%", - nailRadius: 15, - startWidth: 15, - borderAlpha: 0.8, - nailBorderAlpha: 0 - }, - - GaugeAxis: { - tickColor: "#000000", - tickAlpha: 1, - tickLength: 15, - minorTickLength: 8, - axisThickness: 3, - axisColor: '#000000', - axisAlpha: 1, - bandAlpha: 0.8 - }, - - TrendLine: { - lineColor: "#c03246", - lineAlpha: 0.8 - }, - - // ammap - AreasSettings: { - alpha: 0.8, - color: "#67b7dc", - colorSolid: "#003767", - unlistedAreasAlpha: 0.4, - unlistedAreasColor: "#000000", - outlineColor: "#FFFFFF", - outlineAlpha: 0.5, - outlineThickness: 0.5, - rollOverColor: "#3c5bdc", - rollOverOutlineColor: "#FFFFFF", - selectedOutlineColor: "#FFFFFF", - selectedColor: "#f15135", - unlistedAreasOutlineColor: "#FFFFFF", - unlistedAreasOutlineAlpha: 0.5 - }, - - LinesSettings: { - color: "#000000", - alpha: 0.8 - }, - - ImagesSettings: { - alpha: 0.8, - labelColor: "#000000", - color: "#000000", - labelRollOverColor: "#3c5bdc" - }, - - ZoomControl: { - buttonRollOverColor: "#3c5bdc", - buttonFillColor: "#3994e2", - buttonBorderColor: "#3994e2", - buttonFillAlpha: 0.8, - gridBackgroundColor: "#FFFFFF", - buttonBorderAlpha:0, - buttonCornerRadius:2, - gridColor:"#FFFFFF", - gridBackgroundColor:"#000000", - buttonIconAlpha:0.6, - gridAlpha: 0.6, - buttonSize:20 - }, - - SmallMap: { - mapColor: "#000000", - rectangleColor: "#f15135", - backgroundColor: "#FFFFFF", - backgroundAlpha: 0.7, - borderThickness: 1, - borderAlpha: 0.8 - }, - - // the defaults below are set using CSS syntax, you can use any existing css property - // if you don't use Stock chart, you can delete lines below - PeriodSelector: { - color: "#000000" - }, - - PeriodButton: { - color: "#000000", - background: "transparent", - opacity: 0.7, - border: "1px solid rgba(0, 0, 0, .3)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - boxSizing: "border-box" - }, - - PeriodButtonSelected: { - color: "#000000", - backgroundColor: "#b9cdf5", - border: "1px solid rgba(0, 0, 0, .3)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - opacity: 1, - boxSizing: "border-box" - }, - - PeriodInputField: { - color: "#000000", - background: "transparent", - border: "1px solid rgba(0, 0, 0, .3)", - outline: "none" - }, - - DataSetSelector: { - - color: "#000000", - selectedBackgroundColor: "#b9cdf5", - rollOverBackgroundColor: "#a8b0e4" - }, - - DataSetCompareList: { - color: "#000000", - lineHeight: "100%", - boxSizing: "initial", - webkitBoxSizing: "initial", - border: "1px solid rgba(0, 0, 0, .3)" - }, - - DataSetSelect: { - border: "1px solid rgba(0, 0, 0, .3)", - outline: "none" - } - +AmCharts.themes.light = { + + themeName:"light", + + AmChart: { + color: "#000000", backgroundColor: "#FFFFFF" + }, + + AmCoordinateChart: { + colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"] + }, + + AmStockChart: { + colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"] + }, + + AmSlicedChart: { + colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"], + outlineAlpha: 1, + outlineThickness: 2, + labelTickColor: "#000000", + labelTickAlpha: 0.3 + }, + + AmRectangularChart: { + zoomOutButtonColor: '#000000', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lens.png" + }, + + AxisBase: { + axisColor: "#000000", + axisAlpha: 0.3, + gridAlpha: 0.1, + gridColor: "#000000" + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.12, + graphFillAlpha: 0.5, + graphLineAlpha: 0, + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.4, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#000000", + color: "#FFFFFF", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#000000" + }, + + AmGraph: { + lineAlpha: 0.9 + }, + GaugeArrow: { + color: "#000000", + alpha: 0.8, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#000000", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: '#000000', + axisAlpha: 1, + bandAlpha: 0.8 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#67b7dc", + colorSolid: "#003767", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#000000", + outlineColor: "#FFFFFF", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#3c5bdc", + rollOverOutlineColor: "#FFFFFF", + selectedOutlineColor: "#FFFFFF", + selectedColor: "#f15135", + unlistedAreasOutlineColor: "#FFFFFF", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#000000", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#000000", + color: "#000000", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonRollOverColor: "#3c5bdc", + buttonFillColor: "#3994e2", + buttonBorderColor: "#3994e2", + buttonFillAlpha: 0.8, + gridBackgroundColor: "#FFFFFF", + buttonBorderAlpha:0, + buttonCornerRadius:2, + gridColor:"#FFFFFF", + gridBackgroundColor:"#000000", + buttonIconAlpha:0.6, + gridAlpha: 0.6, + buttonSize:20 + }, + + SmallMap: { + mapColor: "#000000", + rectangleColor: "#f15135", + backgroundColor: "#FFFFFF", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#000000" + }, + + PeriodButton: { + color: "#000000", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#000000", + backgroundColor: "#b9cdf5", + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#000000", + background: "transparent", + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + }, + + DataSetSelector: { + + color: "#000000", + selectedBackgroundColor: "#b9cdf5", + rollOverBackgroundColor: "#a8b0e4" + }, + + DataSetCompareList: { + color: "#000000", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(0, 0, 0, .3)" + }, + + DataSetSelect: { + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + } + }; \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/themes/patterns.js b/web/src/main/webapp/components/amcharts/themes/patterns.js index 6446276c8985..7de88d482422 100755 --- a/web/src/main/webapp/components/amcharts/themes/patterns.js +++ b/web/src/main/webapp/components/amcharts/themes/patterns.js @@ -1,259 +1,259 @@ -AmCharts.themes.patterns = { - - themeName:"patterns", - - AmChart: { - color: "#000000", backgroundColor: "#FFFFFF" - }, - - AmCoordinateChart: { - colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"], - patterns:[ - {"url":"../amcharts/patterns/black/pattern1.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern2.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern3.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern4.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern5.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern6.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern7.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern8.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern9.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern10.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern11.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern12.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern13.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern14.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern15.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern16.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern17.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern18.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern19.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern20.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern21.png", "width":4, "height":4}] - }, - - - AmStockChart: { - colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"] - }, - - AmPieChart: { - depth3D:0, - angle:0, - labelRadius:10 - }, - - AmSlicedChart: { - outlineAlpha: 0.3, - colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"], - outlineThickness: 1, - outlineColor:"#000000", - labelTickColor: "#000000", - labelTickAlpha: 0.3, - patterns:[ - {"url":"../amcharts/patterns/black/pattern1.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern2.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern3.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern4.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern5.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern6.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern7.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern8.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern9.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern10.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern11.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern12.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern13.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern14.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern15.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern16.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern17.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern18.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern19.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern20.png", "width":4, "height":4}, - {"url":"../amcharts/patterns/black/pattern21.png", "width":4, "height":4}] - }, - - AmRectangularChart: { - zoomOutButtonColor: '#000000', - zoomOutButtonRollOverAlpha: 0.15, - zoomOutButtonImage: "lens.png" - }, - - - - AxisBase: { - axisColor: "#000000", - axisAlpha: 0.3, - gridAlpha: 0.05, - gridColor: "#000000" - }, - - ChartScrollbar: { - backgroundColor: "#000000", - backgroundAlpha: 0.13, - graphFillAlpha: 0.4, - selectedGraphFillAlpha: 0.7, - graphLineAlpha: 0, - selectedBackgroundColor: "#FFFFFF", - selectedBackgroundAlpha: 0.9, - gridAlpha: 0.15 - }, - - ChartCursor: { - cursorColor: "#000000", - color: "#FFFFFF", - cursorAlpha: 0.5 - }, - - AmLegend: { - color: "#000000", - markerBorderAlpha:0.1, - markerSize:20, - switchColor:"#000000" - }, - - AmGraph: { - lineAlpha: 0.4, - fillAlphas:0.5 - }, - - AmAngularGauge:{ - faceAlpha:0.5, - facePattern:{"url":"../amcharts/patterns/black/pattern1.png", "width":4, "height":4} - }, - - - GaugeArrow: { - color: "#000000", - alpha: 1, - nailAlpha: 1, - innerRadius: "0%", - nailRadius: 15, - startWidth: 15, - borderAlpha: 1, - radius:"70%", - nailBorderAlpha: 1 - }, - - GaugeAxis: { - tickColor: "#000000", - tickAlpha: 1, - tickLength: 15, - minorTickLength: 8, - axisThickness: 1, - axisColor: '#000000', - axisAlpha: 1, - bandAlpha: 1 - }, - - TrendLine: { - lineColor: "#c03246", - lineAlpha: 0.8 - }, - - // ammap - AreasSettings: { - alpha: 0.8, - color: "#000000", - colorSolid: "#000000", - unlistedAreasAlpha: 0.4, - unlistedAreasColor: "#000000", - outlineColor: "#FFFFFF", - outlineAlpha: 0.5, - outlineThickness: 0.5, - rollOverColor: "#3c5bdc", - rollOverOutlineColor: "#FFFFFF", - selectedOutlineColor: "#FFFFFF", - selectedColor: "#f15135", - unlistedAreasOutlineColor: "#FFFFFF", - unlistedAreasOutlineAlpha: 0.5 - }, - - LinesSettings: { - color: "#000000", - alpha: 0.8 - }, - - ImagesSettings: { - alpha: 0.8, - labelColor: "#000000", - color: "#000000", - labelRollOverColor: "#3c5bdc" - }, - - ZoomControl: { - buttonRollOverColor: "#3c5bdc", - buttonFillColor: "#f15135", - buttonFillAlpha: 0.8, - buttonBorderColor: "#000000", - gridBackgroundColor: "#000000", - gridAlpha: 0.8 - }, - - SmallMap: { - mapColor: "#000000", - rectangleColor: "#FFFFFF", - backgroundColor: "#FFFFFF", - backgroundAlpha: 0.7, - borderThickness: 1, - borderAlpha: 0.8 - }, - - // the defaults below are set using CSS syntax, you can use any existing css property - // if you don't use Stock chart, you can delete lines below - PeriodSelector: { - color: "#000000" - }, - - PeriodButton: { - color: "#000000", - background: "transparent", - opacity: 0.7, - border: "1px solid rgba(0, 0, 0, .3)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - boxSizing: "border-box" - }, - - PeriodButtonSelected: { - color: "#000000", - backgroundColor: "rgba(0, 0, 0, 0.1)", - border: "1px solid rgba(0, 0, 0, .3)", - MozBorderRadius: "5px", - borderRadius: "5px", - margin: "1px", - outline: "none", - opacity: 1, - boxSizing: "border-box" - }, - - PeriodInputField: { - color: "#000000", - background: "transparent", - border: "1px solid rgba(0, 0, 0, .3)", - outline: "none" - }, - - DataSetSelector: { - color: "#000000", - selectedBackgroundColor: "rgba(0, 0, 0, .25)", - rollOverBackgroundColor: "rgba(0, 0, 0, .15)" - }, - - DataSetCompareList: { - color: "#000000", - lineHeight: "100%", - boxSizing: "initial", - webkitBoxSizing: "initial", - border: "1px solid rgba(0, 0, 0, .3)" - }, - - DataSetSelect: { - border: "1px solid rgba(0, 0, 0, .3)", - outline: "none" - } - +AmCharts.themes.patterns = { + + themeName:"patterns", + + AmChart: { + color: "#000000", backgroundColor: "#FFFFFF" + }, + + AmCoordinateChart: { + colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"], + patterns:[ + {"url":"../amcharts/patterns/black/pattern1.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern2.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern3.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern4.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern5.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern6.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern7.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern8.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern9.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern10.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern11.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern12.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern13.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern14.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern15.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern16.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern17.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern18.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern19.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern20.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern21.png", "width":4, "height":4}] + }, + + + AmStockChart: { + colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"] + }, + + AmPieChart: { + depth3D:0, + angle:0, + labelRadius:10 + }, + + AmSlicedChart: { + outlineAlpha: 0.3, + colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"], + outlineThickness: 1, + outlineColor:"#000000", + labelTickColor: "#000000", + labelTickAlpha: 0.3, + patterns:[ + {"url":"../amcharts/patterns/black/pattern1.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern2.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern3.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern4.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern5.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern6.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern7.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern8.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern9.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern10.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern11.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern12.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern13.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern14.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern15.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern16.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern17.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern18.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern19.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern20.png", "width":4, "height":4}, + {"url":"../amcharts/patterns/black/pattern21.png", "width":4, "height":4}] + }, + + AmRectangularChart: { + zoomOutButtonColor: '#000000', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lens.png" + }, + + + + AxisBase: { + axisColor: "#000000", + axisAlpha: 0.3, + gridAlpha: 0.05, + gridColor: "#000000" + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.13, + graphFillAlpha: 0.4, + selectedGraphFillAlpha: 0.7, + graphLineAlpha: 0, + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.9, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#000000", + color: "#FFFFFF", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#000000", + markerBorderAlpha:0.1, + markerSize:20, + switchColor:"#000000" + }, + + AmGraph: { + lineAlpha: 0.4, + fillAlphas:0.5 + }, + + AmAngularGauge:{ + faceAlpha:0.5, + facePattern:{"url":"../amcharts/patterns/black/pattern1.png", "width":4, "height":4} + }, + + + GaugeArrow: { + color: "#000000", + alpha: 1, + nailAlpha: 1, + innerRadius: "0%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 1, + radius:"70%", + nailBorderAlpha: 1 + }, + + GaugeAxis: { + tickColor: "#000000", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 1, + axisColor: '#000000', + axisAlpha: 1, + bandAlpha: 1 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#000000", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#000000", + outlineColor: "#FFFFFF", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#3c5bdc", + rollOverOutlineColor: "#FFFFFF", + selectedOutlineColor: "#FFFFFF", + selectedColor: "#f15135", + unlistedAreasOutlineColor: "#FFFFFF", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#000000", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#000000", + color: "#000000", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonRollOverColor: "#3c5bdc", + buttonFillColor: "#f15135", + buttonFillAlpha: 0.8, + buttonBorderColor: "#000000", + gridBackgroundColor: "#000000", + gridAlpha: 0.8 + }, + + SmallMap: { + mapColor: "#000000", + rectangleColor: "#FFFFFF", + backgroundColor: "#FFFFFF", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#000000" + }, + + PeriodButton: { + color: "#000000", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#000000", + backgroundColor: "rgba(0, 0, 0, 0.1)", + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#000000", + background: "transparent", + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + }, + + DataSetSelector: { + color: "#000000", + selectedBackgroundColor: "rgba(0, 0, 0, .25)", + rollOverBackgroundColor: "rgba(0, 0, 0, .15)" + }, + + DataSetCompareList: { + color: "#000000", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(0, 0, 0, .3)" + }, + + DataSetSelect: { + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + } + }; \ No newline at end of file diff --git a/web/src/main/webapp/components/amcharts/xy.js b/web/src/main/webapp/components/amcharts/xy.js index 92489e175347..3487e4f2f9b1 100755 --- a/web/src/main/webapp/components/amcharts/xy.js +++ b/web/src/main/webapp/components/amcharts/xy.js @@ -1,17 +1,17 @@ -AmCharts.AmXYChart=AmCharts.Class({inherits:AmCharts.AmRectangularChart,construct:function(a){this.type="xy";AmCharts.AmXYChart.base.construct.call(this,a);this.cname="AmXYChart";this.theme=a;this.createEvents("zoomed");this.maxZoomFactor=20;AmCharts.applyTheme(this,a,this.cname)},initChart:function(){AmCharts.AmXYChart.base.initChart.call(this);this.dataChanged&&(this.updateData(),this.dataChanged=!1,this.dispatchDataUpdated=!0);this.updateScrollbar=!0;this.drawChart();this.autoMargins&&!this.marginsUpdated&& -(this.marginsUpdated=!0,this.measureMargins());var a=this.marginLeftReal,c=this.marginTopReal,b=this.plotAreaWidth,d=this.plotAreaHeight;this.graphsSet.clipRect(a,c,b,d);this.bulletSet.clipRect(a,c,b,d);this.trendLinesSet.clipRect(a,c,b,d)},prepareForExport:function(){var a=this.bulletSet;a.clipPath&&this.container.remove(a.clipPath)},createValueAxes:function(){var a=[],c=[];this.xAxes=a;this.yAxes=c;var b=this.valueAxes,d,e;for(e=0;ee){var f=e;e=d;d=f}b.dispatchZoomEvent(d,e)}}}},zoomObjects:function(a){var c=a.length,b;for(b=0;be&&(e=h);hthis.maxZoomFactor&&(a=this.maxZoomFactor);return a},handleHSBZoom:function(a){var c=this.fitMultiplier(a.multiplier);a=-a.position*c;var b=-(this.plotAreaWidth*c-this.plotAreaWidth);ae){var f=e;e=d;d=f}b.dispatchZoomEvent(d,e)}}}},zoomObjects:function(a){var c=a.length,b;for(b=0;be&&(e=h);hthis.maxZoomFactor&&(a=this.maxZoomFactor);return a},handleHSBZoom:function(a){var c=this.fitMultiplier(a.multiplier);a=-a.position*c;var b=-(this.plotAreaWidth*c-this.plotAreaWidth);a -See a Bootstrap 3.0.2 example [here](http://silviomoreto.github.com/bootstrap-select/3) (work-in-progress). - -## Authors - -[Silvio Moreto](http://github.com/silviomoreto), -[Ana Carolina](http://github.com/anacarolinats), -[caseyjhol](https://github.com/caseyjhol), and -[Matt Bryson](https://github.com/mattbryson). - -## Usage - -Create your ` - - - - - -Enable Bootstrap-Select via JavaScript: - - $('.selectpicker').selectpicker(); - -Or just - - $('select').selectpicker(); - -Checkout the [documentation](http://silviomoreto.github.com/bootstrap-select/) for further information. - -## Bugs and feature requests - -Anyone and everyone is welcome to contribute. Please take a moment to -review the [guidelines for contributing](CONTRIBUTING.md). Make sure you're using the latest version of bootstrap-select before submitting an issue. - -* [Bug reports](CONTRIBUTING.md#bugs) -* [Feature requests](CONTRIBUTING.md#features) - -## Copyright and license - -Copyright (C) 2013 bootstrap-select - -Licensed under the MIT license. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +bootstrap-select +================ + +A custom select / multiselect for Bootstrap using button dropdown, designed to behave like regular Bootstrap selects; + +## Demo and Documentation + +See a Bootstrap 2.3.2 example [here](http://silviomoreto.github.com/bootstrap-select/).
+See a Bootstrap 3.0.2 example [here](http://silviomoreto.github.com/bootstrap-select/3) (work-in-progress). + +## Authors + +[Silvio Moreto](http://github.com/silviomoreto), +[Ana Carolina](http://github.com/anacarolinats), +[caseyjhol](https://github.com/caseyjhol), and +[Matt Bryson](https://github.com/mattbryson). + +## Usage + +Create your ` + + + + + +Enable Bootstrap-Select via JavaScript: + + $('.selectpicker').selectpicker(); + +Or just + + $('select').selectpicker(); + +Checkout the [documentation](http://silviomoreto.github.com/bootstrap-select/) for further information. + +## Bugs and feature requests + +Anyone and everyone is welcome to contribute. Please take a moment to +review the [guidelines for contributing](CONTRIBUTING.md). Make sure you're using the latest version of bootstrap-select before submitting an issue. + +* [Bug reports](CONTRIBUTING.md#bugs) +* [Feature requests](CONTRIBUTING.md#features) + +## Copyright and license + +Copyright (C) 2013 bootstrap-select + +Licensed under the MIT license. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/web/src/main/webapp/components/datejs/build/core.js b/web/src/main/webapp/components/datejs/build/core.js index a33aae601c42..d2ebd9d66245 100644 --- a/web/src/main/webapp/components/datejs/build/core.js +++ b/web/src/main/webapp/components/datejs/build/core.js @@ -1,11 +1,11 @@ -/** - * @version: 1.0 Alpha-1 - * @author: Coolite Inc. http://www.coolite.com/ - * @date: 2008-05-13 - * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved. - * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. - * @website: http://www.datejs.com/ - */ +/** + * @version: 1.0 Alpha-1 + * @author: Coolite Inc. http://www.coolite.com/ + * @date: 2008-05-13 + * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved. + * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. + * @website: http://www.datejs.com/ + */ (function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo,p=function(s,l){if(!l){l=2;} return("000"+s).slice(l*-1);};$P.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};$P.setTimeToNow=function(){var n=new Date();this.setHours(n.getHours());this.setMinutes(n.getMinutes());this.setSeconds(n.getSeconds());this.setMilliseconds(n.getMilliseconds());return this;};$D.today=function(){return new Date().clearTime();};$D.compare=function(date1,date2){if(isNaN(date1)||isNaN(date2)){throw new Error(date1+" - "+date2);}else if(date1 instanceof Date&&date2 instanceof Date){return(date1date2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;id2&&d1.clone().addDays(-d1.getDaysInMonth())>d2){d1.addMonths(-1);this.months--;}} var diff=d2-d1;if(diff!==0){var ts=new TimeSpan(diff);this.setDays(ts.getDays());this.setHours(ts.getHours());this.setMinutes(ts.getMinutes());this.setSeconds(ts.getSeconds());this.setMilliseconds(ts.getMilliseconds());}} -return this;}; +return this;}; diff --git a/web/src/main/webapp/components/gojs/go-debug.js b/web/src/main/webapp/components/gojs/go-debug.js index 59eda6c6be48..a77fd6e70905 100644 --- a/web/src/main/webapp/components/gojs/go-debug.js +++ b/web/src/main/webapp/components/gojs/go-debug.js @@ -1,1926 +1,1926 @@ -/* - * GoJS v1.3.9 JavaScript Library for HTML Canvas Diagrams - * Northwoods Software, http://www.nwoods.com/ - * GoJS and Northwoods Software are registered trademarks of Northwoods Software Corporation. - * Copyright (C) 1998-2014 by Northwoods Software Corporation. All Rights Reserved. - * THIS SOFTWARE IS LICENSED. THE LICENSE AGREEMENT IS AT: http://www.gojs.net/1.3.9/doc/license.html. - */ -(function(window) { var aa,ba={};if(void 0===document.createElement("canvas").getContext)throw window.console&&window.console.log("The HTML Canvas element is not supported in this browser,or this browser is in Compatibility mode."),Error("The HTML Canvas element is not supported in this browser,or this browser is in Compatibility mode.");if(!Object.prototype.__defineGetter__&&!Object.defineProperty)throw Error("GoJS requires a newer version of JavaScript"); -Object.prototype.__defineGetter__&&!Object.defineProperty&&(Object.defineProperty=function(a,b,c){c.get&&a.__defineGetter__(b,c.get);c.set&&a.__defineSetter__(b,c.set)});Object.prototype.__lookupGetter__&&!Object.getOwnPropertyDescriptor&&(Object.getOwnPropertyDescriptor=function(a,b){return{get:a.__lookupGetter__(b),set:a.__lookupSetter__(b)}});Object.getPrototypeOf||(Object.getPrototypeOf=function(a){return a.__proto__});Object.isFrozen||(Object.isFrozen=function(a){return!0===a.zG}); -Object.freeze||(Object.freeze=function(a){a.zG=!0});Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)});Function.prototype.bind||(Function.prototype.bind=function(a){function b(){return g.apply(a,e.concat(d.call(arguments)))}function c(){}var d=Array.prototype.slice,e=d.call(arguments,1),g=this;c.prototype=this.prototype;b.prototype=new c;return b}); -(function(){for(var a=0,b=["ms","moz","webkit","o"],c=0;c=la||(e%=10,a.fillStyle="blue",a.fillText(e.toString(),g,h+b.kd))}}}},RH:function(a){if(a instanceof u)for(a=a.Um;a.next();){var b=a.value;t.trace(b.toString());for(b=b.sl;b.next();)f.RH(b.value)}else if(a instanceof -w){t.trace("References for "+a);a.layer&&t.trace(" "+a.layer.toString()+' LayerName: "'+a.Xd+'"');a.bn!==a&&t.trace(" SelectionObject: "+a.bn.toString()+' SelectionObjectName: "'+a.vt+'"');a.Ub!==a&&t.trace(" LocationObject: "+a.Ub.toString()+' LocationObjectName: "'+a.Zs+'"');if(a.Cg){for(var c="",b=a.Cg.k;b.next();)c+=b.key+" ";t.trace(" Adornments: "+c)}a.fb&&t.trace(" ContainingGroup: "+a.fb.toString());if(a instanceof y){if(a.yd)for(b=a.yd.k;b.next(););if(0=a.length?a.push(c):a.splice(b,0,c):t.m("Cannot insert an object into an HTMLCollection or NodeList: "+c+" at "+b)},Fi:function(a,b){t.qc&&t.qc(a)&&(a=a());Array.isArray(a)?b>=a.length?a.pop():a.splice(b,1):t.m("Cannot remove an object from an HTMLCollection or NodeList at "+b)},xx:[],O:function(){var a=t.xx.pop();return void 0===a?new C:a},ic:function(a,b){var c=t.xx.pop();if(void 0===c)return new C(a,b);c.x=a;c.y=b;return c},B:function(a){t.xx.push(a)}, -AB:[],yl:function(){var a=t.AB.pop();return void 0===a?new pa:a},dk:function(a){t.AB.push(a)},yx:[],wf:function(){var a=t.yx.pop();return void 0===a?new D:a},lk:function(a,b,c,d){var e=t.yx.pop();if(void 0===e)return new D(a,b,c,d);e.x=a;e.y=b;e.width=c;e.height=d;return e},Pc:function(a){t.yx.push(a)},BB:[],bh:function(){var a=t.BB.pop();return void 0===a?new qa:a},Se:function(a){t.BB.push(a)},zx:null,u:function(){var a=t.zx;return null!==a?(t.zx=null,a):new ra},v:function(a){a.reset();t.zx=a},zB:[], -Cb:function(){var a=t.zB.pop();return void 0===a?[]:a},Da:function(a){a.length=0;t.zB.push(a)},CB:1,zc:function(a){a.__gohashid=t.CB++},Os:function(a){var b=a.__gohashid;void 0===b&&(b=t.CB++,a.__gohashid=b);return b},oc:function(a){return a.__gohashid},g:function(a,b,c){"name"!==b&&"length"!==b&&(a[b]=c)},ia:function(a,b){b.Gx=a;ba[a]=b},Oa:function(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a},Fh:function(a){a.EG=!0},defineProperty:function(a,b,c,d,e){t.j(a, -"function","Util.defineProperty:classfunc");t.j(b,"object","Util.defineProperty:propobj");t.j(c,"function","Util.defineProperty:getter");t.j(d,"function","Util.defineProperty:setter");for(var g in b){var h=b[g];b={get:c,set:d};if(void 0!==e)for(var k in e)b[k]=e[k];Object.defineProperty(a.prototype,g,b);e=Object.getOwnPropertyDescriptor(a.prototype,g);h&&e&&Object.defineProperty(a.prototype,h,e);if(f&&h){var l=h.charAt(0).toUpperCase()+h.slice(1);h==l&&t.m('Defining capitalized property "'+l+'"!?'); -Object.defineProperty(a.prototype,l,{get:function(){t.m('Getting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')},set:function(){t.m('Setting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')}})}break}},A:function(a,b,c,d){t.j(a,"function","Util.defineReadOnlyProperty:classfunc");t.j(b,"object","Util.defineReadOnlyProperty:propobj");t.j(c,"function","Util.defineReadOnlyProperty:getter");for(var e in b){var g= -b[e];b={get:c,set:function(a){t.m('The property "'+g+'" is read-only and cannot be set to '+a)}};if(void 0!==d)for(var h in d)b[h]=d[h];Object.defineProperty(a.prototype,e,b);d=Object.getOwnPropertyDescriptor(a.prototype,e);g&&d&&Object.defineProperty(a.prototype,g,d);if(f&&g){var k=g.charAt(0).toUpperCase()+g.slice(1);Object.defineProperty(a.prototype,k,{get:function(){t.m('Getting the property "'+k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'"')},set:function(){t.m('Setting the read-only property "'+ -k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'", and cannot be set anyway')}})}break}},je:function(a,b){for(var c in b)b[c]=!0;a.prototype.EC=b},Hh:function(a){return void 0===a?"":"string"===typeof a?a:"function"===typeof a?t.Ug(a):null===a?"*":""},Ug:function(a){if("function"===typeof a){if(a.Gx)return a.Gx;if(a.name)return a.name;var b=a.toString(),c=b.indexOf("(");if(b=b.substring(9,c).trim())return a.Gx=b}else if("object"===typeof a&&a.constructor)return t.Ug(a.constructor); -return typeof a},w:function(a,b,c){t.j(a,"function","Util.defineEnumValue:classfunc");t.j(b,"string","Util.defineEnumValue:name");t.j(c,"number","Util.defineEnumValue:num");c=new oa(a,b,c);Object.freeze(c);a[b]=c;var d=a.Jt;d||(d=new sa("string",oa),a.Jt=d);d.add(b,c);return c},Lm:function(a,b){if(!b)return null;t.j(a,"function","Util.findEnumValueForName:classfunc");t.j(b,"string","Util.findEnumValueForName:name");var c=a.Jt;return c?c.Ba(b):null},qH:function(a,b,c,d){var e={},g;for(g in a){for(var h= -!1,k=1;k=d.length)){var e=t.hb(b,d);null===e||"function"===typeof e||t.mw(b,d)||(""===c&&(c=b+"\n"),c+=' unknown property "'+d+'" has value: '+e+" at "+a+"\n")}return c},Ov:function(a,b){if(b&&"number"!==typeof b&&"string"!==typeof b&&"boolean"!==typeof b&&"function"!==typeof b)if(void 0!==t.oc(b)){if(!t.jv.contains(b))if(t.jv.add(b), -t.Ku.add(t.nD(a,b)),b instanceof H||b instanceof ua||b instanceof sa)for(var c=b.k;c.next();)t.Ov(a+"["+c.key+"]",c.value);else for(c in b){var d=t.hb(b,c);if(void 0!==d&&null!==d&&t.pb(d)&&d!==b.EC){if(b instanceof wa){if(d===b.Zn)continue}else if(b instanceof B){if("data"===c||d===b.Ll)continue;if("itemArray"===c||d===b.sj)continue;if(b instanceof w&&d===b.Aj)continue}else if(!(b instanceof u))if(b instanceof xa){if("archetypeGroupData"===c||d===b.Cx)continue}else if(b instanceof Aa){if("archetypeLinkData"=== -c||d===b.Vt)continue;if("archetypeLabelNodeData"===c||d===b.Ut)continue}else if(b instanceof Ba){if("archetypeNodeData"===c||d===b.bj)continue}else if(b instanceof I){if("nodeDataArray"===c||d===b.Ke)continue;if("linkDataArray"===c||d===b.Mg||d===b.Zl)continue;if(d===b.uc)continue;if(d===b.Uf)continue}else if(b instanceof Ca||b instanceof Da||b instanceof Ea)continue;t.Ov(a+"."+c,d)}}}else if(Array.isArray(b))for(c=0;cc;c++)b[c]=c;for(var d=0,e,c=0;256>c;c++)d=(d+b[c]+119)%256,e=b[c],b[c]=b[d],b[d]=e;for(var d=c=0,g="",h=0;hc;c++)b["0123456789abcdef".charAt(c>>4)+"0123456789abcdef".charAt(c&15)]=String.fromCharCode(c); -a.length%2&&(a="0"+a);for(var d=[],e=0,c=0;cd;d++)b[t.Qa("7ca11abfd7330390")](t.Qa(c[d-1]),10,15*d+0);b[t.Qa("7ca11abfd022028846")]=t.Qa("39f046ebb36e4b");for(d=1;5>d;d++)b[t.Qa("7ca11abfd7330390")](t.Qa(c[d- -1]),10,15*d+0);if(4!==c.length||"5"!==c[0][0]||"7"!==c[3][0])t.w=function(a,b){var c=new oa(a,b,2);Object.freeze(c);a[b]=c;var d=a.Jt;d||(d=new sa("string",oa),a.Jt=d);d.add(b,c);return c};return a}();function oa(a,b,c){t.zc(this);this.GB=a;this.Rb=b;this.JG=c}oa.prototype.toString=function(){return t.Ug(this.GB)+"."+this.Rb};t.A(oa,{Pe:"classType"},function(){return this.GB});t.A(oa,{name:"name"},function(){return this.Rb});t.A(oa,{value:"value"},function(){return this.JG}); -function Fa(){this.FB=[]}Fa.prototype.toString=function(){return this.FB.join("")};Fa.prototype.add=function(a){a&&this.FB.push(a)};function Ia(){}t.A(Ia,{k:"iterator"},function(){return this});Ia.prototype.reset=Ia.prototype.reset=function(){};Ia.prototype.next=Ia.prototype.hasNext=Ia.prototype.next=function(){return!1};Ia.prototype.first=Ia.prototype.eb=function(){return null};t.A(Ia,{count:"count"},function(){return 0});Ia.prototype.Gg=function(){};Ia.prototype.toString=function(){return"EmptyIterator"}; -t.dh=new Ia;function La(a){this.key=-1;this.value=a}t.je(La,{key:!0,value:!0});t.A(La,{k:"iterator"},function(){return this});La.prototype.reset=La.prototype.reset=function(){this.key=-1};La.prototype.next=La.prototype.hasNext=La.prototype.next=function(){return-1===this.key?(this.key=0,!0):!1};La.prototype.first=La.prototype.eb=function(){this.key=0;return this.value};t.A(La,{count:"count"},function(){return 1});La.prototype.Gg=function(){this.value=null}; -La.prototype.toString=function(){return"SingletonIterator("+this.value+")"};function Ma(a){this.zf=a;this.io=null;this.reset()}t.je(Ma,{key:!0,value:!0});t.A(Ma,{k:"iterator"},function(){return this});t.g(Ma,"predicate",Ma.prototype.tl);t.defineProperty(Ma,{tl:"predicate"},function(){return this.io},function(a){this.io=a});Ma.prototype.reset=Ma.prototype.reset=function(){var a=this.zf;a.qh=null;this.kb=a.Wb;this.te=-1}; -Ma.prototype.next=Ma.prototype.hasNext=Ma.prototype.next=function(){var a=this.zf;a.Wb!==this.kb&&t.m("the List has been modified during iteration");var a=a.p,b=a.length,c=++this.te,d=this.io;if(null!==d)for(;ca||a>=b.length)&&t.ha(a,"0 <= i < length",H,"elt:i");return b[a]}; -H.prototype.setElt=H.prototype.set=H.prototype.xg=function(a,b){f&&(this.Dg(b),t.o(a,H,"setElt:i"));var c=this.p;(0>a||a>=c.length)&&t.ha(a,"0 <= i < length",H,"setElt:i");t.J(this,a);c[a]=b};H.prototype.first=H.prototype.eb=function(){var a=this.p;return 0===a.length?null:a[0]};H.prototype.insertAt=H.prototype.Ad=function(a,b){f&&(this.Dg(b),t.o(a,H,"insertAt:i"));0>a&&t.ha(a,">= 0",H,"insertAt:i");t.J(this,a);var c=this.p;a>=c.length?c.push(b):c.splice(a,0,b);this.Nd();return!0}; -H.prototype.remove=H.prototype["delete"]=H.prototype.remove=function(a){if(null===a)return!1;f&&this.Dg(a);t.J(this,a);var b=this.p;a=b.indexOf(a);if(-1===a)return!1;a===b.length-1?b.pop():b.splice(a,1);this.Nd();return!0};H.prototype.removeAt=H.prototype.gd=function(a){f&&t.o(a,H,"removeAt:i");var b=this.p;(0>a||a>=b.length)&&t.ha(a,"0 <= i < length",H,"removeAt:i");t.J(this,a);a===b.length-1?b.pop():b.splice(a,1);this.Nd()}; -H.prototype.removeRange=H.prototype.removeRange=function(a,b){f&&(t.o(a,H,"removeRange:from"),t.o(b,H,"removeRange:to"));var c=this.p;(0>a||a>=c.length)&&t.ha(a,"0 <= from < length",H,"elt:from");(0>b||b>=c.length)&&t.ha(b,"0 <= to < length",H,"elt:to");t.J(this,a);var d=c.slice((b||a)+1||c.length);c.length=0>a?c.length+a:a;c.push.apply(c,d);this.Nd()};H.prototype.copy=function(){for(var a=new H(this.ba),b=this.p,c=this.count,d=0;d=g)return this;(0>b||b>=e-1)&&t.ha(b,"0 <= from < length",H,"sortRange:from");if(2===g)return c=d[b],e=d[b+1],0=e)d.sort(a);else for(g=d.slice(0,c),g.sort(a),a=0;a=e)for(g=d.slice(b),g.sort(a), -a=b;a=this.p.length)return t.dh;var a=this.qh;return null!==a?(a.reset(),a):new Ma(this)}); -t.A(H,{Sm:"iteratorBackwards"},function(){if(0>=this.p.length)return t.dh;var a=this.Cy;return null!==a?(a.reset(),a):new Oa(this)});function Pa(a){this.q=a;this.reset()}t.je(Pa,{key:!0,value:!0});t.A(Pa,{k:"iterator"},function(){return this});Pa.prototype.reset=Pa.prototype.reset=function(){var a=this.q;a.qh=null;this.kb=a.Wb;this.ce=null}; -Pa.prototype.next=Pa.prototype.hasNext=Pa.prototype.next=function(){var a=this.q;a.Wb!==this.kb&&t.m("the Set has been modified during iteration");var b=this.ce,b=null===b?a.se:b.Bj;if(null!==b)return this.ce=b,this.value=b.value,this.key=b.key,!0;this.Gg();return!1};Pa.prototype.first=Pa.prototype.eb=function(){var a=this.q;this.kb=a.Wb;a=a.se;if(null!==a){this.ce=a;var b=a.value;this.key=a.key;return this.value=b}return null};t.A(Pa,{count:"count"},function(){return this.q.ld}); -Pa.prototype.Gg=function(){this.value=null;this.kb=-1;this.q.qh=this};Pa.prototype.toString=function(){return null!==this.ce?"SetIterator@"+this.ce.value:"SetIterator"}; -function ua(a){t.zc(this);this.jb=!1;void 0===a||null===a?this.ba=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.ba=a:t.ha(a,"the string 'object', 'number' or 'string'","Set constructor: type"):"function"===typeof a?this.ba=a===Object?"object":a===String?"string":a===Number?"number":a:t.ha(a,"null, a primitive type name, or a class type","Set constructor: type");this.Wc={};this.ld=0;this.qh=null;this.Wb=0;this.sh=this.se=null}t.ia("Set",ua); -ua.prototype.Dg=function(a){null!==this.ba&&("string"===typeof this.ba?typeof a===this.ba&&null!==a||t.Vb(a,this.ba):a instanceof this.ba||t.Vb(a,this.ba))};ua.prototype.Nd=function(){var a=this.Wb;a++;999999999=this.ld)return t.dh;var a=this.qh;return null!==a?(a.reset(),a):new Pa(this)});function Ra(a){this.Cc=a;this.reset()}t.je(Ra,{key:!0,value:!0});t.A(Ra,{k:"iterator"},function(){return this});Ra.prototype.reset=Ra.prototype.reset=function(){this.kb=this.Cc.Wb;this.ce=null}; -Ra.prototype.next=Ra.prototype.hasNext=Ra.prototype.next=function(){var a=this.Cc;a.Wb!==this.kb&&t.m("the Map has been modified during iteration");var b=this.ce,b=null===b?a.se:b.Bj;if(null!==b)return this.ce=b,this.value=this.key=a=b.key,!0;this.Gg();return!1};Ra.prototype.first=Ra.prototype.eb=function(){var a=this.Cc;this.kb=a.Wb;a=a.se;return null!==a?(this.ce=a,this.value=this.key=a=a.key):null};t.A(Ra,{count:"count"},function(){return this.Cc.ld}); -Ra.prototype.Gg=function(){this.value=null;this.kb=-1};Ra.prototype.toString=function(){return null!==this.ce?"MapKeySetIterator@"+this.ce.value:"MapKeySetIterator"};function Sa(a){t.zc(this);this.jb=!0;this.Cc=a}t.Oa(Sa,ua);Sa.prototype.freeze=function(){return this};Sa.prototype.Ua=function(){return this};Sa.prototype.toString=function(){return"MapKeySet("+this.Cc.toString()+")"};Sa.prototype.add=Sa.prototype.set=Sa.prototype.add=function(){t.m("This Set is read-only: "+this.toString());return!1}; -Sa.prototype.contains=Sa.prototype.has=Sa.prototype.contains=function(a){return this.Cc.contains(a)};Sa.prototype.remove=Sa.prototype["delete"]=Sa.prototype.remove=function(){t.m("This Set is read-only: "+this.toString());return!1};Sa.prototype.clear=Sa.prototype.clear=function(){t.m("This Set is read-only: "+this.toString())};Sa.prototype.first=Sa.prototype.eb=function(){var a=this.Cc.se;return null!==a?a.key:null};Sa.prototype.copy=function(){return new Sa(this.Cc)}; -Sa.prototype.toSet=function(){var a=new ua(this.Cc.rh),b=this.Cc.Wc,c;for(c in b)a.add(b[c].key);return a};Sa.prototype.toArray=Sa.prototype.af=function(){var a=this.Cc.Wc,b=Array(this.Cc.ld),c=0,d;for(d in a)b[c]=a[d].key,c++;return b};Sa.prototype.toList=function(){var a=new H(this.ba),b=this.Cc.Wc,c;for(c in b)a.add(b[c].key);return a};t.A(Sa,{count:"count"},function(){return this.Cc.ld});t.A(Sa,{size:"size"},function(){return this.Cc.ld}); -t.A(Sa,{k:"iterator"},function(){return 0>=this.Cc.ld?t.dh:new Ra(this.Cc)});function Qa(a,b){this.key=a;this.value=b;this.jo=this.Bj=null}t.je(Qa,{key:!0,value:!0});Qa.prototype.toString=function(){return"{"+this.key+":"+this.value+"}"};function Ua(a){this.Cc=a;this.reset()}t.je(Ua,{key:!0,value:!0});t.A(Ua,{k:"iterator"},function(){return this});Ua.prototype.reset=Ua.prototype.reset=function(){var a=this.Cc;a.qh=null;this.kb=a.Wb;this.ce=null}; -Ua.prototype.next=Ua.prototype.hasNext=Ua.prototype.next=function(){var a=this.Cc;a.Wb!==this.kb&&t.m("the Map has been modified during iteration");var b=this.ce,b=null===b?a.se:b.Bj;if(null!==b)return this.ce=b,this.key=b.key,this.value=b.value,!0;this.Gg();return!1};Ua.prototype.first=Ua.prototype.eb=function(){var a=this.Cc;this.kb=a.Wb;a=a.se;if(null!==a){this.ce=a;var b=a.key;this.key=b;this.value=a.value;return b}return null};t.A(Ua,{count:"count"},function(){return this.Cc.ld}); -Ua.prototype.Gg=function(){this.value=this.key=null;this.kb=-1;this.Cc.qh=this};Ua.prototype.toString=function(){return null!==this.ce?"MapIterator@"+this.ce:"MapIterator"}; -function sa(a,b){t.zc(this);this.jb=!1;void 0===a||null===a?this.rh=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.rh=a:t.ha(a,"the string 'object', 'number' or 'string'","Map constructor: keytype"):"function"===typeof a?this.rh=a===Object?"object":a===String?"string":a===Number?"number":a:t.ha(a,"null, a primitive type name, or a class type","Map constructor: keytype");void 0===b||null===b?this.Ci=null:"string"===typeof b?"object"===b||"string"===b||"boolean"===b||"number"=== -b||"function"===b?this.Ci=b:t.ha(b,"the string 'object', 'number', 'string', 'boolean', or 'function'","Map constructor: valtype"):"function"===typeof b?this.Ci=b===Object?"object":b===String?"string":b===Number?"number":b===Boolean?"boolean":b===Function?"function":b:t.ha(b,"null, a primitive type name, or a class type","Map constructor: valtype");this.Wc={};this.ld=0;this.qh=null;this.Wb=0;this.sh=this.se=null}t.ia("Map",sa); -function Va(a,b){null!==a.rh&&("string"===typeof a.rh?typeof b===a.rh&&null!==b||t.Vb(b,a.rh):b instanceof a.rh||t.Vb(b,a.rh))}sa.prototype.Nd=function(){var a=this.Wb;a++;999999999=this.count)return t.dh;var a=this.qh;return null!==a?(a.reset(),a):new Ua(this)});function C(a,b){void 0===a?this.M=this.L=0:"number"===typeof a&&"number"===typeof b?(this.L=a,this.M=b):t.m("Invalid arguments to Point constructor")}t.ia("Point",C);t.Fh(C);t.je(C,{x:!0,y:!0});C.prototype.assign=function(a){this.L=a.L;this.M=a.M};C.prototype.q=function(a,b){this.L=a;this.M=b}; -C.prototype.setTo=C.prototype.Fp=function(a,b){f&&(t.j(a,"number",C,"setTo:x"),t.j(b,"number",C,"setTo:y"));t.J(this);this.L=a;this.M=b;return this};C.prototype.set=C.prototype.set=function(a){f&&t.l(a,C,C,"set:p");t.J(this);this.L=a.L;this.M=a.M;return this};C.prototype.copy=function(){var a=new C;a.L=this.L;a.M=this.M;return a};C.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};C.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; -C.prototype.freeze=function(){this.jb=!0;return this};C.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this};C.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new C(c,e)}return new C};C.stringify=function(a){return a instanceof C?a.x.toString()+" "+a.y.toString():a.toString()}; -C.prototype.toString=function(){return"Point("+this.x+","+this.y+")"};C.prototype.equals=C.prototype.N=function(a){return a instanceof C?this.L===a.x&&this.M===a.y:!1};C.prototype.equalTo=function(a,b){return this.L===a&&this.M===b};C.prototype.bk=function(a){return J.Ka(this.L,a.x)&&J.Ka(this.M,a.y)};C.prototype.Oi=function(a){return J.I(this.L,a.x)&&J.I(this.M,a.y)};C.prototype.add=C.prototype.add=function(a){f&&t.l(a,C,C,"add:p");t.J(this);this.L+=a.x;this.M+=a.y;return this}; -C.prototype.subtract=C.prototype.At=function(a){f&&t.l(a,C,C,"subtract:p");t.J(this);this.L-=a.x;this.M-=a.y;return this};C.prototype.offset=C.prototype.offset=function(a,b){f&&(t.o(a,C,"offset:dx"),t.o(b,C,"offset:dy"));t.J(this);this.L+=a;this.M+=b;return this}; -C.prototype.rotate=C.prototype.rotate=function(a){f&&t.o(a,C,"rotate:angle");t.J(this);if(0===a)return this;var b=this.L,c=this.M;if(0===b&&0===c)return this;var d;90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));this.L=a*b-d*c;this.M=d*b+a*c;return this};C.prototype.scale=C.prototype.scale=function(a,b){f&&(t.o(a,C,"scale:sx"),t.o(b,C,"scale:sy"));this.L*=a;this.M*=b;return this}; -C.prototype.distanceSquaredPoint=C.prototype.$j=function(a){f&&t.l(a,C,C,"distanceSquaredPoint:p");var b=a.x-this.L;a=a.y-this.M;return b*b+a*a};C.prototype.distanceSquared=C.prototype.Fs=function(a,b){f&&(t.o(a,C,"distanceSquared:px"),t.o(b,C,"distanceSquared:py"));var c=a-this.L,d=b-this.M;return c*c+d*d};C.prototype.normalize=C.prototype.normalize=function(){t.J(this);var a=this.L,b=this.M,c=Math.sqrt(a*a+b*b);0b?270:0;if(0===b)return 0a?c=0>b?c+180:180-c:0>b&&(c=360-c);return c} -C.prototype.projectOntoLineSegment=function(a,b,c,d){f&&(t.o(a,C,"projectOntoLineSegment:px"),t.o(b,C,"projectOntoLineSegment:py"),t.o(c,C,"projectOntoLineSegment:qx"),t.o(d,C,"projectOntoLineSegment:qy"));J.Zm(a,b,c,d,this.L,this.M,this);return this};C.prototype.projectOntoLineSegmentPoint=function(a,b){f&&(t.l(a,C,C,"projectOntoLineSegmentPoint:p"),t.l(b,C,C,"projectOntoLineSegmentPoint:q"));J.Zm(a.x,a.y,b.x,b.y,this.L,this.M,this);return this}; -C.prototype.snapToGrid=function(a,b,c,d){f&&(t.o(a,C,"snapToGrid:originx"),t.o(b,C,"snapToGrid:originy"),t.o(c,C,"snapToGrid:cellwidth"),t.o(d,C,"snapToGrid:cellheight"));J.Hs(this.L,this.M,a,b,c,d,this);return this};C.prototype.snapToGridPoint=function(a,b){f&&(t.l(a,C,C,"snapToGridPoint:p"),t.l(b,pa,C,"snapToGridPoint:q"));J.Hs(this.L,this.M,a.x,a.y,b.width,b.height,this);return this}; -C.prototype.setRectSpot=C.prototype.wt=function(a,b){f&&(t.l(a,D,C,"setRectSpot:r"),t.l(b,K,C,"setRectSpot:spot"));t.J(this);this.L=a.x+b.x*a.width+b.offsetX;this.M=a.y+b.y*a.height+b.offsetY;return this}; -C.prototype.setSpot=C.prototype.xt=function(a,b,c,d,e){f&&(t.o(a,C,"setSpot:x"),t.o(b,C,"setSpot:y"),t.o(c,C,"setSpot:w"),t.o(d,C,"setSpot:h"),(0>c||0>d)&&t.m("Point.setSpot:Width and height cannot be negative"),t.l(e,K,C,"setSpot:spot"));t.J(this);this.L=a+e.x*c+e.offsetX;this.M=b+e.y*d+e.offsetY;return this};C.prototype.transform=function(a){f&&t.l(a,qa,C,"transform:t");a.Va(this);return this};function $a(a,b){f&&t.l(b,qa,C,"transformInverted:t");b.Ri(a);return a}var cb; -C.distanceLineSegmentSquared=cb=function(a,b,c,d,e,g){f&&(t.o(a,C,"distanceLineSegmentSquared:px"),t.o(b,C,"distanceLineSegmentSquared:py"),t.o(c,C,"distanceLineSegmentSquared:ax"),t.o(d,C,"distanceLineSegmentSquared:ay"),t.o(e,C,"distanceLineSegmentSquared:bx"),t.o(g,C,"distanceLineSegmentSquared:by"));var h=e-c,k=g-d,l=h*h+k*k;c-=a;d-=b;var m=-c*h-d*k;if(0>=m||m>=l)return h=e-a,k=g-b,Math.min(c*c+d*d,h*h+k*k);a=h*d-k*c;return a*a/l};var eb; -C.distanceSquared=eb=function(a,b,c,d){f&&(t.o(a,C,"distanceSquared:px"),t.o(b,C,"distanceSquared:py"),t.o(c,C,"distanceSquared:qx"),t.o(d,C,"distanceSquared:qy"));a=c-a;b=d-b;return a*a+b*b};var kb; -C.direction=kb=function(a,b,c,d){f&&(t.o(a,C,"direction:px"),t.o(b,C,"direction:py"),t.o(c,C,"direction:qx"),t.o(d,C,"direction:qy"));a=c-a;b=d-b;if(0===a)return 0b?270:0;if(0===b)return 0a?d=0>b?d+180:180-d:0>b&&(d=360-d);return d};t.g(C,"x",C.prototype.x);t.defineProperty(C,{x:"x"},function(){return this.L},function(a){t.J(this,a);f&&t.j(a,"number",C,"x");this.L=a});t.g(C,"y",C.prototype.y); -t.defineProperty(C,{y:"y"},function(){return this.M},function(a){t.J(this,a);f&&t.j(a,"number",C,"y");this.M=a});C.prototype.isReal=C.prototype.Q=function(){return isFinite(this.x)&&isFinite(this.y)};function pa(a,b){void 0===a?this.xa=this.ya=0:"number"===typeof a&&(0<=a||isNaN(a))&&"number"===typeof b&&(0<=b||isNaN(b))?(this.ya=a,this.xa=b):t.m("Invalid arguments to Size constructor")}t.ia("Size",pa);t.Fh(pa);t.je(pa,{width:!0,height:!0});pa.prototype.assign=function(a){this.ya=a.ya;this.xa=a.xa}; -pa.prototype.q=function(a,b){this.ya=a;this.xa=b};pa.prototype.setTo=pa.prototype.Fp=function(a,b){f&&(t.j(a,"number",pa,"setTo:w"),t.j(b,"number",pa,"setTo:h"));0>a&&t.ha(a,">= 0",pa,"setTo:w");0>b&&t.ha(b,">= 0",pa,"setTo:h");t.J(this);this.ya=a;this.xa=b;return this};pa.prototype.set=pa.prototype.set=function(a){f&&t.l(a,pa,pa,"set:s");t.J(this);this.ya=a.ya;this.xa=a.xa;return this};pa.prototype.copy=function(){var a=new pa;a.ya=this.ya;a.xa=this.xa;return a}; -pa.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};pa.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()};pa.prototype.freeze=function(){this.jb=!0;return this};pa.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this}; -pa.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new pa(c,e)}return new pa};pa.stringify=function(a){return a instanceof pa?a.width.toString()+" "+a.height.toString():a.toString()};pa.prototype.toString=function(){return"Size("+this.width+","+this.height+")"}; -pa.prototype.equals=pa.prototype.N=function(a){return a instanceof pa?this.ya===a.width&&this.xa===a.height:!1};pa.prototype.equalTo=function(a,b){return this.ya===a&&this.xa===b};pa.prototype.bk=function(a){return J.Ka(this.ya,a.width)&&J.Ka(this.xa,a.height)};pa.prototype.Oi=function(a){return J.I(this.ya,a.width)&&J.I(this.xa,a.height)};t.g(pa,"width",pa.prototype.width); -t.defineProperty(pa,{width:"width"},function(){return this.ya},function(a){t.J(this,a);f&&t.j(a,"number",pa,"width");0>a&&t.ha(a,">= 0",pa,"width");this.ya=a});t.g(pa,"height",pa.prototype.height);t.defineProperty(pa,{height:"height"},function(){return this.xa},function(a){t.J(this,a);f&&t.j(a,"number",pa,"height");0>a&&t.ha(a,">= 0",pa,"height");this.xa=a});pa.prototype.isReal=pa.prototype.Q=function(){return isFinite(this.width)&&isFinite(this.height)}; -function D(a,b,c,d){void 0===a?this.xa=this.ya=this.M=this.L=0:a instanceof C?b instanceof C?(this.L=Math.min(a.L,b.L),this.M=Math.min(a.M,b.M),this.ya=Math.abs(a.L-b.L),this.xa=Math.abs(a.M-b.M)):b instanceof pa?(this.L=a.L,this.M=a.M,this.ya=b.ya,this.xa=b.xa):t.m("Incorrect arguments supplied"):"number"===typeof a&&"number"===typeof b&&"number"===typeof c&&(0<=c||isNaN(c))&&"number"===typeof d&&(0<=d||isNaN(d))?(this.L=a,this.M=b,this.ya=c,this.xa=d):t.m("Invalid arguments to Rect constructor")} -t.ia("Rect",D);t.Fh(D);t.je(D,{x:!0,y:!0,width:!0,height:!0});D.prototype.assign=function(a){this.L=a.L;this.M=a.M;this.ya=a.ya;this.xa=a.xa};D.prototype.q=function(a,b,c,d){this.L=a;this.M=b;this.ya=c;this.xa=d};function nb(a,b,c){a.ya=b;a.xa=c} -D.prototype.setTo=D.prototype.Fp=function(a,b,c,d){f&&(t.j(a,"number",D,"setTo:x"),t.j(b,"number",D,"setTo:y"),t.j(c,"number",D,"setTo:w"),t.j(d,"number",D,"setTo:h"));0>c&&t.ha(c,">= 0",D,"setTo:w");0>d&&t.ha(d,">= 0",D,"setTo:h");t.J(this);this.L=a;this.M=b;this.ya=c;this.xa=d;return this};D.prototype.set=D.prototype.set=function(a){f&&t.l(a,D,D,"set:r");t.J(this);this.L=a.L;this.M=a.M;this.ya=a.ya;this.xa=a.xa;return this}; -D.prototype.setPoint=D.prototype.uf=function(a){f&&t.l(a,C,D,"setPoint:p");t.J(this);this.L=a.L;this.M=a.M;return this};D.prototype.setSize=function(a){f&&t.l(a,pa,D,"setSize:s");t.J(this);this.ya=a.ya;this.xa=a.xa;return this};D.prototype.copy=function(){var a=new D;a.L=this.L;a.M=this.M;a.ya=this.ya;a.xa=this.xa;return a};D.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};D.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; -D.prototype.freeze=function(){this.jb=!0;return this};D.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this};D.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new D(c,e,g,h)}return new D}; -D.stringify=function(a){return a instanceof D?a.x.toString()+" "+a.y.toString()+" "+a.width.toString()+" "+a.height.toString():a.toString()};D.prototype.toString=function(){return"Rect("+this.x+","+this.y+","+this.width+","+this.height+")"};D.prototype.equals=D.prototype.N=function(a){return a instanceof D?this.L===a.x&&this.M===a.y&&this.ya===a.width&&this.xa===a.height:!1};D.prototype.equalTo=function(a,b,c,d){return this.L===a&&this.M===b&&this.ya===c&&this.xa===d}; -D.prototype.bk=function(a){return J.Ka(this.L,a.x)&&J.Ka(this.M,a.y)&&J.Ka(this.ya,a.width)&&J.Ka(this.xa,a.height)};D.prototype.Oi=function(a){return J.I(this.L,a.x)&&J.I(this.M,a.y)&&J.I(this.ya,a.width)&&J.I(this.xa,a.height)};D.prototype.containsPoint=D.prototype.Ia=function(a){f&&t.l(a,C,D,"containsPoint:p");return this.L<=a.x&&this.L+this.ya>=a.x&&this.M<=a.y&&this.M+this.xa>=a.y}; -D.prototype.containsRect=D.prototype.Wj=function(a){f&&t.l(a,D,D,"containsRect:r");return this.L<=a.x&&a.x+a.width<=this.L+this.ya&&this.M<=a.y&&a.y+a.height<=this.M+this.xa}; -D.prototype.contains=D.prototype.contains=function(a,b,c,d){f?(t.o(a,D,"contains:x"),t.o(b,D,"contains:y"),void 0===c?c=0:t.o(c,D,"contains:w"),void 0===d?d=0:t.o(d,D,"contains:h"),(0>c||0>d)&&t.m("Rect.contains:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return this.L<=a&&a+c<=this.L+this.ya&&this.M<=b&&b+d<=this.M+this.xa};D.prototype.reset=function(){t.J(this);this.xa=this.ya=this.M=this.L=0}; -D.prototype.offset=D.prototype.offset=function(a,b){f&&(t.o(a,D,"offset:dx"),t.o(b,D,"offset:dy"));t.J(this);this.L+=a;this.M+=b;return this};D.prototype.inflate=D.prototype.Vg=function(a,b){f&&(t.o(a,D,"inflate:w"),t.o(b,D,"inflate:h"));return ob(this,b,a,b,a)};D.prototype.addMargin=D.prototype.Ev=function(a){f&&t.l(a,pb,D,"addMargin:m");return ob(this,a.top,a.right,a.bottom,a.left)}; -D.prototype.subtractMargin=D.prototype.gJ=function(a){f&&t.l(a,pb,D,"subtractMargin:m");return ob(this,-a.top,-a.right,-a.bottom,-a.left)};D.prototype.grow=function(a,b,c,d){f&&(t.o(a,D,"grow:t"),t.o(b,D,"grow:r"),t.o(c,D,"grow:b"),t.o(d,D,"grow:l"));return ob(this,a,b,c,d)};function ob(a,b,c,d,e){t.J(a);var g=a.ya;c+e<=-g?(a.L+=g/2,a.ya=0):(a.L-=e,a.ya+=c+e);c=a.xa;b+d<=-c?(a.M+=c/2,a.xa=0):(a.M-=b,a.xa+=b+d);return a} -D.prototype.intersectRect=function(a){f&&t.l(a,D,D,"intersectRect:r");return ub(this,a.x,a.y,a.width,a.height)};D.prototype.intersect=function(a,b,c,d){f&&(t.o(a,D,"intersect:x"),t.o(b,D,"intersect:y"),t.o(c,D,"intersect:w"),t.o(d,D,"intersect:h"),(0>c||0>d)&&t.m("Rect.intersect:Width and height cannot be negative"));return ub(this,a,b,c,d)}; -function ub(a,b,c,d,e){t.J(a);var g=Math.max(a.L,b),h=Math.max(a.M,c);b=Math.min(a.L+a.ya,b+d);c=Math.min(a.M+a.xa,c+e);a.L=g;a.M=h;a.ya=Math.max(0,b-g);a.xa=Math.max(0,c-h);return a}D.prototype.intersectsRect=D.prototype.If=function(a){f&&t.l(a,D,D,"intersectsRect:r");return this.wE(a.x,a.y,a.width,a.height)}; -D.prototype.intersects=D.prototype.wE=function(a,b,c,d){f&&(t.o(a,D,"intersects:x"),t.o(b,D,"intersects:y"),t.o(a,D,"intersects:w"),t.o(b,D,"intersects:h"),(0>c||0>d)&&t.m("Rect.intersects:Width and height cannot be negative"));var e=this.ya,g=this.L;if(Infinity!==e&&Infinity!==c&&(e+=g,c+=a,isNaN(c)||isNaN(e)||g>c||a>e))return!1;a=this.xa;c=this.M;return Infinity!==a&&Infinity!==d&&(a+=c,d+=b,isNaN(d)||isNaN(a)||c>d||b>a)?!1:!0}; -function vb(a,b){var c=a.ya,d=b.width+10+10,e=a.L,g=b.x-10;if(e>d+g||g>c+e)return!1;c=a.xa;d=b.height+10+10;e=a.M;g=b.y-10;return e>d+g||g>c+e?!1:!0}D.prototype.unionPoint=D.prototype.$i=function(a){f&&t.l(a,C,D,"unionPoint:p");return wb(this,a.x,a.y,0,0)};D.prototype.unionRect=D.prototype.nk=function(a){f&&t.l(a,D,D,"unionRect:r");return wb(this,a.L,a.M,a.ya,a.xa)}; -D.prototype.union=D.prototype.YF=function(a,b,c,d){t.J(this);f?(t.o(a,D,"union:x"),t.o(b,D,"union:y"),void 0===c?c=0:t.o(c,D,"union:w"),void 0===d?d=0:t.o(d,D,"union:h"),(0>c||0>d)&&t.m("Rect.union:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return wb(this,a,b,c,d)};function wb(a,b,c,d,e){var g=Math.min(a.L,b),h=Math.min(a.M,c);b=Math.max(a.L+a.ya,b+d);c=Math.max(a.M+a.xa,c+e);a.L=g;a.M=h;a.ya=b-g;a.xa=c-h;return a} -D.prototype.setSpot=D.prototype.xt=function(a,b,c){f&&(t.o(a,D,"setSpot:x"),t.o(b,D,"setSpot:y"),t.l(c,K,D,"setSpot:spot"));t.J(this);this.L=a-c.offsetX-c.x*this.ya;this.M=b-c.offsetY-c.y*this.xa;return this};var Db; -D.contains=Db=function(a,b,c,d,e,g,h,k){f?(t.o(a,D,"contains:rx"),t.o(b,D,"contains:ry"),t.o(c,D,"contains:rw"),t.o(d,D,"contains:rh"),t.o(e,D,"contains:x"),t.o(g,D,"contains:y"),void 0===h?h=0:t.o(h,D,"contains:w"),void 0===k?k=0:t.o(k,D,"contains:h"),(0>c||0>d||0>h||0>k)&&t.m("Rect.contains:Width and height cannot be negative")):(void 0===h&&(h=0),void 0===k&&(k=0));return a<=e&&e+h<=a+c&&b<=g&&g+k<=b+d}; -D.intersects=function(a,b,c,d,e,g,h,k){f&&(t.o(a,D,"intersects:rx"),t.o(b,D,"intersects:ry"),t.o(c,D,"intersects:rw"),t.o(d,D,"intersects:rh"),t.o(e,D,"intersects:x"),t.o(g,D,"intersects:y"),t.o(h,D,"intersects:w"),t.o(k,D,"intersects:h"),(0>c||0>d||0>h||0>k)&&t.m("Rect.intersects:Width and height cannot be negative"));c+=a;h+=e;if(a>h||e>c)return!1;a=d+b;k+=g;return b>k||g>a?!1:!0};t.g(D,"x",D.prototype.x); -t.defineProperty(D,{x:"x"},function(){return this.L},function(a){t.J(this,a);f&&t.j(a,"number",D,"x");this.L=a});t.g(D,"y",D.prototype.y);t.defineProperty(D,{y:"y"},function(){return this.M},function(a){t.J(this,a);f&&t.j(a,"number",D,"y");this.M=a});t.g(D,"width",D.prototype.width);t.defineProperty(D,{width:"width"},function(){return this.ya},function(a){t.J(this,a);f&&t.j(a,"number",D,"width");0>a&&t.ha(a,">= 0",D,"width");this.ya=a});t.g(D,"height",D.prototype.height); -t.defineProperty(D,{height:"height"},function(){return this.xa},function(a){t.J(this,a);f&&t.j(a,"number",D,"height");0>a&&t.ha(a,">= 0",D,"height");this.xa=a});t.g(D,"left",D.prototype.left);t.defineProperty(D,{left:"left"},function(){return this.L},function(a){t.J(this,a);f&&t.j(a,"number",D,"left");this.L=a});t.g(D,"top",D.prototype.top);t.defineProperty(D,{top:"top"},function(){return this.M},function(a){t.J(this,a);f&&t.j(a,"number",D,"top");this.M=a});t.g(D,"right",D.prototype.right); -t.defineProperty(D,{right:"right"},function(){return this.L+this.ya},function(a){t.J(this,a);f&&t.o(a,D,"right");this.L+=a-(this.L+this.ya)});t.g(D,"bottom",D.prototype.bottom);t.defineProperty(D,{bottom:"bottom"},function(){return this.M+this.xa},function(a){t.J(this,a);f&&t.o(a,D,"top");this.M+=a-(this.M+this.xa)});t.g(D,"position",D.prototype.position); -t.defineProperty(D,{position:"position"},function(){return new C(this.L,this.M)},function(a){t.J(this,a);f&&t.l(a,C,D,"position");this.L=a.x;this.M=a.y});t.g(D,"size",D.prototype.size);t.defineProperty(D,{size:"size"},function(){return new pa(this.ya,this.xa)},function(a){t.J(this,a);f&&t.l(a,pa,D,"size");this.ya=a.width;this.xa=a.height});t.g(D,"center",D.prototype.Iz); -t.defineProperty(D,{Iz:"center"},function(){return new C(this.L+this.ya/2,this.M+this.xa/2)},function(a){t.J(this,a);f&&t.l(a,C,D,"center");this.L=a.x-this.ya/2;this.M=a.y-this.xa/2});t.g(D,"centerX",D.prototype.Fa);t.defineProperty(D,{Fa:"centerX"},function(){return this.L+this.ya/2},function(a){t.J(this,a);f&&t.o(a,D,"centerX");this.L=a-this.ya/2});t.g(D,"centerY",D.prototype.Sa); -t.defineProperty(D,{Sa:"centerY"},function(){return this.M+this.xa/2},function(a){t.J(this,a);f&&t.o(a,D,"centerY");this.M=a-this.xa/2});D.prototype.isReal=D.prototype.Q=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)};D.prototype.isEmpty=function(){return 0===this.width&&0===this.height}; -function pb(a,b,c,d){void 0===a?this.$f=this.Sf=this.dg=this.gg=0:void 0===b?this.left=this.bottom=this.right=this.top=a:void 0===c?(d=b,this.top=a,this.right=b,this.bottom=a,this.left=d):void 0!==d?(this.top=a,this.right=b,this.bottom=c,this.left=d):t.m("Invalid arguments to Margin constructor")}t.ia("Margin",pb);t.Fh(pb);t.je(pb,{top:!0,right:!0,bottom:!0,left:!0});pb.prototype.assign=function(a){this.gg=a.gg;this.dg=a.dg;this.Sf=a.Sf;this.$f=a.$f}; -pb.prototype.setTo=pb.prototype.Fp=function(a,b,c,d){f&&(t.j(a,"number",pb,"setTo:t"),t.j(b,"number",pb,"setTo:r"),t.j(c,"number",pb,"setTo:b"),t.j(d,"number",pb,"setTo:l"));t.J(this);this.gg=a;this.dg=b;this.Sf=c;this.$f=d;return this};pb.prototype.set=pb.prototype.set=function(a){f&&t.l(a,pb,pb,"assign:m");t.J(this);this.gg=a.gg;this.dg=a.dg;this.Sf=a.Sf;this.$f=a.$f;return this};pb.prototype.copy=function(){var a=new pb;a.gg=this.gg;a.dg=this.dg;a.Sf=this.Sf;a.$f=this.$f;return a}; -pb.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};pb.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()};pb.prototype.freeze=function(){this.jb=!0;return this};pb.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this}; -pb.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=void 0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=void 0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=void 0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new pb(c,e,g,h)}return new pb};pb.stringify=function(a){return a instanceof pb?a.top.toString()+" "+a.right.toString()+" "+a.bottom.toString()+" "+a.left.toString():a.toString()}; -pb.prototype.toString=function(){return"Margin("+this.top+","+this.right+","+this.bottom+","+this.left+")"};pb.prototype.equals=pb.prototype.N=function(a){return a instanceof pb?this.gg===a.top&&this.dg===a.right&&this.Sf===a.bottom&&this.$f===a.left:!1};pb.prototype.equalTo=function(a,b,c,d){return this.gg===a&&this.dg===b&&this.Sf===c&&this.$f===d};pb.prototype.bk=function(a){return J.Ka(this.gg,a.top)&&J.Ka(this.dg,a.right)&&J.Ka(this.Sf,a.bottom)&&J.Ka(this.$f,a.left)}; -pb.prototype.Oi=function(a){return J.I(this.gg,a.top)&&J.I(this.dg,a.right)&&J.I(this.Sf,a.bottom)&&J.I(this.$f,a.left)};t.g(pb,"top",pb.prototype.top);t.defineProperty(pb,{top:"top"},function(){return this.gg},function(a){t.J(this,a);f&&t.o(a,pb,"top");this.gg=a});t.g(pb,"right",pb.prototype.right);t.defineProperty(pb,{right:"right"},function(){return this.dg},function(a){t.J(this,a);f&&t.o(a,pb,"right");this.dg=a});t.g(pb,"bottom",pb.prototype.bottom); -t.defineProperty(pb,{bottom:"bottom"},function(){return this.Sf},function(a){t.J(this,a);f&&t.o(a,pb,"bottom");this.Sf=a});t.g(pb,"left",pb.prototype.left);t.defineProperty(pb,{left:"left"},function(){return this.$f},function(a){t.J(this,a);f&&t.o(a,pb,"left");this.$f=a});pb.prototype.isReal=pb.prototype.Q=function(){return isFinite(this.top)&&isFinite(this.right)&&isFinite(this.bottom)&&isFinite(this.left)};function qa(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}t.Fh(qa); -t.je(qa,{m11:!0,m12:!0,m21:!0,m22:!0,dx:!0,dy:!0});qa.prototype.set=qa.prototype.set=function(a){f&&t.l(a,qa,qa,"set:t");this.m11=a.m11;this.m12=a.m12;this.m21=a.m21;this.m22=a.m22;this.dx=a.dx;this.dy=a.dy;return this};qa.prototype.copy=function(){var a=new qa;a.m11=this.m11;a.m12=this.m12;a.m21=this.m21;a.m22=this.m22;a.dx=this.dx;a.dy=this.dy;return a};qa.prototype.toString=function(){return"Transform("+this.m11+","+this.m12+","+this.m21+","+this.m22+","+this.dx+","+this.dy+")"}; -qa.prototype.equals=qa.prototype.N=function(a){return a instanceof qa?this.m11===a.m11&&this.m12===a.m12&&this.m21===a.m21&&this.m22===a.m22&&this.dx===a.dx&&this.dy===a.dy:!1};qa.prototype.reset=qa.prototype.reset=function(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}; -qa.prototype.multiply=qa.prototype.multiply=function(a){f&&t.l(a,qa,qa,"multiply:matrix");var b=this.m12*a.m11+this.m22*a.m12,c=this.m11*a.m21+this.m21*a.m22,d=this.m12*a.m21+this.m22*a.m22,e=this.m11*a.dx+this.m21*a.dy+this.dx,g=this.m12*a.dx+this.m22*a.dy+this.dy;this.m11=this.m11*a.m11+this.m21*a.m12;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g;return this}; -qa.prototype.multiplyInverted=qa.prototype.yA=function(a){f&&t.l(a,qa,qa,"multiplyInverted:matrix");var b=1/(a.m11*a.m22-a.m12*a.m21),c=a.m22*b,d=-a.m12*b,e=-a.m21*b,g=a.m11*b,h=b*(a.m21*a.dy-a.m22*a.dx),k=b*(a.m12*a.dx-a.m11*a.dy);a=this.m12*c+this.m22*d;b=this.m11*e+this.m21*g;e=this.m12*e+this.m22*g;g=this.m11*h+this.m21*k+this.dx;h=this.m12*h+this.m22*k+this.dy;this.m11=this.m11*c+this.m21*d;this.m12=a;this.m21=b;this.m22=e;this.dx=g;this.dy=h;return this}; -qa.prototype.invert=qa.prototype.jA=function(){var a=1/(this.m11*this.m22-this.m12*this.m21),b=-this.m12*a,c=-this.m21*a,d=this.m11*a,e=a*(this.m21*this.dy-this.m22*this.dx),g=a*(this.m12*this.dx-this.m11*this.dy);this.m11=this.m22*a;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g}; -qa.prototype.rotate=qa.prototype.rotate=function(a,b,c){f&&(t.o(a,qa,"rotate:angle"),t.o(b,qa,"rotate:rx"),t.o(c,qa,"rotate:ry"));this.translate(b,c);var d;0===a?(a=1,d=0):90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));var e=this.m12*a+this.m22*d,g=this.m11*-d+this.m21*a,h=this.m12*-d+this.m22*a;this.m11=this.m11*a+this.m21*d;this.m12=e;this.m21=g;this.m22=h;this.translate(-b,-c)}; -qa.prototype.translate=qa.prototype.translate=function(a,b){f&&(t.o(a,qa,"translate:x"),t.o(b,qa,"translate:y"));this.dx+=this.m11*a+this.m21*b;this.dy+=this.m12*a+this.m22*b};qa.prototype.scale=qa.prototype.scale=function(a,b){void 0===b&&(b=a);f&&(t.o(a,qa,"translate:sx"),t.o(b,qa,"translate:sy"));this.m11*=a;this.m12*=a;this.m21*=b;this.m22*=b}; -qa.prototype.transformPoint=qa.prototype.Va=function(a){f&&t.l(a,C,qa,"transformPoint:p");var b=a.L,c=a.M;a.L=b*this.m11+c*this.m21+this.dx;a.M=b*this.m12+c*this.m22+this.dy;return a};qa.prototype.invertedTransformPoint=qa.prototype.Ri=function(a){f&&t.l(a,C,qa,"invertedTransformPoint:p");var b=1/(this.m11*this.m22-this.m12*this.m21),c=-this.m12*b,d=this.m11*b,e=b*(this.m12*this.dx-this.m11*this.dy),g=a.L,h=a.M;a.L=g*this.m22*b+h*-this.m21*b+b*(this.m21*this.dy-this.m22*this.dx);a.M=g*c+h*d+e;return a}; -qa.prototype.transformRect=qa.prototype.TF=function(a){f&&t.l(a,D,qa,"transformRect:rect");var b=a.L,c=a.M,d=b+a.ya,e=c+a.xa,g=this.m11,h=this.m12,k=this.m21,l=this.m22,m=this.dx,n=this.dy,p=b*g+c*k+m,q=b*h+c*l+n,r=d*g+c*k+m,c=d*h+c*l+n,s=b*g+e*k+m,b=b*h+e*l+n,g=d*g+e*k+m,d=d*h+e*l+n,e=p,h=q,p=Math.min(p,r),e=Math.max(e,r),h=Math.min(h,c),q=Math.max(q,c),p=Math.min(p,s),e=Math.max(e,s),h=Math.min(h,b),q=Math.max(q,b),p=Math.min(p,g),e=Math.max(e,g),h=Math.min(h,d),q=Math.max(q,d);a.L=p;a.M=h;a.ya= -e-p;a.xa=q-h};qa.prototype.isIdentity=qa.prototype.Ts=function(){return 1===this.m11&&0===this.m12&&0===this.m21&&1===this.m22&&0===this.dx&&0===this.dy};function K(a,b,c,d){void 0===a?this.cg=this.bg=this.M=this.L=0:(void 0===b&&(b=0),void 0===c&&(c=0),void 0===d&&(d=0),this.x=a,this.y=b,this.offsetX=c,this.offsetY=d)}t.ia("Spot",K);t.Fh(K);t.je(K,{x:!0,y:!0,offsetX:!0,offsetY:!0});K.prototype.assign=function(a){this.L=a.L;this.M=a.M;this.bg=a.bg;this.cg=a.cg}; -K.prototype.setTo=K.prototype.Fp=function(a,b,c,d){f&&(Eb(a,"setTo:x"),Eb(b,"setTo:y"),Fb(c,"setTo:offx"),Fb(d,"setTo:offy"));t.J(this);this.L=a;this.M=b;this.bg=c;this.cg=d;return this};K.prototype.set=K.prototype.set=function(a){f&&t.l(a,K,K,"set:s");t.J(this);this.L=a.L;this.M=a.M;this.bg=a.bg;this.cg=a.cg;return this};K.prototype.copy=function(){var a=new K;a.L=this.L;a.M=this.M;a.bg=this.bg;a.cg=this.cg;return a};K.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this}; -K.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()};K.prototype.freeze=function(){this.jb=!0;return this};K.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this};function Jb(a,b){a.L=NaN;a.M=NaN;a.bg=b;return a}function Eb(a,b){(isNaN(a)||1a)&&t.ha(a,"0 <= "+b+" <= 1",K,b)}function Fb(a,b){(isNaN(a)||Infinity===a||-Infinity===a)&&t.ha(a,"real number, not NaN or Infinity",K,b)}var Nb; -K.parse=Nb=function(a){if("string"===typeof a){a=a.trim();if("None"===a)return t.NONE;if("TopLeft"===a)return t.sx;if("Top"===a||"TopCenter"===a||"MiddleTop"===a)return t.Tp;if("TopRight"===a)return t.ux;if("Left"===a||"LeftCenter"===a||"MiddleLeft"===a)return t.Qp;if("Center"===a)return t.ex;if("Right"===a||"RightCenter"===a||"MiddleRight"===a)return t.Rp;if("BottomLeft"===a)return t.Yw;if("Bottom"===a||"BottomCenter"===a||"MiddleBottom"===a)return t.Pp;if("BottomRight"===a)return t.$w;if("TopSide"=== -a)return t.wx;if("LeftSide"===a)return t.jx;if("RightSide"===a)return t.px;if("BottomSide"===a)return t.bx;if("TopBottomSides"===a)return t.qx;if("LeftRightSides"===a)return t.ix;if("TopLeftSides"===a)return t.tx;if("TopRightSides"===a)return t.vx;if("BottomLeftSides"===a)return t.Zw;if("BottomRightSides"===a)return t.ax;if("NotTopSide"===a)return t.nx;if("NotLeftSide"===a)return t.lx;if("NotRightSide"===a)return t.mx;if("NotBottomSide"===a)return t.kx;if("AllSides"===a)return t.Xw;if("Default"=== -a)return t.gx;a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new K(c,e,g,h)}return new K};K.stringify=function(a){return a instanceof K?a.rd()?a.x.toString()+" "+a.y.toString()+" "+a.offsetX.toString()+" "+a.offsetY.toString():a.toString():a.toString()}; -K.prototype.toString=function(){return this.rd()?0===this.bg&&0===this.cg?"Spot("+this.x+","+this.y+")":"Spot("+this.x+","+this.y+","+this.offsetX+","+this.offsetY+")":this.N(t.NONE)?"None":this.N(t.sx)?"TopLeft":this.N(t.Tp)?"Top":this.N(t.ux)?"TopRight":this.N(t.Qp)?"Left":this.N(t.ex)?"Center":this.N(t.Rp)?"Right":this.N(t.Yw)?"BottomLeft":this.N(t.Pp)?"Bottom":this.N(t.$w)?"BottomRight":this.N(t.wx)?"TopSide":this.N(t.jx)?"LeftSide":this.N(t.px)?"RightSide":this.N(t.bx)?"BottomSide":this.N(t.qx)? -"TopBottomSides":this.N(t.ix)?"LeftRightSides":this.N(t.tx)?"TopLeftSides":this.N(t.vx)?"TopRightSides":this.N(t.Zw)?"BottomLeftSides":this.N(t.ax)?"BottomRightSides":this.N(t.nx)?"NotTopSide":this.N(t.lx)?"NotLeftSide":this.N(t.mx)?"NotRightSide":this.N(t.kx)?"NotBottomSide":this.N(t.Xw)?"AllSides":this.N(t.gx)?"Default":"None"}; -K.prototype.equals=K.prototype.N=function(a){return a instanceof K?(this.L===a.x||isNaN(this.L)&&isNaN(a.x))&&(this.M===a.y||isNaN(this.M)&&isNaN(a.y))&&this.bg===a.offsetX&&this.cg===a.offsetY:!1};K.prototype.opposite=function(){return new K(0.5-(this.L-0.5),0.5-(this.M-0.5),-this.bg,-this.cg)};K.prototype.includesSide=function(a){if(!this.dp()||!a.dp())return!1;a=a.offsetY;return(this.cg&a)===a};t.g(K,"x",K.prototype.x); -t.defineProperty(K,{x:"x"},function(){return this.L},function(a){t.J(this,a);f&&Eb(a,"x");this.L=a});t.g(K,"y",K.prototype.y);t.defineProperty(K,{y:"y"},function(){return this.M},function(a){t.J(this,a);f&&Eb(a,"y");this.M=a});t.g(K,"offsetX",K.prototype.offsetX);t.defineProperty(K,{offsetX:"offsetX"},function(){return this.bg},function(a){t.J(this,a);f&&Fb(a,"offsetX");this.bg=a});t.g(K,"offsetY",K.prototype.offsetY); -t.defineProperty(K,{offsetY:"offsetY"},function(){return this.cg},function(a){t.J(this,a);f&&Fb(a,"offsetY");this.cg=a});K.prototype.isSpot=K.prototype.rd=function(){return!isNaN(this.x)&&!isNaN(this.y)};K.prototype.isNoSpot=K.prototype.qd=function(){return isNaN(this.x)||isNaN(this.y)};K.prototype.isSide=K.prototype.dp=function(){return this.qd()&&1===this.offsetX&&0!==this.offsetY};K.prototype.isDefault=K.prototype.Fc=function(){return isNaN(this.x)&&isNaN(this.y)&&-1===this.offsetX&&0===this.offsetY}; -t.Fd=1;t.hd=2;t.ud=4;t.td=8;t.NONE=Jb(new K(0,0,0,0),0).Na();t.gx=Jb(new K(0,0,-1,0),-1).Na();t.sx=(new K(0,0,0,0)).Na();t.Tp=(new K(0.5,0,0,0)).Na();t.ux=(new K(1,0,0,0)).Na();t.Qp=(new K(0,0.5,0,0)).Na();t.ex=(new K(0.5,0.5,0,0)).Na();t.Rp=(new K(1,0.5,0,0)).Na();t.Yw=(new K(0,1,0,0)).Na();t.Pp=(new K(0.5,1,0,0)).Na();t.$w=(new K(1,1,0,0)).Na();t.wx=Jb(new K(0,0,1,t.Fd),1).Na();t.jx=Jb(new K(0,0,1,t.hd),1).Na();t.px=Jb(new K(0,0,1,t.ud),1).Na();t.bx=Jb(new K(0,0,1,t.td),1).Na(); -t.qx=Jb(new K(0,0,1,t.Fd|t.td),1).Na();t.ix=Jb(new K(0,0,1,t.hd|t.ud),1).Na();t.tx=Jb(new K(0,0,1,t.Fd|t.hd),1).Na();t.vx=Jb(new K(0,0,1,t.Fd|t.ud),1).Na();t.Zw=Jb(new K(0,0,1,t.td|t.hd),1).Na();t.ax=Jb(new K(0,0,1,t.td|t.ud),1).Na();t.nx=Jb(new K(0,0,1,t.hd|t.ud|t.td),1).Na();t.lx=Jb(new K(0,0,1,t.Fd|t.ud|t.td),1).Na();t.mx=Jb(new K(0,0,1,t.Fd|t.hd|t.td),1).Na();t.kx=Jb(new K(0,0,1,t.Fd|t.hd|t.ud),1).Na();t.Xw=Jb(new K(0,0,1,t.Fd|t.hd|t.ud|t.td),1).Na();var Ob;K.None=Ob=t.NONE;var Pb; -K.Default=Pb=t.gx;var Tb;K.TopLeft=Tb=t.sx;var Ub;K.TopCenter=Ub=t.Tp;var Vb;K.TopRight=Vb=t.ux;K.LeftCenter=t.Qp;var Wb;K.Center=Wb=t.ex;K.RightCenter=t.Rp;var Xb;K.BottomLeft=Xb=t.Yw;var Yb;K.BottomCenter=Yb=t.Pp;var $b;K.BottomRight=$b=t.$w;var ac;K.MiddleTop=ac=t.Tp;var bc;K.MiddleLeft=bc=t.Qp;var cc;K.MiddleRight=cc=t.Rp;var dc;K.MiddleBottom=dc=t.Pp;K.Top=t.Tp;var ic;K.Left=ic=t.Qp;var nc;K.Right=nc=t.Rp;K.Bottom=t.Pp;var oc;K.TopSide=oc=t.wx;var pc;K.LeftSide=pc=t.jx;var tc; -K.RightSide=tc=t.px;var uc;K.BottomSide=uc=t.bx;K.TopBottomSides=t.qx;K.LeftRightSides=t.ix;K.TopLeftSides=t.tx;K.TopRightSides=t.vx;K.BottomLeftSides=t.Zw;K.BottomRightSides=t.ax;K.NotTopSide=t.nx;K.NotLeftSide=t.lx;K.NotRightSide=t.mx;K.NotBottomSide=t.kx;var vc;K.AllSides=vc=t.Xw;function xc(){this.Xe=[1,0,0,1,0,0]}xc.prototype.copy=function(){var a=new xc;a.Xe[0]=this.Xe[0];a.Xe[1]=this.Xe[1];a.Xe[2]=this.Xe[2];a.Xe[3]=this.Xe[3];a.Xe[4]=this.Xe[4];a.Xe[5]=this.Xe[5];return a}; -function yc(a){this.type=a;this.r2=this.y2=this.x2=this.r1=this.y1=this.x1=0;this.rD=[]}yc.prototype.addColorStop=function(a,b){this.rD.push({offset:a,color:b})}; -function zc(a){this.fillStyle="#000000";this.font="10px sans-serif";this.globalAlpha=1;this.lineCap="butt";this.xw=0;this.lineJoin="miter";this.lineWidth=1;this.miterLimit=10;this.shadowBlur=0;this.shadowColor="rgba(0, 0, 0, 0)";this.shadowOffsetY=this.shadowOffsetX=0;this.strokeStyle="#000000";this.textAlign="start";this.path=[];this.Ki=new xc;this.stack=[];this.og=[];this.AF=this.hE=this.Rv=0;this.bw=a;this.II="http://www.w3.org/2000/svg";this.Bt=Ac(this,"svg",{width:this.bw.width+"px",height:this.bw.height+ -"px",KJ:"0 0 "+this.bw.width+" "+this.bw.height})}aa=zc.prototype;aa.arc=function(a,b,c,d,e,g){Ic(this,a,b,c,d,e,g)};aa.beginPath=function(){this.path=[]};aa.bezierCurveTo=function(a,b,c,d,e,g){this.path.push(["C",a,b,c,d,e,g])};aa.clearRect=function(){};aa.clip=function(){Jc(this,"clipPath",this.path,new xc)};aa.closePath=function(){this.path.push(["z"])};aa.createLinearGradient=function(a,b,c,d){var e=new yc("linear");e.x1=a;e.y1=b;e.x2=c;e.y2=d;return e};aa.createPattern=function(){}; -aa.createRadialGradient=function(a,b,c,d,e,g){var h=new yc("radial");h.x1=a;h.y1=b;h.r1=c;h.x2=d;h.y2=e;h.r2=g;return h}; -aa.drawImage=function(a,b,c,d,e,g,h,k,l){a=[b,c,d,e,g,h,k,l,a];b=this.Ki;e=a[8];c={x:0,y:0,width:e.naturalWidth,height:e.naturalHeight,href:e.src};d="";g=a[6]/a[2];h=a[7]/a[3];if(0!==a[4]||0!==a[5])d+=" translate("+a[4]+", "+a[5]+")";if(1!==g||1!==h)d+=" scale("+g+", "+h+")";if(0!==a[0]||0!==a[1])d+=" translate("+-a[0]+", "+-a[1]+")";if(0!==a[0]||0!==a[1]||a[2]!==e.naturalWidth||a[3]!==e.naturalHeight)e="CLIP"+this.Rv,this.Rv++,g=Ac(this,"clipPath",{id:e}),g.appendChild(Ac(this,"rect",{x:a[0],y:a[1], -width:a[2],height:a[3]})),this.Bt.appendChild(g),c["clip-path"]="url(#"+e+")";Kc(this,"image",c,b,d);this.addElement("image",c)};aa.fill=function(){Jc(this,"fill",this.path,this.Ki)};aa.fillRect=function(a,b,c,d){Lc(this,"fill",[a,b,c,d],this.Ki)};aa.fillText=function(a,b,c){a=[a,b,c];b=this.textAlign;"left"===b?b="start":"right"===b?b="end":"center"===b&&(b="middle");b={x:a[1],y:a[2],style:"font: "+this.font,"text-anchor":b};Kc(this,"fill",b,this.Ki);this.addElement("text",b,a[0])}; -aa.lineTo=function(a,b){this.path.push(["L",a,b])};aa.moveTo=function(a,b){this.path.push(["M",a,b])};aa.quadraticCurveTo=function(a,b,c,d){this.path.push(["Q",a,b,c,d])};aa.rect=function(a,b,c,d){this.path.push(["M",a,b],["L",a+c,b],["L",a+c,b+d],["L",a,b+d],["z"])}; -aa.restore=function(){this.Ki=this.stack.pop();this.path=this.stack.pop();var a=this.stack.pop();this.fillStyle=a.fillStyle;this.font=a.font;this.globalAlpha=a.globalAlpha;this.lineCap=a.lineCap;this.xw=a.xw;this.lineJoin=a.lineJoin;this.lineWidth=a.lineWidth;this.miterLimit=a.miterLimit;this.shadowBlur=a.shadowBlur;this.shadowColor=a.shadowColor;this.shadowOffsetX=a.shadowOffsetX;this.shadowOffsetY=a.shadowOffsetY;this.strokeStyle=a.strokeStyle;this.textAlign=a.textAlign}; -aa.save=function(){this.stack.push({fillStyle:this.fillStyle,font:this.font,globalAlpha:this.globalAlpha,lineCap:this.lineCap,xw:this.xw,lineJoin:this.lineJoin,lineWidth:this.lineWidth,miterLimit:this.miterLimit,shadowBlur:this.shadowBlur,shadowColor:this.shadowColor,shadowOffsetX:this.shadowOffsetX,shadowOffsetY:this.shadowOffsetY,strokeStyle:this.strokeStyle,textAlign:this.textAlign});for(var a=[],b=0;bb.offset?1:-1});for(k=0;k=2*Math.PI?(Ic(a,b,c,d,e,e+Math.PI,h),Ic(a,b,c,d,e+Math.PI,e+2*Math.PI,h),a.path.push(["M",l,g])):(b+=d*Math.cos(e),c+=d*Math.sin(e),k=180*k/Math.PI,e=h?0:1,h=180<=k==!!h?0:1,0!=a.path.length?a.path.push(["L",b,c]):a.path.push(["M",b,c]),a.path.push(["A",d,d,k,h,e,l,g]))}} -function Mc(a,b,c,d,e,g,h){var k=new xc;k.Xe=[b,c,d,e,g,h];b={};Kc(a,"g",b,k);k=a.addElement("g",b);a.og.push(k)} -aa.ab=function(){var a="SHADOW"+this.AF;this.AF++;var b=this.addElement("filter",{id:a,width:"250%",height:"250%"},null),c,d,e,g,h;if(0!=this.shadowOffsetX||0!=this.shadowOffsetY)c=Ac(this,"feGaussianBlur",{"in":"SourceAlpha",result:"blur",IJ:this.shadowBlur/2}),d=Ac(this,"feFlood",{"in":"blur",result:"flood","flood-color":this.shadowColor}),e=Ac(this,"feComposite",{"in":"flood",in2:"blur",operator:"in",result:"comp"}),g=Ac(this,"feOffset",{"in":"comp",result:"offsetBlur",dx:this.shadowOffsetX,dy:this.shadowOffsetY}), -h=Ac(this,"feMerge",{}),h.appendChild(Ac(this,"feMergeNode",{"in":"offsetBlur"})),h.appendChild(Ac(this,"feMergeNode",{"in":"SourceGraphic"})),b.appendChild(c),b.appendChild(d),b.appendChild(e),b.appendChild(g),b.appendChild(h);0=a)return 0;var b=J.xB;if(null===b){for(var b=[],c=0;2E3>=c;c++)b[c]=Math.sqrt(c);J.xB=b}return 1>a?(c=1/a,2E3>=c?1/b[c| -0]:Math.sqrt(a)):2E3>=a?b[a|0]:Math.sqrt(a)},I:function(a,b){var c=a-b;return 0.5>c&&-0.5c&&-5E-8=e&&(e=1E-6);var k,l,m,n;am-n)if(a-c>e||c-a>e){if(g=(d-b)/(c-a)*(g-a)+b,g-e<=h&&h<=g+e)return!0}else return!0;else if(b-d>e||d-b>e){if(h=(c- -a)/(d-b)*(h-b)+a,h-e<=g&&g<=h+e)return!0}else return!0;return!1},Mv:function(a,b,c,d,e,g,h,k,l,m,n,p){if(J.Cd(a,b,h,k,p,c,d)&&J.Cd(a,b,h,k,p,e,g))return J.Cd(a,b,h,k,p,m,n);var q=(a+c)/2,r=(b+d)/2,s=(c+e)/2,v=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(q+s)/2;c=(r+v)/2;var s=(s+e)/2,v=(v+g)/2,x=(d+s)/2,E=(c+v)/2;return J.Mv(a,b,q,r,d,c,x,E,l,m,n,p)||J.Mv(x,E,s,v,e,g,h,k,l,m,n,p)},kH:function(a,b,c,d,e,g,h,k,l){var m=(c+e)/2,n=(d+g)/2;l.x=(((a+c)/2+m)/2+(m+(e+h)/2)/2)/2;l.y=(((b+d)/2+n)/2+(n+(g+k)/2)/2)/2;return l}, -jH:function(a,b,c,d,e,g,h,k){var l=(c+e)/2,m=(d+g)/2;return kb(((a+c)/2+l)/2,((b+d)/2+m)/2,(l+(e+h)/2)/2,(m+(g+k)/2)/2)},Eo:function(a,b,c,d,e,g,h,k,l,m){if(J.Cd(a,b,h,k,l,c,d)&&J.Cd(a,b,h,k,l,e,g))wb(m,a,b,0,0),wb(m,h,k,0,0);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,v=(c+r)/2;J.Eo(a,b,n,p,d,c,s,v,l,m);J.Eo(s,v,q,r,e,g,h,k,l,m)}return m},ze:function(a,b,c,d,e,g,h,k,l,m){if(J.Cd(a,b,h,k,l,c,d)&&J.Cd(a,b,h,k,l,e,g))0=== -m.length&&m.push([a,b]),m.push([h,k]);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,v=(c+r)/2;J.ze(a,b,n,p,d,c,s,v,l,m);J.ze(s,v,q,r,e,g,h,k,l,m)}return m},JA:function(a,b,c,d,e,g,h,k,l,m){if(J.Cd(a,b,e,g,m,c,d))return J.Cd(a,b,e,g,m,k,l);var n=(a+c)/2,p=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var q=(n+c)/2,r=(p+d)/2;return J.JA(a,b,n,p,q,r,h,k,l,m)||J.JA(q,r,c,d,e,g,h,k,l,m)},HJ:function(a,b,c,d,e,g,h){h.x=((a+c)/2+(c+e)/2)/2;h.y=((b+ -d)/2+(d+g)/2)/2;return h},IA:function(a,b,c,d,e,g,h,k){if(J.Cd(a,b,e,g,h,c,d))wb(k,a,b,0,0),wb(k,e,g,0,0);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;J.IA(a,b,l,m,n,p,h,k);J.IA(n,p,c,d,e,g,h,k)}return k},xp:function(a,b,c,d,e,g,h,k){if(J.Cd(a,b,e,g,h,c,d))0===k.length&&k.push([a,b]),k.push([e,g]);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;J.xp(a,b,l,m,n,p,h,k);J.xp(n,p,c,d,e,g,h,k)}return k},ws:function(a,b,c,d,e,g,h,k,l,m,n,p,q,r){0>=q&& -(q=1E-6);if(J.Cd(a,b,h,k,q,c,d)&&J.Cd(a,b,h,k,q,e,g)){var s=(a-h)*(m-p)-(b-k)*(l-n);if(!s)return!1;q=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/s;s=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/s;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(bh)return!1}else if(ah)return!1;r.x=q;r.y=s;return!0}var s=(a+c)/2,v=(b+d)/2;c=(c+e)/2;d=(d+g)/2;e=(e+h)/2;g=(g+k)/2;var x=(s+c)/2,E=(v+d)/2;c=(c+e)/2;d=(d+g)/2;var F=(x+c)/2,G=(E+d)/2,L=(n-l)*(n-l)+(p-m)*(p-m),N=!1;J.ws(a,b,s,v,x,E,F,G, -l,m,n,p,q,r)&&(a=(r.x-l)*(r.x-l)+(r.y-m)*(r.y-m),a=q&&(q=1E-6);if(J.Cd(a,b,h,k,q,c,d)&&J.Cd(a,b,h,k,q,e,g)){q=(a-h)*(m-p)-(b-k)*(l-n);if(!q)return r;var s=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/q,v=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/q;if(s>=n)return r;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(ba)return r}else if(a< -h?(l=a,a=h):l=h,sa)return r;0q&&r--}else{var s=(a+c)/2,v=(b+d)/2,x=(c+e)/2,E=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(s+x)/2;c=(v+E)/2;var x=(x+e)/2,E=(E+g)/2,F=(d+x)/2,G=(c+E)/2,r=r+J.xs(a,b,s,v,d,c,F,G,l,m,n,p,q),r=r+J.xs(F,G,x,E,e,g,h,k,l,m,n,p,q)}return r},Zm:function(a,b,c,d,e,g,h){if(J.Ka(a,c)){var k;bc)return h.x=a,h.y=c,!1;h.x=a;h.y=d;return!0}if(J.Ka(b,d)){ac)return h.x= -c,h.y=b,!1;h.x=d;h.y=b;return!0}k=((a-e)*(a-c)+(b-g)*(b-d))/((c-a)*(c-a)+(d-b)*(d-b));if(-5E-6>k)return h.x=a,h.y=b,!1;if(1.000005c)return l.x=a,l.y=c,!1;l.x=a; -l.y=g;return!0}h=(d-b)/(c-a);if(J.Ka(k,h))return J.Zm(a,b,c,d,e,g,l),!1;e=(h*a-k*e+g-b)/(h-k);if(J.Ka(h,0)){ac)return l.x=c,l.y=b,!1;l.x=e;l.y=b;return!0}g=h*(e-a)+b;return J.Zm(a,b,c,d,e,g,l)},vJ:function(a,b,c,d,e){return J.$g(c.x,c.y,d.x,d.y,a.x,a.y,b.x,b.y,e)},tJ:function(a,b,c,d,e,g,h,k,l,m){function n(c,d){var e=(c-a)*(c-a)+(d-b)*(d-b);e(c>a?c-a:a-c)){q=1-(c-e)*(c-e)/(q*q);if(0>q)return l;q=Math.sqrt(q);d=-m*q+g;n(c,m*q+g);n(c,d)}else{c=(d-b)/(c-a);d=1/(q*q)+c*c/(m*m);k=2*c*(b-c*a)/(m*m)-2*c*g/(m*m)-2*e/(q*q);q=k*k-4*d*(2*c*a*g/(m*m)-2*b*g/(m*m)+g*g/(m*m)+e*e/(q*q)-1+(b-c*a)*(b-c*a)/(m*m));if(0>q)return l;q=Math.sqrt(q);m=(-k+q)/(2*d);n(m,c*m-c*a+b);q=(-k-q)/(2*d);n(q,c*q-c*a+b)}return l},ml:function(a,b,c,d,e,g,h,k,l){var m=1E21,n=a,p=b;if(J.$g(a,b,a, -d,e,g,h,k,l)){var q=(l.x-e)*(l.x-e)+(l.y-g)*(l.y-g);qm},ow:function(a,b,c){var d=b.x,e=b.y,g=c.x,h=c.y,k=a.left,l=a.right,m=a.top,n=a.bottom;return d===g?(e=m): -e===h?(d=k):a.Ia(b)||a.Ia(c)||J.nw(k,m,l,m,d,e,g,h)||J.nw(l,m,l,n,d,e,g,h)||J.nw(l,n,k,n,d,e,g,h)||J.nw(k,n,k,m,d,e,g,h)?!0:!1},nw:function(a,b,c,d,e,g,h,k){return 0>=J.Tv(a,b,c,d,e,g)*J.Tv(a,b,c,d,h,k)&&0>=J.Tv(e,g,h,k,a,b)*J.Tv(e,g,h,k,c,d)},Tv:function(a,b,c,d,e,g){c-=a;d-=b;a=e-a;b=g-b;g=a*d-b*c;0===g&&(g=a*c+b*d,0g&&(g=0)));return 0>g?-1:0a&&(a+=360);360<=a&&(a-=360);return a},AD:function(a,b,c,d,e,g){var h= -Math.PI;g||(d*=h/180,e*=h/180);g=dc,g=0>d,h,k;am;++m){b=0.5*(k+l);if(b===k||b===l)break;var n=a/(b+g),p=h/(b+e),n=n*n+p*p-1;if(0n)l=b;else break}c=g*c/(b+g)-c;d=e*d/(b+e)-d;c=Math.sqrt(c*c+d*d)}else c=Math.abs(d-b);else d=a*a-b*b,e=a*c,e=x-1?!0:null!==m[n+1].match(/[A-Za-z]/)}function d(){n++;return m[n]}function e(){var a=new C(parseFloat(d()),parseFloat(d()));p===p.toLowerCase()&&(a.x=v.x+a.x,a.y=v.y+a.y);return a}function g(){return v=e()}function h(){return s=e()}function k(){var a=[parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d())];c()||(a.push(parseFloat(d())),c()||a.push(parseFloat(d())));p===p.toLowerCase()&&(a[2]+=v.x,a[3]+=v.y);return a}function l(){return"c"!== -q.toLowerCase()&&"s"!==q.toLowerCase()?v:new C(2*v.x-s.x,2*v.y-s.y)}void 0===b&&(b=!1);"string"!==typeof a&&t.Vb(a,"string",M,"parse:str");a=a.replace(/,/gm," ");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([^\s])/gm,"$1 $2");a=a.replace(/([^\s])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([0-9])([+\-])/gm,"$1 $2");a= -a.replace(/(\.[0-9]*)(\.)/gm,"$1 $2");a=a.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,"$1 $3 $4 ");a=a.replace(/[\s\r\t\n]+/gm," ");a=a.replace(/^\s+|\s+$/g,"");for(var m=a.split(" "),n=-1,p="",q="",r=new C(0,0),s=new C(0,0),v=new C(0,0),x=m.length,E=t.u(),F,G=!1,L=!1,N=!0;!(n>=x-1);)if(q=p,p=d(),""!==p)switch(p.toUpperCase()){case "X":N=!0;L=G=!1;break;case "M":F=g();null===E.Qb||!0===N?(O(E,F.x,F.y,G,!1,!L),N=!1):E.moveTo(F.x,F.y);for(r=v;!c();)F=g(),E.lineTo(F.x,F.y);break;case "L":for(;!c();)F= -g(),E.lineTo(F.x,F.y);break;case "H":for(;!c();)v=F=new C((p===p.toLowerCase()?v.x:0)+parseFloat(d()),v.y),E.lineTo(v.x,v.y);break;case "V":for(;!c();)v=F=new C(v.x,(p===p.toLowerCase()?v.y:0)+parseFloat(d())),E.lineTo(v.x,v.y);break;case "C":for(;!c();){var W=e(),T=h();F=g();P(E,W.x,W.y,T.x,T.y,F.x,F.y)}break;case "S":for(;!c();)W=l(),T=h(),F=g(),P(E,W.x,W.y,T.x,T.y,F.x,F.y);break;case "Q":for(;!c();)T=h(),F=g(),cd(E,T.x,T.y,F.x,F.y);break;case "T":for(;!c();)s=T=l(),F=g(),cd(E,T.x,T.y,F.x,F.y); -break;case "B":for(;!c();)F=k(),E.arcTo(F[0],F[1],F[2],F[3],F[4],F[5],F[6]);break;case "A":for(;!c();){var W=Math.abs(parseFloat(d())),T=Math.abs(parseFloat(d())),U=parseFloat(d()),da=!!parseFloat(d()),R=!!parseFloat(d());F=g();dd(E,W,T,U,da,R,F.x,F.y)}break;case "Z":Q(E);v=r;break;case "F":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Uu]/))W++;else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?G=!0:ed(E);break;case "U":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Ff]/))W++; -else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?L=!0:E.ab(!1)}r=E.s;t.v(E);if(b)for(E=r.ub.k;E.next();)E.value.bp=!0;return r};function fd(a,b){for(var c=a.length,d=t.O(),e=0;e=a&&t.ha(a,"scale must be greater than zero",M,"scale:x"),0>=b&&t.ha(b,"scale must be greater than zero",M,"scale:y"));this.transform(a,0,0,b,0,0)}; -M.prototype.rotate=M.prototype.rotate=function(a,b,c){t.J(this);void 0===b&&(b=0);void 0===c&&(c=0);f&&(t.o(a,M,"rotate:angle"),t.o(b,M,"rotate:x"),t.o(c,M,"rotate:y"));var d=t.bh();d.reset();d.rotate(a,b,c);this.transform(d.m11,d.m12,d.m21,d.m22,d.dx,d.dy);t.Se(d)}; -M.prototype.transform=M.prototype.transform=function(a,b,c,d,e,g){var h,k;switch(this.type){case Vc:case Wc:case Xc:h=this.ec;k=this.nc;this.ec=h*a+k*c+e;this.nc=h*b+k*d+g;h=this.md;k=this.xd;this.md=h*a+k*c+e;this.xd=h*b+k*d+g;break;case Oc:for(var l=this.ub,m=l.length,n=0;n=a)return 0;if((e>h?e-h:h-e)<(g>k?g-k:k-g)){if(ge)return 0}else if(ee)return 0;return 0a||1a)return n=(a-m)/l,t.Da(c),new C(b[0]+(d[0]-b[0])*n,b[1]+(d[1]-b[1])*n);m+=l}b=d}t.Da(c);return null};t.g(M,"type",M.prototype.type);t.defineProperty(M,{type:"type"},function(){return this.ba},function(a){this.ba!==a&&(f&&t.tb(a,M,M,"type"),t.J(this,a),this.ba=a,this.Xa=!0)});t.g(M,"startX",M.prototype.na);t.defineProperty(M,{na:"startX"},function(){return this.ec},function(a){this.ec!==a&&(f&&t.o(a,M,"startX"),t.J(this,a),this.ec=a,this.Xa=!0)}); -t.g(M,"startY",M.prototype.oa);t.defineProperty(M,{oa:"startY"},function(){return this.nc},function(a){this.nc!==a&&(f&&t.o(a,M,"startY"),t.J(this,a),this.nc=a,this.Xa=!0)});t.g(M,"endX",M.prototype.D);t.defineProperty(M,{D:"endX"},function(){return this.md},function(a){this.md!==a&&(f&&t.o(a,M,"endX"),t.J(this,a),this.md=a,this.Xa=!0)});t.g(M,"endY",M.prototype.F);t.defineProperty(M,{F:"endY"},function(){return this.xd},function(a){this.xd!==a&&(f&&t.o(a,M,"endY"),t.J(this,a),this.xd=a,this.Xa=!0)}); -t.g(M,"figures",M.prototype.ub);t.defineProperty(M,{ub:"figures"},function(){return this.Fk},function(a){this.Fk!==a&&(f&&t.l(a,H,M,"figures"),t.J(this,a),this.Fk=a,this.Xa=!0)});t.defineProperty(M,{G:"spot1"},function(){return this.xi},function(a){f&&t.l(a,K,M,"spot1");t.J(this,a);this.xi=a.Z()});t.defineProperty(M,{H:"spot2"},function(){return this.yi},function(a){f&&t.l(a,K,M,"spot2");t.J(this,a);this.yi=a.Z()});t.A(M,{Mb:"bounds"},function(){this.mA()&&(this.pB(),this.kf());return this.au}); -t.g(M,"minSize",M.prototype.Ye);t.defineProperty(M,{Ye:"minSize"},function(){return this.de},function(a){this.de.N(a)||(f&&t.l(a,pa,M,"minSize"),a=a.Z(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.de=a)});function Pc(a,b,c){t.zc(this);void 0===c&&(c=!0);this.Ql=c;this.Rn=!0;void 0!==a?(f&&t.o(a,Pc,"sx"),this.ec=a):this.ec=0;void 0!==b?(f&&t.o(b,Pc,"sy"),this.nc=b):this.nc=0;this.Sr=new H(S);this.kv=this.Sr.Wb;this.Xa=!0}t.ia("PathFigure",Pc);t.Fh(Pc); -Pc.prototype.copy=function(){var a=new Pc;a.Ql=this.Ql;a.Rn=this.Rn;a.ec=this.ec;a.nc=this.nc;for(var b=this.Sr,c=b.length,d=a.Sr,e=0;ea&&(a+=360),this.uo=a):(void 0!==b?(f&&t.o(b,S,"ex"),this.ve=b):this.ve=0,void 0!==c?(f&&t.o(c,S,"ey"),this.we=c):this.we=0,void 0!==d&&(f&&t.o(d,S,"x1"),this.Pg=d),void 0!==e&&(f&&t.o(e,S,"y1"),this.Qg=e),void 0!==g&&(f&&t.o(g,S,"x2"),this.Tk=g),void 0!==h&&"number"===typeof h&&(f&&t.o(h,S,"y2"),this.Uk=h));this.Xa=!0;this.ph= -!1;this.cj=null}t.ia("PathSegment",S);t.Fh(S);S.prototype.copy=function(){var a=new S;a.ba=this.ba;this.ba===qd?(a.xe=this.xe,a.ye=this.ye,a.sn=this.sn,a.tn=this.tn,a.Ej=this.Ej,a.Fj=this.Fj):this.ba===rd?(a.xe=this.xe,a.ye=this.ye,a.ve=this.ve,a.we=this.we,a.Ej=this.Ej,a.Fj=this.Fj,a.uo=this.uo):(a.ve=this.ve,a.we=this.we,a.Pg=this.Pg,a.Qg=this.Qg,a.Tk=this.Tk,a.Uk=this.Uk);a.Xa=this.Xa;a.ph=this.ph;return a}; -S.prototype.equalsApprox=S.prototype.bk=function(a){if(!(a instanceof S)||this.type!==a.type||this.Ss!==a.Ss)return!1;switch(this.type){case md:case Zc:return J.I(this.D,a.D)&&J.I(this.F,a.F);case od:return J.I(this.D,a.D)&&J.I(this.F,a.F)&&J.I(this.vb,a.vb)&&J.I(this.Lb,a.Lb)&&J.I(this.oe,a.oe)&&J.I(this.pe,a.pe);case pd:return J.I(this.D,a.D)&&J.I(this.F,a.F)&&J.I(this.vb,a.vb)&&J.I(this.Lb,a.Lb);case qd:return J.I(this.yg,a.yg)&&J.I(this.Th,a.Th)&&J.I(this.Fa,a.Fa)&&J.I(this.Sa,a.Sa)&&J.I(this.radiusX, -a.radiusX)&&J.I(this.radiusY,a.radiusY);case rd:return this.pw===a.pw&&this.sw===a.sw&&J.I(this.Ww,a.Ww)&&J.I(this.D,a.D)&&J.I(this.F,a.F)&&J.I(this.radiusX,a.radiusX)&&J.I(this.radiusY,a.radiusY);default:return!1}}; -S.prototype.toString=function(a){switch(this.type){case md:a=void 0===a?"M"+this.D.toString()+" "+this.F.toString():"M"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case Zc:a=void 0===a?"L"+this.D.toString()+" "+this.F.toString():"L"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case od:a=void 0===a?"C"+this.vb.toString()+" "+this.Lb.toString()+" "+this.oe.toString()+" "+this.pe.toString()+" "+this.D.toString()+" "+this.F.toString():"C"+this.vb.toFixed(a)+" "+this.Lb.toFixed(a)+" "+this.oe.toFixed(a)+ -" "+this.pe.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case pd:a=void 0===a?"Q"+this.vb.toString()+" "+this.Lb.toString()+" "+this.D.toString()+" "+this.F.toString():"Q"+this.vb.toFixed(a)+" "+this.Lb.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case qd:a=void 0===a?"B"+this.yg.toString()+" "+this.Th.toString()+" "+this.Fa.toString()+" "+this.Sa.toString()+" "+this.radiusX:"B"+this.yg.toFixed(a)+" "+this.Th.toFixed(a)+" "+this.Fa.toFixed(a)+" "+this.Sa.toFixed(a)+ -" "+this.radiusX;break;case rd:a=void 0===a?"A"+this.radiusX.toString()+" "+this.radiusY.toString()+" "+this.Ww.toString()+" "+(this.sw?1:0)+" "+(this.pw?1:0)+" "+this.D.toString()+" "+this.F.toString():"A"+this.radiusX.toFixed(a)+" "+this.radiusY.toFixed(a)+" "+this.Ww.toFixed(a)+" "+(this.sw?1:0)+" "+(this.pw?1:0)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;default:a=this.type.toString()}return a+(this.ph?"z":"")};var md;S.Move=md=t.w(S,"Move",0);var Zc;S.Line=Zc=t.w(S,"Line",1);var od; -S.Bezier=od=t.w(S,"Bezier",2);var pd;S.QuadraticBezier=pd=t.w(S,"QuadraticBezier",3);var qd;S.Arc=qd=t.w(S,"Arc",4);var rd;S.SvgArc=rd=t.w(S,"SvgArc",4);S.prototype.freeze=function(){this.jb=!0;return this};S.prototype.Ua=function(){this.jb=!1;return this};S.prototype.close=S.prototype.close=function(){this.ph=!0;return this}; -function sd(a,b){if(null!==a.cj&&!1===b.Xa)return a.cj;var c=a.radiusX,d=a.radiusY;void 0===d&&(d=c);var e=a.sn,g=a.tn,h=J.AD(0,0,c=g(p,r)&&(q=Math.PI);1<=g(p,r)&&(q=0);0===m&&0q&&(q+=2*Math.PI);m=b>h?1:b/h; -r=b>h?h/b:1;b=J.AD(0,0,b>h?b:h,k,k+q,!0);h=t.bh();h.reset();h.translate(c,d);h.rotate(a.uo,0,0);h.scale(m,r);fd(b,h);t.Se(h);a.cj=b;return a.cj}t.g(S,"isClosed",S.prototype.Ss);t.defineProperty(S,{Ss:"isClosed"},function(){return this.ph},function(a){this.ph!==a&&(this.ph=a,this.Xa=!0)});t.g(S,"type",S.prototype.type);t.defineProperty(S,{type:"type"},function(){return this.ba},function(a){f&&t.tb(a,S,S,"type");t.J(this,a);this.ba=a;this.Xa=!0});t.g(S,"endX",S.prototype.D); -t.defineProperty(S,{D:"endX"},function(){return this.ve},function(a){f&&t.o(a,S,"endX");t.J(this,a);this.ve=a;this.Xa=!0});t.g(S,"endY",S.prototype.F);t.defineProperty(S,{F:"endY"},function(){return this.we},function(a){f&&t.o(a,S,"endY");t.J(this,a);this.we=a;this.Xa=!0});t.defineProperty(S,{vb:"point1X"},function(){return this.Pg},function(a){f&&t.o(a,S,"point1X");t.J(this,a);this.Pg=a;this.Xa=!0}); -t.defineProperty(S,{Lb:"point1Y"},function(){return this.Qg},function(a){f&&t.o(a,S,"point1Y");t.J(this,a);this.Qg=a;this.Xa=!0});t.defineProperty(S,{oe:"point2X"},function(){return this.Tk},function(a){f&&t.o(a,S,"point2X");t.J(this,a);this.Tk=a;this.Xa=!0});t.defineProperty(S,{pe:"point2Y"},function(){return this.Uk},function(a){f&&t.o(a,S,"point2Y");t.J(this,a);this.Uk=a;this.Xa=!0}); -t.defineProperty(S,{Fa:"centerX"},function(){return this.sn},function(a){f&&t.o(a,S,"centerX");t.J(this,a);this.sn=a;this.Xa=!0});t.defineProperty(S,{Sa:"centerY"},function(){return this.tn},function(a){f&&t.o(a,S,"centerY");t.J(this,a);this.tn=a;this.Xa=!0});t.defineProperty(S,{radiusX:"radiusX"},function(){return this.Ej},function(a){f&&t.o(a,S,"radiusX");0>a&&t.ha(a,">= zero",S,"radiusX");t.J(this,a);this.Ej=a;this.Xa=!0}); -t.defineProperty(S,{radiusY:"radiusY"},function(){return this.Fj},function(a){f&&t.o(a,S,"radiusY");0>a&&t.ha(a,">= zero",S,"radiusY");t.J(this,a);this.Fj=a;this.Xa=!0});t.defineProperty(S,{yg:"startAngle"},function(){return this.xe},function(a){this.xe!==a&&(t.J(this,a),f&&t.o(a,S,"startAngle"),a%=360,0>a&&(a+=360),this.xe=a,this.Xa=!0)}); -t.defineProperty(S,{Th:"sweepAngle"},function(){return this.ye},function(a){f&&t.o(a,S,"sweepAngle");t.J(this,a);360a&&(a=-360);this.ye=a;this.Xa=!0});t.defineProperty(S,{pw:"isClockwiseArc"},function(){return!!this.ye},function(a){t.J(this,a);this.ye=a?1:0;this.Xa=!0});t.defineProperty(S,{sw:"isLargeArc"},function(){return!!this.xe},function(a){t.J(this,a);this.xe=a?1:0;this.Xa=!0}); -t.defineProperty(S,{Ww:"xAxisRotation"},function(){return this.uo},function(a){f&&t.o(a,S,"xAxisRotation");a%=360;0>a&&(a+=360);t.J(this,a);this.uo=a;this.Xa=!0});function wd(){this.ea=null;this.sz=(new C(0,0)).freeze();this.Yx=(new C(0,0)).freeze();this.Yt=this.Nu=0;this.Bu="";this.yv=this.lu=!1;this.iu=this.$t=0;this.dj=this.su=!1;this.Aq=null;this.wv=0;this.eg=this.uv=null}t.ia("InputEvent",wd); -wd.prototype.copy=function(){var a=new wd;a.ea=this.ea;a.sz=this.Ac.copy().freeze();a.Yx=this.W.copy().freeze();a.Nu=this.Nu;a.Yt=this.Yt;a.Bu=this.Bu;a.lu=this.lu;a.yv=this.yv;a.$t=this.$t;a.iu=this.iu;a.su=this.su;a.dj=this.dj;a.Aq=this.Aq;a.wv=this.wv;a.uv=this.uv;a.eg=this.eg;return a}; -wd.prototype.toString=function(){var a="^";this.Tc&&(a+="M:"+this.Tc);this.button&&(a+="B:"+this.button);this.key&&(a+="K:"+this.key);this.Be&&(a+="C:"+this.Be);this.Zj&&(a+="D:"+this.Zj);this.Fe&&(a+="h");this.bubbles&&(a+="b");null!==this.W&&(a+="@"+this.W.toString());return a};t.g(wd,"diagram",wd.prototype.h);t.defineProperty(wd,{h:"diagram"},function(){return this.ea},function(a){this.ea=a});t.g(wd,"viewPoint",wd.prototype.Ac); -t.defineProperty(wd,{Ac:"viewPoint"},function(){return this.sz},function(a){t.l(a,C,wd,"viewPoint");this.sz.assign(a)});t.g(wd,"documentPoint",wd.prototype.W);t.defineProperty(wd,{W:"documentPoint"},function(){return this.Yx},function(a){t.l(a,C,wd,"documentPoint");this.Yx.assign(a)});t.g(wd,"modifiers",wd.prototype.Tc);t.defineProperty(wd,{Tc:"modifiers"},function(){return this.Nu},function(a){this.Nu=a});t.g(wd,"button",wd.prototype.button); -t.defineProperty(wd,{button:"button"},function(){return this.Yt},function(a){this.Yt=a});t.g(wd,"key",wd.prototype.key);t.defineProperty(wd,{key:"key"},function(){return this.Bu},function(a){this.Bu=a});t.g(wd,"down",wd.prototype.ak);t.defineProperty(wd,{ak:"down"},function(){return this.lu},function(a){this.lu=a});t.g(wd,"up",wd.prototype.aj);t.defineProperty(wd,{aj:"up"},function(){return this.yv},function(a){this.yv=a});t.g(wd,"clickCount",wd.prototype.Be); -t.defineProperty(wd,{Be:"clickCount"},function(){return this.$t},function(a){this.$t=a});t.g(wd,"delta",wd.prototype.Zj);t.defineProperty(wd,{Zj:"delta"},function(){return this.iu},function(a){this.iu=a});t.g(wd,"handled",wd.prototype.Fe);t.defineProperty(wd,{Fe:"handled"},function(){return this.su},function(a){this.su=a});t.g(wd,"bubbles",wd.prototype.bubbles);t.defineProperty(wd,{bubbles:"bubbles"},function(){return this.dj},function(a){this.dj=a});t.g(wd,"event",wd.prototype.event); -t.defineProperty(wd,{event:"event"},function(){return this.Aq},function(a){this.Aq=a});t.A(wd,{vw:"isTouchEvent"},function(){var a=window.TouchEvent;return a&&this.event instanceof a});t.g(wd,"timestamp",wd.prototype.timestamp);t.defineProperty(wd,{timestamp:"timestamp"},function(){return this.wv},function(a){this.wv=a});t.g(wd,"targetDiagram",wd.prototype.zg);t.defineProperty(wd,{zg:"targetDiagram"},function(){return this.uv},function(a){this.uv=a});t.g(wd,"targetObject",wd.prototype.Yd); -t.defineProperty(wd,{Yd:"targetObject"},function(){return this.eg},function(a){this.eg=a});t.g(wd,"control",wd.prototype.control);t.defineProperty(wd,{control:"control"},function(){return 0!==(this.Tc&1)},function(a){this.Tc=a?this.Tc|1:this.Tc&-2});t.g(wd,"shift",wd.prototype.shift);t.defineProperty(wd,{shift:"shift"},function(){return 0!==(this.Tc&4)},function(a){this.Tc=a?this.Tc|4:this.Tc&-5});t.g(wd,"alt",wd.prototype.alt); -t.defineProperty(wd,{alt:"alt"},function(){return 0!==(this.Tc&2)},function(a){this.Tc=a?this.Tc|2:this.Tc&-3});t.g(wd,"meta",wd.prototype.Xm);t.defineProperty(wd,{Xm:"meta"},function(){return 0!==(this.Tc&8)},function(a){this.Tc=a?this.Tc|8:this.Tc&-9});t.g(wd,"left",wd.prototype.left);t.defineProperty(wd,{left:"left"},function(){return 0===this.button},function(a){this.button=a?0:2});t.g(wd,"middle",wd.prototype.EI); -t.defineProperty(wd,{EI:"middle"},function(){return 1===this.button},function(a){this.button=a?1:0});t.g(wd,"right",wd.prototype.right);t.defineProperty(wd,{right:"right"},function(){return 2===this.button},function(a){this.button=a?2:0});function Fd(){this.ea=null;this.Rb="";this.$u=this.qv=null;this.Zt=!1}t.ia("DiagramEvent",Fd);Fd.prototype.copy=function(){var a=new Fd;a.ea=this.ea;a.Rb=this.Rb;a.qv=this.qv;a.$u=this.$u;a.Zt=this.Zt;return a}; -Fd.prototype.toString=function(){var a="*"+this.name;this.cancel&&(a+="x");null!==this.Sw&&(a+=":"+this.Sw.toString());null!==this.Fw&&(a+="("+this.Fw.toString()+")");return a};t.g(Fd,"diagram",Fd.prototype.h);t.defineProperty(Fd,{h:"diagram"},function(){return this.ea},function(a){this.ea=a});t.g(Fd,"name",Fd.prototype.name);t.defineProperty(Fd,{name:"name"},function(){return this.Rb},function(a){this.Rb=a});t.g(Fd,"subject",Fd.prototype.Sw); -t.defineProperty(Fd,{Sw:"subject"},function(){return this.qv},function(a){this.qv=a});t.g(Fd,"parameter",Fd.prototype.Fw);t.defineProperty(Fd,{Fw:"parameter"},function(){return this.$u},function(a){this.$u=a});t.g(Fd,"cancel",Fd.prototype.cancel);t.defineProperty(Fd,{cancel:"cancel"},function(){return this.Zt},function(a){this.Zt=a});function Gd(){this.clear()}t.ia("ChangedEvent",Gd);var Hd;Gd.Transaction=Hd=t.w(Gd,"Transaction",-1);var Id;Gd.Property=Id=t.w(Gd,"Property",0);var Jd; -Gd.Insert=Jd=t.w(Gd,"Insert",1);var Td;Gd.Remove=Td=t.w(Gd,"Remove",2);Gd.prototype.clear=Gd.prototype.clear=function(){this.gq=Id;this.hm=this.Mu="";this.Qu=this.Ru=this.Xu=this.co=this.Wu=this.ea=this.Md=null}; -Gd.prototype.copy=function(){var a=new Gd;a.Md=this.Md;a.ea=this.ea;a.gq=this.gq;a.Mu=this.Mu;a.hm=this.hm;a.Wu=this.Wu;var b=this.co;a.co=t.pb(b)&&"function"===typeof b.Z?b.Z():b;b=this.Xu;a.Xu=t.pb(b)&&"function"===typeof b.Z?b.Z():b;b=this.Ru;a.Ru=t.pb(b)&&"function"===typeof b.Z?b.Z():b;b=this.Qu;a.Qu=t.pb(b)&&"function"===typeof b.Z?b.Z():b;return a}; -Gd.prototype.toString=function(){var a="",a=this.od===Hd?a+"* ":this.od===Id?a+(null!==this.fa?"!m":"!d"):a+((null!==this.fa?"!m":"!d")+this.od);this.propertyName&&"string"===typeof this.propertyName&&(a+=" "+this.propertyName);this.rf&&this.rf!==this.propertyName&&(a+=" "+this.rf);a+=": ";this.od===Hd?null!==this.oldValue&&(a+=" "+this.oldValue):(null!==this.object&&(a+=ma(this.object)),null!==this.oldValue&&(a+=" old: "+ma(this.oldValue)),null!==this.Mf&&(a+=" "+this.Mf),null!==this.newValue&& -(a+=" new: "+ma(this.newValue)),null!==this.Kf&&(a+=" "+this.Kf));return a};Gd.prototype.getValue=Gd.prototype.Ba=function(a){return a?this.oldValue:this.newValue};Gd.prototype.getParam=function(a){return a?this.Mf:this.Kf};Gd.prototype.canUndo=Gd.prototype.canUndo=function(){return null!==this.fa||null!==this.h?!0:!1};Gd.prototype.undo=Gd.prototype.undo=function(){this.canUndo()&&(null!==this.fa?this.fa.changeState(this,!0):null!==this.h&&this.h.changeState(this,!0))}; -Gd.prototype.canRedo=Gd.prototype.canRedo=function(){return null!==this.fa||null!==this.h?!0:!1};Gd.prototype.redo=Gd.prototype.redo=function(){this.canRedo()&&(null!==this.fa?this.fa.changeState(this,!1):null!==this.h&&this.h.changeState(this,!1))};t.g(Gd,"model",Gd.prototype.fa);t.defineProperty(Gd,{fa:"model"},function(){return this.Md},function(a){this.Md=a});t.g(Gd,"diagram",Gd.prototype.h);t.defineProperty(Gd,{h:"diagram"},function(){return this.ea},function(a){this.ea=a});t.g(Gd,"change",Gd.prototype.od); -t.defineProperty(Gd,{od:"change"},function(){return this.gq},function(a){f&&t.tb(a,Gd,Gd,"change");this.gq=a});t.g(Gd,"modelChange",Gd.prototype.rf);t.defineProperty(Gd,{rf:"modelChange"},function(){return this.Mu},function(a){f&&t.j(a,"string",Gd,"modelChange");this.Mu=a});t.g(Gd,"propertyName",Gd.prototype.propertyName);t.defineProperty(Gd,{propertyName:"propertyName"},function(){return this.hm},function(a){f&&"string"!==typeof a&&t.l(a,Function,Gd,"propertyName");this.hm=a}); -t.g(Gd,"isTransactionFinished",Gd.prototype.rI);t.A(Gd,{rI:"isTransactionFinished"},function(){return this.gq===Hd&&("CommittedTransaction"===this.hm||"FinishedUndo"===this.hm||"FinishedRedo"===this.hm)});t.g(Gd,"object",Gd.prototype.object);t.defineProperty(Gd,{object:"object"},function(){return this.Wu},function(a){this.Wu=a});t.g(Gd,"oldValue",Gd.prototype.oldValue);t.defineProperty(Gd,{oldValue:"oldValue"},function(){return this.co},function(a){this.co=a});t.g(Gd,"oldParam",Gd.prototype.Mf); -t.defineProperty(Gd,{Mf:"oldParam"},function(){return this.Xu},function(a){this.Xu=a});t.g(Gd,"newValue",Gd.prototype.newValue);t.defineProperty(Gd,{newValue:"newValue"},function(){return this.Ru},function(a){this.Ru=a});t.g(Gd,"newParam",Gd.prototype.Kf);t.defineProperty(Gd,{Kf:"newParam"},function(){return this.Qu},function(a){this.Qu=a}); -function I(a){1b||(t.Fi(this.Ke,b),ze(this,"nodeDataArray",Td,"nodeDataArray",this,a,null,b,null),this.Ft(a)))}};I.prototype.removeNodeDataCollection=function(a){if(t.isArray(a))for(var b=t.yb(a),c=0;cb&&(b=t.yb(a));t.Ei(a,b,c);ze(this,"",Jd,"",a,null,c,null,b)}; -I.prototype.removeArrayItem=function(a,b){void 0===b&&(b=-1);f&&(t.ys(a,I,"removeArrayItem:arr"),t.o(b,I,"removeArrayItem:idx"));a===this.Ke&&t.m("Model.removeArrayItem should not be called on the Model.nodeDataArray");-1===b&&(b=t.yb(a)-1);var c=t.sb(a,b);t.Fi(a,b);ze(this,"",Td,"",a,c,null,b,null)};t.g(I,"nodeCategoryProperty",I.prototype.rl); -t.defineProperty(I,{rl:"nodeCategoryProperty"},function(){return this.ur},function(a){var b=this.ur;b!==a&&(Ae(a,I,"nodeCategoryProperty"),this.ur=a,this.i("nodeCategoryProperty",b,a))});I.prototype.getCategoryForNodeData=I.prototype.getCategoryForNodeData=function(a){if(null===a)return"";var b=this.ur;if(""===b)return"";b=t.hb(a,b);if(void 0===b)return"";if("string"===typeof b)return b;t.m("getCategoryForNodeData found a non-string category for "+a+": "+b);return""}; -I.prototype.setCategoryForNodeData=I.prototype.Mw=function(a,b){t.j(b,"string",I,"setCategoryForNodeData:cat");if(null!==a){var c=this.ur;if(""!==c)if(this.ie(a)){var d=t.hb(a,c);void 0===d&&(d="");d!==b&&(t.Ta(a,c,b),ze(this,"nodeCategory",Id,c,a,d,b))}else t.Ta(a,c,b)}}; -function V(a,b){2e||(t.Fi(d,e),this.Ji(a)&&(Ee(this,b,a),ze(this,"linkLabelKeys",Td,c,a,b,null)))}else void 0!==d&&t.m(c+" property is not an Array; cannot removeLabelKeyforLinkData: "+a)}}};t.g(V,"linkDataArray",V.prototype.Vi); -t.defineProperty(V,{Vi:"linkDataArray"},function(){return this.Mg},function(a){var b=this.Mg;if(b!==a){t.ys(a,V,"linkDataArray");this.Vd&&t.qc&&(null!==b&&t.Tm(b,"linkDataArray",this,!0),a=t.Tm(a,"linkDataArray",this,!1));for(var c=t.yb(a),d=0;db)){t.Fi(this.Mg,b);ze(this,"linkDataArray",Td,"linkDataArray",this,a,null,b,null);b=this.Om(a);Ee(this,b,a);b=this.Pm(a);Ee(this,b,a);var c=this.ll(a);if(t.isArray(c))for(var d=t.yb(c),e=0;ea.Cl&&t.trace("Ending transaction without having started a transaction: "+c);var d=1===a.Cl;d&&b&&a.isEnabled&&a.Lc("CommittingTransaction",c,a.gl);var e=0;if(0a.gk;e--)g=d.qa(e),null!==g&&g.clear(), -d.gd(e);e=a.rA;0===e&&(e=1);0=e&&(g=d.qa(0),null!==g&&g.clear(),d.gd(0),a.Jk--);d.add(b);a.Jk++;d.freeze();g=b}a.Lc("CommittedTransaction",c,g)}else{a.ji=!0;try{a.isEnabled&&null!==g&&(g.ap=!0,g.undo())}finally{a.Lc("RolledBackTransaction",c,g),a.ji=!1}null!==g&&g.clear()}a.hu=null;return!0}if(a.isEnabled&&!b&&null!==g){a=e;c=g.Eh;for(b=c.count-1;b>=a;b--)d=c.qa(b),null!==d&&d.undo(),c.Ua(),c.gd(b);c.freeze()}return!1} -Ud.prototype.canUndo=Ud.prototype.canUndo=function(){if(!this.isEnabled||0=this.Cl&&!this.hy&&(a=a.h,null!==a&&!1===a.Xf||t.trace("Change not within a transaction: "+c.toString()))}}; -Ud.prototype.skipsEvent=function(a){if(null===a||0>a.od.value)return!0;a=a.object;if(a instanceof X){if(a=a.layer,null!==a&&a.pc)return!0}else if(a instanceof pe&&a.pc)return!0;return!1};t.A(Ud,{FI:"models"},function(){return this.Iy.k});t.g(Ud,"isEnabled",Ud.prototype.isEnabled);t.defineProperty(Ud,{isEnabled:"isEnabled"},function(){return this.ii},function(a){this.ii=a});t.A(Ud,{SF:"transactionToUndo"},function(){return 0<=this.gk&&this.gk<=this.history.count-1?this.history.qa(this.gk):null}); -t.A(Ud,{RF:"transactionToRedo"},function(){return this.gkb.pg||(b.scale=a))};xa.prototype.canDecreaseZoom=function(a){void 0===a&&(a=1/this.It);t.o(a,xa,"canDecreaseZoom:factor");var b=this.h;if(null===b||b.Am!==$e)return!1;a*=b.scale;return ab.pg?!1:b.us}; -xa.prototype.increaseZoom=function(a){void 0===a&&(a=this.It);t.o(a,xa,"increaseZoom:factor");var b=this.h;null!==b&&b.Am===$e&&(a*=b.scale,ab.pg||(b.scale=a))};xa.prototype.canIncreaseZoom=function(a){void 0===a&&(a=this.It);t.o(a,xa,"canIncreaseZoom:factor");var b=this.h;if(null===b||b.Am!==$e)return!1;a*=b.scale;return ab.pg?!1:b.us};xa.prototype.resetZoom=function(a){void 0===a&&(a=this.GD);t.o(a,xa,"resetZoom:newscale");var b=this.h;null===b||ab.pg||(b.scale=a)}; -xa.prototype.canResetZoom=function(a){void 0===a&&(a=1);t.o(a,xa,"canResetZoom:newscale");var b=this.h;return null===b||ab.pg?!1:b.us};xa.prototype.zoomToFit=function(){var a=this.h;if(null!==a){var b=a.scale,c=a.position;b!==this.$C||isNaN(this.Dy)?(this.Dy=b,this.oC=c.copy(),a.zoomToFit(),a.Nh(),this.$C=a.scale):(a.scale=this.Dy,a.position=this.oC)}};xa.prototype.canZoomToFit=function(){var a=this.h;return null===a?!1:a.us}; -xa.prototype.collapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b)return!1;b.rc("Collapse Tree");var c=new H(y);if(a instanceof y&&a.Gc)a.collapseTree(),c.add(a);else for(a=b.selection.k;a.next();){var d=a.value;d instanceof y&&d.Gc&&(d.collapseTree(),c.add(d))}b.Ja("TreeCollapsed",c);b.De("Collapse Tree")}; -xa.prototype.canCollapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b||b.$a)return!1;if(a instanceof y){if(!a.Gc)return!1;if(0c||Math.abs(b.y-a.y)>d};t.A(qe,{h:"diagram"},function(){return this.ea}); -t.g(qe,"name",qe.prototype.name);t.defineProperty(qe,{name:"name"},function(){return this.Rb},function(a){this.Rb=a});t.g(qe,"isEnabled",qe.prototype.isEnabled);t.defineProperty(qe,{isEnabled:"isEnabled"},function(){return this.ii},function(a){this.ii=a});t.g(qe,"isActive",qe.prototype.ra);t.defineProperty(qe,{ra:"isActive"},function(){return this.eC},function(a){this.eC=a});t.g(qe,"transactionResult",qe.prototype.bf); -t.defineProperty(qe,{bf:"transactionResult"},function(){return this.WC},function(a){this.WC=a}); -function gf(){0e&&(e=k),l>g&&(g=l))}}Infinity===c?b.q(0,0,0,0):b.q(c,d,e-c,g-d)} -function Gf(a,b){if(null===a.pd){var c=a.h;if(null!==c&&!c.$a&&!c.Ue&&null!==a.wc){Df(a);c.Bb=!b;a.Zp=!b;a.Zi=c.Ec.W;for(var c=a.xD?c.copyParts(a.wc.Bl(),c,!0):c.copyParts(c.selection,c,!0),d=c.k;d.next();)d.value.location=d.key.location;d=t.wf();Ff(c,d);t.Pc(d);for(var d=new sa(w,Object),e=a.wc.k;e.next();){var g=e.key;g.Ud()&&g.canCopy()&&(g=c.Ba(g),null!==g&&(a.Zp&&(g.Xd="Tool"),g.Gf(),d.add(g,wf(g.location))))}for(c=c.k;c.next();)e=c.value,e instanceof A&&e.canCopy()&&d.add(e,wf());a.pd=d;hf(a, -d.Bl());null!==a.dd&&(c=a.dd,d=c.oj(),c.ql(a.Zi.x-(d.x+d.width/2),a.Zi.y-(d.y+d.height/2)))}}}function Cf(a){var b=a.h;null!==b&&(null!==a.pd&&(b.PA(a.pd.Bl(),!1),a.pd=null),b.Bb=!1,a.Zp=!1,a.Zi=b.Ec.W)}function Bf(a){if(null!==a.dd){if(a.Ni&&null!==a.vi){var b=a.vi;b.h.remove(b.Zd);b.h.remove(b.$d)}a.dd=null;a.vi=null}}function Qf(a,b,c){var d=a.h;if(null!==d){var e=a.Zi,g=t.O();g.assign(d.U.W);a.moveParts(b,g.At(e),c);t.B(g)}} -gf.prototype.moveParts=function(a,b,c){if(null!==a&&(t.l(a,sa,gf,"moveParts:parts"),0!==a.count)){var d=t.O(),e=t.O();e.assign(b);isNaN(e.x)&&(e.x=0);isNaN(e.y)&&(e.y=0);var g=this.rv;g||rf(this,a);for(var h=new H,k=new H(Qa),l=a.k;l.next();){var m=l.key;if(m.Ud()){var n=Rf(this,m,a);if(null!==n)h.add({Ic:m,info:l.value,cI:n});else if(!c||m.canMove()){n=l.value.point;d.assign(n);var p=this.computeMove(m,d.add(e),a);m.location=p;l.value.Zy=p.At(n)}}else l.key instanceof A&&k.add(l.ce)}for(c=h.k;c.next();)h= -c.value,n=h.info.point,d.assign(n),h.Ic.location=d.add(h.cI.Zy);n=t.O();c=t.O();for(k=k.k;k.next();)if(p=k.value,h=p.key,h instanceof A)if(h.Kp)if(l=h.da,m=h.ja,null!==this.dd&&this.Ni)p=p.value.point,a.add(h,wf(e)),l=b.x-p.x,m=b.y-p.y,h.ql(l,m);else{if(null!==l){n.assign(l.location);var q=a.Ba(l);null!==q&&n.At(q.point)}null!==m&&(c.assign(m.location),q=a.Ba(m),null!==q&&c.At(q.point));null!==l&&null!==m?n.Oi(c)?(p=p.value.point,l=d,l.assign(n),l.At(p),a.add(h,wf(n)),h.ql(l.x,l.y)):(h.Kp=!1,h.$b()): -(p=p.value.point,a.add(h,wf(null!==l?n:null!==m?c:b)),l=e.x-p.x,m=e.y-p.y,h.ql(l,m))}else if(null===h.da||null===h.ja)p=p.value.point,a.add(h,wf(b)),l=e.x-p.x,m=e.y-p.y,h.ql(l,m);t.B(d);t.B(e);t.B(n);t.B(c);g||zf(this,a)}};function Rf(a,b,c){b=b.fb;if(null!==b){a=Rf(a,b,c);if(null!==a)return a;a=c.Ba(b);if(null!==a)return a}return null} -function Df(a){if(null!==a.wc){for(var b=a.h,c=a.wc.k;c.next();){var d=c.key;d.Ud()&&(d.location=c.value.point)}for(c=a.wc.k;c.next();)if(d=c.key,d instanceof A&&d.Kp){var e=c.value.point;a.wc.add(d,wf());d.ql(-e.x,-e.y)}b.Nh()}} -gf.prototype.computeMove=function(a,b,c,d){void 0===d&&(d=new C);d.assign(b);if(null===a)return d;void 0===c&&(c=null);var e=b;if(this.cp&&(this.yE||null===c||this.h.U.aj)&&(e=t.O(),c=e,c.assign(b),null!==a)){var g=this.h;if(null!==g){var h=g.Yo,k=this.dA,g=k.width,k=k.height,l=this.jE,m=l.x,l=l.y,n=this.iE;if(null!==h){var p=h.Ms;isNaN(g)&&(g=p.width);isNaN(k)&&(k=p.height);h=h.cA;isNaN(m)&&(m=h.x);isNaN(l)&&(l=h.y)}h=t.ic(0,0);h.xt(0,0,g,k,n);J.Hs(b.x,b.y,m+h.x,l+h.y,g,k,c);t.B(h)}}c=null!==a.Sz? -a.Sz(a,b,e):e;k=a.TE;g=k.x;isNaN(g)&&(g=a.location.x);k=k.y;isNaN(k)&&(k=a.location.y);h=a.NE;m=h.x;isNaN(m)&&(m=a.location.x);h=h.y;isNaN(h)&&(h=a.location.y);d.q(Math.max(g,Math.min(c.x,m)),Math.max(k,Math.min(c.y,h)));e!==b&&t.B(e);return d};function Sf(a,b){if(null===b)return!0;var c=b.S;return null===c||c instanceof We||c.layer.pc||a.wc&&a.wc.contains(c)||a.pd&&a.pd.contains(c)?!0:!1} -function Tf(a,b,c,d){var e=a.h;if(null!==e){a.Ni&&(null!==a.dd&&(a.dd.da=null,a.dd.ja=null),Uf(a,!1));var g=!1;!1===a.mv&&(g=e.Bb,e.Bb=!0);var h=!1,k=Vf(e,b,null,function(b){return!Sf(a,b)}),l=e.U;l.Yd=k;var m=e.Bb;e.Bb=!0;if(k!==a.Kl){var n=a.Kl;a.bv=n;for(a.Kl=k;null!==n;){var p=n.uA;if(null!==p){if(k===n)break;if(null!==k&&k.Ti(n))break;p(l,n,k);h=!0;if(l.Fe)break}n=n.ga}for(n=a.bv;null!==k;){p=k.UE;if(null!==p){if(n===k)break;if(null!==n&&n.Ti(k))break;p(l,k,n);h=!0;if(l.Fe)break}k=k.ga}k=a.Kl}null=== -k&&(p=e.VE,null!==p&&(p(l),h=!0));a.doDragOver(b,k);e.Bb=m;h&&e.Nh();!1===a.mv&&(e.Bb=g);(e.hf||e.jf)&&(c||d)&&Wf(e,b)}}function Xf(a,b,c){var d=a.vi;if(null===d)return null;var e=a.h.Mm(b,d.FA,function(a){return d.findValidLinkablePort(a,c)});a=t.O();for(var g=Infinity,h=null,e=e.k;e.next();){var k=e.value;if(null!==k.S){var l=k.gb(Wb,a),l=b.$j(l);lc.ma)){var d=a.h;if(null!==d&&!d.$a&&(d=a.vi,null!==d)){var e=null,g=null;null===c.da&&(e=Xf(a,c.n(0),!1),null!==e&&(g=e.S));var h=null,k=null;null===c.ja&&(h=Xf(a,c.n(c.ma-1),!0),null!==h&&(k=h.S));if((null===g||g instanceof y)&&(null===k||k instanceof y)){var l=d.isValidLink(g,e,k,h);b?(c.xn=c.n(0).copy(),c.Bn=c.n(c.ma-1).copy(),c.Kp=!1,c.da=g,null!==e&&(c.nf=e.sd),c.ja=k,null!==h&&(c.Qf=h.sd)):l?Yf(d,g,e,k,h):Yf(d,null,null,null,null)}}}} -gf.prototype.doDragOver=function(){};function Zf(a,b){var c=a.h;if(null!==c&&null!==c.fa){a.Ni&&Uf(a,!0);yf(a);var d=Vf(c,b,null,function(b){return!Sf(a,b)}),e=c.U;e.Yd=d;if(null!==d)for(var g=d;null!==g;){var h=g.bt;if(null!==h&&(h(e,g),e.Fe))break;g=g.ga}else h=c.bt,null!==h&&h(e);a.doDropOnto(b,d);for(d=c.selection.k;d.next();)e=d.value,e instanceof y&&$f(c,e.wa)}}gf.prototype.doDropOnto=function(){}; -gf.prototype.doMouseMove=function(){if(this.ra){var a=this.h;if(null!==a&&null!==this.Jo&&null!==this.wc){var b=!1,c=!1;this.mayCopy()?(b=!0,Gf(this,!1),Qf(this,this.pd,!0)):this.mayMove()?(c=!0,Cf(this),Qf(this,this.wc,!0)):Cf(this);Tf(this,a.U.W,c,b)}}}; -gf.prototype.doMouseUp=function(){if(this.ra){this.wq=!0;var a=this.h;if(null!==a){var b=!1,c=this.mayCopy();c&&null!==this.pd?(Df(this),Cf(this),Gf(this,!0),Qf(this,this.pd,!0),null!==this.pd&&a.tF(this.pd.Bl())):(b=!0,Cf(this),this.mayMove()&&(Qf(this,this.wc,!0),this.mv=!1,Tf(this,a.U.W,!0,!1),this.mv=!0));Zf(this,a.U.W);if(this.ra){this.pd=null;if(b&&null!==this.wc)for(b=this.wc.k;b.next();){var d=b.key;d instanceof y&&(d=d.fb,null===d||null===d.placeholder||this.wc.contains(d)||d.Kz&&d.aa())}a.Rc(); -zf(this,this.wc);this.bf=c?"Copy":"Move";a.Ja(c?"SelectionCopied":"SelectionMoved",a.selection)}this.stopTool()}}};gf.prototype.mayCopy=function(){var a=this.h;if(null===a||a.$a||a.Ue||!a.wm||!a.Rj||(a.Sl?!a.U.Xm:!a.U.control))return!1;for(a=a.selection.k;a.next();){var b=a.value;if(b.Ud()&&b.canCopy())return!0}return null!==this.dd&&this.Ni&&this.dd.canCopy()?!0:!1}; -gf.prototype.mayMove=function(){var a=this.h;if(null===a||a.$a||!a.al)return!1;for(a=a.selection.k;a.next();){var b=a.value;if(b.Ud()&&b.canMove())return!0}return null!==this.dd&&this.Ni&&this.dd.canMove()?!0:!1};var Af=new H(gf),sf=null,tf=null;gf.prototype.mayCopyExternal=function(){var a=this.h;return null===a||!a.Bz||a.$a||a.Ue||!a.wm||null===a.fa?!1:!0}; -gf.prototype.doSimulatedDragEnter=function(){if(this.mayCopyExternal()){var a=sf;if(null!==a){Cf(a);Df(a);var b=a.h;null!==b&&a.oo.Q()&&(b.position=a.oo);null!==b&&xf(b)}Af.contains(this)||Af.add(this)}};gf.prototype.doSimulatedDragLeave=function(){sf.qw=!1;this.doCancel()};gf.prototype.doSimulatedDragOver=function(){if(this.mayCopyExternal()){var a=this.h;if(null!==a){var b=sf;null!==b&&null!==b.wc&&(ag(this,b.wc.Bl(),!1),Qf(this,this.pd,!1),Tf(this,a.U.W,!1,!0))}}}; -gf.prototype.doSimulatedDrop=function(){var a=sf;if(null!==a&&(a.wq=!0,Cf(this),this.mayCopyExternal())){var b=this.h;null!==b&&(this.rc("Drop"),ag(this,a.wc.Bl(),!0),Qf(this,this.pd,!0),null!==this.pd&&b.tF(this.pd.Bl()),this.bf="ExternalCopy",Zf(this,b.U.W),this.pd=null,b.Ja("ExternalObjectsDropped",b.selection),this.kk(),b.Rc())}}; -function ag(a,b,c){if(null===a.pd){var d=a.h;if(null!==d&&!d.$a&&!d.Ue&&null!==d.fa){d.Bb=!c;a.Zp=!c;a.Zi=d.U.W;d=d.copyParts(b,d,!0);c=t.wf();Ff(b,c);var e=c.x+c.width/2,g=c.y+c.height/2;t.Pc(c);var h=a.ov;c=new sa(w,Object);var k=t.O();for(b=b.k;b.next();){var l=b.value;if(l.Ud()&&l.canCopy()){var m=l.location,l=d.Ba(l);k.q(h.x-(e-m.x),h.y-(g-m.y));l.location=k;a.Zp&&(l.Xd="Tool");l.Gf();c.add(l,wf(k))}}t.B(k);for(d=d.k;d.next();)e=d.value,e instanceof A&&e.canCopy()&&c.add(e,wf());a.pd=c;hf(a, -c.Bl());null!==a.dd&&(c=a.dd,d=c.oj(),c.ql(a.Zi.x-(d.x+d.width/2),a.Zi.y-(d.y+d.height/2)))}}} -function bg(){0=d&&(d=0.1);for(var e=this,g=b.Mm(c,d,function(b){return e.findValidLinkablePort(b,a)},null,!0),d=Infinity,b=null,g=g.k;g.next();){var h=g.value,k=h.S;if(k instanceof y){var l=h.gb(Wb,t.O()),m=c.x-l.x,n=c.y-l.y;t.B(l);l=m*m+n*n;lc){if(null!==this.fc&&a===this.tg&&b===this.ug)return!0;var d=b.sd;null===d&&(d="");if(a.fw(d).count>=c)return!1}return!0}; -bg.prototype.isValidTo=function(a,b){if(null===a||null===b)return this.Rm;if(this.h.Za===this&&(null!==a.layer&&!a.layer.xm||!0!==b.kB))return!1;var c=b.NF;if(Infinity>c){if(null!==this.fc&&a===this.vg&&b===this.wg)return!0;var d=b.sd;null===d&&(d="");if(a.mg(d).count>=c)return!1}return!0};bg.prototype.isInSameNode=function(a,b){if(null===a||null===b)return!1;if(a===b)return!0;var c=a.S,d=b.S;return null!==c&&c===d}; -bg.prototype.isLinked=function(a,b){if(null===a||null===b)return!1;var c=a.S;if(!(c instanceof y))return!1;var d=a.sd;null===d&&(d="");var e=b.S;if(!(e instanceof y))return!1;var g=b.sd;null===g&&(g="");for(e=e.mg(g);e.next();)if(g=e.value,g.da===c&&g.nf===d)return!0;return!1}; -bg.prototype.isValidLink=function(a,b,c,d){if(!this.isValidFrom(a,b)||!this.isValidTo(c,d)||!(null===b||null===d||(b.cE&&d.MF||!this.isInSameNode(b,d))&&(b.bE&&d.LF||!this.isLinked(b,d)))||null!==this.fc&&(null!==a&&cg(this,a,this.fc)||null!==c&&cg(this,c,this.fc))||null!==a&&null!==c&&(null===a.data&&null!==c.data||null!==a.data&&null===c.data)||!ig(this,a,c,this.fc))return!1;if(null!==a){var e=a.op;if(null!==e&&!e(a,b,c,d,this.fc))return!1}if(null!==c&&(e=c.op,null!==e&&!e(a,b,c,d,this.fc)))return!1; -e=this.op;return null!==e?e(a,b,c,d,this.fc):!0};function cg(a,b,c){if(null===b)return!1;var d=b.Sc;if(null===d)return!1;if(d===c)return!0;var e=new ua(y);e.add(b);return jg(a,d,c,e)}function jg(a,b,c,d){if(b===c)return!0;var e=b.da;if(null!==e&&e.Ih&&(d.add(e),jg(a,e.Sc,c,d)))return!0;b=b.ja;return null!==b&&b.Ih&&(d.add(b),jg(a,b.Sc,c,d))?!0:!1} -function ig(a,b,c,d){if(null===b||null===c)return a.Rm;var e=a.h.aG;if(e!==kg){if(e===lg){if(null!==d&&!d.xc)return!0;for(e=c.Dd;e.next();){var g=e.value;if(g!==d&&g.xc&&g.ja===c)return!1}return!mg(a,b,c,d,!0)}if(e===ng){if(null!==d&&!d.xc)return!0;for(e=b.Dd;e.next();)if(g=e.value,g!==d&&g.xc&&g.da===b)return!1;return!mg(a,b,c,d,!0)}if(e===og)return b===c?a=!0:(e=new ua(y),e.add(c),a=pg(a,e,b,c,d)),!a;if(e===qg)return!mg(a,b,c,d,!1);if(e===rg)return b===c?a=!0:(e=new ua(y),e.add(c),a=sg(a,e,b,c, -d)),!a}return!0}function mg(a,b,c,d,e){if(b===c)return!0;if(null===b||null===c)return!1;for(var g=b.Dd;g.next();){var h=g.value;if(h!==d&&(!e||h.xc)&&h.ja===b&&(h=h.da,h!==b&&mg(a,h,c,d,e)))return!0}return!1}function pg(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.Dd;g.next();){var h=g.value;if(h!==e&&h.ja===c&&(h=h.da,h!==c&&pg(a,b,h,d,e)))return!0}return!1} -function sg(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.Dd;g.next();){var h=g.value;if(h!==e){var k=h.da,h=h.ja,k=k===c?h:k;if(k!==c&&sg(a,b,k,d,e))return!0}}return!1}t.g(bg,"linkValidation",bg.prototype.op);t.defineProperty(bg,{op:"linkValidation"},function(){return this.Nk},function(a){null!==a&&t.j(a,"function",bg,"linkValidation");this.Nk=a});t.g(bg,"portTargeted",bg.prototype.mt); -t.defineProperty(bg,{mt:"portTargeted"},function(){return this.FC},function(a){null!==a&&t.j(a,"function",bg,"portTargeted");this.FC=a});function Aa(){0b.Ls+1&&ch.$j(e)&&(k=b.points.copy(),k.gd(c), -b.points=k,b.Ae(),b.updateAdornments()),t.B(h)}a.Rc();this.bf=this.name;a.Ja("LinkReshaped",this.ts)}this.stopTool()};function Sg(a,b,c,d,e,g){return g?Math.abs(b.y-c.y)=a.x)c=0>=a.y?c+225:1<=a.y?c+135:c+180;else if(1<=a.x)0>=a.y?c+=315:1<=a.y&&(c+=45);else if(0>=a.y)c+=270;else if(1<=a.y)c+=90;else break a;0>c?c+=360:360<=c&&(c-=360);b.cursor=22.5>c?"e-resize":67.5>c?"se-resize":112.5>c?"s-resize":157.5>c?"sw-resize":202.5>c?"w-resize":247.5>c?"nw-resize":292.5>c?"n-resize":337.5>c?"ne-resize":"e-resize"}else if(b instanceof B)for(b=b.elements;b.next();)Ug(a, -b.value,c)}t.defineProperty(Tg,{Ns:"handleArchetype"},function(){return this.Hk},function(a){a&&t.l(a,X,Tg,"handleArchetype");this.Hk=a});t.A(Tg,{handle:"handle"},function(){return this.Xb});t.defineProperty(Tg,{Nc:"adornedObject"},function(){return this.La},function(a){a&&t.l(a,X,Tg,"adornedObject");this.La=a});Tg.prototype.canStart=function(){if(!this.isEnabled)return!1;var a=this.h;return null!==a&&!a.$a&&a.Ao&&a.U.left?null!==this.findToolHandleAt(a.Ec.W,this.name)?!0:!1:!1}; -Tg.prototype.doActivate=function(){var a=this.h;null!==a&&(this.Xb=this.findToolHandleAt(a.Ec.W,this.name),null!==this.Xb&&(this.La=this.Xb.S.Nc,this.eo=this.La.angle,this.CG.set(this.La.Ga),this.Oy.set(this.La.S.location),this.Yu.set(this.La.Ca),this.by=this.computeCellSize(),this.gy=this.computeMinSize(),this.ey=this.computeMaxSize(),a.Bd=!0,this.rc(this.name),this.ra=!0))};Tg.prototype.doDeactivate=function(){var a=this.h;null!==a&&(this.kk(),this.La=this.Xb=null,this.ra=a.Bd=!1)}; -Tg.prototype.doCancel=function(){this.La.Ca=this.Yu;this.La.S.location=this.Oy;this.stopTool()};Tg.prototype.doMouseMove=function(){var a=this.h;if(this.ra&&null!==a){var b=this.gy,c=this.ey,d=this.by,e=this.La.gE(a.U.W,t.O()),g=Xg;this.La instanceof Y&&(g=this.La.kw,g===Yg&&(g=this.La.Ra.kc));b=this.computeResize(e,this.Xb.alignment,b,c,d,!(g===Zg||g===$g||a.U.shift));this.resize(b);a.Nh();t.B(e)}}; -Tg.prototype.doMouseUp=function(){var a=this.h;if(this.ra&&null!==a){var b=this.gy,c=this.ey,d=this.by,e=this.La.gE(a.U.W,t.O()),g=Xg;this.La instanceof Y&&(g=this.La.kw,g===Yg&&(g=this.La.Ra.kc));b=this.computeResize(e,this.Xb.alignment,b,c,d,!(g===Zg||g===$g||a.U.shift));this.resize(b);t.B(e);a.Rc();this.bf=this.name;a.Ja("PartResized",this.La,this.Yu)}this.stopTool()}; -Tg.prototype.resize=function(a){if(null!==this.h){var b=this.La.S,c=b.position.copy(),d=this.La.Ga.copy(),e=this.La.jl(),g=this.La.fk();360<=e?e-=360:0>e&&(e+=360);var h=Math.PI*e/180,k=Math.cos(h),h=Math.sin(h),l=a.width-d.width,d=a.height-d.height,m=90e?1:0;c.x+=g*((a.x+l*m)*k-(a.y+d*(0e?1:0))*h);c.y+=g*((a.x+l*(180e?1:0))*h+(a.y+d*m)*k);this.La.Ca=a.size;b.Gf();b.move(c)}}; -Tg.prototype.computeResize=function(a,b,c,d,e,g){b.qd()&&(b=Wb);var h=this.La.Ga,k=h.x,l=h.y,m=h.x+h.width,n=h.y+h.height,p=1;if(!g){var p=h.width,q=h.height;0>=p&&(p=1);0>=q&&(q=1);p=q/p}q=t.O();J.Hs(a.x,a.y,k,l,e.width,e.height,q);a=h.copy();0>=b.x?0>=b.y?(a.x=Math.max(q.x,m-d.width),a.x=Math.min(a.x,m-c.width),a.width=Math.max(m-a.x,c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.width=Math.max(Math.min(q.x-k,d.width),c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y, -n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=n-a.y,g||(a.width= -a.height/p,a.x=k+0.5*(m-k-a.width))):1<=b.y&&(a.height=Math.max(Math.min(q.y-l,d.height),c.height),g||(a.width=a.height/p,a.x=k+0.5*(m-k-a.width)));t.B(q);return a};Tg.prototype.computeMinSize=function(){var a=this.La.Ye.copy(),b=this.Ye;!isNaN(b.width)&&b.width>a.width&&(a.width=b.width);!isNaN(b.height)&&b.height>a.height&&(a.height=b.height);return a}; -Tg.prototype.computeMaxSize=function(){var a=this.La.He.copy(),b=this.He;!isNaN(b.width)&&b.widtha&&(a+=360));var b=Math.min(Math.abs(this.FF),180),c=Math.min(Math.abs(this.EF),b/2);!this.h.U.shift&&0b-c&&(a=(Math.floor(a/b)+1)*b));360<=a?a-=360:0>a&&(a+=360);return a};t.g(ah,"snapAngleMultiple",ah.prototype.FF); -t.defineProperty(ah,{FF:"snapAngleMultiple"},function(){return this.bz},function(a){this.bz!==a&&(f&&t.j(a,"number",ah,"snapAngleMultiple"),this.bz=a)});t.g(ah,"snapAngleEpsilon",ah.prototype.EF);t.defineProperty(ah,{EF:"snapAngleEpsilon"},function(){return this.az},function(a){this.az!==a&&(f&&t.j(a,"number",ah,"snapAngleEpsilon"),this.az=a)});t.g(ah,"originalAngle",ah.prototype.KI);t.A(ah,{KI:"originalAngle"},function(){return this.eo}); -function ch(){0e.right&&(c.x-=d.width+5);c.xe.bottom&&(c.y-=d.height+5);c.ye.right&&(c.x-=d.width+5);c.xe.bottom?c.y-(d.height+5):c.y+20;c.y=a)return b;for(var c=0,d=0,e=0,g=0,h=0,k=this.cb.k;k.next();){var l=k.value;l instanceof z?e++:l instanceof y?d++:l instanceof A?g++:l instanceof We?h++:c++}k="";0=d.count)a=d.count;else if(d.qa(a)===b)return-1;d.Ad(a,b);b.Ps();d=this.h;null!==d&&(c?d.pa():d.Qm(b));b instanceof z&&this.Pw(b);return a};aa.Te=function(a,b,c){var d=this.cb;if(0>a||a>=d.length){if(a=d.indexOf(b),0>a)return-1}else if(d.qa(a)!==b&&(a=d.indexOf(b),0>a))return-1;b.Qs();d.gd(a);d=this.h;null!==d&&(c?d.pa():d.Te(b));b.Vn=null;return a}; -aa.Pw=function(a){for(;null!==a;){if(a.layer===this){var b=a;if(b.Hc.next()){for(var c=-1,d=-1,e=this.cb.p,g=e.length,h=0;hd&&k.fb===b&&(d=h,0<=c))break}!(0>d)&&da||1=a)return b;for(var c=this.Kb.k;c.next();)b+="\n "+c.value.toString(a-1);return b};u.prototype.checkProperties=function(){return t.lH(this)};u.fromDiv=function(a){var b=a;"string"===typeof a&&(b=document.getElementById(a));return b instanceof HTMLDivElement&&b.ea instanceof u?b.ea:null};t.g(u,"div",u.prototype.Mi); -t.defineProperty(u,{Mi:"div"},function(){return this.Ab},function(a){null!==a&&t.l(a,HTMLDivElement,u,"div");if(this.Ab!==a){var b=this.Ab;if(null!==b){delete b.ea;b.innerHTML="";null!==this.Pa&&(this.Pa.ea=null,this.Pa.removeEventListener("touchstart",this.QF,!1),this.Pa.removeEventListener("touchmove",this.PF,!1),this.Pa.removeEventListener("touchend",this.OF,!1));b=this.xv;if(null!==b){for(var c=b.vC.p,d=c.length,e=0;e=d&&t.Qa(t.Gv)!==t.Qa("7da71ca0ad381e90")&&(d=a[t.Qa("73a612b6fb191d")](t.Qa("76a715b2ef3e149757")));if(this.jj=!(0a.scale&&h.canIncreaseZoom()||gc)b.preventDefault();else{a.em=null;return}if(null!==a.em){var d=a.Pa,e=d.getBoundingClientRect();b=new C(b.pageX-window.scrollX-d.width/e.width*e.left,b.pageY-window.scrollY-d.height/e.height*e.top);d=a.Wh;c*=a.em;e=a.lg;if(c>a.scale&&e.canIncreaseZoom()||cl&&(a.position= -new C(-(a.Hj.scrollWidth-a.tc)+this.scrollLeft-a.tc/r+a.vc.right,a.position.y))),this.KC&&a.jf&&(bn&&(a.position=new C(a.position.x,-(a.Ij.scrollHeight-a.sc)+this.scrollTop-a.sc/r+a.vc.bottom))),t.B(s),ai(a),a.gv=!1,a.rj=!1,b=a.vc,c=a.nb,k=b.right,l=c.right,m=b.bottom,n=c.bottom,p=b.x,q=c.x,b=b.y,c=c.y,e>=d&&p>=q&&k<=l&&(a.Xy.style.width="1px"),h>=g&&b>=c&&m<=n&&(a.Yy.style.height="1px")}}else bi(this.ea)}; -u.prototype.BC=function(){this.ea.isEnabled?this.ea.Wy=!0:bi(this.ea)};u.prototype.computeBounds=u.prototype.kf=function(){0a.pg&&(l=a.pg),l):b===oi?(l=k>h?(g-a.gf)/c:(e-a.gf)/d,1a.pg&&(l=a.pg),l):a.scale}}u.prototype.zoomToFit=u.prototype.zoomToFit=function(){this.scale=fi(this,ni)}; -u.prototype.zoomToRect=function(a,b){void 0===b&&(b=ni);var c=a.width,d=a.height;if(!(0===c||0===d||isNaN(c)&&isNaN(d))){var e=1;if(b===ni||b===oi)if(isNaN(c))e=this.nb.height*this.scale/d;else if(isNaN(d))e=this.nb.width*this.scale/c;else var e=this.tc,g=this.sc,e=b===oi?g/d>e/c?(g-(this.Ol?this.gf:0))/d:(e-(this.Pl?this.gf:0))/c:Math.min(g/d,e/c);this.scale=e;this.position=new C(a.x,a.y)}}; -u.prototype.alignDocument=function(a,b){this.qj&&hi(this,this.kf());var c=this.vc,d=this.nb,e=this.lc;this.lc=!0;this.position=new C(c.x+(a.x*c.width+a.offsetX)-(b.x*d.width-b.offsetX),c.y+(a.y*c.height+a.offsetY)-(b.y*d.height-b.offsetY));this.lc=e;this.pa()}; -function gi(a,b,c,d,e,g){g.rd()&&(d>c.width&&(b.x=c.x+(g.x*c.width+g.offsetX)-(g.x*d-g.offsetX)),e>c.height&&(b.y=c.y+(g.y*c.height+g.offsetY)-(g.y*e-g.offsetY)));dc.left?b.x=c.left:b.xc.top?b.y=c.top:b.yc.touches.length)&&c.preventDefault();c.cancelBubble=!0;return!1} -u.prototype.xI=function(a){if(this.ea.isEnabled){var b=this.ea.cc;Wh(this.ea,this.ea,a,b,!1);b.key=String.fromCharCode(a.which);b.ak=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del";break;case 48:b.key="0";break;case 187:b.key="Add";break;case 189:b.key="Subtract"; -break;case 107:b.key="Add";break;case 109:b.key="Subtract";break;case 27:b.key="Esc"}this.ea.doKeyDown();return 187!==a.which&&189!==a.which&&48!==a.which&&107!==a.which&&109!==a.which||!0!==a.ctrlKey?ga(this.ea,b,a):(a.cancelBubble=!0,void 0!==a.preventDefault?a.preventDefault():a.returnValue=!1,Event.stop&&(t.m("Event.stop can fire for this browser"),Event.stop(a)),void 0!==a.stopPropagation&&a.stopPropagation(),!1)}}; -u.prototype.yI=function(a){if(this.ea.isEnabled){var b=this.ea.cc;Wh(this.ea,this.ea,a,b,!1);b.key=String.fromCharCode(a.which);b.aj=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del"}this.ea.doKeyUp();return ga(this.ea,b,a)}}; -u.prototype.Ig=function(a){var b=this.Pa;if(null===b)return new C(0,0);var c=b.getBoundingClientRect(),d=a.clientX-b.width/c.width*c.left;a=a.clientY-b.height/c.height*c.top;return null!==this.bd?(d=new C(d,a),$a(d,this.bd),d):new C(d,a)};t.g(u,"renderingHints",u.prototype.gF);t.defineProperty(u,{gF:"renderingHints"},function(){return this.GC},function(a){this.GC=a;this.ot()});u.prototype.invalidateDocumentBounds=u.prototype.Rc=function(){this.qj=!0;this.Nf()}; -function pi(a){a.Jd||ci(a);a.qj&&hi(a,a.kf());ei(a);for(a=a.ho.k;a.next();)pi(a.value)}u.prototype.redraw=u.prototype.ot=function(){this.lc||this.Jd||(this.pa(),qi(this),ai(this),this.Rc(),this.Nh())};u.prototype.isUpdateRequested=function(){return this.hg};u.prototype.delayInitialization=function(a){ri(this);this.Xf=!1;a&&setTimeout(a,1)}; -u.prototype.requestUpdate=u.prototype.Nf=function(a){void 0===a&&(a=!1);if(!0!==this.hg&&!(this.lc||!1===a&&this.Jd)){this.hg=!0;var b=this;requestAnimationFrame(function(){b.hg&&b.Nh()})}};u.prototype.maybeUpdate=u.prototype.Nh=function(){if(!this.Bq||this.hg)this.Bq&&(this.Bq=!1),ri(this)}; -function ri(a){if(!a.Jd&&(a.hg=!1,null!==a.Ab)){a.Jd=!0;a.sA();!a.lc&&a.rj&&(bi(a)||bi(a));null!==a.Xc&&(a.Xc.visible&&!a.qu&&(si(a),a.qu=!0),!a.Xc.visible&&a.qu&&(a.qu=!1));ci(a);var b=!1;if(!a.Xf||a.Tt)a.Xf?ti(a,!a.ju):(a.rc("Initial Layout"),ti(a,!1)),b=!0;a.ju=!1;ci(a);a.$y||pi(a);b&&(a.Xf||(ui(a),si(a)),a.Ja("LayoutCompleted"));vi(a);ci(a);a.lc||!a.rj||bi(a)||(bi(a),ci(a));b&&!a.Xf&&(a.Xf=!0,a.De("Initial Layout"),a.Aa.clear(),setTimeout(function(){a.hk=!1},1));a.Re();a.Jd=!1}} -function ui(a){if(a.Kk!==$e)a.scale=fi(a,a.Kk);else if(a.Fl!==$e)a.scale=fi(a,a.Fl);else{var b=a.tE;isFinite(b)&&0b;b++){var c=a.Yf.k;if(null===c||0===a.Yf.count)break;a.Yf=new ua(X);var d=a,e=a.Yf;for(c.reset();c.next();){var g=c.value;!g.Ud()||g instanceof z||(g.nl()?(Bh(g,Infinity,Infinity),g.Dc()):e.add(g))}for(c.reset();c.next();)g=c.value,g instanceof z&&wi(d,g);for(c.reset();c.next();)d=c.value,d instanceof A&&(d.nl()?(Bh(d,Infinity,Infinity),d.Dc(),d.zw()):e.add(d));for(c.reset();c.next();)d=c.value,d instanceof We&&(d.nl()?(Bh(d,Infinity,Infinity),d.Dc()): -e.add(d))}}function wi(a,b){for(var c=b.Hc,d=t.Cb();c.next();){var e=c.value;e instanceof z?(xi(e)||yi(e)||zi(e))&&wi(a,e):e instanceof A?d.push(e):(Bh(e,Infinity,Infinity),e.Dc())}c=d.length;for(e=0;e=l[0]&&c>=l[1]&&b+d<=l[0]+l[2]&&c+e<=l[1]+l[3])return!1;b<=l[0]&&c<=l[1]&&b+d>=l[0]+l[2]&&c+e>=l[1]+l[3]?(g[k][2]=0,g[k][3]=0):b>=l[0]&&b=l[1]&&c+e<=l[1]+l[3]?(d=b+d-(l[0]+l[2]),b=l[0]+l[2],k=-1):b+d>l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c+e<=l[1]+l[3]?(d=l[0]-b,k=-1):b>=l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c= -l[0]&&b+d<=l[0]+l[2]&&c+e>l[1]&&c+e<=l[1]+l[3]?(e=l[1]-c,k=-1):g[k][0]>=b&&g[k][0]=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]-=b+d-g[k][0],g[k][0]=b+d,k=-1):g[k][0]+g[k][2]>b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]=b-g[k][0],k=-1):g[k][0]>=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]+g[k][3]>c&&g[k][1]+g[k][3]<=c+e&&(g[k][3]=c-g[k][1],k=-1)}for(k=0;kk&&c/W>l||(a.nE&&a.hf&&(q+1E+1&&(n=(x-E)*W+a.tc+"px",a.Hj.scrollLeft=a.position.x*W)),a.oE&&a.jf&&(r+1N+1&&(p=(L-N)*W+a.sc+"px",a.Ij.scrollTop=a.position.y*W)));m="1px"!==n;c="1px"!==p;m!==a.Ol&&(a.sc="1px"===n?a.sc+a.gf:Math.max(a.sc-a.gf,1),b.height=a.sc,h=!0);a.Ol=m;a.Xy.style.width=n;c!==a.Pl&&(a.tc= -"1px"===p?a.tc+a.gf:Math.max(a.tc-a.gf,1),b.width=a.tc,h=!0);a.Pl=c;a.Yy.style.height=p;h&&ca(a);m=a.tc;c=a.sc;a.Ij.style.height=c+"px";a.Ij.style.width=m+(a.Pl?a.gf:0)+"px";a.Hj.style.width=m+"px";a.Hj.style.height=c+(a.Ol?a.gf:0)+"px";a.Wy=!1;return d!==m||e!==c?(n=a.nb,a.kt(g,n,h?!0:void 0),!1):!0}}} -u.prototype.add=u.prototype.add=function(a){t.l(a,w,u,"add:part");var b=a.h;if(b!==this){null!==b&&t.m("Cannot add part "+a.toString()+" to "+this.toString()+". It is already a part of "+b.toString());var c=a.Xd,b=this.il(c);null===b&&(b=this.il(""));null===b&&t.m('Cannot add a Part when unable find a Layer named "'+c+'" and there is no default Layer');a.layer!==b&&(c=a.h===this?b.Qm(99999999,a,!0):b.Qm(99999999,a),0<=c&&this.Uc(Jd,"parts",b,null,a,null,c),b.pc||this.Rc(),a.K(Hi),c=a.fp,null!==c&& -c(a,null,b))}};u.prototype.Qm=function(a){if(a instanceof y){if(this.Vu.add(a),a instanceof z){var b=a.fb;null===b?this.Vk.add(a):b.cm.add(a);b=a.Tb;null!==b&&(b.h=this)}}else a instanceof A?this.Eu.add(a):a instanceof We||this.cb.add(a);a.wb&&a.aa();if(b=a.data){a instanceof We||(a instanceof A?this.Dk.add(b,a):this.di.add(b,a));var c=this;Ii(a,function(a){Ji(c,a)})}!0!==yi(a)&&!0!==zi(a)||this.Yf.add(a);Ki(a,!0,this);a.zb()&&(a.wa.Q()&&this.pa(Jh(a,a.wa)),this.Rc())}; -u.prototype.Te=function(a){a.Ae();if(a instanceof y){if(this.Vu.remove(a),a instanceof z){var b=a.fb;null===b?this.Vk.remove(a):b.cm.remove(a);b=a.Tb;null!==b&&(b.h=null)}}else a instanceof A?this.Eu.remove(a):a instanceof We||this.cb.remove(a);if(b=a.data){a instanceof We||(a instanceof A?this.Dk.remove(b):this.di.remove(b));var c=this;Ii(a,function(a){Li(c,a)})}this.Yf.remove(a);a.zb()&&(a.wa.Q()&&this.pa(Jh(a,a.wa)),this.Rc())}; -u.prototype.remove=u.prototype.remove=function(a){t.l(a,w,u,"remove:part");a.bb=!1;var b=a.layer;if(null!==b&&b.h===this){a.K(Mi);a.Jm();var c=b.Te(-1,a);0<=c&&this.Uc(Td,"parts",b,a,null,c,null);c=a.fp;null!==c&&c(a,b,null);b.pc||this.Rc()}};u.prototype.removeParts=u.prototype.PA=function(a,b){if(a===this.selection){var c=new ua;c.Me(a);a=c}for(c=a.k;c.next();){var d=c.value;d.h===this&&(b&&!d.canDelete()||this.remove(d))}}; -u.prototype.copyParts=u.prototype.copyParts=function(a,b,c){return this.lg.copyParts(a,b,c)};u.prototype.moveParts=u.prototype.moveParts=function(a,b,c){t.l(b,C,u,"moveParts:offset");var d=this.Db;if(null!==d){d=d.ke;null===d&&(d=new gf,d.h=this);var e=new sa(w,Object);if(a)a=a.k;else{for(a=this.sl;a.next();)vf(d,e,a.value,c);for(a=this.Yi;a.next();)vf(d,e,a.value,c);a=this.links}for(;a.next();)vf(d,e,a.value,c);d.moveParts(e,b,c)}}; -function Ni(a,b,c){t.l(b,pe,u,"addLayer:layer");null!==b.h&&b.h!==a&&t.m("Cannot share a Layer with another Diagram: "+b+" of "+b.h);null===c?null!==b.h&&t.m("Cannot add an existing Layer to this Diagram again: "+b):(t.l(c,pe,u,"addLayer:existingLayer"),c.h!==a&&t.m("Existing Layer must be in this Diagram: "+c+" not in "+c.h),b===c&&t.m("Cannot move a Layer before or after itself: "+b));if(b.h!==a){b=b.name;a=a.Kb;c=a.count;for(var d=0;dd&&this.Rc()}; -u.prototype.addLayerAfter=function(a,b){Ni(this,a,b);a.qe(this);var c=this.Kb,d=c.indexOf(a);0<=d&&(c.remove(a),null!==this.Md&&this.Uc(Td,"layers",this,a,null,d,null));for(var e=c.count,g=0;gd&&this.Rc()}; -u.prototype.removeLayer=function(a){t.l(a,pe,u,"removeLayer:layer");a.h!==this&&t.m("Cannot remove a Layer from another Diagram: "+a+" of "+a.h);if(""!==a.name){var b=this.Kb,c=b.indexOf(a);if(b.remove(a)){for(b=a.cb.copy().k;b.next();){var d=b.value,e=d.Xd;d.Xd=e!==a.name?e:""}null!==this.Md&&this.Uc(Td,"layers",this,a,null,c,null);this.pa();this.Rc()}}};u.prototype.findLayer=u.prototype.il=function(a){for(var b=this.Um;b.next();){var c=b.value;if(c.name===a)return c}return null}; -u.prototype.addChangedListener=u.prototype.zz=function(a){t.j(a,"function",u,"addChangedListener:listener");null===this.fj&&(this.fj=new H("function"));this.fj.add(a)};u.prototype.removeChangedListener=u.prototype.NA=function(a){t.j(a,"function",u,"removeChangedListener:listener");null!==this.fj&&(this.fj.remove(a),0===this.fj.count&&(this.fj=null))}; -u.prototype.Nv=function(a){this.Bb||this.Aa.lE(a);a.od!==Hd&&(this.hk=!0);if(null!==this.fj){var b=this.fj,c=b.length;if(1===c)b=b.qa(0),b(a);else if(0!==c)for(var d=b.af(),e=0;em||("LineV"===l.Ib?g=g*m/J.eE(g,m):e=e*m/J.eE(e,m))}h=c.Ms;d.q(g*h.width,e*h.height);if(b)k=b.width,l=b.height,g=b.x,h=b.y;else{e=t.wf();g=a.nb;e.q(g.x,g.y,g.width,g.height);for(h=a.ho.k;h.next();)g=h.value.nb,wb(e,g.x,g.y,g.width,g.height);k=e.width;l=e.height;g=e.x;h=e.y;if(!e.Q())return}c.width=k+2*d.width;c.height=l+2*d.height;e=t.O();J.Hs(g,h,0,0,d.width,d.height, -e);e.offset(-d.width,-d.height);t.dk(d);c.S.location=e;t.B(e)}}u.prototype.clearSelection=u.prototype.Pv=function(){var a=0a&&t.ha(a,">= zero",u,"linkSpacing"),this.uj=a,this.i("linkSpacing",b,a))});t.A(u,{Um:"layers"},function(){return this.Kb.k});t.g(u,"isModelReadOnly",u.prototype.Ue);t.defineProperty(u,{Ue:"isModelReadOnly"},function(){var a=this.Md;return null===a?!1:a.$a},function(a){var b=this.Md;null!==b&&(b.$a=a)});t.g(u,"isReadOnly",u.prototype.$a); -t.defineProperty(u,{$a:"isReadOnly"},function(){return this.Mk},function(a){var b=this.Mk;b!==a&&(t.j(a,"boolean",u,"isReadOnly"),this.Mk=a,this.i("isReadOnly",b,a))});t.g(u,"isEnabled",u.prototype.isEnabled);t.defineProperty(u,{isEnabled:"isEnabled"},function(){return this.ii},function(a){var b=this.ii;b!==a&&(t.j(a,"boolean",u,"isEnabled"),this.ii=a,this.i("isEnabled",b,a))});t.g(u,"allowClipboard",u.prototype.Hv); -t.defineProperty(u,{Hv:"allowClipboard"},function(){return this.Lt},function(a){var b=this.Lt;b!==a&&(t.j(a,"boolean",u,"allowClipboard"),this.Lt=a,this.i("allowClipboard",b,a))});t.g(u,"allowCopy",u.prototype.Rj);t.defineProperty(u,{Rj:"allowCopy"},function(){return this.pk},function(a){var b=this.pk;b!==a&&(t.j(a,"boolean",u,"allowCopy"),this.pk=a,this.i("allowCopy",b,a))});t.g(u,"allowDelete",u.prototype.$k); -t.defineProperty(u,{$k:"allowDelete"},function(){return this.qk},function(a){var b=this.qk;b!==a&&(t.j(a,"boolean",u,"allowDelete"),this.qk=a,this.i("allowDelete",b,a))});t.g(u,"allowDragOut",u.prototype.Iv);t.defineProperty(u,{Iv:"allowDragOut"},function(){return this.Mt},function(a){var b=this.Mt;b!==a&&(t.j(a,"boolean",u,"allowDragOut"),this.Mt=a,this.i("allowDragOut",b,a))});t.g(u,"allowDrop",u.prototype.Bz); -t.defineProperty(u,{Bz:"allowDrop"},function(){return this.Nt},function(a){var b=this.Nt;b!==a&&(t.j(a,"boolean",u,"allowDrop"),this.Nt=a,this.i("allowDrop",b,a))});t.g(u,"allowTextEdit",u.prototype.Co);t.defineProperty(u,{Co:"allowTextEdit"},function(){return this.zk},function(a){var b=this.zk;b!==a&&(t.j(a,"boolean",u,"allowTextEdit"),this.zk=a,this.i("allowTextEdit",b,a))});t.g(u,"allowGroup",u.prototype.yo); -t.defineProperty(u,{yo:"allowGroup"},function(){return this.rk},function(a){var b=this.rk;b!==a&&(t.j(a,"boolean",u,"allowGroup"),this.rk=a,this.i("allowGroup",b,a))});t.g(u,"allowUngroup",u.prototype.Do);t.defineProperty(u,{Do:"allowUngroup"},function(){return this.Ak},function(a){var b=this.Ak;b!==a&&(t.j(a,"boolean",u,"allowUngroup"),this.Ak=a,this.i("allowUngroup",b,a))});t.g(u,"allowInsert",u.prototype.wm); -t.defineProperty(u,{wm:"allowInsert"},function(){return this.Pt},function(a){var b=this.Pt;b!==a&&(t.j(a,"boolean",u,"allowInsert"),this.Pt=a,this.i("allowInsert",b,a))});t.g(u,"allowLink",u.prototype.xm);t.defineProperty(u,{xm:"allowLink"},function(){return this.sk},function(a){var b=this.sk;b!==a&&(t.j(a,"boolean",u,"allowLink"),this.sk=a,this.i("allowLink",b,a))});t.g(u,"allowRelink",u.prototype.Sj); -t.defineProperty(u,{Sj:"allowRelink"},function(){return this.uk},function(a){var b=this.uk;b!==a&&(t.j(a,"boolean",u,"allowRelink"),this.uk=a,this.i("allowRelink",b,a))});t.g(u,"allowMove",u.prototype.al);t.defineProperty(u,{al:"allowMove"},function(){return this.tk},function(a){var b=this.tk;b!==a&&(t.j(a,"boolean",u,"allowMove"),this.tk=a,this.i("allowMove",b,a))});t.g(u,"allowReshape",u.prototype.zo); -t.defineProperty(u,{zo:"allowReshape"},function(){return this.vk},function(a){var b=this.vk;b!==a&&(t.j(a,"boolean",u,"allowReshape"),this.vk=a,this.i("allowReshape",b,a))});t.g(u,"allowResize",u.prototype.Ao);t.defineProperty(u,{Ao:"allowResize"},function(){return this.wk},function(a){var b=this.wk;b!==a&&(t.j(a,"boolean",u,"allowResize"),this.wk=a,this.i("allowResize",b,a))});t.g(u,"allowRotate",u.prototype.Bo); -t.defineProperty(u,{Bo:"allowRotate"},function(){return this.xk},function(a){var b=this.xk;b!==a&&(t.j(a,"boolean",u,"allowRotate"),this.xk=a,this.i("allowRotate",b,a))});t.g(u,"allowSelect",u.prototype.Ne);t.defineProperty(u,{Ne:"allowSelect"},function(){return this.yk},function(a){var b=this.yk;b!==a&&(t.j(a,"boolean",u,"allowSelect"),this.yk=a,this.i("allowSelect",b,a))});t.g(u,"allowUndo",u.prototype.Cz); -t.defineProperty(u,{Cz:"allowUndo"},function(){return this.Qt},function(a){var b=this.Qt;b!==a&&(t.j(a,"boolean",u,"allowUndo"),this.Qt=a,this.i("allowUndo",b,a))});t.g(u,"allowZoom",u.prototype.us);t.defineProperty(u,{us:"allowZoom"},function(){return this.St},function(a){var b=this.St;b!==a&&(t.j(a,"boolean",u,"allowZoom"),this.St=a,this.i("allowZoom",b,a))});t.g(u,"hasVerticalScrollbar",u.prototype.oE); -t.defineProperty(u,{oE:"hasVerticalScrollbar"},function(){return this.uu},function(a){var b=this.uu;b!==a&&(t.j(a,"boolean",u,"hasVerticalScrollbar"),this.uu=a,qi(this),this.pa(),this.i("hasVerticalScrollbar",b,a),ei(this))});t.g(u,"hasHorizontalScrollbar",u.prototype.nE);t.defineProperty(u,{nE:"hasHorizontalScrollbar"},function(){return this.tu},function(a){var b=this.tu;b!==a&&(t.j(a,"boolean",u,"hasHorizontalScrollbar"),this.tu=a,qi(this),this.pa(),this.i("hasHorizontalScrollbar",b,a),ei(this))}); -t.g(u,"allowHorizontalScroll",u.prototype.hf);t.defineProperty(u,{hf:"allowHorizontalScroll"},function(){return this.Ot},function(a){var b=this.Ot;b!==a&&(t.j(a,"boolean",u,"allowHorizontalScroll"),this.Ot=a,this.i("allowHorizontalScroll",b,a),ei(this))});t.g(u,"allowVerticalScroll",u.prototype.jf);t.defineProperty(u,{jf:"allowVerticalScroll"},function(){return this.Rt},function(a){var b=this.Rt;b!==a&&(t.j(a,"boolean",u,"allowVerticalScroll"),this.Rt=a,this.i("allowVerticalScroll",b,a),ei(this))}); -t.g(u,"scrollHorizontalLineChange",u.prototype.Dp);t.defineProperty(u,{Dp:"scrollHorizontalLineChange"},function(){return this.hv},function(a){var b=this.hv;b!==a&&(t.j(a,"number",u,"scrollHorizontalLineChange"),0>a&&t.ha(a,">= 0",u,"scrollHorizontalLineChange"),this.hv=a,this.i("scrollHorizontalLineChange",b,a))});t.g(u,"scrollVerticalLineChange",u.prototype.Ep); -t.defineProperty(u,{Ep:"scrollVerticalLineChange"},function(){return this.iv},function(a){var b=this.iv;b!==a&&(t.j(a,"number",u,"scrollVerticalLineChange"),0>a&&t.ha(a,">= 0",u,"scrollVerticalLineChange"),this.iv=a,this.i("scrollVerticalLineChange",b,a))});t.g(u,"lastInput",u.prototype.U);t.defineProperty(u,{U:"lastInput"},function(){return this.cc},function(a){f&&t.l(a,wd,u,"lastInput");this.cc=a});t.g(u,"firstInput",u.prototype.Ec); -t.defineProperty(u,{Ec:"firstInput"},function(){return this.Hg},function(a){f&&t.l(a,wd,u,"firstInput");this.Hg=a});t.g(u,"currentCursor",u.prototype.cd);t.defineProperty(u,{cd:"currentCursor"},function(){return this.fu},function(a){t.j(a,"string",u,"currentCursor");null===this.Pa||this.fu===a||""===a&&this.fu===this.uq||(this.fu=a,""!==a?(this.Pa.style.cursor=a,this.Ab.style.cursor=a):(this.Pa.style.cursor=this.Pz,this.Ab.style.cursor=this.Pz))});t.g(u,"defaultCursor",u.prototype.Pz); -t.defineProperty(u,{Pz:"defaultCursor"},function(){return this.uq},function(a){t.j(a,"string",u,"defaultCursor");var b=this.uq;b!==a&&(this.uq=a,this.i("defaultCursor",b,a))});t.g(u,"hasGestureZoom",u.prototype.eI);t.defineProperty(u,{eI:"hasGestureZoom"},function(){return this.hi},function(a){var b=this.hi;b!==a&&(t.j(a,"boolean",u,"hasGestureZoom"),this.hi=a,this.i("hasGestureZoom",b,a))});t.g(u,"click",u.prototype.click); -t.defineProperty(u,{click:"click"},function(){return this.$h},function(a){var b=this.$h;b!==a&&(null!==a&&t.j(a,"function",u,"click"),this.$h=a,this.i("click",b,a))});t.g(u,"doubleClick",u.prototype.Km);t.defineProperty(u,{Km:"doubleClick"},function(){return this.fi},function(a){var b=this.fi;b!==a&&(null!==a&&t.j(a,"function",u,"doubleClick"),this.fi=a,this.i("doubleClick",b,a))});t.g(u,"contextClick",u.prototype.Cs); -t.defineProperty(u,{Cs:"contextClick"},function(){return this.bi},function(a){var b=this.bi;b!==a&&(null!==a&&t.j(a,"function",u,"contextClick"),this.bi=a,this.i("contextClick",b,a))});t.g(u,"mouseOver",u.prototype.et);t.defineProperty(u,{et:"mouseOver"},function(){return this.pi},function(a){var b=this.pi;b!==a&&(null!==a&&t.j(a,"function",u,"mouseOver"),this.pi=a,this.i("mouseOver",b,a))});t.g(u,"mouseHover",u.prototype.dt); -t.defineProperty(u,{dt:"mouseHover"},function(){return this.oi},function(a){var b=this.oi;b!==a&&(null!==a&&t.j(a,"function",u,"mouseHover"),this.oi=a,this.i("mouseHover",b,a))});t.g(u,"mouseHold",u.prototype.ct);t.defineProperty(u,{ct:"mouseHold"},function(){return this.ni},function(a){var b=this.ni;b!==a&&(null!==a&&t.j(a,"function",u,"mouseHold"),this.ni=a,this.i("mouseHold",b,a))});t.g(u,"mouseDragOver",u.prototype.VE); -t.defineProperty(u,{VE:"mouseDragOver"},function(){return this.Ou},function(a){var b=this.Ou;b!==a&&(null!==a&&t.j(a,"function",u,"mouseDragOver"),this.Ou=a,this.i("mouseDragOver",b,a))});t.g(u,"mouseDrop",u.prototype.bt);t.defineProperty(u,{bt:"mouseDrop"},function(){return this.mi},function(a){var b=this.mi;b!==a&&(null!==a&&t.j(a,"function",u,"mouseDrop"),this.mi=a,this.i("mouseDrop",b,a))});t.g(u,"toolTip",u.prototype.Et); -t.defineProperty(u,{Et:"toolTip"},function(){return this.zi},function(a){var b=this.zi;b!==a&&(null!==a&&t.l(a,We,u,"toolTip"),this.zi=a,this.i("toolTip",b,a))});t.g(u,"contextMenu",u.prototype.contextMenu);t.defineProperty(u,{contextMenu:"contextMenu"},function(){return this.ci},function(a){var b=this.ci;b!==a&&(null!==a&&t.l(a,We,u,"contextMenu"),this.ci=a,this.i("contextMenu",b,a))});t.g(u,"commandHandler",u.prototype.lg); -t.defineProperty(u,{lg:"commandHandler"},function(){return this.Hx},function(a){var b=this.Hx;b!==a&&(t.l(a,xa,u,"commandHandler"),null!==a.h&&t.m("Cannot share CommandHandlers between Diagrams: "+a.toString()),null!==b&&b.qe(null),this.Hx=a,a.qe(this))});t.g(u,"toolManager",u.prototype.Db); -t.defineProperty(u,{Db:"toolManager"},function(){return this.xv},function(a){var b=this.xv;b!==a&&(t.l(a,Ke,u,"toolManager"),null!==a.h&&t.m("Cannot share ToolManagers between Diagrams: "+a.toString()),null!==b&&b.qe(null),this.xv=a,a.qe(this))});t.g(u,"defaultTool",u.prototype.Yv);t.defineProperty(u,{Yv:"defaultTool"},function(){return this.Vx},function(a){var b=this.Vx;b!==a&&(t.l(a,qe,u,"defaultTool"),this.Vx=a,this.Za===b&&(this.Za=a))});t.g(u,"currentTool",u.prototype.Za); -t.defineProperty(u,{Za:"currentTool"},function(){return this.Qx},function(a){var b=this.Qx;null!==b&&(b.ra&&b.doDeactivate(),b.cancelWaitAfter(),b.doStop());null===a&&(a=this.Yv);null!==a&&(t.l(a,qe,u,"currentTool"),this.Qx=a,a.qe(this),a.doStart())});t.A(u,{selection:"selection"},function(){return this.lv});t.g(u,"maxSelectionCount",u.prototype.OE); -t.defineProperty(u,{OE:"maxSelectionCount"},function(){return this.Ju},function(a){var b=this.Ju;if(b!==a)if(t.j(a,"number",u,"maxSelectionCount"),0<=a&&!isNaN(a)){if(this.Ju=a,this.i("maxSelectionCount",b,a),!this.Aa.qb&&(a=this.selection.count-a,0= 0",u,"maxSelectionCount")});t.g(u,"nodeSelectionAdornmentTemplate",u.prototype.YE); -t.defineProperty(u,{YE:"nodeSelectionAdornmentTemplate"},function(){return this.Uu},function(a){var b=this.Uu;b!==a&&(t.l(a,We,u,"nodeSelectionAdornmentTemplate"),this.Uu=a,this.i("nodeSelectionAdornmentTemplate",b,a))});t.g(u,"groupSelectionAdornmentTemplate",u.prototype.kE);t.defineProperty(u,{kE:"groupSelectionAdornmentTemplate"},function(){return this.ru},function(a){var b=this.ru;b!==a&&(t.l(a,We,u,"groupSelectionAdornmentTemplate"),this.ru=a,this.i("groupSelectionAdornmentTemplate",b,a))}); -t.g(u,"linkSelectionAdornmentTemplate",u.prototype.LE);t.defineProperty(u,{LE:"linkSelectionAdornmentTemplate"},function(){return this.Du},function(a){var b=this.Du;b!==a&&(t.l(a,We,u,"linkSelectionAdornmentTemplate"),this.Du=a,this.i("linkSelectionAdornmentTemplate",b,a))});t.g(u,"isModified",u.prototype.hk); -t.defineProperty(u,{hk:"isModified"},function(){var a=this.Aa;return null===a?this.wy:null!==a.gl?!0:this.wy&&this.Jk!==a.gk},function(a){if(this.wy!==a){t.j(a,"boolean",u,"isModified");this.wy=a;var b=this.Aa;!a&&b&&(this.Jk=b.gk);a||Oi(this)}});function Oi(a){var b=a.hk;a.YC!==b&&(a.YC=b,a.Ja("Modified"))}t.g(u,"model",u.prototype.fa); -t.defineProperty(u,{fa:"model"},function(){return this.Md},function(a){var b=this.Md;if(b!==a){t.l(a,I,u,"model");null!==b&&b.Aa!==a.Aa&&b.Aa.mI&&t.m("Do not replace a Diagram.model while a transaction is in progress.");this.Pv();this.Xf=!1;this.Bq=!0;this.hg=!1;var c=this.Jd;this.Jd=!0;null!==b&&(b.NA(this.tC),b instanceof V&&Pi(this,b.Vi),Pi(this,b.sg));this.Md=a;a.zz(this.sC);Qi(this,a.sg);a instanceof V&&Ri(this,a.Vi);a.NA(this.sC);a.zz(this.tC);this.Jd=c;this.lc||this.pa();null!==b&&(a.Aa.isEnabled= -b.Aa.isEnabled)}});t.defineProperty(u,{Wa:null},function(){return this.mC},function(a){this.mC=a}); -function Ph(a,b){if(b.fa===a.fa&&a.Wa){a.Wa=!1;try{var c=b.od,d=b.rf;if(""!==d)if(c===Id){if("linkFromKey"===d){var e=b.object,g=a.Hf(e);if(null!==g){var h=b.newValue,k=a.ng(h);g.da=k}}else if("linkToKey"===d)e=b.object,g=a.Hf(e),null!==g&&(h=b.newValue,k=a.ng(h),g.ja=k);else if("linkFromPortId"===d){if(e=b.object,g=a.Hf(e),null!==g){var l=b.newValue;"string"===typeof l&&(g.nf=l)}}else if("linkToPortId"===d)e=b.object,g=a.Hf(e),null!==g&&(l=b.newValue,"string"===typeof l&&(g.Qf=l));else if("nodeGroupKey"=== -d){var e=b.object,m=a.Pi(e);if(null!==m){var n=b.newValue;if(void 0!==n){var p=a.ng(n);m.fb=p instanceof z?p:null}else m.fb=null}}else if("linkLabelKeys"===d){if(e=b.object,g=a.Hf(e),null!==g){var q=b.oldValue,r=b.newValue;if(t.isArray(q))for(var s=t.yb(q),v=0;vthis.pg&&(a=this.pg);if(b!==a){var c=this.Sb=a;if(!this.lc&&!this.Jd&&(this.lc=!0,null!==this.Pa)){a=this.nb.copy();var d=this.tc/c,e=this.sc/c;a.width=this.tc/b;a.height=this.sc/b;var g=this.Wh.copy();if(isNaN(g.x))switch(this.Uv){case pc:g.x=0;break;case tc:g.x=d-1;break;case Wb:g.x=d/2;break;case Pb:case vc:g.x=d/2}if(isNaN(g.y))switch(this.Uv){case oc:g.y=0;break;case uc:g.y= -e-1;break;case Wb:g.y=e/2;break;case Pb:case vc:g.y=e/2}var h=this.position,b=new C(h.x+g.x/b-g.x/c,h.y+g.y/b-g.y/c);gi(this,b,this.vc,d,e,this.Il);this.position=b;this.lc=!1;this.kt(a,this.nb)}this.pa();qi(this)}});t.g(u,"autoScale",u.prototype.Am);t.defineProperty(u,{Am:"autoScale"},function(){return this.Fl},function(a){var b=this.Fl;b!==a&&(t.tb(a,u,u,"autoScale"),this.Fl=a,this.i("autoScale",b,a),a!==$e&&ei(this))});t.g(u,"initialAutoScale",u.prototype.iI); -t.defineProperty(u,{iI:"initialAutoScale"},function(){return this.Kk},function(a){var b=this.Kk;b!==a&&(t.tb(a,u,u,"initialAutoScale"),this.Kk=a,this.i("initialAutoScale",b,a))});t.g(u,"initialViewportSpot",u.prototype.uE);t.defineProperty(u,{uE:"initialViewportSpot"},function(){return this.wu},function(a){var b=this.wu;b!==a&&(t.l(a,K,u,"initialViewportSpot"),a.rd()||t.m("initialViewportSpot must be a real Spot: "+a),this.wu=a,this.i("initialViewportSpot",b,a))});t.g(u,"initialDocumentSpot",u.prototype.rE); -t.defineProperty(u,{rE:"initialDocumentSpot"},function(){return this.vu},function(a){var b=this.vu;b!==a&&(t.l(a,K,u,"initialDocumentSpot"),a.rd()||t.m("initialViewportSpot must be a real Spot: "+a),this.vu=a,this.i("initialDocumentSpot",b,a))});t.g(u,"minScale",u.prototype.qg);t.defineProperty(u,{qg:"minScale"},function(){return this.Lu},function(a){t.o(a,u,"minScale");var b=this.Lu;b!==a&&0this.scale&&(this.scale=a)):t.ha(a,"> 0",u,"minScale")}); -t.g(u,"maxScale",u.prototype.pg);t.defineProperty(u,{pg:"maxScale"},function(){return this.Iu},function(a){t.o(a,u,"maxScale");var b=this.Iu;b!==a&&0 0",u,"maxScale")});t.g(u,"zoomPoint",u.prototype.Wh);t.defineProperty(u,{Wh:"zoomPoint"},function(){return this.Cv},function(a){this.Cv.N(a)||(t.l(a,C,u,"zoomPoint"),this.Cv=a=a.Z())});t.g(u,"contentAlignment",u.prototype.Uv); -t.defineProperty(u,{Uv:"contentAlignment"},function(){return this.Il},function(a){var b=this.Il;b.N(a)||(t.l(a,K,u,"contentAlignment"),this.Il=a=a.Z(),this.i("contentAlignment",b,a),ei(this))});t.g(u,"initialContentAlignment",u.prototype.jI);t.defineProperty(u,{jI:"initialContentAlignment"},function(){return this.Nn},function(a){var b=this.Nn;b.N(a)||(t.l(a,K,u,"initialContentAlignment"),this.Nn=a=a.Z(),this.i("initialContentAlignment",b,a))});t.g(u,"padding",u.prototype.padding); -t.defineProperty(u,{padding:"padding"},function(){return this.Le},function(a){"number"===typeof a?a=new pb(a):t.l(a,pb,u,"padding");var b=this.Le;b.N(a)||(this.Le=a=a.Z(),this.Rc(),this.i("padding",b,a))});t.A(u,{Yi:"nodes"},function(){return this.Vu.k});t.A(u,{links:"links"},function(){return this.Eu.k});t.A(u,{sl:"parts"},function(){return this.cb.k});u.prototype.findTopLevelGroups=function(){return this.Vk.k};t.g(u,"layout",u.prototype.Tb); -t.defineProperty(u,{Tb:"layout"},function(){return this.Ld},function(a){var b=this.Ld;b!==a&&(t.l(a,xe,u,"layout"),null!==b&&(b.h=null,b.group=null),this.Ld=a,a.h=this,a.group=null,this.Tt=!0,this.i("layout",b,a),this.Nf())});u.prototype.layoutDiagram=function(a){ci(this);a&&aj(this,!0);ti(this,!1)};function aj(a,b){for(var c=a.Vk.k;c.next();)bj(a,c.value,b);null!==a.Tb&&(b?a.Tb.of=!1:a.Tb.K())} -function bj(a,b,c){if(null!==b){for(var d=b.cm.k;d.next();)bj(a,d.value,c);null!==b.Tb&&(c?b.Tb.of=!1:b.Tb.K())}}function ti(a,b){for(var c=a.Vk.k;c.next();)cj(a,c.value,b);c=a.Tb;if(null!==c&&!c.of){if(b&&!c.nA)return;c.doLayout(a);ci(a);c.of=!0}a.Tt=!1}function cj(a,b,c){if(null!==b){for(var d=b.cm.k;d.next();)cj(a,d.value,c);d=b.Tb;null===d||d.of||c&&!d.nA||(b.zC=!b.location.Q(),d.doLayout(b),b.K(dj),d.of=!0,wi(a,b))}}t.g(u,"isTreePathToChildren",u.prototype.fd); -t.defineProperty(u,{fd:"isTreePathToChildren"},function(){return this.Au},function(a){var b=this.Au;if(b!==a&&(t.j(a,"boolean",u,"isTreePathToChildren"),this.Au=a,this.i("isTreePathToChildren",b,a),!this.Aa.qb))for(a=this.Yi;a.next();)ej(a.value)});u.prototype.findTreeRoots=function(){for(var a=new H(y),b=this.Yi.k;b.next();){var c=b.value;c.ep&&null===c.Ks()&&a.add(c)}return a.k};t.g(u,"isCollapsingExpanding",u.prototype.Sd); -t.defineProperty(u,{Sd:null},function(){return this.fC},function(a){this.fC=a}); -function Nh(a){function b(a){var b=a.toLowerCase(),h=new H("function");c.add(a,h);c.add(b,h);d.add(a,a);d.add(b,a)}var c=new sa("string",H),d=new sa("string","string");b("BackgroundSingleClicked");b("BackgroundDoubleClicked");b("BackgroundContextClicked");b("ClipboardChanged");b("ClipboardPasted");b("DocumentBoundsChanged");b("ExternalObjectsDropped");b("InitialLayoutCompleted");b("LayoutCompleted");b("LinkDrawn");b("LinkRelinked");b("LinkReshaped");b("Modified");b("ObjectSingleClicked");b("ObjectDoubleClicked"); -b("ObjectContextClicked");b("PartCreated");b("PartResized");b("PartRotated");b("SelectionMoved");b("SelectionCopied");b("SelectionDeleting");b("SelectionDeleted");b("SelectionGrouped");b("SelectionUngrouped");b("ChangingSelection");b("ChangedSelection");b("SubGraphCollapsed");b("SubGraphExpanded");b("TextEdited");b("TreeCollapsed");b("TreeExpanded");b("ViewportBoundsChanged");a.Xx=c;a.Wx=d}function ta(a,b){var c=a.Wx.Ba(b);return null!==c?c:a.Wx.Ba(b.toLowerCase())} -function fj(a,b){var c=a.Xx.Ba(b);if(null!==c)return c;c=a.Xx.Ba(b.toLowerCase());if(null!==c)return c;t.m("Unknown DiagramEvent name: "+b);return null}u.prototype.addDiagramListener=u.prototype.Az=function(a,b){t.j(a,"string",u,"addDiagramListener:name");t.j(b,"function",u,"addDiagramListener:listener");var c=fj(this,a);null!==c&&c.add(b)}; -u.prototype.removeDiagramListener=u.prototype.eF=function(a,b){t.j(a,"string",u,"removeDiagramListener:name");t.j(b,"function",u,"addDiagramListener:listener");var c=fj(this,a);null!==c&&c.remove(b)};u.prototype.raiseDiagramEvent=u.prototype.Ja=function(a,b,c){f&&t.j(a,"string",u,"raiseDiagramEvent:name");var d=fj(this,a),e=new Fd;e.h=this;e.name=ta(this,a);void 0!==b&&(e.Sw=b);void 0!==c&&(e.Fw=c);a=d.length;if(1===a)d=d.qa(0),d(e);else if(0!==a)for(b=d.af(),c=0;c=d.top&&0>=d.left&&0>=d.right&&0>=d.bottom)return c;var e=a.nb,g=a.scale,e=t.lk(0,0,e.width*g,e.height*g),h=t.ic(0,0);if(b.x>=e.x&&b.xe.x+e.width-d.right&&(k=Math.max(a.Dp,1),k|=0,h.x+=k,b.x>e.x+e.width-d.right/2&&(h.x+=k),b.x>e.x+e.width-d.right/4&&(h.x+=4*k));b.y>=e.y&&b.ye.y+e.height-d.bottom&&(k=Math.max(a.Ep,1),k|=0,h.y+=k,b.y>e.y+e.height-d.bottom/2&&(h.y+=k),b.y>e.y+e.height-d.bottom/4&&(h.y+=4*k));h.Oi(J.ok)||(c=new C(c.x+h.x/g,c.y+h.y/g));t.Pc(e);t.B(h);return c}u.prototype.makeSVG=function(a){void 0===a&&(a={});a.context="svg";a=Bj(this,a);return null!==a?a.Bt:null}; -u.prototype.makeImage=function(a){var b=document.createElement("img");b.src=this.BI(a);return b instanceof HTMLImageElement?b:null};u.prototype.makeImageData=u.prototype.BI=function(a){void 0===a&&(a={});var b=Bj(this,a);return null!==b?b.toDataURL(a.type,a.details):""}; -function Bj(a,b){a.Nh();if(null===a.Pa)return null;"object"!==typeof b&&t.m("properties argument must be an Object.");var c=!1,d=b.size||null,e=b.scale||null;void 0!==b.scale&&isNaN(b.scale)&&(e="NaN");var g=b.maxSize||new pa(2E3,2E3);void 0===b.maxSize&&(c=!0);var h=b.position||null,k=b.parts||null,l=void 0===b.padding?1:b.padding,m=b.background||null,n=b.omitTemporary;void 0===n&&(n=!0);var p=b.showTemporary;void 0===p&&(p=!n);n=b.showGrid;void 0===n&&(n=p);null!==d&&isNaN(d.width)&&isNaN(d.height)&& -(d=null);l&&"number"===typeof l&&(l=new pb(l));l||(l=new pb(0));l.left=Math.max(l.left,0);l.right=Math.max(l.right,0);l.top=Math.max(l.top,0);l.bottom=Math.max(l.bottom,0);a.Fn=!1;ca(a);var q=document.createElement("canvas"),r=q.getContext("2d"),s=q;if(!(d||e||k||h))return q.width=a.Pa.width+Math.ceil(l.left+l.right),q.height=a.Pa.height+Math.ceil(l.top+l.bottom),"svg"===b.context&&(r=s=new zc(q),r instanceof zc&&(a.Fn=!0)),Ci(a,r,l,new pa(q.width,q.height),a.Sb,a.rb,k,m,p,n),a.Fn=!0,s;var v,x=new C(0, -0);v=a.vc.copy();v.gJ(a.padding);null!==h&&h.Q()?(x=h,e||(e=1)):(x.x=v.x,x.y=v.y);if(k){var E,h=!0,k=k.k;for(k.reset();k.next();){var F=k.value;if(F instanceof w){var G=F.layer;G&&!G.visible||G&&G.pc||!F.zb()||(F=F.wa,F.Q()&&(h?(h=!1,E=F.copy()):E.nk(F)))}}h&&(E=new D(0,0,0,0));v.width=E.width;v.height=E.height;x.x=E.x;x.y=E.y}h=E=0;l&&(E=l.left+l.right,h=l.top+l.bottom);F=G=0;d&&(G=d.width,F=d.height,isFinite(G)&&(G=Math.max(0,G-E)),isFinite(F)&&(F=Math.max(0,F-h)));d&&e?("NaN"===e&&(e=1),d.Q()? -(d=G,v=F):isNaN(F)?(d=G,v=v.height*e):(d=v.width*e,v=F)):d?d.Q()?(e=Math.min(G/v.width,F/v.height),d=G,v=F):isNaN(F)?(e=G/v.width,d=G,v=v.height*e):(e=F/v.height,d=v.width*e,v=F):e?"NaN"===e&&g.Q()?(e=Math.min((g.width-E)/v.width,(g.height-h)/v.height),1E||v>g)&&(t.trace("Diagram.makeImage(data): Diagram width or height is larger than the default max size. ("+ -Math.ceil(d)+"x"+Math.ceil(v)+" vs 2000x2000) Consider increasing the max size."),t.cG=!0),isNaN(E)&&(E=2E3),isNaN(g)&&(g=2E3),isFinite(E)&&(d=Math.min(d,E)),isFinite(g)&&(v=Math.min(v,g)));q.width=Math.ceil(d);q.height=Math.ceil(v);"svg"===b.context&&(r=s=new zc(q),r instanceof zc&&(a.Fn=!0));Ci(a,r,l,new pa(Math.ceil(d),Math.ceil(v)),e,x,k,m,p,n);a.Fn=!0;return s} -u.inherit=function(a,b){t.j(a,"function",u,"inherit");t.j(b,"function",u,"inherit");b.EG&&t.m("Cannot inherit from "+t.Ug(b));t.Oa(a,b)};function Cj(a){1a)&&t.ha(a,"0 <= loc <= 1",ke,"addColorStop:loc");t.j(b,"string",ke,"addColorStop:color");null===this.Eg&&(this.Eg=new sa("number","string"));this.Eg.add(a,b);this.ba===me&&(this.type=ne);this.Fg=null};t.g(ke,"type",ke.prototype.type); -t.defineProperty(ke,{type:"type"},function(){return this.ba},function(a){t.J(this,a);t.tb(a,ke,ke,"type");this.ba=a;this.start.qd()&&(a===ne?this.start=Ub:a===oe&&(this.start=Wb));this.end.qd()&&(a===ne?this.end=Yb:a===oe&&(this.end=Wb));this.Fg=null});t.g(ke,"color",ke.prototype.color);t.defineProperty(ke,{color:"color"},function(){return this.un},function(a){t.J(this,a);t.j(a,"string",ke,"color");this.un=a;this.Fg=null});t.g(ke,"start",ke.prototype.start); -t.defineProperty(ke,{start:"start"},function(){return this.no},function(a){t.J(this,a);a instanceof K||t.Vb(a,"Spot",ke,"start");this.no=a.Z();this.Fg=null});t.g(ke,"end",ke.prototype.end);t.defineProperty(ke,{end:"end"},function(){return this.Hn},function(a){t.J(this,a);a instanceof K||t.Vb(a,"Spot",ke,"end");this.Hn=a.Z();this.Fg=null});t.g(ke,"startRadius",ke.prototype.Jp); -t.defineProperty(ke,{Jp:"startRadius"},function(){return this.pv},function(a){t.J(this,a);t.o(a,ke,"startRadius");0>a&&t.ha(a,">= zero",ke,"startRadius");this.pv=a;this.Fg=null});t.g(ke,"endRadius",ke.prototype.Mo);t.defineProperty(ke,{Mo:"endRadius"},function(){return this.nu},function(a){t.J(this,a);t.o(a,ke,"endRadius");0>a&&t.ha(a,">= zero",ke,"endRadius");this.nu=a;this.Fg=null});t.g(ke,"colorStops",ke.prototype.Go); -t.defineProperty(ke,{Go:"colorStops"},function(){return this.Eg},function(a){t.J(this,a);f&&t.l(a,sa,ke,"colorStops");this.Eg=a;this.Fg=null});t.g(ke,"pattern",ke.prototype.pattern);t.defineProperty(ke,{pattern:"pattern"},function(){return this.av},function(a){t.J(this,a);this.av=a;this.Fg=null}); -ke.randomColor=function(a,b){void 0===a&&(a=128);f&&(t.o(a,ke,"randomColor:min"),(0>a||255d.length&&(d="0"+d);2>e.length&&(e="0"+e);2>c.length&&(c="0"+c);return"#"+ -d+e+c}; -function X(){t.zc(this);this.ka=30723;this.ti=null;this.Rb="";this.jc=this.Gb=null;this.rb=(new C(NaN,NaN)).freeze();this.df=(new pa(NaN,NaN)).freeze();this.de=J.ln;this.zj=J.qG;this.bd=new qa;this.Yh=new qa;this.Ok=new qa;this.Sb=1;this.pn=0;this.zh=Yg;this.fr=J.Up;this.Kc=(new D(NaN,NaN,NaN,NaN)).freeze();this.Fb=(new D(NaN,NaN,NaN,NaN)).freeze();this.Yc=(new D(0,0,NaN,NaN)).freeze();this.gs=this.Cq=this.V=this.Ar=this.ee=null;this.hs=this.Dq=Infinity;this.aq=this.re=Pb;this.Lr=0;this.Gj=1;this.hq= -0;this.gj=1;this.Pr=-Infinity;this.Nr=0;this.Qr=J.ok;this.Rr=Jg;this.oq="";this.gm=this.ai=this.Jl=this.Bc=this.R=null}t.ia("GraphObject",X);t.Fh(X); -X.prototype.cloneProtected=function(a){a.ka=this.ka|6144;a.Rb=this.Rb;a.Gb=this.Gb;a.jc=this.jc;a.rb.assign(this.rb);a.df.assign(this.df);a.de=this.de.Z();a.zj=this.zj.Z();a.Ok=this.Ok.copy();a.Sb=this.Sb;a.pn=this.pn;a.zh=this.zh;a.fr=this.fr.Z();a.Kc.assign(this.Kc);a.Fb.assign(this.Fb);a.Yc.assign(this.Yc);a.Ar=this.Ar;a.re=this.re.Z();a.aq=this.aq.Z();a.Lr=this.Lr;a.Gj=this.Gj;a.hq=this.hq;a.gj=this.gj;a.Pr=this.Pr;a.Nr=this.Nr;a.Qr=this.Qr.Z();a.Rr=this.Rr;a.oq=this.oq;if(null!==this.R){var b= -this.R;a.R={$h:b.$h,fi:b.fi,bi:b.bi,qr:b.qr,rr:b.rr,pi:b.pi,oi:b.oi,ni:b.ni,or:b.or,pr:b.pr,mi:b.mi,Wp:b.Wp,Xp:b.Xp,Yp:b.Yp,Vp:b.Vp,zi:b.zi,ci:b.ci}}null!==this.V&&(b=this.V,a.V={nj:b.nj.Z(),Pj:b.Pj.Z(),lj:b.lj,Nj:b.Nj,kj:b.kj,Mj:b.Mj,mj:b.mj,Oj:b.Oj});a.Cq=this.Cq;a.Dq=this.Dq;a.gs=this.gs;a.hs=this.hs;a.Bc=this.Bc;if(Array.isArray(this.Jl))for(a.Jl=this.Jl.slice(0),b=0;bk;)k+=g[n++%l],p=!p;q=!1}else k=g[n++%l];k>m&&(k=m);var r=Math.sqrt(k*k/(1+e*e));0>d&&(r=-r);b+=r;c+=e*r;p?a.lineTo(b,c):a.moveTo(b,c);m-=k;p=!p}}aa.Uc=function(a,b,c,d,e,g,h){var k=this.S;null!==k&&(k.$m(a,b,c,d,e,g,h),0!==(this.ka&1024)&&c===this&&a===Id&&Mj(this,k,b))}; -function Mj(a,b,c){var d=a.Ro();if(null!==d)for(var e=a.Bc.k;e.next();){var g=e.value,h=d.data,k=g.zt;null!==k&&(h=d.le(k));if(null!==h&&(g.ZF(a,h,c,null!==k?null:b.h),null!==k&&(h=d,""!==k&&(h=d.le(k)),null!==h))){var k=g.fn,l=d;""!==k&&(l=d.le(k));null!==l&&g.$F(l,h,c)}}}aa.i=function(a,b,c){this.Uc(Id,a,this,b,c)};function Nj(a,b,c,d,e){var g=a.Kc,h=a.Ok;h.reset();Oj(a,h,b,c,d,e);a.Ok=h;g.x=b;g.y=c;g.width=d;g.height=e;h.Ts()||h.TF(g)} -function Pj(a,b,c,d){if(!1===a.Ze)return!1;d.multiply(a.transform);return c?a.If(b,d):a.Fm(b,d)}aa.XD=function(a,b,c){if(!1===this.Ze)return!1;var d=this.Ga;b=a.$j(b);var e=!1;c&&(e=cb(a.x,a.y,0,0,0,d.height)d.width*e&&10>d.height*e)return a=Db(c.x-5*g,c.y-5*g,c.width+10*g,c.height+10*g,b.x,b.y),t.B(b),a}if(void 0!==this.Nc||this instanceof Y?Db(c.x-5,c.y-5,c.width+10,c.height+10,b.x,b.y):c.Ia(b)){if(this.ai&&!this.ai.Ia(b))return!1;if(null!==this.jc&&c.Ia(b)||null!== -this.Gb&&this.Yc.Ia(a))return!0;t.B(b);return this.Vj(a)}t.B(b);return!1};X.prototype.Vj=function(a){var b=this.Ga;return Db(0,0,b.width,b.height,a.x,a.y)}; -X.prototype.containsRect=X.prototype.Wj=function(a){f&&t.l(a,D,X,"containsRect:r");if(0===this.angle)return this.wa.Wj(a);var b=this.Ga,b=t.lk(0,0,b.width,b.height),c=this.transform,d=!1,e=t.ic(a.x,a.y);b.Ia(c.Ri(e))&&(e.q(a.x,a.bottom),b.Ia(c.Ri(e))&&(e.q(a.right,a.bottom),b.Ia(c.Ri(e))&&(e.q(a.right,a.y),b.Ia(c.Ri(e))&&(d=!0))));t.B(e);t.Pc(b);return d}; -X.prototype.containedInRect=X.prototype.Fm=function(a,b){f&&t.l(a,D,X,"containedInRect:r");if(void 0===b)return a.Wj(this.wa);var c=this.Ga,d=!1,e=t.ic(0,0);a.Ia(b.Va(e))&&(e.q(0,c.height),a.Ia(b.Va(e))&&(e.q(c.width,c.height),a.Ia(b.Va(e))&&(e.q(c.width,0),a.Ia(b.Va(e))&&(d=!0))));return d}; -X.prototype.intersectsRect=X.prototype.If=function(a,b){f&&t.l(a,D,X,"intersectsRect:r");if(void 0===b&&(b=this.transform,0===this.angle))return a.If(this.wa);var c=this.Ga,d=b,e=t.ic(0,0),g=t.ic(0,c.height),h=t.ic(c.width,c.height),k=t.ic(c.width,0),l=!1;if(a.Ia(d.Va(e))||a.Ia(d.Va(g))||a.Ia(d.Va(h))||a.Ia(d.Va(k)))l=!0;else{var c=t.lk(0,0,c.width,c.height),m=t.ic(a.x,a.y);c.Ia(d.Ri(m))?l=!0:(m.q(a.x,a.bottom),c.Ia(d.Ri(m))?l=!0:(m.q(a.right,a.bottom),c.Ia(d.Ri(m))?l=!0:(m.q(a.right,a.y),c.Ia(d.Ri(m))&& -(l=!0))));t.B(m);t.Pc(c);!l&&(J.ow(a,e,g)||J.ow(a,g,h)||J.ow(a,h,k)||J.ow(a,k,e))&&(l=!0)}t.B(e);t.B(g);t.B(h);t.B(k);return l};X.prototype.getDocumentPoint=X.prototype.gb=function(a,b){void 0===b&&(b=new C);a.qd()&&t.m("Spot must be real");var c=this.Ga;b.q(a.x*c.width+a.offsetX,a.y*c.height+a.offsetY);this.he.Va(b);return b};X.prototype.getDocumentAngle=X.prototype.jl=function(){var a=this.he,a=180/Math.PI*Math.atan2(a.m12,a.m11);0>a&&(a+=360);return a}; -X.prototype.getDocumentScale=X.prototype.fk=function(){var a=this.Sb;return null!==this.ga?a*this.ga.fk():a};X.prototype.getLocalPoint=X.prototype.gE=function(a,b){void 0===b&&(b=new C);b.assign(a);this.he.Ri(b);return b};X.prototype.getNearestIntersectionPoint=X.prototype.ml=function(a,b,c){return this.Wo(a.x,a.y,b.x,b.y,c)};aa=X.prototype; -aa.Wo=function(a,b,c,d,e){var g=this.transform,h=1/(g.m11*g.m22-g.m12*g.m21),k=g.m22*h,l=-g.m12*h,m=-g.m21*h,n=g.m11*h,p=h*(g.m21*g.dy-g.m22*g.dx),q=h*(g.m12*g.dx-g.m11*g.dy);if(null!==this.Tj)return g=this.wa,J.ml(g.left,g.top,g.right,g.bottom,a,b,c,d,e);h=a*k+b*m+p;a=a*l+b*n+q;b=c*k+d*m+p;c=c*l+d*n+q;e.q(0,0);d=this.Ga;c=J.ml(0,0,d.width,d.height,h,a,b,c,e);e.transform(g);return c}; -function Bh(a,b,c,d,e){if(!1!==xi(a)){var g=a.margin,h=g.top+g.bottom;b=Math.max(b-(g.right+g.left),0);c=Math.max(c-h,0);g=a.angle;if(90===g||270===g)g=b,b=c,c=g,g=d,d=e,e=g;g=a.Ca;h=0;a.ib&&(h=a.ib);b=isFinite(g.width)?g.width+h:b;c=isFinite(g.height)?g.height+h:c;var g=d||0,h=e||0,k=a instanceof B;switch(Qj(a)){case Xg:h=g=0;k&&(c=b=Infinity);break;case Qc:isFinite(b)&&b>d&&(g=b);isFinite(c)&&c>e&&(h=c);break;case Ij:isFinite(b)&&b>d&&(g=b);h=0;k&&(c=Infinity);break;case Hj:isFinite(c)&&c>e&&(h= -c),g=0,k&&(b=Infinity)}var k=a.He,l=a.Ye;g>k.width&&l.widthk.height&&l.heighta.height||this.Zn.Wi>a.width))&&(c=!0);this.ka=c?this.ka|256:this.ka&-257;this.Fb.Q()||t.m("Non-real actualBounds has been set. Object "+ -this+", actualBounds: "+this.Fb.toString());Tj(this,g,this.Fb);t.Pc(g)};aa.Uj=function(){};function Uj(a,b,c,d,e){var g=a.wa;g.x=b;g.y=c;g.width=d;g.height=e;if(!a.Ca.Q()){g=a.Kc;c=a.margin;b=c.right+c.left;var h=c.top+c.bottom;c=g.width+b;g=g.height+h;d+=b;e+=h;b=Qj(a);c===d&&g===e&&(b=Xg);switch(b){case Xg:if(c>d||g>e)Rj(a,!0),Bh(a,c>d?d:c,g>e?e:g);break;case Qc:Rj(a,!0);Bh(a,d,e,0,0);break;case Ij:Rj(a,!0);Bh(a,d,g,0,0);break;case Hj:Rj(a,!0),Bh(a,c,e,0,0)}}} -function Tj(a,b,c){Vj(a,!1);var d=a.S;if(null!==d){var e=d.h;if(null!==e)if(Wj(d),a instanceof w){var g=!1,d=b.Q();if(!1===e.qj){var h=e.vc,k=e.padding,l=h.x+k.left,m=h.y+k.top,n=h.width-2*k.right,h=h.height-2*k.bottom;d&&b.x>l&&b.y>m&&b.rightl&&c.y>m&&c.rightc.width+c.x||c.x>h.width+h.x||m>c.height+c.y||c.y>h.height+h.y)break a;h=!0;Mc(a,1,0,0,1,0,0);a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}l=!1;if(this instanceof w&&(l=!0,!this.zb()))break a;m=!1;this.S&&(m=this.S.Lh);a.Ki.Xe=[1,0,0,1,0,0];null!==this.jc&&(dk(this,a,this.jc,!0,!0),this.jc instanceof ke&&this.jc.type===oe?(a.beginPath(),a.rect(c.x,c.y,c.width,c.height),ek(a,this.jc,!0)):a.fillRect(c.x, -c.y,c.width,c.height));l&&this.Lh&&(Mc(a,1,0,0,1,0,0),c=this.pm,a.shadowOffsetX=c.x,a.shadowOffsetY=c.y,a.shadowColor=this.om,a.shadowBlur=this.nm/b.scale,a.ab());this instanceof B?Mc(a,d.m11,d.m12,d.m21,d.m22,d.dx,d.dy):a.Ki.Xe=[d.m11,d.m12,d.m21,d.m22,d.dx,d.dy];if(null!==this.Gb){var k=this.Ga,c=d=0,n=k.width,k=k.height,p=0;this instanceof Y&&(k=this.Ra.Mb,d=k.x,c=k.y,n=k.width,k=k.height,p=this.fe);dk(this,a,this.Gb,!0);this.Gb instanceof ke&&this.Gb.type===oe?(a.beginPath(),a.rect(d-p/2,c-p/ -2,n+p,k+p),ek(a,this.Gb,!0)):a.fillRect(d-p/2,c-p/2,n+p,k+p)}if(m&&(null!==this.Gb||null!==this.jc||null!==e&&0!==(e.ka&512)||null!==e&&e.type===Vh&&e.gw()!==this)){fk(this,!0);var q=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}else fk(this,!1);this.hl(a,b);m&&0!==(this.ka&512)===!0&&(a.shadowOffsetX=q[0],a.shadowOffsetY=q[1],a.shadowBlur=q[2]);l&&m&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);g?(a.restore(),h&&a.og.pop(),ca(b,a)):this instanceof -B&&a.og.pop();l&&m&&a.og.pop()}}}else if(this instanceof B&&(this.type===Zj||this.type===ak))bk(this,a,b);else if(d=this.Fb,0!==d.width&&0!==d.height&&!isNaN(d.x)&&!isNaN(d.y)){!f||!f.Gi||this instanceof We||f.JH(a,this);q=this.transform;g=this.ga;h=this.Yh;h.reset();null!==g&&(g.Bg()?h.multiply(g.he):null!==g.ga&&h.multiply(g.ga.he));h.multiply(this.bd);h=0!==(this.ka&256);this instanceof wa&&ck(this,a);if(h){f&&f.UD&&t.trace("clip"+this.toString());c=g.Bg()?g.Ga:g.wa;this.ai?(k=this.ai,l=k.x,m= -k.y,n=k.width,k=k.height):(l=Math.max(d.x,c.x),m=Math.max(d.y,c.y),n=Math.min(d.right,c.right)-l,k=Math.min(d.bottom,c.bottom)-m);if(l>d.width+d.x||d.x>c.width+c.x||m>d.height+d.y||d.y>c.height+c.y)return;f&&f.UD&&f.LH(a,l,m,n,k);a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}c=!1;if(this instanceof w){c=!0;if(!this.zb())return;this.Lh&&(l=this.pm,a.shadowOffsetX=l.x*b.scale,a.shadowOffsetY=l.y*b.scale,a.shadowColor=this.om,a.shadowBlur=this.nm)}l=!1;this.S&&(l=this.S.Lh);null!==this.jc&&(dk(this, -a,this.jc,!0,!0),this.jc instanceof ke&&this.jc.type===oe?(a.beginPath(),a.rect(d.x,d.y,d.width,d.height),ek(a,this.jc,!0)):a.fillRect(d.x,d.y,d.width,d.height));q.Ts()||a.transform(q.m11,q.m12,q.m21,q.m22,q.dx,q.dy);null!==this.Gb&&(k=this.Ga,m=d=0,n=k.width,k=k.height,p=0,this instanceof Y&&(k=this.Ra.Mb,d=k.x,m=k.y,n=k.width,k=k.height,p=this.fe),dk(this,a,this.Gb,!0),this.Gb instanceof ke&&this.Gb.type===oe?(a.beginPath(),a.rect(d-p/2,m-p/2,n+p,k+p),ek(a,this.Gb,!0)):a.fillRect(d-p/2,m-p/2,n+ -p,k+p));f&&f.Gi&&f.KH(a,this);l&&(null!==this.Gb||null!==this.jc||null!==g&&0!==(g.ka&512)||null!==g&&g.type===Vh&&g.gw()!==this)?(fk(this,!0),e=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0):fk(this,!1);this.hl(a,b);l&&0!==(this.ka&512)===!0&&(a.shadowOffsetX=e[0],a.shadowOffsetY=e[1],a.shadowBlur=e[2]);c&&l&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);h?(a.restore(),this instanceof B?ca(b,a,!0):ca(b,a,!1)):q.Ts()||(e=1/(q.m11*q.m22-q.m12* -q.m21),a.transform(q.m22*e,-q.m12*e,-q.m21*e,q.m11*e,e*(q.m21*q.dy-q.m22*q.dx),e*(q.m12*q.dx-q.m11*q.dy)))}}; -function bk(a,b,c){var d=a.Fb;0===d.width||0===d.height||isNaN(d.x)||isNaN(d.y)||(null!==a.jc&&(dk(a,b,a.jc,!0,!0),a.jc instanceof ke&&a.jc.type===oe?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),ek(b,a.jc,!0)):b.fillRect(d.x,d.y,d.width,d.height)),null!==a.Gb&&(dk(a,b,a.Gb,!0),a.Gb instanceof ke&&a.Gb.type===oe?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),ek(b,a.Gb,!0)):b.fillRect(d.x,d.y,d.width,d.height)),a.hl(b,c))}aa.hl=function(){}; -function ek(a,b,c){if(c)if(a instanceof CanvasRenderingContext2D&&b instanceof ke&&b.type===oe){var d=b.Kx;b=b.Jx;b>d?(a.scale(d/b,1),a.translate((b-d)/2,0),c?a.fill():a.stroke(),a.translate(-(b-d)/2,0),a.scale(1/(d/b),1)):d>b?(a.scale(1,b/d),a.translate(0,(d-b)/2),c?a.fill():a.stroke(),a.translate(0,-(d-b)/2),a.scale(1,1/(b/d))):c?a.fill():a.stroke()}else c?a.fill():a.stroke();else a.stroke()} -function dk(a,b,c,d,e){if(null!==c){var g=1,h=1;if("string"===typeof c)d?b.El!==c&&(b.fillStyle=c,b.El=c):b.mn!==c&&(b.strokeStyle=c,b.mn=c);else if(c.type===me)c=c.color,d?b.El!==c&&(b.fillStyle=c,b.El=c):b.mn!==c&&(b.strokeStyle=c,b.mn=c);else{var k,h=a.Ga,g=h.width,h=h.height;if(e)var l=a.wa,g=l.width,h=l.height;var m=b instanceof CanvasRenderingContext2D;if(m&&(c.Fg&&c.type===Gj||c.Kx===g&&c.Jx===h))k=c.Fg;else{var n,p,q=p=0;e&&(l=a.wa,g=l.width,h=l.height,p=l.x,q=l.y);c.start instanceof C?(a= -c.start.x,e=c.start.y):c.start instanceof K?(a=c.start.x*g,e=c.start.y*h):(a=Wb.x*g,e=Wb.y*h);c.end instanceof C?(l=c.end.x,n=c.end.y):c.end instanceof K?(l=c.end.x*g,n=c.end.y*h):c.type===ne?(l=Yb.x*g,n=Yb.y*h):(l=Wb.x*g,n=Wb.y*h);a+=p;l+=p;e+=q;n+=q;c.type===ne?k=b.createLinearGradient(a,e,l,n):c.type===oe?(p=isNaN(c.Mo)?Math.max(g,h)/2:c.Mo,isNaN(c.Jp)?(k=0,p=Math.max(g,h)/2):k=c.Jp,k=b.createRadialGradient(a,e,k,l,n,p)):c.type===Gj?k=b.createPattern(c.pattern,"repeat"):t.Vb(c.type,"Brush type"); -if(c.type!==Gj&&(p=c.Go))for(p=p.k;p.next();)k.addColorStop(p.key,p.value);m&&(c.Fg=k,c.Kx=g,c.Jx=h)}d?b.El!==k&&(b.fillStyle=k,b.El=k):b.mn!==k&&(b.strokeStyle=k,b.mn=k)}}}X.prototype.isContainedBy=X.prototype.Ti=function(a){if(a instanceof B)a:{if(this!==a&&null!==a)for(var b=this.ga;null!==b;){if(b===a){a=!0;break a}b=b.ga}a=!1}else a=!1;return a};X.prototype.isVisibleObject=X.prototype.pl=function(){if(!this.visible)return!1;var a=this.ga;return null!==a?a.pl():!0}; -function gk(a){if(0!==(a.ka&2048)===!0){var b=a.bd;b.reset();if(!a.Fb.Q()||!a.Kc.Q()){hk(a,!1);return}b.translate(a.Fb.x,a.Fb.y);b.translate(-a.Ea.x,-a.Ea.y);var c=a.Ga;Oj(a,b,c.x,c.y,c.width,c.height);hk(a,!1);ik(a,!0)}0!==(a.ka&4096)===!0&&(null===a.ga?(a.Yh.set(a.bd),ik(a,!1)):null!==a.ga.he&&(b=a.Yh,b.reset(),b.multiply(a.ga.Yh),b.multiply(a.bd),ik(a,!1)))} -function Oj(a,b,c,d,e,g){1!==a.scale&&b.scale(a.scale);if(0!==a.angle){var h=Wb;a.We&&a.We.rd()&&(h=a.We);var k=t.O();if(a instanceof w&&a.Ub!==a)for(c=a.Ub,d=c.Ga,k.xt(d.x,d.y,d.width,d.height,h),c.Ok.Va(k),k.offset(-c.Ea.x,-c.Ea.y),h=c.ga;null!==h&&h!==a;)h.Ok.Va(k),k.offset(-h.Ea.x,-h.Ea.y),h=h.ga;else k.xt(c,d,e,g,h);b.rotate(a.angle,k.x,k.y);t.B(k)}} -X.prototype.aa=function(a){if(!0!==xi(this)){Rj(this,!0);Vj(this,!0);var b=this.ga;null!==b?a||b.aa():(a=this.h,null!==a&&(a.Yf.add(this),this instanceof y&&(a.Aa.qb||this.Wg(),null!==this.Sc&&jk(this.Sc)),a.Nf()));if(this instanceof B){var c=null;a=this.za;b=a.length;this.ba===Vh&&(c=kk(this,a,b))&&c.aa(!0);a=a.p;for(c=0;ca?a=0:1=a&&t.m("GraphObject.scale must be greater than zero"),this.Sb=a,Sj(this),this.aa(),this.i("scale",b,a))});t.g(X,"angle",X.prototype.angle);t.defineProperty(X,{angle:"angle"},function(){return this.pn},function(a){var b=this.pn;b!==a&&(f&&t.o(a,X,"angle"),a%=360,0>a&&(a+=360),b!==a&&(this.pn=a,this.aa(),Sj(this),this.i("angle",b,a)))}); -t.g(X,"desiredSize",X.prototype.Ca);t.defineProperty(X,{Ca:"desiredSize"},function(){return this.df},function(a){var b=this.df;b.N(a)||(f&&t.l(a,pa,X,"desiredSize"),this.df=a=a.Z(),this.aa(),this instanceof Y&&this.Jf(),this.i("desiredSize",b,a),a=this.S,null!==a&&0!==(this.ka&1024)&&(Mj(this,a,"width"),Mj(this,a,"height")))});t.g(X,"width",X.prototype.width); -t.defineProperty(X,{width:"width"},function(){return this.df.width},function(a){if(this.df.width!==a){f&&t.j(a,"number",X,"width");var b=this.df;this.df=a=(new pa(a,this.df.height)).freeze();this.aa();this instanceof Y&&this.Jf();this.i("desiredSize",b,a);b=this.S;null!==b&&0!==(this.ka&1024)&&Mj(this,b,"width")}});t.g(X,"height",X.prototype.height); -t.defineProperty(X,{height:"height"},function(){return this.df.height},function(a){if(this.df.height!==a){f&&t.j(a,"number",X,"height");var b=this.df;this.df=a=(new pa(this.df.width,a)).freeze();this.aa();this instanceof Y&&this.Jf();this.i("desiredSize",b,a);b=this.S;null!==b&&0!==(this.ka&1024)&&Mj(this,b,"height")}});t.g(X,"minSize",X.prototype.Ye); -t.defineProperty(X,{Ye:"minSize"},function(){return this.de},function(a){var b=this.de;b.N(a)||(f&&t.l(a,pa,X,"minSize"),a=a.copy(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.de=a,this.aa(),this.i("minSize",b,a))});t.g(X,"maxSize",X.prototype.He); -t.defineProperty(X,{He:"maxSize"},function(){return this.zj},function(a){var b=this.zj;b.N(a)||(f&&t.l(a,pa,X,"maxSize"),a=a.copy(),isNaN(a.width)&&(a.width=Infinity),isNaN(a.height)&&(a.height=Infinity),a.freeze(),this.zj=a,this.aa(),this.i("maxSize",b,a))});t.A(X,{Ea:"measuredBounds"},function(){return this.Kc});t.A(X,{Ga:"naturalBounds"},function(){return this.Yc},{configurable:!0});t.g(X,"margin",X.prototype.margin); -t.defineProperty(X,{margin:"margin"},function(){return this.fr},function(a){"number"===typeof a?a=new pb(a):f&&t.l(a,pb,X,"margin");var b=this.fr;b.N(a)||(this.fr=a=a.Z(),this.aa(),this.i("margin",b,a))});t.A(X,{transform:null},function(){0!==(this.ka&2048)===!0&&gk(this);return this.bd});t.A(X,{he:null},function(){0!==(this.ka&4096)===!0&&gk(this);return this.Yh});t.g(X,"alignment",X.prototype.alignment); -t.defineProperty(X,{alignment:"alignment"},function(){return this.re},function(a){var b=this.re;b.N(a)||(f?t.l(a,K,X,"alignment"):a.qd()&&!a.Fc()&&t.m("alignment must be a real Spot or Spot.Default"),this.re=a=a.Z(),jk(this),this.i("alignment",b,a))});t.g(X,"column",X.prototype.column);t.defineProperty(X,{column:"column"},function(){return this.hq},function(a){f&&t.o(a,X,"column");a=Math.round(a);var b=this.hq;b!==a&&(0>a&&t.ha(a,">= 0",X,"column"),this.hq=a,this.aa(),this.i("column",b,a))}); -t.g(X,"columnSpan",X.prototype.tD);t.defineProperty(X,{tD:"columnSpan"},function(){return this.gj},function(a){f&&t.o(a,X,"columnSpan");a=Math.round(a);var b=this.gj;b!==a&&(1>a&&t.ha(a,">= 1",X,"columnSpan"),this.gj=a,this.aa(),this.i("columnSpan",b,a))});t.g(X,"row",X.prototype.gc);t.defineProperty(X,{gc:"row"},function(){return this.Lr},function(a){f&&t.o(a,X,"row");a=Math.round(a);var b=this.Lr;b!==a&&(0>a&&t.ha(a,">= 0",X,"row"),this.Lr=a,this.aa(),this.i("row",b,a))});t.g(X,"rowSpan",X.prototype.rowSpan); -t.defineProperty(X,{rowSpan:"rowSpan"},function(){return this.Gj},function(a){f&&t.o(a,X,"rowSpan");a=Math.round(a);var b=this.Gj;b!==a&&(1>a&&t.ha(a,">= 1",X,"rowSpan"),this.Gj=a,this.aa(),this.i("rowSpan",b,a))});t.g(X,"alignmentFocus",X.prototype.Qj); -t.defineProperty(X,{Qj:"alignmentFocus"},function(){return this.aq},function(a){var b=this.aq;b.N(a)||(f?t.l(a,K,X,"alignmentFocus"):a.qd()&&!a.Fc()&&t.m("alignmentFocus must be a real Spot or Spot.Default"),this.aq=a=a.Z(),this.aa(),this.i("alignmentFocus",b,a))});t.g(X,"portId",X.prototype.sd); -t.defineProperty(X,{sd:"portId"},function(){return this.Ar},function(a){var b=this.Ar;if(b!==a){f&&null!==a&&t.j(a,"string",X,"portId");var c=this.S;null===c||c instanceof y||(t.m("portID being set on a Link: "+a),c=null);null!==b&&c&&sk(c,this);this.Ar=a;if(null!==a&&c){c.pj=!0;null===c.yd&&tk(c);var d=this.sd;null!==d&&c.yd.add(d,this)}this.i("portId",b,a)}});function uk(a){var b={value:null};vk(a,b);return b.value} -function vk(a,b){var c=a.ga;return null===c||!vk(c,b)&&a.visible?(b.value=a,!1):!0}function ok(a){var b=a.S;b instanceof y&&(a=a.h)&&!a.Aa.qb&&b.Wg()}t.g(X,"toSpot",X.prototype.mb);t.defineProperty(X,{mb:"toSpot"},function(){return null!==this.V?this.V.Pj:Ob},function(a){null===this.V&&this.Ge();var b=this.V.Pj;b.N(a)||(f&&t.l(a,K,X,"toSpot"),a=a.Z(),this.V.Pj=a,this.i("toSpot",b,a),ok(this))});t.g(X,"toEndSegmentLength",X.prototype.mk); -t.defineProperty(X,{mk:"toEndSegmentLength"},function(){return null!==this.V?this.V.Nj:10},function(a){null===this.V&&this.Ge();var b=this.V.Nj;b!==a&&(f&&t.j(a,"number",X,"toEndSegmentLength"),0>a&&t.ha(a,">= 0",X,"toEndSegmentLength"),this.V.Nj=a,this.i("toEndSegmentLength",b,a),ok(this))});t.g(X,"toEndSegmentDirection",X.prototype.Lp); -t.defineProperty(X,{Lp:"toEndSegmentDirection"},function(){return null!==this.V?this.V.Mj:Kj},function(a){null===this.V&&this.Ge();var b=this.V.Mj;b!==a&&(f&&t.tb(a,y,X,"toEndSegmentDirection"),this.V.Mj=a,this.i("toEndSegmentDirection",b,a),ok(this))});t.g(X,"toShortLength",X.prototype.Mp); -t.defineProperty(X,{Mp:"toShortLength"},function(){return null!==this.V?this.V.Oj:0},function(a){null===this.V&&this.Ge();var b=this.V.Oj;b!==a&&(f&&t.j(a,"number",X,"toShortLength"),this.V.Oj=a,this.i("toShortLength",b,a),ok(this))});t.g(X,"toLinkable",X.prototype.kB);t.defineProperty(X,{kB:"toLinkable"},function(){return this.gs},function(a){var b=this.gs;b!==a&&(f&&null!==a&&t.j(a,"boolean",X,"toLinkable"),this.gs=a,this.i("toLinkable",b,a))});t.g(X,"toMaxLinks",X.prototype.NF); -t.defineProperty(X,{NF:"toMaxLinks"},function(){return this.hs},function(a){var b=this.hs;b!==a&&(f&&t.o(a,X,"toMaxLinks"),0>a&&t.ha(a,">= 0",X,"toMaxLinks"),this.hs=a,this.i("toMaxLinks",b,a))});t.g(X,"fromSpot",X.prototype.lb);t.defineProperty(X,{lb:"fromSpot"},function(){return null!==this.V?this.V.nj:Ob},function(a){null===this.V&&this.Ge();var b=this.V.nj;b.N(a)||(f&&t.l(a,K,X,"fromSpot"),a=a.Z(),this.V.nj=a,this.i("fromSpot",b,a),ok(this))});t.g(X,"fromEndSegmentLength",X.prototype.ek); -t.defineProperty(X,{ek:"fromEndSegmentLength"},function(){return null!==this.V?this.V.lj:10},function(a){null===this.V&&this.Ge();var b=this.V.lj;b!==a&&(f&&t.j(a,"number",X,"fromEndSegmentLength"),0>a&&t.ha(a,">= 0",X,"fromEndSegmentLength"),this.V.lj=a,this.i("fromEndSegmentLength",b,a),ok(this))});t.g(X,"fromEndSegmentDirection",X.prototype.So); -t.defineProperty(X,{So:"fromEndSegmentDirection"},function(){return null!==this.V?this.V.kj:Kj},function(a){null===this.V&&this.Ge();var b=this.V.kj;b!==a&&(f&&t.tb(a,y,X,"fromEndSegmentDirection"),this.V.kj=a,this.i("fromEndSegmentDirection",b,a),ok(this))});t.g(X,"fromShortLength",X.prototype.To); -t.defineProperty(X,{To:"fromShortLength"},function(){return null!==this.V?this.V.mj:0},function(a){null===this.V&&this.Ge();var b=this.V.mj;b!==a&&(f&&t.j(a,"number",X,"fromShortLength"),this.V.mj=a,this.i("fromShortLength",b,a),ok(this))});t.g(X,"fromLinkable",X.prototype.$z);t.defineProperty(X,{$z:"fromLinkable"},function(){return this.Cq},function(a){var b=this.Cq;b!==a&&(f&&null!==a&&t.j(a,"boolean",X,"fromLinkable"),this.Cq=a,this.i("fromLinkable",b,a))});t.g(X,"fromMaxLinks",X.prototype.dE); -t.defineProperty(X,{dE:"fromMaxLinks"},function(){return this.Dq},function(a){var b=this.Dq;b!==a&&(f&&t.o(a,X,"fromMaxLinks"),0>a&&t.ha(a,">= 0",X,"fromMaxLinks"),this.Dq=a,this.i("fromMaxLinks",b,a))});t.g(X,"cursor",X.prototype.cursor);t.defineProperty(X,{cursor:"cursor"},function(){return this.oq},function(a){var b=this.oq;b!==a&&(t.j(a,"string",X,"cursor"),this.oq=a,this.i("cursor",b,a))});t.g(X,"click",X.prototype.click); -t.defineProperty(X,{click:"click"},function(){return null!==this.R?this.R.$h:null},function(a){null===this.R&&Jj(this);var b=this.R.$h;b!==a&&(null!==a&&t.j(a,"function",X,"click"),this.R.$h=a,this.i("click",b,a))});t.g(X,"doubleClick",X.prototype.Km);t.defineProperty(X,{Km:"doubleClick"},function(){return null!==this.R?this.R.fi:null},function(a){null===this.R&&Jj(this);var b=this.R.fi;b!==a&&(null!==a&&t.j(a,"function",X,"doubleClick"),this.R.fi=a,this.i("doubleClick",b,a))}); -t.g(X,"contextClick",X.prototype.Cs);t.defineProperty(X,{Cs:"contextClick"},function(){return null!==this.R?this.R.bi:null},function(a){null===this.R&&Jj(this);var b=this.R.bi;b!==a&&(null!==a&&t.j(a,"function",X,"contextClick"),this.R.bi=a,this.i("contextClick",b,a))});t.g(X,"mouseEnter",X.prototype.vA); -t.defineProperty(X,{vA:"mouseEnter"},function(){return null!==this.R?this.R.qr:null},function(a){null===this.R&&Jj(this);var b=this.R.qr;b!==a&&(null!==a&&t.j(a,"function",X,"mouseEnter"),this.R.qr=a,this.i("mouseEnter",b,a))});t.g(X,"mouseLeave",X.prototype.wA);t.defineProperty(X,{wA:"mouseLeave"},function(){return null!==this.R?this.R.rr:null},function(a){null===this.R&&Jj(this);var b=this.R.rr;b!==a&&(null!==a&&t.j(a,"function",X,"mouseLeave"),this.R.rr=a,this.i("mouseLeave",b,a))}); -t.g(X,"mouseOver",X.prototype.et);t.defineProperty(X,{et:"mouseOver"},function(){return null!==this.R?this.R.pi:null},function(a){null===this.R&&Jj(this);var b=this.R.pi;b!==a&&(null!==a&&t.j(a,"function",X,"mouseOver"),this.R.pi=a,this.i("mouseOver",b,a))});t.g(X,"mouseHover",X.prototype.dt); -t.defineProperty(X,{dt:"mouseHover"},function(){return null!==this.R?this.R.oi:null},function(a){null===this.R&&Jj(this);var b=this.R.oi;b!==a&&(null!==a&&t.j(a,"function",X,"mouseHover"),this.R.oi=a,this.i("mouseHover",b,a))});t.g(X,"mouseHold",X.prototype.ct);t.defineProperty(X,{ct:"mouseHold"},function(){return null!==this.R?this.R.ni:null},function(a){null===this.R&&Jj(this);var b=this.R.ni;b!==a&&(null!==a&&t.j(a,"function",X,"mouseHold"),this.R.ni=a,this.i("mouseHold",b,a))}); -t.g(X,"mouseDragEnter",X.prototype.UE);t.defineProperty(X,{UE:"mouseDragEnter"},function(){return null!==this.R?this.R.or:null},function(a){null===this.R&&Jj(this);var b=this.R.or;b!==a&&(null!==a&&t.j(a,"function",X,"mouseDragEnter"),this.R.or=a,this.i("mouseDragEnter",b,a))});t.g(X,"mouseDragLeave",X.prototype.uA); -t.defineProperty(X,{uA:"mouseDragLeave"},function(){return null!==this.R?this.R.pr:null},function(a){null===this.R&&Jj(this);var b=this.R.pr;b!==a&&(null!==a&&t.j(a,"function",X,"mouseDragLeave"),this.R.pr=a,this.i("mouseDragLeave",b,a))});t.g(X,"mouseDrop",X.prototype.bt);t.defineProperty(X,{bt:"mouseDrop"},function(){return null!==this.R?this.R.mi:null},function(a){null===this.R&&Jj(this);var b=this.R.mi;b!==a&&(null!==a&&t.j(a,"function",X,"mouseDrop"),this.R.mi=a,this.i("mouseDrop",b,a))}); -t.g(X,"actionDown",X.prototype.wz);t.defineProperty(X,{wz:"actionDown"},function(){return null!==this.R?this.R.Wp:null},function(a){null===this.R&&Jj(this);var b=this.R.Wp;b!==a&&(null!==a&&t.j(a,"function",X,"actionDown"),this.R.Wp=a,this.i("actionDown",b,a))});t.g(X,"actionUp",X.prototype.yz); -t.defineProperty(X,{yz:"actionUp"},function(){return null!==this.R?this.R.Yp:null},function(a){null===this.R&&Jj(this);var b=this.R.Yp;b!==a&&(null!==a&&t.j(a,"function",X,"actionUp"),this.R.Yp=a,this.i("actionUp",b,a))});t.g(X,"actionMove",X.prototype.xz);t.defineProperty(X,{xz:"actionMove"},function(){return null!==this.R?this.R.Xp:null},function(a){null===this.R&&Jj(this);var b=this.R.Xp;b!==a&&(null!==a&&t.j(a,"function",X,"actionMove"),this.R.Xp=a,this.i("actionMove",b,a))}); -t.g(X,"actionCancel",X.prototype.vz);t.defineProperty(X,{vz:"actionCancel"},function(){return null!==this.R?this.R.Vp:null},function(a){null===this.R&&Jj(this);var b=this.R.Vp;b!==a&&(null!==a&&t.j(a,"function",X,"actionCancel"),this.R.Vp=a,this.i("actionCancel",b,a))});t.g(X,"toolTip",X.prototype.Et); -t.defineProperty(X,{Et:"toolTip"},function(){return null!==this.R?this.R.zi:null},function(a){null===this.R&&Jj(this);var b=this.R.zi;b!==a&&(null!==a&&t.l(a,We,X,"toolTip"),this.R.zi=a,this.i("toolTip",b,a))});t.g(X,"contextMenu",X.prototype.contextMenu);t.defineProperty(X,{contextMenu:"contextMenu"},function(){return null!==this.R?this.R.ci:null},function(a){null===this.R&&Jj(this);var b=this.R.ci;b!==a&&(null!==a&&t.l(a,We,X,"contextMenu"),this.R.ci=a,this.i("contextMenu",b,a))}); -X.prototype.bind=X.prototype.bind=function(a){a.eg=this;var b=this.Ro();null!==b&&wk(b)&&t.m("Cannot add a Binding to a template that has already been copied: "+a);null===this.Bc&&(this.Bc=new H(Ge));this.Bc.add(a)};X.prototype.findTemplateBinder=X.prototype.Ro=function(){for(var a=this instanceof B?this:this.ga;null!==a;){if(null!==a.Gl&&a instanceof B)return a;a=a.ga}return null};X.fromSvg=function(a){return xk(a)};X.prototype.setProperties=function(a){t.Nw(this,a)};var yk; -X.make=yk=function(a,b){var c=arguments,d=null,e=null;if("function"===typeof a)e=a;else if("string"===typeof a){var g=zk.Ba(a);"function"===typeof g?(c=Array.prototype.slice.call(arguments),d=g(c)):e=ba[a]}null===d&&(void 0===e&&(d=window.$,void 0!==d&&void 0!==d.noop&&t.m("GraphObject.make failed to complete. Is it conflicting with another $ var? (such as jQuery)"),t.m("GraphObject.make failed to complete, it may be conflicting with another var.")),null!==e&&e.constructor||t.m("GraphObject.make requires a class function or class name, not: "+ -a),d=new e);g=1;d instanceof u&&1d)&&t.m("Must specify non-negative integer row for RowColumnDefinition "+b),c.Tl=!0,c.te=d):void 0!==b.column?(d=b.column,(void 0===d||null===d||Infinity===d||isNaN(d)||0>d)&&t.m("Must specify non-negative integer column for RowColumnDefinition "+b),c.Tl=!1,c.te=d):t.m("Must specify row or column value in a RowColumnDefinition "+b),d=t.qH(b,"row","column"),t.Nw(c,d)):t.Nw(c,b);else t.m('Unknown initializer "'+b+'" for object being constructed by GraphObject.make: '+ -a)}var zk;X.Builders=zk=new sa("string","function"); -zk.add("Button",function(){var a=new ke(ne);a.addColorStop(0,"white");a.addColorStop(1,"lightgray");var b=new ke(ne);b.addColorStop(0,"white");b.addColorStop(1,"dodgerblue");var c=yk(B,Vh,{Rs:!0},yk(Y,{name:"ButtonBorder",Ib:"RoundedRectangle",fill:a,stroke:"gray"}));c.vA=function(a,c){var g=c.qa(0),h=c._buttonFillOver;void 0===h&&(h=b);c._buttonFillNormal=g.fill;g.fill=h;h=c._buttonStrokeOver;void 0===h&&(h="blue");c._buttonStrokeNormal=g.stroke;g.stroke=h};c.wA=function(b,c){var g=c.qa(0),h=c._buttonFillNormal; -void 0===h&&(h=a);g.fill=h;h=c._buttonStrokeNormal;void 0===h&&(h="gray");g.stroke=h};return c}); -zk.add("TreeExpanderButton",function(){var a=yk("Button",yk(Y,{name:"ButtonIcon",Ib:"MinusLine",Ca:J.Sp},(new Ge("figure","isTreeExpanded",function(a,c){var d=null,e=c.ga;e&&(d=a?e._treeExpandedFigure:e._treeCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).DA("")),{visible:!1},(new Ge("visible","isTreeLeaf",function(a){return!a})).DA(""));a.click=function(a,c){var d=c.S;d instanceof We&&(d=d.Dh);if(d instanceof y){var e=d.h;if(null!==e){e=e.lg;if(d.Gc){if(!e.canCollapseTree(d))return}else if(!e.canExpandTree(d))return; -a.Fe=!0;d.Gc?e.collapseTree(d):e.expandTree(d)}}};return a}); -zk.add("SubGraphExpanderButton",function(){var a=yk("Button",yk(Y,{name:"ButtonIcon",Ib:"MinusLine",Ca:J.Sp},(new Ge("figure","isSubGraphExpanded",function(a,c){var d=null,e=c.ga;e&&(d=a?e._subGraphExpandedFigure:e._subGraphCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).DA("")));a.click=function(a,c){var d=c.S;d instanceof We&&(d=d.Dh);if(d instanceof z){var e=d.h;if(null!==e){e=e.lg;if(d.Ve){if(!e.canCollapseSubGraph(d))return}else if(!e.canExpandSubGraph(d))return;a.Fe=!0;d.Ve?e.collapseSubGraph(d): -e.expandSubGraph(d)}}};return a});zk.add("ContextMenuButton",function(){var a=yk("Button");a.Sh=Ij;var b=a.le("ButtonBorder");b instanceof Y&&(b.Ib="Rectangle",b.G=new K(0,0,2,2),b.H=new K(1,1,-2,-2));return a}); -function B(a){X.call(this);void 0===a?0===arguments.length?this.ba=bh:t.m("invalid argument to Panel constructor: undefined"):(t.tb(a,B,B,"type"),this.ba=a);this.za=new H(X);this.Le=J.Up;this.Jg=!1;this.ba===$h&&(this.Jg=!0);this.Df=1;this.rq=Pb;this.kc=Yg;this.ba===ea&&fl(this);this.to=Zg;this.Hq=(new pa(10,10)).freeze();this.Iq=J.ok;this.Gl=this.Ll=null;this.By="";this.Kg=this.sj=null;this.Tn="category";this.Zf=null;this.Bi=new D(NaN,NaN,NaN,NaN);this.ro=null;this.pj=!1}t.ia("Panel",B);t.Fh(B); -t.Oa(B,X);function fl(a){a.hj=J.Up;a.lh=1;a.ei=null;a.Nl=null;a.kh=1;a.jh=null;a.Ml=null;a.$c=[];a.Vc=[];a.lm=gl;a.Hl=gl;a.Ai=0;a.ki=0} -B.prototype.cloneProtected=function(a){X.prototype.cloneProtected.call(this,a);a.ba=this.ba;a.Le=this.Le.Z();a.Jg=this.Jg;a.Df=this.Df;a.rq=this.rq.Z();a.kc=this.kc;if(a.ba===ea){a.hj=this.hj.Z();a.lh=this.lh;a.ei=this.ei;a.Nl=this.Nl;a.kh=this.kh;a.jh=this.jh;a.Ml=this.Ml;var b=[];if(0a&&t.ha(a,">= 0",B,"padding"),a=new pb(a)):(t.l(a,pb,B,"padding"),0>a.left&&t.ha(a.left,">= 0",B,"padding:val.left"),0>a.right&&t.ha(a.right,">= 0",B,"padding:val.right"),0>a.top&&t.ha(a.top,">= 0",B,"padding:val.top"),0>a.bottom&&t.ha(a.bottom,">= 0",B,"padding:val.bottom"));var b=this.Le;b.N(a)||(this.Le=a=a.Z(),this.aa(),this.i("padding",b,a))});t.g(B,"defaultAlignment",B.prototype.Yj); -t.defineProperty(B,{Yj:"defaultAlignment"},function(){return this.rq},function(a){var b=this.rq;b.N(a)||(f&&t.l(a,K,B,"defaultAlignment"),this.rq=a=a.Z(),this.aa(),this.i("defaultAlignment",b,a))});t.g(B,"defaultStretch",B.prototype.Qz);t.defineProperty(B,{Qz:"defaultStretch"},function(){return this.kc},function(a){var b=this.kc;b!==a&&(t.tb(a,X,B,"defaultStretch"),this.kc=a,this.aa(),this.i("defaultStretch",b,a))});t.g(B,"defaultSeparatorPadding",B.prototype.CH); -t.defineProperty(B,{CH:"defaultSeparatorPadding"},function(){return void 0===this.hj?J.Up:this.hj},function(a){if(void 0!==this.hj){"number"===typeof a?a=new pb(a):f&&t.l(a,pb,B,"defaultSeparatorPadding");var b=this.hj;b.N(a)||(this.hj=a=a.Z(),this.i("defaultSeparatorPadding",b,a))}});t.g(B,"defaultRowSeparatorStroke",B.prototype.AH); -t.defineProperty(B,{AH:"defaultRowSeparatorStroke"},function(){return void 0===this.ei?null:this.ei},function(a){var b=this.ei;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.ei=a,this.i("defaultRowSeparatorStroke",b,a))});t.g(B,"defaultRowSeparatorStrokeWidth",B.prototype.BH); -t.defineProperty(B,{BH:"defaultRowSeparatorStrokeWidth"},function(){return void 0===this.lh?1:this.lh},function(a){if(void 0!==this.lh){var b=this.lh;b!==a&&(this.lh=a,this.i("defaultRowSeparatorStrokeWidth",b,a))}});t.g(B,"defaultRowSeparatorDashArray",B.prototype.zH); -t.defineProperty(B,{zH:"defaultRowSeparatorDashArray"},function(){return void 0===this.Nl?null:this.Nl},function(a){if(void 0!==this.Nl){var b=this.Nl;b!==a&&(Array.isArray(a)||t.Vb(a,"Array",B,"defaultRowSeparatorDashArray:val"),this.Nl=a,this.i("defaultRowSeparatorDashArray",b,a))}});t.g(B,"defaultColumnSeparatorStroke",B.prototype.vH); -t.defineProperty(B,{vH:"defaultColumnSeparatorStroke"},function(){return void 0===this.jh?null:this.jh},function(a){if(void 0!==this.jh){var b=this.jh;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.jh=a,this.i("defaultColumnSeparatorStroke",b,a))}});t.g(B,"defaultColumnSeparatorStrokeWidth",B.prototype.wH); -t.defineProperty(B,{wH:"defaultColumnSeparatorStrokeWidth"},function(){return void 0===this.kh?1:this.kh},function(a){if(void 0!==this.kh){var b=this.kh;b!==a&&(this.kh=a,this.i("defaultColumnSeparatorStrokeWidth",b,a))}});t.g(B,"defaultColumnSeparatorDashArray",B.prototype.uH); -t.defineProperty(B,{uH:"defaultColumnSeparatorDashArray"},function(){return void 0===this.Ml?null:this.Ml},function(a){if(void 0!==this.Ml){var b=this.Ml;b!==a&&(Array.isArray(a)||t.Vb(a,"Array",B,"defaultColumnSeparatorDashArray:val"),this.Ml=a,this.i("defaultColumnSeparatorDashArray",b,a))}});t.g(B,"viewboxStretch",B.prototype.lJ); -t.defineProperty(B,{lJ:"viewboxStretch"},function(){return this.to},function(a){var b=this.to;b!==a&&(t.tb(a,X,B,"viewboxStretch"),this.to=a,this.i("viewboxStretch",b,a))});t.g(B,"gridCellSize",B.prototype.Ms); -t.defineProperty(B,{Ms:"gridCellSize"},function(){return this.Hq},function(a){var b=this.Hq;b.N(a)||(t.l(a,pa,B,"gridCellSize"),a.Q()&&0!==a.width&&0!==a.height||t.m("Invalid Panel.gridCellSize: "+a),this.Hq=a.Z(),null!==this.h&&this===this.h.Yo&&si(this.h),this.pa(),this.i("gridCellSize",b,a))});t.g(B,"gridOrigin",B.prototype.cA); -t.defineProperty(B,{cA:"gridOrigin"},function(){return this.Iq},function(a){var b=this.Iq;b.N(a)||(t.l(a,C,B,"gridOrigin"),a.Q()||t.m("Invalid Panel.gridOrigin: "+a),this.Iq=a.Z(),this.h&&si(this.h),this.pa(),this.i("gridOrigin",b,a))}); -B.prototype.hl=function(a,b){var c=this.opacity,d=1;1!==c&&(d=a.globalAlpha,a.globalAlpha=d*c);if(this.ba===$h){c=this.fk()*b.scale;0>=c&&(c=1);var e=this.Ms,d=e.width,e=e.height,g=this.Ga,h=g.width,g=g.height,k=Math.ceil(h/d),l=Math.ceil(g/e),m=this.cA;a.save();a.beginPath();a.rect(0,0,h,g);a.clip();for(var n=[],p=this.za.p,q=this.za.length,r=0;rd*v*c))break}else for(L=G=Math.floor(-m.y/e);L<=G+l&&!(N=L*e+m.y,0<=N&&N<=g&&hl(L,v,s)&&(x&&!F?Lj(a,0,N,h,N,E,r.ad):(a.moveTo(0,N),a.lineTo(h,N)),2>e*v*c));L++);a.stroke();x&&(void 0!==a.setLineDash?(a.setLineDash(t.Xh),a.lineDashOffset=0):void 0!==a.webkitLineDash?(a.webkitLineDash=t.Xh,a.webkitLineDashOffset=0):void 0!==a.mozDash&&(a.mozDash=null,a.mozDashOffset=0))}a.restore();ca(b,a,!1)}else{this.ba===ea&&(a.lineCap="butt",il(this,a,!0,this.$c,!0),il(this, -a,!1,this.Vc,!0),nl(this,a,!0,this.$c),nl(this,a,!1,this.Vc),il(this,a,!0,this.$c,!1),il(this,a,!1,this.Vc,!1));F=this.za.length;for(e=0;e -h.height&&(m-=r-h.height):r>h.width&&(m-=r-h.width);g=g.position+m/2;b.lineWidth=m;r=a.padding;c?(g+=r.top,m=r.left,r=h.width-r.right,n&&!q?Lj(b,m,g,r,g,p,0):(b.moveTo(m,g),b.lineTo(r,g))):(g+=r.left,m=r.top,r=h.height-r.bottom,n&&!q?Lj(b,g,m,g,r,p,0):(b.moveTo(g,m),b.lineTo(g,r)));b.stroke();n&&(void 0!==b.setLineDash?(b.setLineDash(t.Xh),b.lineDashOffset=0):void 0!==b.webkitLineDash?(b.webkitLineDash=t.Xh,b.webkitLineDashOffset=0):void 0!==b.mozDash&&(b.mozDash=null,b.mozDashOffset=0))}}} -function il(a,b,c,d,e){for(var g=d.length,h,k=a.wa,l=0;lm)){var n=ol(h),p=h.dn;isNaN(p)&&(p=c?a.lh:a.kh);var q=h.cn;null===q&&(q=c?a.ei:a.jh);null===q&&(p=0);n-=p;p=h.position+p;n+=h.Yb;p+n>m&&(n=m-p);0>=n||(m=a.padding,dk(a,b,h.background,!0),c?b.fillRect(m.left,p+m.top,k.width-(m.left+m.right),n):b.fillRect(p+m.left,m.top,n,k.height-(m.top+m.bottom)))}}} -function hl(a,b,c){if(0!==a%b)return!1;b=c.length;for(var d=0;dGc&&(mc=Gc),sl(ha,ha.Yb+mc),Gc=Math.max(Gc-mc,0));1!==na.gj||!qh&&Od!==Xg&&Od!==Hj||(ha=this.me(rc),mc=Math.max(Qe-ha.Yb,0),mc>wc&&(mc=wc),sl(ha,ha.Yb+mc),wc=Math.max(wc-mc,0));fg&&lk(na)}}}t.Da(ph);for(var ee=0,fe=0,tb=this.Sv,ka=0;ka=this.Kw);hc++)ha=this.ne(na.gc+hc),Qd.height+=Math.max(ha.Oh,isNaN(ha.Ef)?ha.qf:Math.min(ha.Ef,ha.qf));for(hc=1;hc=this.Sv);hc++)ha=this.me(na.column+hc),Qd.width+=Math.max(ha.Oh,isNaN(ha.Ef)?ha.qf:Math.min(ha.Ef,ha.qf));yb.width+=Qd.width;yb.height+=Qd.height;Rb=na.margin;Lf=Rb.right+Rb.left;Mf=Rb.top+Rb.bottom;Bh(na,yb.width,yb.height,mf,bb);for(var te=na.Ea,Qe=Math.max(te.width+Lf,0),Re=Math.max(te.height+Mf,0),Eg=0,hc=0;hcsc&&(sl(ha,Math.min(ha.qf,sc+Rd)),ha.Eb!==sc&&(Rd-=ha.Eb-sc));if(-1===ha.index-1)break;ha=this.ne(ha.index-1)}for(var Se=0,hc=0;hcsc&&(sl(ha,Math.min(ha.qf,sc+Rd)),ha.Eb!==sc&&(Rd-=ha.Eb-sc));if(-1===ha.index-1)break;ha=this.me(ha.index-1)}}t.Da(Ag);t.dk(Qd);t.dk(yb);for(var pf=0,he=0,Od=Qj(this),Fg= -this.Ca,gg=this.He,Hc=fe=ee=0,ie=0,tb=this.Sv,ka=0;kash)Bh(Sb, -Infinity,Infinity),Sd=Sb.Ea,ue.nk(Sd),this.Zh.add(Sd);else{var Pf=Sb.tf,uo=Sb.tt,ll=Sb.Qj;ll.qd()&&(ll=Wb);var uj=Sb.ut,pq=Sb.VA,ki,li,vj=0;if(Pf<-sh||Pf>=sh){var vo=rj.SE,wj=rj.RE;uj!==Jg&&(vj=rj.computeAngle(Sb,uj,wj),Sb.angle=vj);ki=vo.x-Ue.x;li=vo.y-Ue.y}else{var qf,uh;if(0<=Pf)qf=ji.p[Pf],uh=Pfc||q>d)this.aa(),Bh(this,p>c?c:p,q>d?d:q);break;case Qc:Rj(this,!0);Bh(this,c+s,d+v,0,0);break;case Ij:Rj(this,!0);Bh(this,c+s,q+v,0,0);break;case Hj:Rj(this,!0),Bh(this,p+s,d+v,0,0)}}l=this.wa;l.x=a; -l.y=b;l.width=c;l.height=d;var x=this.ba.Rb;switch(x){case "Position":for(var E=e.x-this.padding.left,F=e.y-this.padding.top,G=0;G=this.Kw);ka++){var na=this.ne(Bb+ka);Cb.height+=na.total}for(ka=1;ka=this.Sv);ka++){var kj=this.me(Dd+ka);Cb.width+=kj.total}var zg=fc.Eb+Cb.width,rc=Cd.Eb+Cb.height;k.x=be;k.y=Bc;k.width=zg;k.height=rc;Bc+rc>e.height&&(rc=Math.max(e.height- -Bc,0));be+zg>e.width&&(zg=Math.max(e.width-be,0));var oh=be,gc=Bc,ph=zg,Ag=rc,Dc=bb.alignment,Ec,Fc,wc,Gc;if(Dc.Fc()){Dc=this.Yj;Dc.rd()||(Dc=Wb);Ec=Dc.x;Fc=Dc.y;wc=Dc.offsetX;Gc=Dc.offsetY;var Kf=fc.alignment,ha=Cd.alignment;Kf.rd()&&(Ec=Kf.x,wc=Kf.offsetX);ha.rd()&&(Fc=ha.y,Gc=ha.offsetY)}else Ec=Dc.x,Fc=Dc.y,wc=Dc.offsetX,Gc=Dc.offsetY;if(isNaN(Ec)||isNaN(Fc))Fc=Ec=0.5,Gc=wc=0;var Nd=ce.width,Ed=ce.height,lj=bb.He,mj=bb.Ye,Nd=Math.min(lj.width,Nd),Ed=Math.min(lj.height,Ed),Nd=Math.max(mj.width, -Nd),Ed=Math.max(mj.height,Ed),mc=bb.margin,lb=mc.left+mc.right,mb=mc.top+mc.bottom,Bg=nk(bb,Cd,fc);if(isNaN(bb.Ca.width)&&isNaN(fc.width)&&Bg===Qc||Bg===Ij)Nd=Math.max(zg-lb,0);if(isNaN(bb.Ca.height)&&isNaN(Cd.height)&&Bg===Qc||Bg===Hj)Ed=Math.max(rc-mb,0);var jl=Ed+mb;k.x+=k.width*Ec-(Nd+lb)*Ec+wc+mc.left;k.y+=k.height*Fc-jl*Fc+Gc+mc.top;bb.visible&&(Db(oh,gc,ph,Ag,k.x,k.y,Nd,Ed)?bb.Dc(k.x,k.y,Nd,Ed):bb.Dc(k.x,k.y,Nd,Ed,new D(oh,gc,ph,Ag)))}}}}t.dk(Cb);for(Bb=0;Bb=rh){var Eg=this.SE,Rd=this.RE;ge!==Jg&&(hc= -this.computeAngle(nd,ge,Rd),nd.angle=hc);of=Eg.x;Qd=Eg.y}else{var sc=void 0,Se=void 0;if(0<=Pd)sc=Cg.p[Pd],Se=Pdn.width||m.y>n.height||0>m.x+m.width||0>m.y+m.height)){m=t.bh();m.set(h);if(l instanceof B?l.ck(a,b,c,d,e,m):Pj(l,a,d,m))null!==b&&(l=b(l)),l&& -(null===c||c(l))&&e.add(l);t.Se(m)}}}void 0===g&&t.Se(h);return d}void 0===g&&t.Se(h);return!1};function Dl(a,b,c,d){for(var e=a.za.length;e--;){var g=a.za.p[e];if(g.visible){var h=g.wa,k=a.Ga;h.x>k.width||h.y>k.height||0>h.x+h.width||0>h.y+h.height||(g instanceof B&&Dl(g,b,c,d),null!==b&&(g=b(g)),g&&(null===c||c(g))&&d.add(g))}}} -aa.Mm=function(a,b,c,d,e,g){if(!1===this.Ze)return!1;void 0===c&&(c=null);void 0===d&&(d=null);var h=this.Ga,k=this.Bg(),l=k?a:$a(t.ic(a.x,a.y),this.transform),m=k?b:$a(t.ic(b.x,b.y),this.transform),n=l.$j(m),p=0r.width||q.y>r.height||0>q.x+q.width||0>q.y+q.height||(n.Bg()?(q=n.transform,$a(k.set(a),q),$a(l.set(b),q)):(k.set(a),l.set(b)),n instanceof B?!n.Mm(k,l,c,d,e,g):!n.XD(k,l,e))||(null!==c&&(n=c(n)),n&&(null===d||d(n))&&g.add(n))}t.B(k);t.B(l)}return e?p:h}return!1}; -function pl(a){var b=a.G;if(void 0===b||b===Pb)b=null;null===b&&a instanceof Y&&(a=a.Ra,null!==a&&(b=a.G));null===b&&(b=Tb);return b}function ql(a){var b=a.H;if(void 0===b||b===Pb)b=null;null===b&&a instanceof Y&&(a=a.Ra,null!==a&&(b=a.H));null===b&&(b=$b);return b}B.prototype.add=B.prototype.add=function(a){t.l(a,X,B,"add:element");this.Ad(this.za.count,a)};B.prototype.elt=B.prototype.qa=function(a){return this.za.qa(a)}; -B.prototype.insertAt=B.prototype.Ad=function(a,b){b instanceof w&&t.m("Cannot add a Part to a Panel: "+b);if(this===b||this.Ti(b))this===b&&t.m("Cannot make a Panel contain itself: "+this.toString()),t.m("Cannot make a Panel indirectly contain itself: "+this.toString()+" already contains "+b.toString());var c=b.ga;null!==c&&c!==this&&t.m("Cannot add a GraphObject that already belongs to another Panel to this Panel: "+b.toString()+", already contained by "+c.toString()+", cannot be shared by this Panel: "+ -this.toString());this.ba!==$h||b instanceof Y||t.m("Can only add Shapes to a Grid Panel, not: "+b);b.vl(this);b.gm=null;if(null!==this.Xs){var d=b.data;null!==d&&"object"===typeof d&&(null===this.Zf&&(this.Zf=new sa(Object,B)),this.Zf.add(d,b))}var e=this.za,d=-1;if(c===this){for(var g=-1,h=e.count,k=0;k=e.count&&a>=e.count)return;e.gd(g);d=g}else t.m("element "+b.toString()+" has panel "+c.toString()+" but is not contained by it.")}if(0>a|| -a>e.count)a=e.count;e.Ad(a,b);this.aa();b.aa();null!==b.sd&&(this.pj=!0);b instanceof B&&!0===b.pj&&(this.pj=!0);c=this.S;null!==c&&(c.Aj=null,c.yj=NaN,null!==b.sd&&c instanceof y&&(c.pj=!0),e=this.h,null!==e&&e.Aa.qb||(-1!==d&&c.Uc(Td,"elements",this,b,null,d,null),c.Uc(Jd,"elements",this,null,b,null,a)))};B.prototype.remove=B.prototype.remove=function(a){t.l(a,X,B,"remove:element");for(var b=this.za,c=b.count,d=-1,e=0;ea&&t.ha(a,">= 0",B,"getRowDefinition:idx");a=Math.round(a);var b=this.$c;if(void 0===b[a]){var c=new Ck;c.vl(this);c.Tl=!0;c.te=a;b[a]=c}return b[a]};B.prototype.removeRowDefinition=function(a){if(void 0!==this.$c){f&&t.o(a,B,"removeRowDefinition:idx");0>a&&t.ha(a,">= 0",B,"removeRowDefinition:idx");a=Math.round(a);var b=this.$c;b[a]&&(b[a]=void 0)}}; -t.A(B,{Sv:"columnCount"},function(){return void 0===this.Vc?0:this.Vc.length});B.prototype.getColumnDefinition=B.prototype.me=function(a){if(void 0===this.Vc)return null;f&&t.o(a,B,"getColumnDefinition:idx");0>a&&t.ha(a,">= 0",B,"getColumnDefinition:idx");a=Math.round(a);var b=this.Vc;if(void 0===b[a]){var c=new Ck;c.vl(this);c.Tl=!1;c.te=a;b[a]=c}return b[a]}; -B.prototype.removeColumnDefinition=function(a){if(void 0!==this.Vc){f&&t.o(a,B,"removeColumnDefinition:idx");0>a&&t.ha(a,">= 0",B,"removeColumnDefinition:idx");a=Math.round(a);var b=this.Vc;b[a]&&(b[a]=void 0)}};t.g(B,"rowSizing",B.prototype.qF); -t.defineProperty(B,{qF:"rowSizing"},function(){return void 0===this.lm?gl:this.lm},function(a){if(void 0!==this.lm){var b=this.lm;b!==a&&(a!==gl&&a!==ul&&t.m("rowSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.lm=a,this.aa(),this.i("rowSizing",b,a))}});t.g(B,"columnSizing",B.prototype.sD); -t.defineProperty(B,{sD:"columnSizing"},function(){return void 0===this.Hl?gl:this.Hl},function(a){if(void 0!==this.Hl){var b=this.Hl;b!==a&&(a!==gl&&a!==ul&&t.m("columnSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.Hl=a,this.aa(),this.i("columnSizing",b,a))}});t.g(B,"topIndex",B.prototype.mB); -t.defineProperty(B,{mB:"topIndex"},function(){return void 0===this.Ai?0:this.Ai},function(a){if(void 0!==this.Ai){var b=this.Ai;b!==a&&((!isFinite(a)||0>a)&&t.m("topIndex must be greater than zero and a real number. Was "+a),this.Ai=a,this.aa(),this.i("topIndex",b,a))}});t.g(B,"leftIndex",B.prototype.oA); -t.defineProperty(B,{oA:"leftIndex"},function(){return void 0===this.ki?0:this.ki},function(a){if(void 0!==this.ki){var b=this.ki;b!==a&&((!isFinite(a)||0>a)&&t.m("leftIndex must be greater than zero and a real number. Was "+a),this.ki=a,this.aa(),this.i("leftIndex",b,a))}});B.prototype.findRowForLocalY=function(a){if(0>a)return-1;if(this.type!==ea)return NaN;for(var b=0,c=this.$c,d=c.length,e=this.Ai;ea)return-1;if(this.type!==ea)return NaN;for(var b=0,c=this.Vc,d=c.length,e=this.ki;ea;)this.Te(a);a=this.Xs;if(null!==a)for(var b=t.yb(a),c=0;ca||1a&&t.ha(a,">= 0",Ck,"height"),this.Ef=a,sl(this,this.Eb),this.Lc("size",b,a))});t.g(Ck,"width",Ck.prototype.width);t.defineProperty(Ck,{width:"width"},function(){return this.Ef},function(a){var b=this.Ef;b!==a&&(f&&t.j(a,"number",Ck,"width"),0>a&&t.ha(a,">= 0",Ck,"width"),this.Ef=a,sl(this,this.Eb),this.Lc("size",b,a))});t.g(Ck,"minimum",Ck.prototype.Oh); -t.defineProperty(Ck,{Oh:"minimum"},function(){return this.am},function(a){var b=this.am;b!==a&&(f&&t.j(a,"number",Ck,"minimum"),(0>a||!isFinite(a))&&t.ha(a,">= 0",Ck,"minimum"),this.am=a,sl(this,this.Eb),this.Lc("minimum",b,a))});t.g(Ck,"maximum",Ck.prototype.qf);t.defineProperty(Ck,{qf:"maximum"},function(){return this.$l},function(a){var b=this.$l;b!==a&&(f&&t.j(a,"number",Ck,"maximum"),0>a&&t.ha(a,">= 0",Ck,"maximum"),this.$l=a,sl(this,this.Eb),this.Lc("maximum",b,a))});t.g(Ck,"alignment",Ck.prototype.alignment); -t.defineProperty(Ck,{alignment:"alignment"},function(){return this.re},function(a){var b=this.re;b.N(a)||(f&&t.l(a,K,Ck,"alignment"),this.re=a.Z(),this.Lc("alignment",b,a))});t.g(Ck,"stretch",Ck.prototype.Sh);t.defineProperty(Ck,{Sh:"stretch"},function(){return this.zh},function(a){var b=this.zh;b!==a&&(f&&t.tb(a,X,Ck,"stretch"),this.zh=a,this.Lc("stretch",b,a))});t.g(Ck,"separatorPadding",Ck.prototype.XA); -t.defineProperty(Ck,{XA:"separatorPadding"},function(){return this.Jj},function(a){"number"===typeof a?a=new pb(a):null!==a&&f&&t.l(a,pb,Ck,"separatorPadding");var b=this.Jj;null!==a&&null!==b&&b.N(a)||(null!==a&&(a=a.Z()),this.Jj=a,this.Lc("separatorPadding",b,a))});t.g(Ck,"separatorStroke",Ck.prototype.cn); -t.defineProperty(Ck,{cn:"separatorStroke"},function(){return this.Wr},function(a){var b=this.Wr;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.Wr=a,this.ga&&this.ga.pa(),this.Lc("separatorStroke",b,a))});t.g(Ck,"separatorStrokeWidth",Ck.prototype.dn);t.defineProperty(Ck,{dn:"separatorStrokeWidth"},function(){return this.Xr},function(a){var b=this.Xr;b!==a&&(this.Xr=a,this.ga&&this.ga.pa(),this.Lc("separatorStrokeWidth",b,a))}); -t.g(Ck,"separatorDashArray",Ck.prototype.wF);t.defineProperty(Ck,{wF:"separatorDashArray"},function(){return this.vh},function(a){var b=this.vh;b!==a&&(Array.isArray(a)||t.Vb(a,"Array",Ck,"separatorDashArray:val"),this.vh=a,this.ga&&this.ga.pa(),this.Lc("separatorDashArray",b,a))});t.g(Ck,"background",Ck.prototype.background); -t.defineProperty(Ck,{background:"background"},function(){return this.Gb},function(a){var b=this.Gb;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.Gb=a,this.ga&&this.ga.pa(),this.Lc("background",b,a))});t.g(Ck,"coversSeparators",Ck.prototype.Xv);t.defineProperty(Ck,{Xv:"coversSeparators"},function(){return this.nq},function(a){var b=this.nq;b!==a&&(t.j(a,"boolean",Ck,"coversSeparators"),this.nq=a,this.Lc("coversSeparators",b,a))});t.g(Ck,"sizing",Ck.prototype.yt); -t.defineProperty(Ck,{yt:"sizing"},function(){return this.Zr},function(a){var b=this.Zr;b!==a&&(f&&t.tb(a,Ck,Ck,"sizing"),this.Zr=a,this.Lc("sizing",b,a))});function tl(a){if(a.yt===Fl){var b=a.ti;return a.Kh?b.qF:b.sD}return a.yt}t.A(Ck,{Yb:"actual"},function(){return this.Eb});t.A(Ck,{total:"total"},function(){return this.Eb+ol(this)});t.A(Ck,{position:"position"},function(){return this.rb}); -Ck.prototype.bind=Ck.prototype.bind=function(a){a.eg=this;var b=this.ga;null!==b&&(b=b.Ro(),null!==b&&wk(b)&&t.m("Cannot add a Binding to a RowColumnDefinition that is already frozen: "+a));null===this.Bc&&(this.Bc=new H(Ge));this.Bc.add(a)}; -function Y(){X.call(this);this.Ra=null;this.In="None";this.Rg=!1;this.Fq=Yg;this.Bk=null;this.xb=this.Jc="black";this.fe=1;this.po="butt";this.qo="miter";this.rm=10;this.qm=null;this.ad=0;this.yi=this.xi=Pb;this.xr=this.wr=0;this.Kq=!1;this.Pq=!0;this.zr=null;this.Kn=this.so="None";this.Jq=1}t.ia("Shape",Y);t.Oa(Y,X); -Y.prototype.cloneProtected=function(a){X.prototype.cloneProtected.call(this,a);a.Ra=this.Ra;a.In=this.In;a.Rg=this.Rg;a.Fq=this.Fq;a.Bk=this.Bk;a.Jc=this.Jc;a.xb=this.xb;a.fe=this.fe;a.po=this.po;a.qo=this.qo;a.rm=this.rm;a.qm=null;this.qm&&(a.qm=this.qm.slice(0));a.ad=this.ad;a.xi=this.xi.Z();a.yi=this.yi.Z();a.wr=this.wr;a.xr=this.xr;a.Kq=this.Kq;a.Pq=this.Pq;a.zr=this.zr;a.so=this.so;a.Kn=this.Kn;a.Jq=this.Jq}; -Y.prototype.toString=function(){return"Shape("+("None"!==this.Ib?this.Ib:"None"!==this.gn?this.gn:this.jw)+")#"+t.oc(this)}; -function Gl(a,b,c,d){var e=0.001,g=d.Ea,h=g.width,g=g.height,k,l,m,n=c.length;if(!(2>n)){k=c[0][0];l=c[0][1];for(var p,q,r,s,v=0,x=t.Cb(),E=1;Ev){t.Da(x);return}e>r?(F=e-r,e=r):F=0;var G=Math.sqrt(e* -e/(1+q*q));0>p&&(G=-G);k+=G;l+=q*G;a.translate(k,l);a.rotate(s);a.translate(-(h/2),-(g/2));0===F&&d.hl(a,b);a.translate(h/2,g/2);a.rotate(-s);a.translate(-k,-l);v-=e;r-=e;if(0!==F){m++;if(m===x.length){t.Da(x);return}r=x[m];p=r[0];s=r[1];q=r[2];r=r[3];e=F}}t.Da(x)}} -Y.prototype.hl=function(a,b){if(null!==this.xb||null!==this.Jc){null!==this.Jc&&dk(this,a,this.Jc,!0);null!==this.xb&&dk(this,a,this.xb,!1);var c=this.fe;if(0===c){var d=this.S;d instanceof We&&d.type===wg&&d.Nc instanceof Y&&(c=d.Nc.ib)}a.lineWidth=c;a.lineJoin=this.qo;a.lineCap=this.po;a.miterLimit=this.rm;var e=!1;this.S&&(e=this.S.Lh);var g=!0;null!==this.xb&&null===this.Jc&&(g=!1);var d=!1,h=this.Rw;if(null!==h){var k=d=!0;void 0!==a.setLineDash?(a.setLineDash(h),a.lineDashOffset=this.ad):void 0!== -a.webkitLineDash?(a.webkitLineDash=h,a.webkitLineDashOffset=this.ad):void 0!==a.mozDash?(a.mozDash=h,a.mozDashOffset=this.ad):k=!1}var l=this.Ra;if(null!==l){if(l.ba===Vc)a.beginPath(),d&&!k?Lj(a,l.ec,l.nc,l.md,l.xd,h,this.ad):(a.moveTo(l.ec,l.nc),a.lineTo(l.md,l.xd)),null!==this.Jc&&ek(a,this.Jc,!0),0!==c&&null!==this.xb&&ek(a,this.xb,!1);else if(l.ba===Wc){var m=l.ec,n=l.nc,p=l.md,l=l.xd,q=Math.min(m,p),r=Math.min(n,l),m=Math.abs(p-m),n=Math.abs(l-n);null!==this.Jc&&(this.Jc instanceof ke&&this.Jc.type=== -oe?(a.beginPath(),a.rect(q,r,m,n),ek(a,this.Jc,!0)):a.fillRect(q,r,m,n));if(null!==this.xb){if(g&&e){var s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}d&&!k?(k=[[q,r],[q+m,r],[q+m,r+n],[q,r+n],[q,r]],a.beginPath(),Hl(a,k,h,this.ad),ek(a,this.xb,!1)):0!==c&&(this.xb instanceof ke&&this.xb.type===oe?(a.beginPath(),a.rect(q,r,m,n),ek(a,this.xb,!1)):a.strokeRect(q,r,m,n));g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2])}}else if(l.ba=== -Xc)m=l.ec,n=l.nc,p=l.md,l=l.xd,q=Math.abs(p-m)/2,r=Math.abs(l-n)/2,m=Math.min(m,p)+q,n=Math.min(n,l)+r,a.beginPath(),a.moveTo(m,n-r),a.bezierCurveTo(m+J.va*q,n-r,m+q,n-J.va*r,m+q,n),a.bezierCurveTo(m+q,n+J.va*r,m+J.va*q,n+r,m,n+r),a.bezierCurveTo(m-J.va*q,n+r,m-q,n+J.va*r,m-q,n),a.bezierCurveTo(m-q,n-J.va*r,m-J.va*q,n-r,m,n-r),a.closePath(),null!==this.Jc&&ek(a,this.Jc,!0),d&&!k&&(k=t.Cb(),J.ze(m,n-r,m+J.va*q,n-r,m+q,n-J.va*r,m+q,n,0.5,k),J.ze(m+q,n,m+q,n+J.va*r,m+J.va*q,n+r,m,n+r,0.5,k),J.ze(m,n+ -r,m-J.va*q,n+r,m-q,n+J.va*r,m-q,n,0.5,k),J.ze(m-q,n,m-q,n-J.va*r,m-J.va*q,n-r,m,n-r,0.5,k),a.beginPath(),Hl(a,k,h,this.ad),t.Da(k)),0!==c&&null!==this.xb&&(g&&e&&(s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0),ek(a,this.xb,!1),g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2]));else if(l.ba===Oc){for(var q=l.Fk,r=q.length,v=0;vN.Th);else for(var G=sd(N,x),W=G.length,T=0;Tm))if(h=b[0][0],k=b[0][1],2===m)Lj(a,h,k,b[1][0],b[1][1],c,d);else{a.moveTo(h,k);for(var n,p,q,r=0,s=t.Cb(),v=1;vr&&(e=r);e>q?(x=e-q,e=q):x=0;var E=Math.sqrt(e*e/(1+p*p));0>n&&(E= --E);h+=E;k+=p*E;m?a.lineTo(h,k):a.moveTo(h,k);r-=e;q-=e;if(0!==x){l++;if(l===s.length){t.Da(s);return}q=s[l];n=q[0];p=q[1];q=q[2];e=x}else m=!m}t.Da(s)}}Y.prototype.getDocumentPoint=Y.prototype.gb=function(a,b){void 0===b&&(b=new C);a.qd()&&t.m("Spot must be real");var c=this.Ga,d=this.ib;b.q(a.x*(c.width+d)-d/2+c.x+a.offsetX,a.y*(c.height+d)-d/2+c.y+a.offsetY);this.he.Va(b);return b}; -Y.prototype.Vj=function(a,b){var c=this.Ra;if(null===c||null===this.fill&&null===this.stroke)return!1;var d=c.Mb,e=this.ib/2;c.type!==Vc||b||(e+=2);var g=t.wf();g.assign(d);g.Vg(e+2,e+2);if(!g.Ia(a))return t.Pc(g),!1;d=e+1E-4;if(c.type===Vc){if(null===this.stroke)return!1;g=(c.D-c.na)*(a.x-c.na)+(c.F-c.oa)*(a.y-c.oa);return 0>(c.na-c.D)*(a.x-c.D)+(c.oa-c.F)*(a.y-c.F)||0>g?!1:J.Cd(c.na,c.oa,c.D,c.F,e,a.x,a.y)}if(c.type===Wc){var h=c.na,k=c.oa,l=c.D,m=c.F,c=Math.min(h,l),n=Math.min(k,m),h=Math.abs(l- -h),k=Math.abs(m-k);g.x=c;g.y=n;g.width=h;g.height=k;if(null===this.fill){g.Vg(-d,-d);if(g.Ia(a))return!1;g.Vg(d,d)}null!==this.stroke&&g.Vg(e,e);e=g.Ia(a);t.Pc(g);return e}if(c.type===Xc){h=c.na;k=c.oa;l=c.D;m=c.F;c=Math.min(h,l);n=Math.min(k,m);h=Math.abs(l-h);k=Math.abs(m-k);g=h/2;k/=2;c=a.x-(c+g);n=a.y-(n+k);if(null===this.fill){g-=d;k-=d;if(0>=g||0>=k||1>=c*c/(g*g)+n*n/(k*k))return!1;g+=d;k+=d}null!==this.stroke&&(g+=e,k+=e);return 0>=g||0>=k?!1:1>=c*c/(g*g)+n*n/(k*k)}if(c.type===Oc)return null=== -this.fill?vd(c,a.x,a.y,e):c.Ia(a,e,1=this.ib)n=J.$g(p.ec,p.nc,p.md,p.xd,g,h,k,l,e);else{var r,s;p.ec===p.md?(r=m,s=0):(b=(p.xd-p.nc)/(p.md-p.ec),s=m/Math.sqrt(1+b*b),r=s*b);d=t.Cb();b=new C;J.$g(p.ec+ -r,p.nc+s,p.md+r,p.xd+s,g,h,k,l,b)&&d.push(b);b=new C;J.$g(p.ec-r,p.nc-s,p.md-r,p.xd-s,g,h,k,l,b)&&d.push(b);b=new C;J.$g(p.ec+r,p.nc+s,p.ec-r,p.nc-s,g,h,k,l,b)&&d.push(b);b=new C;J.$g(p.md+r,p.xd+s,p.md-r,p.xd-s,g,h,k,l,b)&&d.push(b);b=d.length;if(0===b)return t.Da(d),!1;n=!0;s=Infinity;for(r=0;rMath.abs(c)){n=h-b-c*(g-d);if(0>a*a*c*c+x*x-n*n){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(a*a*c*c+x*x-n*n);k=(-(a*a*c*n)+a*x*m)/(x*x+a*a*c*c)+d;a=(-(a*a*c*n)-a*x*m)/(x*x+a*a*c*c)+d;l=c*(k-d)+n+b;b=c*(a-d)+n+b;d=Math.abs((g-k)*(g-k))+Math.abs((h-l)*(h-l));h=Math.abs((g-a)*(g-a))+Math.abs((h-b)* -(h-b));dk){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(k);l=b+m;b-=m;d=Math.abs(l-h);h=Math.abs(b-h);dc?a-c:c-a)<(b>d?b-d:d-b)?(e=be||J.Ka(l.y,e))&&(l.ye||J.Ka(l.x,e))&&(l.x=h&&d<=a}a=h&&c<=a} -Y.prototype.XD=function(a,b,c){function d(a,b){for(var c=a.length,d=0;de)return!0}return!1}if(c&&null!==this.fill&&this.Vj(a,!0))return!0;var e=a.$j(b);b=e;1.5=e||eb(b,g,0,-p)>=e||eb(b,g,0,p)>=e||eb(b,g,n,0)>=e?!1: -!0}else if(g.type===Oc){h=g.Mb;k=h.x;l=h.y;m=h.x+h.width;h=h.y+h.height;if(a.x>m&&a.xh&&a.ye&&cb(a.x,a.y,k,l,m,l)>e&&cb(a.x,a.y,m,h,k,h)>e&&cb(a.x,a.y,m,h,m,l)>e)return!1;b=Math.sqrt(e);if(c){if(null===this.fill?vd(g,a.x,a.y,b):g.Ia(a,b,!0))return!0}else{c=g.ub;for(b=0;be)return!1;l=k.Ha.p;m=l.length;for(h=0;he)return!1;break;case od:g=t.Cb(); -J.ze(n,p,q.vb,q.Lb,q.oe,q.pe,q.D,q.F,0.8,g);n=d(g,a);t.Da(g);if(n)return!1;n=q.D;p=q.F;if(a.Fs(n,p)>e)return!1;break;case pd:g=t.Cb();J.xp(n,p,q.vb,q.Lb,q.D,q.F,0.8,g);n=d(g,a);t.Da(g);if(n)return!1;n=q.D;p=q.F;if(a.Fs(n,p)>e)return!1;break;case qd:case rd:var q=q.type===qd?sd(q,k):td(q,k,n,p),r=q.length,s=null,g=t.Cb();for(b=0;b= 0",Y,"strokeWidth:val")});t.g(Y,"strokeCap",Y.prototype.HF); -t.defineProperty(Y,{HF:"strokeCap"},function(){return this.po},function(a){var b=this.po;b!==a&&("string"!==typeof a||"butt"!==a&&"round"!==a&&"square"!==a?t.ha(a,'"butt", "round", or "square"',Y,"strokeCap"):(this.po=a,this.pa(),this.i("strokeCap",b,a)))});t.g(Y,"strokeJoin",Y.prototype.eJ); -t.defineProperty(Y,{eJ:"strokeJoin"},function(){return this.qo},function(a){var b=this.qo;b!==a&&("string"!==typeof a||"miter"!==a&&"bevel"!==a&&"round"!==a?t.ha(a,'"miter", "bevel", or "round"',Y,"strokeJoin"):(this.qo=a,this.pa(),this.i("strokeJoin",b,a)))});t.g(Y,"strokeMiterLimit",Y.prototype.fJ); -t.defineProperty(Y,{fJ:"strokeMiterLimit"},function(){return this.rm},function(a){var b=this.rm;if(b!==a)if(f&&t.o(a,Y,"strokeMiterLimit"),0 0",Y,"strokeWidth:val")});t.g(Y,"strokeDashArray",Y.prototype.Rw); -t.defineProperty(Y,{Rw:"strokeDashArray"},function(){return this.qm},function(a){var b=this.qm;if(b!==a){null===a||Array.isArray(a)||t.Vb(a,"Array",Y,"strokeDashArray:val");if(null!==a)for(var c=a.length,d=0;de||!isFinite(e))&&t.m("strokeDashArray:val "+e+" is a negative number or not a real number.")}this.qm=a;this.pa();this.i("strokeDashArray",b,a)}});t.g(Y,"strokeDashOffset",Y.prototype.IF); -t.defineProperty(Y,{IF:"strokeDashOffset"},function(){return this.ad},function(a){var b=this.ad;b!==a&&(f&&t.o(a,Y,"strokeDashOffset"),0<=a&&(this.ad=a,this.pa(),this.i("strokeDashOffset",b,a)))});t.g(Y,"figure",Y.prototype.Ib); -t.defineProperty(Y,{Ib:"figure"},function(){return this.In},function(a){var b=this.In;if(b!==a){f&&t.j(a,"string",Y,"figure");var c=J.Qi[a];"function"===typeof c?c=a:(c=J.Qi[a.toLowerCase()])||t.m("Unknown Shape.figure: "+a);if(b!==c){if(a=this.S)a.yj=NaN;this.In=c;this.Rg=!1;this.Jf();this.i("figure",b,c)}}});t.g(Y,"toArrow",Y.prototype.gn); -t.defineProperty(Y,{gn:"toArrow"},function(){return this.so},function(a){var b=this.so;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"toArrow");var c=J.Oo(a);c instanceof M?c=a:(c=J.Oo(a.toLowerCase()))||t.m("Unknown Shape.toArrow: "+a);b!==c&&(this.so=c,this.Rg=!1,this.Jf(),Ll(this,c),this.i("toArrow",b,c))}});t.g(Y,"fromArrow",Y.prototype.jw); -t.defineProperty(Y,{jw:"fromArrow"},function(){return this.Kn},function(a){var b=this.Kn;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"fromArrow");var c=J.Oo(a);c instanceof M?c=a:(c=J.Oo(a.toLowerCase()))||t.m("Unknown Shape.fromArrow: "+a);b!==c&&(this.Kn=c,this.Rg=!1,this.Jf(),Ll(this,c),this.i("fromArrow",b,c))}}); -function Ll(a,b){var c=a.h;if(null===c||!c.Aa.qb){a.ut=Ml;c=cc;switch(b){case "halfarrowtop":c=$b;break;case "halftriangletop":c=$b;break;case "openrighttriangletop":c=$b;break;case "opentriangletop":c=$b}"None"!==a.so?(a.tf=-1,a.Qj=c):"None"!==a.Kn&&(a.tf=0,a.Qj=new K(1-c.x,c.y))}}t.defineProperty(Y,{G:"spot1"},function(){return this.xi},function(a){t.l(a,K,Y,"spot1");var b=this.xi;b.N(a)||(this.xi=a=a.Z(),this.aa(),this.i("spot1",b,a))}); -t.defineProperty(Y,{H:"spot2"},function(){return this.yi},function(a){t.l(a,K,Y,"spot2");var b=this.yi;b.N(a)||(this.yi=a=a.Z(),this.aa(),this.i("spot2",b,a))});t.defineProperty(Y,{yc:"parameter1"},function(){return this.wr},function(a){var b=this.wr;b!==a&&(this.wr=a,this.aa(),this.i("parameter1",b,a))});t.defineProperty(Y,{lt:"parameter2"},function(){return this.xr},function(a){var b=this.xr;b!==a&&(this.xr=a,this.aa(),this.i("parameter2",b,a))}); -t.A(Y,{Ga:"naturalBounds"},function(){if(null!==this.Ra)return this.Yc.assign(this.Ra.Mb),this.Yc;var a=this.Ca;return new D(0,0,a.width,a.height)});t.g(Y,"isRectangular",Y.prototype.pI);t.defineProperty(Y,{pI:"isRectangular"},function(){return this.Pq},function(a){var b=this.Pq;b!==a&&(f&&t.j(a,"boolean",Y,"isRectangular"),this.Pq=a,this.aa(),this.i("isRectangular",b,a))});t.g(Y,"pathObject",Y.prototype.EA); -t.defineProperty(Y,{EA:"pathObject"},function(){return this.zr},function(a){var b=this.zr;b!==a&&(f&&t.l(a,X,Y,"pathObject"),this.zr=a,this.pa(),this.i("pathObject",b,a))});t.g(Y,"geometryStretch",Y.prototype.kw);t.defineProperty(Y,{kw:"geometryStretch"},function(){return this.Fq},function(a){var b=this.Fq;b!==a&&(t.tb(a,X,Y,"geometryStretch"),this.Fq=a,this.i("geometryStretch",b,a))});t.g(Y,"interval",Y.prototype.interval); -t.defineProperty(Y,{interval:"interval"},function(){return this.Jq},function(a){var b=this.Jq;f&&t.o(a,Y,"interval");a=Math.floor(a);b!==a&&0<=a&&(this.Jq=a,this.h&&si(this.h),this.aa(),this.i("interval",b,a))});function wa(){X.call(this);this.ge="";this.xb="black";this.mh="13px sans-serif";this.Pd="start";this.Mq=!0;this.Ul=this.Vl=!1;this.fo=Nl;this.um=Ol;this.Hu=this.Yq=0;this.Jn=this.Ey=this.Fy=null;this.Zn={};this.yq=!1;this.ef=this.Lj=this.fs=null}t.ia("TextBlock",wa);t.Oa(wa,X); -wa.prototype.cloneProtected=function(a){X.prototype.cloneProtected.call(this,a);a.ge=this.ge;a.xb=this.xb;a.mh=this.mh;a.Pd=this.Pd;a.Mq=this.Mq;a.Vl=this.Vl;a.Ul=this.Ul;a.um=this.um;a.fo=this.fo;a.Yq=this.Yq;a.Hu=this.Hu;a.Fy=this.Fy;a.Ey=this.Ey;a.Jn=this.Jn;a.Zn=this.Zn;a.yq=this.yq;a.fs=this.fs;a.Lj=this.Lj;a.ef=this.ef};wa.prototype.toString=function(){return 22m*k*k&&(h=!0);m=e.Di.length;for(k=0;kc&&(n=c);var p=l,l=a,q=g,r=c,s=d,v=0;h?("start"===this.Pd||"left"===this.Pd?v=0:"end"===this.Pd||"right"===this.Pd? -v=r-n:"center"===this.Pd?v=(r-n)/2:t.m("textAlign must be start, end, left, right, or center"),l.fillRect(0+v,q+0.25*s,n,1)):("start"===this.Pd||"left"===this.Pd?v=0:"end"===this.Pd||"right"===this.Pd?v=r:"center"===this.Pd?v=r/2:t.m("textAlign must be start, end, left, right, or center"),l.fillText(p,0+v,q+s-0.25*s),p=s/20|0,this.Vl&&("end"===this.Pd||"right"===this.Pd?v-=n:"center"===this.Pd&&(v-=n/2),l.beginPath(),l.lineWidth=p,l.moveTo(0+v,q+s-0.2*s),l.lineTo(0+v+n,q+s-0.2*s),l.stroke()),this.Ul&& -(l.beginPath(),l.lineWidth=p,q=q+s-s/2.2|0,0!==p%2&&(q+=0.5),l.moveTo(0,q),l.lineTo(0+n,q),l.stroke()));g+=d}}}; -wa.prototype.$s=function(a,b,c,d){var e={},g=0,h=0;if(isNaN(this.Ca.width)){g=this.ge;if(0===g.length)g=0;else if(this.uw){for(var k=h=0,l=!1,m={Vh:0};!l;){var n=Ul(g,k,m);-1===n&&(n=g.length,l=!0);k=Vl(g.substr(k,n-k).replace(/^\s+|\s+$/g,""),this.mh);k>h&&(h=k);k=m.Vh}g=h}else h=Ul(g,0,{}),0<=h&&(g=g.substr(0,h)),g=k=Vl(g,this.mh);g=Math.min(g,a/this.scale);g=Math.max(8,g)}else g=this.Ca.width;this.ga&&(g=Math.min(g,this.ga.He.width),g=Math.max(g,this.ga.Ye.width));h=Tl(this,g,e);h=isNaN(this.Ca.height)? -Math.min(h,b/this.scale):this.Ca.height;if(this.qB===Ql||isNaN(this.Ca.width))g=e.Wi,isNaN(this.Ca.width)&&(g=Math.max(8,g));g=Math.max(c,g);h=Math.max(d,h);nb(this.Yc,g,h);Nj(this,0,0,g,h);this.Zn=e};wa.prototype.Uj=function(a,b,c,d){Uj(this,a,b,c,d)}; -function Sl(a,b,c,d){b=b.replace(/^\s+|\s+$/g,"");void 0===c.Wi&&(c.Wi=0);void 0===c.Di&&(c.Di=[]);void 0===c.ym&&(c.ym=[]);var e=0,g,h,k=a.mh;a.fo===Rl?(t.Hp!==k&&(t.Gp.font=k,t.Hp=k),g=0,void 0!==t.Yz[k]&&5E3>t.$D?g=t.Yz[k]:(g=t.Gp.measureText(t.VD).width,t.Yz[k]=g,t.$D++)):g=0;var l=g;if(a.um===Pl){c.Vh=1;g=Vl(b,k);if(0===l||g<=d)return c.Wi=g,c.Di.push(c.Wi),c.ym.push(b),new pa(g,Ch(a));var m=Wl(b);b=b.substr(m.length);h=Wl(b);for(g=Vl(m+h,k);0d&&1d;){var n=1;g=Vl(m.substr(0,n),k);for(h=0;g<=d;)n++,h=g,g=Vl(m.substr(0,n),k);1===n?(c.Di[l]=g,e=Math.max(e,g)):(c.Di[l]=h,e=Math.max(e,h));n--;1>n&&(n=1);c.ym[l]=m.substr(0,n);l++; -m=m.substr(n)}h=Wl(b);for(g=Vl(m+h,k);0=b?a:a.substr(0,c)} -function Vl(a,b){t.Hp!==b&&(t.Gp.font=b,t.Hp=b);return t.Gp.measureText(a).width}function Ch(a){if(null!==a.Jn)return a.Jn;var b=a.mh;t.Hp!==b&&(t.Gp.font=b,t.Hp=b);var c=0;void 0!==t.Zz[b]&&5E3>t.aE?c=t.Zz[b]:(c=1.3*t.Gp.measureText("M").width,t.Zz[b]=c,t.aE++);return a.Jn=c}function Ul(a,b,c){void 0===c.Vh&&(c.Vh=0);var d=a.indexOf("\r",b);-1===d&&(d=a.indexOf("\n",b));0<=d&&(c.Vh="\r"===a[d]&&d+1e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.2,0.22);b.H=new K(0.8,0.9);t.v(a);return b},DataTransmission:"Hexagon", -Hexagon:function(a,b,c){var d=J.el(6);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;6>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.07,0.25);b.H=new K(0.93,0.75);t.v(a);return b},Heptagon:function(a,b,c){var d=J.el(7);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;7>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.2,0.15);b.H=new K(0.8,0.85);t.v(a);return b},Octagon:function(a,b,c){var d=J.el(8);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;8>e;e++)a.lineTo(d[e].x* -b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.15,0.15);b.H=new K(0.85,0.85);t.v(a);return b},Nonagon:function(a,b,c){var d=J.el(9);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;9>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.17,0.13);b.H=new K(0.82,0.82);t.v(a);return b},Decagon:function(a,b,c){var d=J.el(10);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.16,0.16);b.H=new K(0.84,0.84);t.v(a);return b},Dodecagon:function(a, -b,c){var d=J.el(12);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.16,0.16);b.H=new K(0.84,0.84);t.v(a);return b},FivePointedStar:function(a,b,c){var d=J.Hm(5);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.312,0.383);b.H=new K(0.693,0.765);t.v(a);return b},SixPointedStar:function(a,b,c){var d=J.Hm(6);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x* -b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.17,0.251);b.H=new K(0.833,0.755);t.v(a);return b},SevenPointedStar:function(a,b,c){var d=J.Hm(7);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;14>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.363,0.361);b.H=new K(0.641,0.709);t.v(a);return b},EightPointedStar:function(a,b,c){var d=J.Hm(8);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;16>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.252,0.255);b.H=new K(0.75,0.75);t.v(a); -return b},NinePointedStar:function(a,b,c){var d=J.Hm(9);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;18>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.355,0.361);b.H=new K(0.645,0.651);t.v(a);return b},TenPointedStar:function(a,b,c){var d=J.Hm(10);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;20>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.281,0.261);b.H=new K(0.723,0.748);t.v(a);return b},FivePointedBurst:function(a,b,c){var d=J.Ho(5);a=t.u();O(a,d[0].x*b,d[0].y* -c,!0);for(var e=1;e=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=d*J.va;var e=t.u();O(e,d,0,!0); -e.lineTo(b-d,0);P(e,b-a,0,b,a,b,d);e.lineTo(b,c-d);P(e,b,c-a,b-a,c,b-d,c);e.lineTo(d,c);P(e,a,c,0,c-a,0,c-d);e.lineTo(0,d);P(e,0,a,a,0,d,0);Q(e);b=e.s;1=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=t.u();O(a,d,0,!0);a.lineTo(b-d,0);P(a,b-0,0,b,0,b,d);a.lineTo(b,c-d);P(a,b,c-0,b-0,c,b-d,c);a.lineTo(d,c);P(a,0,c,0,c-0,0,c-d);a.lineTo(0,d);P(a,0,0,0,0,d,0);Q(a);b=a.s;b.G=Tb;b.H=$b; -t.v(a);return b},SquareIBeam:function(a,b,c){var d=a?a.yc:0;0===d&&(d=0.2);a=t.u();O(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,d*c);a.lineTo((0.5+d/2)*b,d*c);a.lineTo((0.5+d/2)*b,(1-d)*c);a.lineTo(1*b,(1-d)*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,(1-d)*c);a.lineTo((0.5-d/2)*b,(1-d)*c);a.lineTo((0.5-d/2)*b,d*c);a.lineTo(0,d*c);Q(a);b=a.s;t.v(a);return b},Trapezoid:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.2);var d=t.u();O(d,a*b,0,!0);d.lineTo((1-a)*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);b=d.s; -b.G=new K(a,0);b.H=new K(1-a,1);t.v(d);return b},ManualLoop:"ManualOperation",ManualOperation:function(a,b,c){var d=a?a.yc:0;a=t.u();O(a,d,0,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);Q(a);b=a.s;b.G=new K(0.1,0);b.H=new K(0.9,1);t.v(a);return b},GenderMale:function(a,b,c){a=t.u();var d=J.va,e=0.4*d,g=0.4,h=t.O(),k=t.O(),l=t.O(),m=t.O();O(a,(0.5-g)*b,0.5*c,!0);P(a,(0.5-g)*b,(0.5-e)*c,(0.5-e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5, -0.44,l,m,k,h,h);P(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);var n=t.ic(k.x,k.y);J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.56,h,h,k,l,m);var p=t.ic(k.x,k.y);a.lineTo((0.1*n.x+0.855)*b,0.1*n.y*c);a.lineTo(0.85*b,0.1*n.y*c);a.lineTo(0.85*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,(0.1*p.y+0.05*0.9)*c);a.lineTo(p.x*b,p.y*c);P(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);P(a,(0.5+g)*b,(0.5+e)*c,(0.5+e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5-e)* -b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);g=0.35;e=0.35*d;O(a,0.5*b,(0.5-g)*c,!0,!0);P(a,(0.5-e)*b,(0.5-g)*c,(0.5-g)*b,(0.5-e)*c,(0.5-g)*b,0.5*c);P(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);P(a,(0.5+g)*b,(0.5-e)*c,(0.5+e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);O(a,(0.5-g)*b,0.5*c,!0);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);t.B(p);b=a.s;b.G=new K(0.202,0.257);b.H=new K(0.692,0.839);b.kc=Zg;t.v(a);return b},GenderFemale:function(a, -b,c){a=t.u();var d=0.375,e=0,g=-0.125,h=4*(Math.SQRT2-1)/3*d;O(a,(0.525+e)*b,(0.5+d+g)*c,!0);P(a,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+d+e)*b,(0.5+g)*c);P(a,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);P(a,(0.5-h+e)*b,(0.5-d+g)*c,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-d+e)*b,(0.5+g)*c);P(a,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-h+e)*b,(0.5+d+g)*c,(0.475+e)*b,(0.5+d+g)*c);a.lineTo(0.475*b,0.85*c);a.lineTo(0.425*b,0.85*c);a.lineTo(0.425*b,0.9*c);a.lineTo(0.475*b,0.9*c);a.lineTo(0.475* -b,1*c);a.lineTo(0.525*b,1*c);a.lineTo(0.525*b,0.9*c);a.lineTo(0.575*b,0.9*c);a.lineTo(0.575*b,0.85*c);a.lineTo(0.525*b,0.85*c);Q(a);d=0.325;e=0;g=-0.125;h=4*(Math.SQRT2-1)/3*d;O(a,(0.5+d+e)*b,(0.5+g)*c,!0,!0);P(a,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+e)*b,(0.5+d+g)*c);P(a,(0.5-h+e)*b,(0.5+d+g)*c,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-d+e)*b,(0.5+g)*c);P(a,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);P(a,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+d+e)*b,(0.5+ -g)*c);O(a,(0.525+e)*b,(0.5+d+g)*c,!0);b=a.s;b.G=new K(0.232,0.136);b.H=new K(0.782,0.611);b.kc=Zg;t.v(a);return b},PlusLine:function(a,b,c){a=t.u();O(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},XLine:function(a,b,c){a=t.u();O(a,0,1*c,!1);a.lineTo(1*b,0);a.moveTo(0,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},AsteriskLine:function(a,b,c){a=t.u();var d=0.2/Math.SQRT2;O(a,d*b,(1-d)*c,!1);a.lineTo((1-d)*b,d*c);a.moveTo(d*b,d*c);a.lineTo((1-d)*b,(1-d)* -c);a.moveTo(0*b,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0*c);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},CircleLine:function(a,b,c){var d=0.5*J.va;a=t.u();O(a,1*b,0.5*c,!1);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new K(0.146,0.146);b.H=new K(0.853,0.853);b.kc=Zg;t.v(a);return b},Pie:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;O(a,(0.5*Math.SQRT2/2+0.5)*b,(0.5- -0.5*Math.SQRT2/2)*c,!0);P(a,0.7*b,0*c,0.5*b,0*c,0.5*b,0*c);P(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);P(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.5*b,1*c);P(a,(0.5+d+0)*b,1*c,1*b,(0.5+d+0)*c,1*b,0.5*c);a.lineTo(0.5*b,0.5*c);Q(a);b=a.s;t.v(a);return b},PiePiece:function(a,b,c){var d=J.va/Math.SQRT2*0.5,e=Math.SQRT2/2,g=1-Math.SQRT2/2;a=t.u();O(a,b,c,!0);P(a,b,(1-d)*c,(e+d)*b,(g+d)*c,e*b,g*c);a.lineTo(0,c);Q(a);b=a.s;t.v(a);return b},StopSign:function(a,b,c){a=1/(Math.SQRT2+2);var d=t.u();O(d,a*b,0,!0); -d.lineTo((1-a)*b,0);d.lineTo(1*b,a*c);d.lineTo(1*b,(1-a)*c);d.lineTo((1-a)*b,1*c);d.lineTo(a*b,1*c);d.lineTo(0,(1-a)*c);d.lineTo(0,a*c);Q(d);b=d.s;b.G=new K(a/2,a/2);b.H=new K(1-a/2,1-a/2);t.v(d);return b},LogicImplies:function(a,b,c){var d=a?a.yc:0;0===d&&(d=0.2);a=t.u();O(a,(1-d)*b,0*c,!1);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);b=a.s;b.G=Tb;b.H=new K(0.8,0.5);t.v(a);return b},LogicIff:function(a,b,c){var d=a?a.yc:0;0===d&&(d=0.2);a=t.u();O(a,(1-d)*b,0*c,!1); -a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(d*b,0);a.lineTo(0,0.5*c);a.lineTo(d*b,c);b=a.s;b.G=new K(0.2,0);b.H=new K(0.8,0.5);t.v(a);return b},LogicNot:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},LogicAnd:function(a,b,c){a=t.u();O(a,0,1*c,!1);a.lineTo(0.5*b,0);a.lineTo(1*b,1*c);b=a.s;b.G=new K(0.25,0.5);b.H=new K(0.75,1);t.v(a);return b},LogicOr:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1* -b,0);b=a.s;b.G=new K(0.219,0);b.H=new K(0.78,0.409);t.v(a);return b},LogicXor:function(a,b,c){a=t.u();O(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);var d=0.5*J.va;P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.kc=Zg;t.v(a);return b},LogicTruth:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b}, -LogicFalsity:function(a,b,c){a=t.u();O(a,0,1*c,!1);a.lineTo(1*b,1*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);b=a.s;t.v(a);return b},LogicThereExists:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);b=a.s;t.v(a);return b},LogicForAll:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1*b,0);a.moveTo(0.25*b,0.5*c);a.lineTo(0.75*b,0.5*c);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,0.5);t.v(a);return b}, -LogicIsDefinedAs:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(b,0);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(0,c);a.lineTo(b,c);b=a.s;b.G=new K(0.01,0.01);b.H=new K(0.99,0.49);t.v(a);return b},LogicIntersect:function(a,b,c){var d=0.5*J.va;a=t.u();O(a,0,1*c,!1);a.lineTo(0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new K(0,0.5);b.H=$b;t.v(a);return b},LogicUnion:function(a,b,c){var d=0.5*J.va;a=t.u();O(a,1*b,0,!1);a.lineTo(1*b, -0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);a.lineTo(0,0);b=a.s;b.G=Tb;b.H=new K(1,0.5);t.v(a);return b},Arrow:function(a,b,c){var d=a?a.yc:0,e=a?a.lt:0;0===d&&(d=0.3);0===e&&(e=0.3);a=t.u();O(a,0,(0.5-e/2)*c,!0);a.lineTo((1-d)*b,(0.5-e/2)*c);a.lineTo((1-d)*b,0);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,1*c);a.lineTo((1-d)*b,(0.5+e/2)*c);a.lineTo(0,(0.5+e/2)*c);Q(a);b=a.s;b.G=new K(0,0.5-e/2);d=J.kl(0,0.5+e/2,1,0.5+e/2,1-d,1,1,0.5,t.O());b.H=new K(d.x,d.y); -t.B(d);t.v(a);return b},ISOProcess:"Chevron",Chevron:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.5*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);Q(a);b=a.s;t.v(a);return b},DoubleArrow:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.3*b,0.214*c);a.lineTo(0.3*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.3*b,1*c);a.lineTo(0.3*b,0.786*c);a.lineTo(0,1*c);Q(a);O(a,0.3*b,0.214*c,!1);a.lineTo(0.3*b,0.786*c);a.ab(!1);b=a.s;t.v(a);return b},DoubleEndArrow:function(a,b,c){a=t.u(); -O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.3*b,0.7*c);a.lineTo(0.3*b,1*c);a.lineTo(0,0.5*c);a.lineTo(0.3*b,0);a.lineTo(0.3*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);Q(a);b=a.s;c=J.kl(0,0.5,0.3,0,0,0.3,0.3,0.3,t.O());b.G=new K(c.x,c.y);c=J.kl(0.7,1,1,0.5,0.7,0.7,1,0.7,c);b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},IBeamArrow:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.2*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0,1*c); -a.lineTo(0,0);a.lineTo(0.2*b,0);a.lineTo(0.2*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);Q(a);b=a.s;b.G=new K(0,0.3);c=J.kl(0.7,1,1,0.5,0.7,0.7,1,0.7,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},Pointer:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0);Q(a);b=a.s;b.G=new K(0.2,0.35);c=J.kl(0.2,0.65,1,0.65,0,1,1,0.5,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},RoundedPointer:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0,1*c);P(a,0.5* -b,0.75*c,0.5*b,0.25*c,0,0);Q(a);b=a.s;b.G=new K(0.4,0.35);c=J.kl(0.2,0.65,1,0.65,0,1,1,0.5,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},SplitEndArrow:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0,0.7*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);Q(a);b=a.s;b.G=new K(0.2,0.3);c=J.kl(0.7,1,1,0.5,0.7,0.7,1,0.7,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},MessageToUser:"SquareArrow",SquareArrow:function(a, -b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.7*b,0);Q(a);b=a.s;b.G=Tb;b.H=new K(0.7,1);t.v(a);return b},Cone1:function(a,b,c){var d=J.va;a=0.5*d;var e=0.1*d,d=t.u();O(d,0,0.9*c,!0);d.lineTo(0.5*b,0);d.lineTo(1*b,0.9*c);P(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);P(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);Q(d);b=d.s;b.G=new K(0.25,0.5);b.H=new K(0.75,0.97);t.v(d);return b},Cone2:function(a,b,c){a=t.u();O(a,0,0.9*c,!0);P(a,(1-0.85/0.9)*b,1*c,0.85/0.9*b,1*c, -1*b,0.9*c);a.lineTo(0.5*b,0);a.lineTo(0,0.9*c);Q(a);O(a,0,0.9*c,!1);P(a,(1-0.85/0.9)*b,0.8*c,0.85/0.9*b,0.8*c,1*b,0.9*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.5);b.H=new K(0.75,0.82);t.v(a);return b},Cube1:function(a,b,c){a=t.u();O(a,0.5*b,1*c,!0);a.lineTo(1*b,0.85*c);a.lineTo(1*b,0.15*c);a.lineTo(0.5*b,0*c);a.lineTo(0*b,0.15*c);a.lineTo(0*b,0.85*c);Q(a);O(a,0.5*b,1*c,!1);a.lineTo(0.5*b,0.3*c);a.lineTo(0,0.15*c);a.moveTo(0.5*b,0.3*c);a.lineTo(1*b,0.15*c);a.ab(!1);b=a.s;b.G=new K(0,0.3);b.H=new K(0.5,0.85); -t.v(a);return b},Cube2:function(a,b,c){a=t.u();O(a,0,0.3*c,!0);a.lineTo(0*b,1*c);a.lineTo(0.7*b,c);a.lineTo(1*b,0.7*c);a.lineTo(1*b,0*c);a.lineTo(0.3*b,0*c);Q(a);O(a,0,0.3*c,!1);a.lineTo(0.7*b,0.3*c);a.lineTo(1*b,0*c);a.moveTo(0.7*b,0.3*c);a.lineTo(0.7*b,1*c);a.ab(!1);b=a.s;b.G=new K(0,0.3);b.H=new K(0.7,1);t.v(a);return b},MagneticData:"Cylinder1",Cylinder1:function(a,b,c){var d=J.va;a=0.5*d;var e=0.1*d,d=t.u();O(d,0,0.1*c,!0);P(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);P(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1* -b,0.1*c);d.lineTo(b,0.9*c);P(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);P(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);d.lineTo(0,0.1*c);O(d,0,0.1*c,!1);P(d,0,(0.1+e)*c,(0.5-a)*b,0.2*c,0.5*b,0.2*c);P(d,(0.5+a)*b,0.2*c,1*b,(0.1+e)*c,1*b,0.1*c);d.ab(!1);b=d.s;b.G=new K(0,0.2);b.H=new K(1,0.9);t.v(d);return b},Cylinder2:function(a,b,c){var d=J.va;a=0.5*d;var e=0.1*d,d=t.u();O(d,0,0.9*c,!0);d.lineTo(0,0.1*c);P(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);P(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1*b,0.1*c);d.lineTo(1*b,0.9*c);P(d,1* -b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);P(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);O(d,0,0.9*c,!1);P(d,0,(0.9-e)*c,(0.5-a)*b,0.8*c,0.5*b,0.8*c);P(d,(0.5+a)*b,0.8*c,1*b,(0.9-e)*c,1*b,0.9*c);d.ab(!1);b=d.s;b.G=new K(0,0.1);b.H=new K(1,0.8);t.v(d);return b},Cylinder3:function(a,b,c){var d=J.va;a=0.1*d;var e=0.5*d,d=t.u();O(d,0.1*b,0,!0);d.lineTo(0.9*b,0);P(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);P(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);P(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);P(d,0,(0.5- -e)*c,(0.1-a)*b,0,0.1*b,0);O(d,0.1*b,0,!1);P(d,(0.1+a)*b,0,0.2*b,(0.5-e)*c,0.2*b,0.5*c);P(d,0.2*b,(0.5+e)*c,(0.1+a)*b,1*c,0.1*b,1*c);d.ab(!1);b=d.s;b.G=new K(0.2,0);b.H=new K(0.9,1);t.v(d);return b},DirectData:"Cylinder4",Cylinder4:function(a,b,c){var d=J.va;a=0.1*d;var e=0.5*d,d=t.u();O(d,0.9*b,0,!0);P(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);P(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);P(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);P(d,0,(0.5-e)*c,(0.1-a)*b,0,0.1*b,0);d.lineTo(0.9*b,0);O(d, -0.9*b,0,!1);P(d,(0.9-a)*b,0,0.8*b,(0.5-e)*c,0.8*b,0.5*c);P(d,0.8*b,(0.5+e)*c,(0.9-a)*b,1*c,0.9*b,1*c);d.ab(!1);b=d.s;b.G=new K(0.1,0);b.H=new K(0.8,1);t.v(d);return b},Prism1:function(a,b,c){a=t.u();O(a,0.25*b,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(b,0.5*c);a.lineTo(0.5*b,c);a.lineTo(0,c);Q(a);O(a,0.25*b,0.25*c,!1);a.lineTo(0.5*b,c);a.ab(!1);b=a.s;b.G=new K(0.408,0.172);b.H=new K(0.833,0.662);t.v(a);return b},Prism2:function(a,b,c){a=t.u();O(a,0,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c); -a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);Q(a);O(a,0,c,!1);a.lineTo(0.25*b,0.5*c);a.lineTo(b,0.25*c);a.moveTo(0,0.25*c);a.lineTo(0.25*b,0.5*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.5);b.H=new K(0.75,0.75);t.v(a);return b},Pyramid1:function(a,b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(b,0.75*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.75*c);Q(a);O(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.367);b.H=new K(0.75,0.875);t.v(a);return b},Pyramid2:function(a,b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(b,0.85* -c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.85*c);Q(a);O(a,0.5*b,0,!1);a.lineTo(0.5*b,0.7*c);a.lineTo(0,0.85*c);a.moveTo(0.5*b,0.7*c);a.lineTo(1*b,0.85*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.367);b.H=new K(0.75,0.875);t.v(a);return b},Actor:function(a,b,c){var d=J.va,e=0.2*d,g=0.1*d,h=0.5,k=0.1;a=t.u();O(a,h*b,(k+0.1)*c,!0);P(a,(h-e)*b,(k+0.1)*c,(h-0.2)*b,(k+g)*c,(h-0.2)*b,k*c);P(a,(h-0.2)*b,(k-g)*c,(h-e)*b,(k-0.1)*c,h*b,(k-0.1)*c);P(a,(h+e)*b,(k-0.1)*c,(h+0.2)*b,(k-g)*c,(h+0.2)*b,k*c);P(a,(h+0.2)*b,(k+g)*c, -(h+e)*b,(k+0.1)*c,h*b,(k+0.1)*c);e=0.05;g=d*e;O(a,0.5*b,0.2*c,!0);a.lineTo(0.95*b,0.2*c);h=0.95;k=0.25;P(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);a.lineTo(1*b,0.6*c);a.lineTo(0.85*b,0.6*c);a.lineTo(0.85*b,0.35*c);e=0.025;g=d*e;h=0.825;k=0.35;P(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.8*b,1*c);a.lineTo(0.55*b,1*c);a.lineTo(0.55*b,0.7*c);e=0.05;g=d*e;h=0.5;k=0.7;P(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h-g)*b,(k-e)* -c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.45*b,1*c);a.lineTo(0.2*b,1*c);a.lineTo(0.2*b,0.35*c);e=0.025;g=d*e;h=0.175;k=0.35;P(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.15*b,0.6*c);a.lineTo(0*b,0.6*c);a.lineTo(0*b,0.25*c);e=0.05;g=d*e;h=0.05;k=0.25;P(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);a.lineTo(0.5*b,0.2*c);b=a.s;b.G=new K(0.2,0.2);b.H=new K(0.8,0.65);t.v(a);return b},Card:function(a,b,c){a=t.u();O(a,1*b,0*c,!0);a.lineTo(1* -b,1*c);a.lineTo(0*b,1*c);a.lineTo(0*b,0.2*c);a.lineTo(0.2*b,0*c);Q(a);b=a.s;b.G=new K(0,0.2);b.H=$b;t.v(a);return b},Collate:function(a,b,c){a=t.u();O(a,0.5*b,0.5*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);O(a,0.5*b,0.5*c,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,0.25);t.v(a);return b},CreateRequest:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,0,a* -c,!1);d.lineTo(1*b,a*c);d.moveTo(0,(1-a)*c);d.lineTo(1*b,(1-a)*c);d.ab(!1);b=d.s;b.G=new K(0,a);b.H=new K(1,1-a);t.v(d);return b},Database:function(a,b,c){a=t.u();var d=J.va,e=0.5*d,d=0.1*d;O(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);P(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);P(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);P(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);P(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);O(a,1*b,0.1*c,!1);P(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);P(a,(0.5-e)*b,0.2*c,0,(0.1+d)* -c,0,0.1*c);a.moveTo(1*b,0.2*c);P(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);P(a,(0.5-e)*b,0.3*c,0,(0.2+d)*c,0,0.2*c);a.moveTo(1*b,0.3*c);P(a,1*b,(0.3+d)*c,(0.5+e)*b,0.4*c,0.5*b,0.4*c);P(a,(0.5-e)*b,0.4*c,0,(0.3+d)*c,0,0.3*c);a.ab(!1);b=a.s;b.G=new K(0,0.4);b.H=new K(1,0.9);t.v(a);return b},StoredData:"DataStorage",DataStorage:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0);P(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0,1*c);P(a,0.25*b,0.9*c,0.25*b,0.1*c,0,0);Q(a);b=a.s;b.G=new K(0.226,0);b.H=new K(0.81, -1);t.v(a);return b},DiskStorage:function(a,b,c){a=t.u();var d=J.va,e=0.5*d,d=0.1*d;O(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);P(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);P(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);P(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);P(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);O(a,1*b,0.1*c,!1);P(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);P(a,(0.5-e)*b,0.2*c,0,(0.1+d)*c,0,0.1*c);a.moveTo(1*b,0.2*c);P(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);P(a,(0.5-e)*b,0.3*c,0,(0.2+d)* -c,0,0.2*c);a.ab(!1);b=a.s;b.G=new K(0,0.3);b.H=new K(1,0.9);t.v(a);return b},Display:function(a,b,c){a=t.u();O(a,0.25*b,0,!0);a.lineTo(0.75*b,0);P(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0.25*b,1*c);a.lineTo(0,0.5*c);Q(a);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,1);t.v(a);return b},DividedEvent:function(a,b,c){a=a?a.yc:0;0===a?a=0.2:0.15>a&&(a=0.15);var d=t.u(),e=0.2*J.va;O(d,0,0.2*c,!0);P(d,0,(0.2-e)*c,(0.2-e)*b,0,0.2*b,0);d.lineTo(0.8*b,0);P(d,(0.8+e)*b,0,1*b,(0.2-e)*c,1*b,0.2*c);d.lineTo(1*b,0.8*c); -P(d,1*b,(0.8+e)*c,(0.8+e)*b,1*c,0.8*b,1*c);d.lineTo(0.2*b,1*c);P(d,(0.2-e)*b,1*c,0,(0.8+e)*c,0,0.8*c);d.lineTo(0,0.2*c);O(d,0,a*c,!1);d.lineTo(1*b,a*c);d.ab(!1);b=d.s;b.G=new K(0,a);b.H=new K(1,1-a);t.v(d);return b},DividedProcess:function(a,b,c){a=a?a.yc:0;0.1>a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,0,a*c,!1);d.lineTo(1*b,a*c);d.ab(!1);b=d.s;b.G=new K(0,a);b.H=$b;t.v(d);return b},Document:function(a,b,c){c/=0.8;a=t.u();O(a,0,0.7*c,!0);a.lineTo(0, -0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);P(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);Q(a);b=a.s;b.G=Tb;b.H=new K(1,0.6);t.v(a);return b},ExternalOrganization:function(a,b,c){a=a?a.yc:0;0.2>a&&(a=0.2);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,a*b,0,!1);d.lineTo(0,a*c);d.moveTo(1*b,a*c);d.lineTo((1-a)*b,0);d.moveTo(0,(1-a)*c);d.lineTo(a*b,1*c);d.moveTo((1-a)*b,1*c);d.lineTo(1*b,(1-a)*c);d.ab(!1);b=d.s;b.G=new K(a/2,a/2);b.H=new K(1-a/2,1-a/2);t.v(d);return b},ExternalProcess:function(a, -b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);Q(a);O(a,0.1*b,0.4*c,!1);a.lineTo(0.1*b,0.6*c);a.moveTo(0.9*b,0.6*c);a.lineTo(0.9*b,0.4*c);a.moveTo(0.6*b,0.1*c);a.lineTo(0.4*b,0.1*c);a.moveTo(0.4*b,0.9*c);a.lineTo(0.6*b,0.9*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.25);b.H=new K(0.75,0.75);t.v(a);return b},File:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);Q(a);O(a,0.75*b,0,!1);a.lineTo(0.75*b,0.25*c); -a.lineTo(1*b,0.25*c);a.ab(!1);b=a.s;b.G=new K(0,0.25);b.H=$b;t.v(a);return b},Interrupt:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);O(a,1*b,0.5*c,!1);a.lineTo(1*b,1*c);O(a,1*b,0.5*c,!1);a.lineTo(1*b,0);b=a.s;b.G=new K(0,0.25);b.H=new K(0.5,0.75);t.v(a);return b},InternalStorage:function(a,b,c){var d=a?a.yc:0;a=a?a.lt:0;0===d&&(d=0.1);0===a&&(a=0.1);var e=t.u();O(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(1*b,1*c);e.lineTo(0,1*c);Q(e);O(e,d*b,0,!1);e.lineTo(d* -b,1*c);e.moveTo(0,a*c);e.lineTo(1*b,a*c);e.ab(!1);b=e.s;b.G=new K(d,a);b.H=$b;t.v(e);return b},Junction:function(a,b,c){a=t.u();var d=1/Math.SQRT2,e=(1-1/Math.SQRT2)/2,g=0.5*J.va;O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+g)*c,(0.5+g)*b,1*c,0.5*b,1*c);P(a,(0.5-g)*b,1*c,0,(0.5+g)*c,0,0.5*c);P(a,0,(0.5-g)*c,(0.5-g)*b,0,0.5*b,0);P(a,(0.5+g)*b,0,1*b,(0.5-g)*c,1*b,0.5*c);O(a,(e+d)*b,(e+d)*c,!1);a.lineTo(e*b,e*c);a.moveTo(e*b,(e+d)*c);a.lineTo((e+d)*b,e*c);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b},LinedDocument:function(a, -b,c){c/=0.8;a=t.u();O(a,0,0.7*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);P(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);Q(a);O(a,0.1*b,0,!1);a.lineTo(0.1*b,0.75*c);a.ab(!1);b=a.s;b.G=new K(0.1,0);b.H=new K(1,0.6);t.v(a);return b},LoopLimit:function(a,b,c){a=t.u();O(a,0,1*c,!0);a.lineTo(0,0.25*c);a.lineTo(0.25*b,0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=$b;t.v(a);return b},SequentialData:"MagneticTape",MagneticTape:function(a,b,c){a=t.u();var d= -0.5*J.va;O(a,0.5*b,1*c,!0);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,0.9*c,0.6*b,0.9*c);a.lineTo(1*b,0.9*c);a.lineTo(1*b,1*c);a.lineTo(0.5*b,1*c);b=a.s;b.G=new K(0.15,0.15);b.H=new K(0.85,0.8);t.v(a);return b},ManualInput:function(a,b,c){a=t.u();O(a,1*b,0,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.25*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=$b;t.v(a);return b},MessageFromUser:function(a,b,c){a= -a?a.yc:0;0===a&&(a=0.7);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(a*b,0.5*c);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);b=d.s;b.G=Tb;b.H=new K(a,1);t.v(d);return b},MicroformProcessing:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.25);var d=t.u();O(d,0,0,!0);d.lineTo(0.5*b,a*c);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.5*b,(1-a)*c);d.lineTo(0,1*c);Q(d);b=d.s;b.G=new K(0,a);b.H=new K(1,1-a);t.v(d);return b},MicroformRecording:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0.25*c);a.lineTo(1*b, -0.15*c);a.lineTo(1*b,0.85*c);a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=new K(1,0.75);t.v(a);return b},MultiDocument:function(a,b,c){c/=0.8;a=t.u();O(a,b,0,!0);a.lineTo(b,0.5*c);P(a,0.96*b,0.47*c,0.93*b,0.45*c,0.9*b,0.44*c);a.lineTo(0.9*b,0.6*c);P(a,0.86*b,0.57*c,0.83*b,0.55*c,0.8*b,0.54*c);a.lineTo(0.8*b,0.7*c);P(a,0.4*b,0.4*c,0.4*b,1*c,0,0.7*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);a.lineTo(0.1*b,0.1*c);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);Q(a);O(a,0.1*b,0.2*c, -!1);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.54*c);a.moveTo(0.2*b,0.1*c);a.lineTo(0.9*b,0.1*c);a.lineTo(0.9*b,0.44*c);a.ab(!1);b=a.s;b.G=new K(0,0.25);b.H=new K(0.8,0.77);t.v(a);return b},MultiProcess:function(a,b,c){a=t.u();O(a,0.1*b,0.1*c,!0);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.8*c);a.lineTo(0.9*b,0.8*c);a.lineTo(0.9*b,0.9*c);a.lineTo(0.8*b,0.9*c);a.lineTo(0.8*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);Q(a);O(a,0.2*b,0.1*c,!1);a.lineTo(0.9*b, -0.1*c);a.lineTo(0.9*b,0.8*c);a.moveTo(0.1*b,0.2*c);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.9*c);a.ab(!1);b=a.s;b.G=new K(0,0.2);b.H=new K(0.8,1);t.v(a);return b},OfflineStorage:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=1-a,e=t.u();O(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(0.5*b,1*c);Q(e);O(e,0.5*a*b,a*c,!1);e.lineTo((1-0.5*a)*b,a*c);e.ab(!1);b=e.s;b.G=new K(d/4+0.5*a,a);b.H=new K(3*d/4+0.5*a,a+0.5*d);t.v(e);return b},OffPageConnector:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1* -b,0.5*c);a.lineTo(0.75*b,1*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=Tb;b.H=new K(0.75,1);t.v(a);return b},Or:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);O(a,1*b,0.5*c,!1);a.lineTo(0,0.5*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b},PaperTape:function(a,b,c){c/=0.8;a=t.u();O(a,0,0.7*c,!0);a.lineTo(0, -0.3*c);P(a,0.5*b,0.6*c,0.5*b,0,1*b,0.3);a.lineTo(1*b,0.7*c);P(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);Q(a);b=a.s;b.G=new K(0,0.49);b.H=new K(1,0.75);t.v(a);return b},PrimitiveFromCall:function(a,b,c){var d=a?a.yc:0;a=a?a.lt:0;0===d&&(d=0.1);0===a&&(a=0.3);var e=t.u();O(e,0,0,!0);e.lineTo(1*b,0);e.lineTo((1-a)*b,0.5*c);e.lineTo(1*b,1*c);e.lineTo(0,1*c);Q(e);b=e.s;b.G=new K(d,0);b.H=new K(1-a,1);t.v(e);return b},PrimitiveToCall:function(a,b,c){var d=a?a.yc:0;a=a?a.lt:0;0===d&&(d=0.1);0===a&&(a=0.3);var e= -t.u();O(e,0,0,!0);e.lineTo((1-a)*b,0);e.lineTo(1*b,0.5*c);e.lineTo((1-a)*b,1*c);e.lineTo(0,1*c);Q(e);b=e.s;b.G=new K(d,0);b.H=new K(1-a,1);t.v(e);return b},Subroutine:"Procedure",Procedure:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,(1-a)*b,0,!1);d.lineTo((1-a)*b,1*c);d.moveTo(a*b,0);d.lineTo(a*b,1*c);d.ab(!1);b=d.s;b.G=new K(a,0);b.H=new K(1-a,1);t.v(d);return b},Process:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d= -t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,a*b,0,!1);d.lineTo(a*b,1*c);d.ab(!1);b=d.s;b.G=new K(a,0);b.H=$b;t.v(d);return b},Sort:function(a,b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);Q(a);O(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.25);b.H=new K(0.75,0.5);t.v(a);return b},Start:function(a,b,c){a=t.u();O(a,0.25*b,0,!0);O(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25* -b,0.5*c,0.25*b,0.5*c);O(a,0.25*b,0,!1);a.lineTo(0.25*b,1*c);a.moveTo(0.75*b,0);a.lineTo(0.75*b,1*c);a.ab(!1);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,1);t.v(a);return b},Terminator:function(a,b,c){a=t.u();O(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25*b,0.5*c,0.25*b,0.5*c);b=a.s;b.G=new K(0.23,0);b.H=new K(0.77,1);t.v(a);return b},TransmittalTape:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.75*b,(1-a)* -c);d.lineTo(0,(1-a)*c);Q(d);b=d.s;b.G=Tb;b.H=new K(1,1-a);t.v(d);return b},AndGate:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0,0,!0);a.lineTo(0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=Tb;b.H=new K(0.55,1);t.v(a);return b},Buffer:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=new K(0.5,0.75);t.v(a);return b},Clock:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,1* -b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);O(a,1*b,0.5*c,!1);a.lineTo(1*b,0.5*c);O(a,0.8*b,0.75*c,!1);a.lineTo(0.8*b,0.25*c);a.lineTo(0.6*b,0.25*c);a.lineTo(0.6*b,0.75*c);a.lineTo(0.4*b,0.75*c);a.lineTo(0.4*b,0.25*c);a.lineTo(0.2*b,0.25*c);a.lineTo(0.2*b,0.75*c);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b},Ground:function(a,b,c){a=t.u();O(a,0.5*b,0,!1);a.lineTo(0.5*b,0.4*c); -a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.3*b,0.8*c);a.lineTo(0.7*b,0.8*c);a.moveTo(0.4*b,1*c);a.lineTo(0.6*b,1*c);b=a.s;t.v(a);return b},Inverter:function(a,b,c){a=t.u();var d=0.1*J.va;O(a,0.8*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.8*b,0.5*c);O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);P(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);P(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);P(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new K(0,0.25); -b.H=new K(0.4,0.75);t.v(a);return b},NandGate:function(a,b,c){a=t.u();var d=J.va,e=0.5*d,g=0.4*d,d=0.1*d;O(a,0.8*b,0.5*c,!0);P(a,0.8*b,(0.5+g)*c,(0.4+e)*b,1*c,0.4*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.4*b,0);P(a,(0.4+e)*b,0,0.8*b,(0.5-g)*c,0.8*b,0.5*c);O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);P(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);P(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);P(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new K(0,0.05);b.H=new K(0.55, -0.95);t.v(a);return b},NorGate:function(a,b,c){a=t.u();var d=J.va,e=0.5,g=d*e,h=0,k=0.5;O(a,0.8*b,0.5*c,!0);P(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0,1*c);P(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);P(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;O(a,(h-e)*b,k*c,!0);P(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);P(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);P(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new K(0.2,0.25); -b.H=new K(0.6,0.75);t.v(a);return b},OrGate:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0,0,!0);P(a,(0+d+d)*b,0*c,0.8*b,(0.5-d)*c,1*b,0.5*c);P(a,0.8*b,(0.5+d)*c,(0+d+d)*b,1*c,0,1*c);P(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);Q(a);b=a.s;b.G=new K(0.2,0.25);b.H=new K(0.75,0.75);t.v(a);return b},XnorGate:function(a,b,c){a=t.u();var d=J.va,e=0.5,g=d*e,h=0.2,k=0.5;O(a,0.1*b,0,!1);P(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);O(a,0.8*b,0.5*c,!0);P(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0.2*b,1*c);P(a,0.45*b,0.75*c,0.45* -b,0.25*c,0.2*b,0);P(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;O(a,(h-e)*b,k*c,!0);P(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);P(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);P(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new K(0.4,0.25);b.H=new K(0.65,0.75);t.v(a);return b},XorGate:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0.1*b,0,!1);P(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);O(a,0.2*b,0,!0);P(a,(0.2+ -d)*b,0*c,0.9*b,(0.5-d)*c,1*b,0.5*c);P(a,0.9*b,(0.5+d)*c,(0.2+d)*b,1*c,0.2*b,1*c);P(a,0.45*b,0.75*c,0.45*b,0.25*c,0.2*b,0);Q(a);b=a.s;b.G=new K(0.4,0.25);b.H=new K(0.8,0.75);t.v(a);return b},Capacitor:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Resistor:function(a,b,c){a=t.u();O(a,0,0.5*c,!1);a.lineTo(0.1*b,0);a.lineTo(0.2*b,1*c);a.lineTo(0.3*b,0);a.lineTo(0.4*b,1*c);a.lineTo(0.5*b,0);a.lineTo(0.6*b,1*c);a.lineTo(0.7*b,0.5*c);b=a.s;t.v(a); -return b},Inductor:function(a,b,c){a=t.u();var d=0.1*J.va,e=0.1,g=0.5;O(a,(e-0.5*d)*b,(g+0.1)*c,!1);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.3;g=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);g=e=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.7;g=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)* -b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.9;g=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,(e+0.5*d)*b,(g+0.1)*c);b=a.s;t.v(a);return b},ACvoltageSource:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0*b,0.5*c,!1);P(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);P(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);a.moveTo(0.1*b,0.5*c);P(a,0.5*b,0*c,0.5*b,1*c,0.9*b,0.5*c);b=a.s;b.kc=Zg;t.v(a);return b},DCvoltageSource:function(a,b,c){a=t.u(); -O(a,0,0.75*c,!1);a.lineTo(0,0.25*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Diode:function(a,b,c){a=t.u();O(a,1*b,0,!1);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new K(0,0.25);b.H=new K(0.5,0.75);t.v(a);return b},Wifi:function(a,b,c){var d=b,e=c;b*=0.38;c*=0.6;a=t.u();var g=J.va,h=0.8*g,k=0.8,l=0,m=0.5,d=(d-b)/2,e=(e-c)/2;O(a,l*b+d,(m+k)*c+e,!0);P(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);P(a,(l-k)*b+d,(m-h)* -c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);P(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);P(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);Q(a);h=0.4*g;k=0.4;l=0.2;m=0.5;O(a,l*b+d,(m+k)*c+e,!0);P(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);P(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);P(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);P(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);Q(a);h=0.2*g;k=0.2; -m=l=0.5;O(a,(l-k)*b+d,m*c+e,!0);P(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);P(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);P(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);P(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);h=0.4*g;k=0.4;l=0.8;m=0.5;O(a,l*b+d,(m-k)*c+e,!0);P(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);P(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);P(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5* -h)*b+d,m*c+e);P(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);Q(a);h=0.8*g;k=0.8;l=1;m=0.5;O(a,l*b+d,(m-k)*c+e,!0);P(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);P(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);P(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5*h)*b+d,m*c+e);P(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);Q(a);b=a.s;t.v(a);return b},Email:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,1*c);a.lineTo(0,1* -c);a.lineTo(0,0);Q(a);O(a,0,0,!1);a.lineTo(0.5*b,0.6*c);a.lineTo(1*b,0);a.moveTo(0,1*c);a.lineTo(0.45*b,0.54*c);a.moveTo(1*b,1*c);a.lineTo(0.55*b,0.54*c);a.ab(!1);b=a.s;t.v(a);return b},Ethernet:function(a,b,c){a=t.u();O(a,0.35*b,0,!0);a.lineTo(0.65*b,0);a.lineTo(0.65*b,0.4*c);a.lineTo(0.35*b,0.4*c);a.lineTo(0.35*b,0);Q(a);O(a,0.1*b,1*c,!0,!0);a.lineTo(0.4*b,1*c);a.lineTo(0.4*b,0.6*c);a.lineTo(0.1*b,0.6*c);a.lineTo(0.1*b,1*c);Q(a);O(a,0.6*b,1*c,!0,!0);a.lineTo(0.9*b,1*c);a.lineTo(0.9*b,0.6*c);a.lineTo(0.6* -b,0.6*c);a.lineTo(0.6*b,1*c);Q(a);O(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.5*b,0.4*c);a.moveTo(0.75*b,0.5*c);a.lineTo(0.75*b,0.6*c);a.moveTo(0.25*b,0.5*c);a.lineTo(0.25*b,0.6*c);a.ab(!1);b=a.s;t.v(a);return b},Power:function(a,b,c){a=t.u();var d=J.va,e=0.4*d,g=0.4,h=t.O(),k=t.O(),l=t.O(),m=t.O();J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.5,h,h,k,l,m);var n=t.ic(k.x,k.y);O(a,k.x*b,k.y*c,!0);P(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);P(a,(0.5+g)*b,(0.5+e)*c,(0.5+ -e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5-e)*b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);J.Hi(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);P(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);e=0.3*d;g=0.3;J.Hi(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);a.lineTo(k.x*b,k.y*c);P(a,m.x*b,m.y*c,l.x*b,l.y*c,(0.5-g)*b,0.5*c);P(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5- -e,0.5+g,0.5,0.5,h,h,k,l,m);P(a,m.x*b,m.y*c,l.x*b,l.y*c,k.x*b,k.y*c);Q(a);O(a,0.45*b,0,!0);a.lineTo(0.45*b,0.5*c);a.lineTo(0.55*b,0.5*c);a.lineTo(0.55*b,0);Q(a);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);b=a.s;b.G=new K(0.25,0.55);b.H=new K(0.75,0.8);t.v(a);return b},Fallout:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0*b,0.5*c,!0);P(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);P(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);var e= -d=0;O(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.4;e=0;Q(a);O(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.2;e=-0.3;Q(a);O(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);Q(a);b=a.s;b.kc=Zg;t.v(a);return b},IrritationHazard:function(a,b,c){a=t.u();O(a,0.2*b,0*c,!0);a.lineTo(0.5* -b,0.3*c);a.lineTo(0.8*b,0*c);a.lineTo(1*b,0.2*c);a.lineTo(0.7*b,0.5*c);a.lineTo(1*b,0.8*c);a.lineTo(0.8*b,1*c);a.lineTo(0.5*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0*b,0.8*c);a.lineTo(0.3*b,0.5*c);a.lineTo(0*b,0.2*c);Q(a);b=a.s;b.G=new K(0.3,0.3);b.H=new K(0.7,0.7);t.v(a);return b},ElectricalHazard:function(a,b,c){a=t.u();O(a,0.37,0*c,!0);a.lineTo(0.5*b,0.11*c);a.lineTo(0.77*b,0.04*c);a.lineTo(0.33*b,0.49*c);a.lineTo(1*b,0.37*c);a.lineTo(0.63*b,0.86*c);a.lineTo(0.77*b,0.91*c);a.lineTo(0.34*b,1*c);a.lineTo(0.34* -b,0.78*c);a.lineTo(0.44*b,0.8*c);a.lineTo(0.65*b,0.56*c);a.lineTo(0*b,0.68*c);Q(a);b=a.s;t.v(a);return b},FireHazard:function(a,b,c){a=t.u();O(a,0.1*b,1*c,!0);P(a,-0.25*b,0.63*c,0.45*b,0.44*c,0.29*b,0*c);P(a,0.48*b,0.17*c,0.54*b,0.35*c,0.51*b,0.42*c);P(a,0.59*b,0.29*c,0.58*b,0.28*c,0.59*b,0.18*c);P(a,0.8*b,0.34*c,0.88*b,0.43*c,0.75*b,0.6*c);P(a,0.87*b,0.48*c,0.88*b,0.43*c,0.88*b,0.31*c);P(a,1.17*b,0.76*c,0.82*b,0.8*c,0.9*b,1*c);Q(a);b=a.s;b.G=new K(0.05,0.645);b.H=new K(0.884,0.908);t.v(a);return b}, -BpmnActivityLoop:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;O(a,(0.5*Math.SQRT2/2+0.5)*b,(1-(0.5-0.5*Math.SQRT2/2))*c,!1);P(a,1*b,0.7*c,1*b,0.5*c,1*b,0.5*c);P(a,1*b,(0.5-d+0)*c,(0.5+d+0)*b,0*c,0.5*b,0*c);P(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);P(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.35*b,0.98*c);a.moveTo(0.35*b,0.8*c);a.lineTo(0.35*b,1*c);a.lineTo(0.15*b,1*c);b=a.s;t.v(a);return b},BpmnActivityParallel:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(0.5*b,0);a.lineTo(0.5* -b,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivitySequential:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0,1*c);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivityAdHoc:function(a,b,c){a=t.u();O(a,0,0,!1);O(a,1*b,1*c,!1);O(a,0,0.5*c,!1);P(a,0.2*b,0.35*c,0.3*b,0.35*c,0.5*b,0.5*c);P(a,0.7*b,0.65*c,0.8*b,0.65*c,1*b,0.5*c);b=a.s;t.v(a);return b},BpmnActivityCompensation:function(a,b,c){a=t.u();O(a,0,0.5*c,!0);a.lineTo(0.5* -b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(0.5*b,1*c);Q(a);b=a.s;t.v(a);return b},BpmnTaskMessage:function(a,b,c){a=t.u();O(a,0,0.2*c,!0);a.lineTo(1*b,0.2*c);a.lineTo(1*b,0.8*c);a.lineTo(0,0.8*c);a.lineTo(0,0.8*c);Q(a);O(a,0,0.2*c,!1);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,0.2*c);a.ab(!1);b=a.s;t.v(a);return b},BpmnTaskScript:function(a,b,c){a=t.u();O(a,0.7*b,1*c,!0);a.lineTo(0.3*b,1*c);P(a,0.6*b,0.5*c,0,0.5*c,0.3*b,0);a.lineTo(0.7*b,0);P(a,0.4*b,0.5*c, -1*b,0.5*c,0.7*b,1*c);Q(a);O(a,0.45*b,0.73*c,!1);a.lineTo(0.7*b,0.73*c);a.moveTo(0.38*b,0.5*c);a.lineTo(0.63*b,0.5*c);a.moveTo(0.31*b,0.27*c);a.lineTo(0.56*b,0.27*c);a.ab(!1);b=a.s;t.v(a);return b},BpmnTaskUser:function(a,b,c){a=t.u();O(a,0,0,!1);O(a,0.335*b,(1-0.555)*c,!0);a.lineTo(0.335*b,0.595*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.665*b,(1-0.555)*c);P(a,0.88*b,0.46*c,0.98*b,0.54*c,1*b,0.68*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.68*c);P(a,0.02*b,0.54*c,0.12*b,0.46*c,0.335*b,(1-0.555)* -c);a.lineTo(0.365*b,0.405*c);var d=0.5-0.285,e=Math.PI/4,g=4*(1-Math.cos(e))/(3*Math.sin(e)),e=g*d,g=g*d;P(a,(0.5-(e+d)/2)*b,(d+(d+g)/2)*c,(0.5-d)*b,(d+g)*c,(0.5-d)*b,d*c);P(a,(0.5-d)*b,(d-g)*c,(0.5-e)*b,(d-d)*c,0.5*b,(d-d)*c);P(a,(0.5+e)*b,(d-d)*c,(0.5+d)*b,(d-g)*c,(0.5+d)*b,d*c);P(a,(0.5+d)*b,(d+g)*c,(0.5+(e+d)/2)*b,(d+(d+g)/2)*c,0.635*b,0.405*c);a.lineTo(0.635*b,0.405*c);a.lineTo(0.665*b,(1-0.555)*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.335*b,0.595*c);O(a,0.2*b,1*c,!1);a.lineTo(0.2*b,0.8*c);O(a, -0.8*b,1*c,!1);a.lineTo(0.8*b,0.8*c);b=a.s;t.v(a);return b},BpmnEventConditional:function(a,b,c){a=t.u();O(a,0.1*b,0,!0);a.lineTo(0.9*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);Q(a);O(a,0.2*b,0.2*c,!1);a.lineTo(0.8*b,0.2*c);a.moveTo(0.2*b,0.4*c);a.lineTo(0.8*b,0.4*c);a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.2*b,0.8*c);a.lineTo(0.8*b,0.8*c);a.ab(!1);b=a.s;t.v(a);return b},BpmnEventError:function(a,b,c){a=t.u();O(a,0,1*c,!0);a.lineTo(0.33*b,0);a.lineTo(0.66*b,0.5*c);a.lineTo(1*b,0);a.lineTo(0.66* -b,1*c);a.lineTo(0.33*b,0.5*c);Q(a);b=a.s;t.v(a);return b},BpmnEventEscalation:function(a,b,c){a=t.u();O(a,0,0,!1);O(a,1*b,1*c,!1);O(a,0.1*b,1*c,!0);a.lineTo(0.5*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.5*b,0.5*c);Q(a);b=a.s;t.v(a);return b},BpmnEventTimer:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);O(a,0.5*b,0,!1);a.lineTo(0.5*b,0.15* -c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0.85*c);a.moveTo(0,0.5*c);a.lineTo(0.15*b,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(0.85*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.58*b,0.1*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.78*b,0.54*c);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b}};for(var Xl in J.Qi)J.Qi[Xl.toLowerCase()]=Xl; -J.Kv={"":"",Standard:"F1 m 0,0 l 8,4 -8,4 2,-4 z",Backward:"F1 m 8,0 l -2,4 2,4 -8,-4 z",Triangle:"F1 m 0,0 l 8,4.62 -8,4.62 z",BackwardTriangle:"F1 m 8,4 l 0,4 -8,-4 8,-4 0,4 z",Boomerang:"F1 m 0,0 l 8,4 -8,4 4,-4 -4,-4 z",BackwardBoomerang:"F1 m 8,0 l -8,4 8,4 -4,-4 4,-4 z",SidewaysV:"m 0,0 l 8,4 -8,4 0,-1 6,-3 -6,-3 0,-1 z",BackwardV:"m 8,0 l -8,4 8,4 0,-1 -6,-3 6,-3 0,-1 z",OpenTriangle:"m 0,0 l 8,4 -8,4",BackwardOpenTriangle:"m 8,0 l -8,4 8,4",OpenTriangleLine:"m 0,0 l 8,4 -8,4 m 8.5,0 l 0,-8", -BackwardOpenTriangleLine:"m 8,0 l -8,4 8,4 m -8.5,0 l 0,-8",OpenTriangleTop:"m 0,0 l 8,4 m 0,4",BackwardOpenTriangleTop:"m 8,0 l -8,4 m 0,4",OpenTriangleBottom:"m 0,8 l 8,-4",BackwardOpenTriangleBottom:"m 0,4 l 8,4",HalfTriangleTop:"F1 m 0,0 l 0,4 8,0 z m 0,8",BackwardHalfTriangleTop:"F1 m 8,0 l 0,4 -8,0 z m 0,8",HalfTriangleBottom:"F1 m 0,4 l 0,4 8,-4 z",BackwardHalfTriangleBottom:"F1 m 8,4 l 0,4 -8,-4 z",ForwardSemiCircle:"m 4,0 b 270 180 0 4 4",BackwardSemiCircle:"m 4,8 b 90 180 0 -4 4",Feather:"m 0,0 l 3,4 -3,4", -BackwardFeather:"m 3,0 l -3,4 3,4",DoubleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardDoubleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4",TripleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardTripleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4 m 3,-8 l -3,4 3,4",ForwardSlash:"m 0,8 l 5,-8",BackSlash:"m 0,0 l 5,8",DoubleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8",DoubleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8",TripleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8 m -2,8 l 4,-8", -TripleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8 m -2,-8 l 4,8",Fork:"m 0,4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4",LineFork:"m 0,0 l 0,8 m 0,-4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardLineFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4 m 8,-8 l 0,8",CircleFork:"F1 m 6,4 b 0 360 -3 0 3 z m 0,0 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4",BackwardCircleFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 6,0 b 0 360 -3 0 3",CircleLineFork:"F1 m 6,4 b 0 360 -3 0 3 z m 1,-4 l 0,8 m 0,-4 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4", -BackwardCircleLineFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 0,-4 l 0,8 m 7,-4 b 0 360 -3 0 3",Circle:"F1 m 8,4 b 0 360 -4 0 4 z",Block:"F1 m 0,0 l 0,8 8,0 0,-8 z",StretchedDiamond:"F1 m 0,3 l 5,-3 5,3 -5,3 -5,-3 z",Diamond:"F1 m 0,4 l 4,-4 4,4 -4,4 -4,-4 z",Chevron:"F1 m 0,0 l 5,0 3,4 -3,4 -5,0 3,-4 -3,-4 z",StretchedChevron:"F1 m 0,0 l 8,0 3,4 -3,4 -8,0 3,-4 -3,-4 z",NormalArrow:"F1 m 0,2 l 4,0 0,-2 4,4 -4,4 0,-2 -4,0 z",X:"m 0,0 l 8,8 m 0,-8 l -8,8",TailedNormalArrow:"F1 m 0,0 l 2,0 1,2 3,0 0,-2 2,4 -2,4 0,-2 -3,0 -1,2 -2,0 1,-4 -1,-4 z", -DoubleTriangle:"F1 m 0,0 l 4,4 -4,4 0,-8 z m 4,0 l 4,4 -4,4 0,-8 z",BigEndArrow:"F1 m 0,0 l 5,2 0,-2 3,4 -3,4 0,-2 -5,2 0,-8 z",ConcaveTailArrow:"F1 m 0,2 h 4 v -2 l 4,4 -4,4 v -2 h -4 l 2,-2 -2,-2 z",RoundedTriangle:"F1 m 0,1 a 1,1 0 0 1 1,-1 l 7,3 a 0.5,1 0 0 1 0,2 l -7,3 a 1,1 0 0 1 -1,-1 l 0,-6 z",SimpleArrow:"F1 m 1,2 l -1,-2 2,0 1,2 -1,2 -2,0 1,-2 5,0 0,-2 2,2 -2,2 0,-2 z",AccelerationArrow:"F1 m 0,0 l 0,8 0.2,0 0,-8 -0.2,0 z m 2,0 l 0,8 1,0 0,-8 -1,0 z m 3,0 l 2,0 2,4 -2,4 -2,0 0,-8 z",BoxArrow:"F1 m 0,0 l 4,0 0,2 2,0 0,-2 2,4 -2,4 0,-2 -2,0 0,2 -4,0 0,-8 z", -TriangleLine:"F1 m 8,4 l -8,-4 0,8 8,-4 z m 0.5,4 l 0,-8",CircleEndedArrow:"F1 m 10,4 l -2,-3 0,2 -2,0 0,2 2,0 0,2 2,-3 z m -4,0 b 0 360 -3 0 3 z",DynamicWidthArrow:"F1 m 0,3 l 2,0 2,-1 2,-2 2,4 -2,4 -2,-2 -2,-1 -2,0 0,-2 z",EquilibriumArrow:"m 0,3 l 8,0 -3,-3 m 3,5 l -8,0 3,3",FastForward:"F1 m 0,0 l 3.5,4 0,-4 3.5,4 0,-4 1,0 0,8 -1,0 0,-4 -3.5,4 0,-4 -3.5,4 0,-8 z",Kite:"F1 m 0,4 l 2,-4 6,4 -6,4 -2,-4 z",HalfArrowTop:"F1 m 0,0 l 4,4 4,0 -8,-4 z m 0,8",HalfArrowBottom:"F1 m 0,8 l 4,-4 4,0 -8,4 z", -OpposingDirectionDoubleArrow:"F1 m 0,4 l 2,-4 0,2 4,0 0,-2 2,4 -2,4 0,-2 -4,0 0,2 -2,-4 z",PartialDoubleTriangle:"F1 m 0,0 4,3 0,-3 4,4 -4,4 0,-3 -4,3 0,-8 z",LineCircle:"F1 m 0,0 l 0,8 m 7 -4 b 0 360 -3 0 3 z",DoubleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",TripleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",CircleLine:"F1 m 6 4 b 0 360 -3 0 3 z m 1,-4 l 0,8",DiamondCircle:"F1 m 8,4 l -4,4 -4,-4 4,-4 4,4 m 8,0 b 0 360 -4 0 4 z",PlusCircle:"F1 m 8,4 b 0 360 -4 0 4 l -8 0 z m -4 -4 l 0 8", -OpenRightTriangleTop:"m 8,0 l 0,4 -8,0 m 0,4",OpenRightTriangleBottom:"m 8,8 l 0,-4 -8,0",Line:"m 0,0 l 0,8",DoubleLine:"m 0,0 l 0,8 m 2,0 l 0,-8",TripleLine:"m 0,0 l 0,8 m 2,0 l 0,-8 m 2,0 l 0,8",PentagonArrow:"F1 m 8,4 l -4,-4 -4,0 0,8 4,0 4,-4 z",None:""};J.GA={};J.Lv={};J.Oo=function(a){if(J.Kv){for(var b in J.Kv){var c=bd(J.Kv[b],!1);J.Lv[b]=c;b.toLowerCase()!==b&&(J.Lv[b.toLowerCase()]=b)}J.Kv=void 0}return J.Lv[a]};Y.FigureGenerators=J.Qi;Y.ArrowheadGeometries=J.Lv; -function w(a){0===arguments.length?B.call(this):B.call(this,a);this.ca=49663;this.Wn=this.gh="";this.Jr=this.Gr=this.Tr=this.Wq=null;this.Vr="";this.Cg=this.Ur=this.mm=null;this.Ir="";this.lo=null;this.Hr=(new pa(NaN,NaN)).freeze();this.Kr="";this.mo=null;this.ge="";this.Vn=this.lq=this.Ck=null;this.li=(new C(NaN,NaN)).freeze();this.dr="";this.Pk=null;this.er=Tb;this.nr=J.nG;this.gr=J.mG;this.vq=null;this.Xq=Yl;this.pm=(new C(6,6)).freeze();this.om="gray";this.nm=4;this.AG=-1;this.xG=new D;this.Aj= -null;this.yj=NaN}t.ia("Part",w);t.Oa(w,B);w.prototype.cloneProtected=function(a){B.prototype.cloneProtected.call(this,a);a.ca=this.ca&-4097|49152;a.gh=this.gh;a.Wn=this.Wn;a.Wq=this.Wq;a.Tr=this.Tr;a.Gr=this.Gr;a.Jr=this.Jr;a.Vr=this.Vr;a.Ur=this.Ur;a.Cg=null;a.Ir=this.Ir;a.Hr.assign(this.Hr);a.Kr=this.Kr;a.ge=this.ge;a.lq=this.lq;a.li.assign(this.li);a.dr=this.dr;a.er=this.er.Z();a.nr=this.nr.Z();a.gr=this.gr.Z();a.vq=this.vq;a.Xq=this.Xq;a.pm.assign(this.pm);a.om=this.om;a.nm=this.nm}; -w.prototype.Gh=function(a){B.prototype.Gh.call(this,a);Wj(a);a.mm=null;a.lo=null;a.mo=null;a.Pk=null;a.Aj=null};w.prototype.toString=function(){var a=t.Ug(Object.getPrototypeOf(this))+"#"+t.oc(this);this.data&&(a+="("+ma(this.data)+")");return a};w.LayoutNone=0;var Hi;w.LayoutAdded=Hi=1;var Mi;w.LayoutRemoved=Mi=2;var Kh;w.LayoutShown=Kh=4;var Lh;w.LayoutHidden=Lh=8;w.LayoutNodeSized=16;var dj;w.LayoutGroupLayout=dj=32;w.LayoutNodeReplaced=64;var Yl;w.LayoutStandard=Yl=Hi|Mi|Kh|Lh|16|dj|64; -w.prototype.$m=function(a,b,c,d,e,g,h){var k=this.h;null!==k&&(a===Jd&&"elements"===b?e instanceof B&&Ii(e,function(a){Ji(k,a)}):a===Td&&"elements"===b&&e instanceof B&&Ii(e,function(a){Li(k,a)}),k.Uc(a,b,c,d,e,g,h))};w.prototype.updateTargetBindings=w.prototype.Jb=function(a){B.prototype.Jb.call(this,a);if(null!==this.data)for(a=this.elements;a.next();){var b=a.value;b instanceof B&&Ii(b,function(a){null!==a.data&&a.Jb()})}};t.A(w,{Fv:"adornments"},function(){return null===this.Cg?t.dh:this.Cg.k}); -w.prototype.findAdornment=w.prototype.No=function(a){f&&t.j(a,"string",w,"findAdornment:category");var b=this.Cg;return null===b?null:b.Ba(a)};w.prototype.addAdornment=w.prototype.Xk=function(a,b){if(null!==b){f&&(t.j(a,"string",w,"addAdornment:category"),t.l(b,We,w,"addAdornment:ad"));var c=null,d=this.Cg;null!==d&&(c=d.Ba(a));if(c!==b){if(null!==c){var e=c.h;null!==e&&e.remove(c)}null===d&&(this.Cg=d=new sa("string",We));b.gh!==a&&(b.Oc=a);d.add(a,b);c=this.h;null!==c&&(c.add(b),b.data=this.data)}}}; -w.prototype.removeAdornment=w.prototype.ul=function(a){f&&t.j(a,"string",w,"removeAdornment:category");var b=this.Cg;if(null!==b){var c=b.Ba(a);if(null!==c){var d=c.h;null!==d&&d.remove(c)}b.remove(a);0===b.count&&(this.Cg=null)}};w.prototype.clearAdornments=w.prototype.Ae=function(){var a=this.Cg;if(null!==a){for(var b=t.Cb(),a=a.k;a.next();)b.push(a.key);for(var a=b.length,c=0;c=c.OE)){this.ca^=4096;var d=!1;if(null!==c){d=c.Bb;c.Bb=!0;var e=c.selection;e.Ua();a?e.add(this):e.remove(this);e.freeze()}this.i("isSelected",b,a);$l(this);a=this.vF;null!==a&&a(this);null!==c&&(c.Nf(),c.Bb=d)}}});t.g(w,"isShadowed",w.prototype.Lh); -t.defineProperty(w,{Lh:"isShadowed"},function(){return 0!==(this.ca&8192)},function(a){var b=0!==(this.ca&8192);b!==a&&(f&&t.j(a,"boolean",w,"isShadowed"),this.ca^=8192,this.i("isShadowed",b,a),this.pa())});function zi(a){return 0!==(a.ca&32768)}function am(a,b){a.ca=b?a.ca|32768:a.ca&-32769}function Yj(a,b){a.ca=b?a.ca|65536:a.ca&-65537}function Fh(a){return 0!==(a.ca&131072)}w.prototype.Of=function(a){this.ca=a?this.ca|131072:this.ca&-131073};t.g(w,"selectionObjectName",w.prototype.vt); -t.defineProperty(w,{vt:"selectionObjectName"},function(){return this.Vr},function(a){var b=this.Vr;b!==a&&(f&&t.j(a,"string",w,"selectionObjectName"),this.Vr=a,this.mm=null,this.i("selectionObjectName",b,a))});t.g(w,"selectionAdornmentTemplate",w.prototype.uF);t.defineProperty(w,{uF:"selectionAdornmentTemplate"},function(){return this.Tr},function(a){var b=this.Tr;b!==a&&(f&&t.l(a,We,w,"selectionAdornmentTemplate"),this instanceof A&&(a.type=wg),this.Tr=a,this.i("selectionAdornmentTemplate",b,a))}); -t.A(w,{bn:"selectionObject"},function(){if(null===this.mm){var a=this.vt;null!==a&&""!==a?(a=this.le(a),this.mm=null!==a?a:this):this instanceof A?(a=this.path,this.mm=null!==a?a:this):this.mm=this}return this.mm});t.g(w,"selectionChanged",w.prototype.vF);t.defineProperty(w,{vF:"selectionChanged"},function(){return this.Ur},function(a){var b=this.Ur;b!==a&&(null!==a&&t.j(a,"function",w,"selectionChanged"),this.Ur=a,this.i("selectionChanged",b,a))});t.g(w,"resizeAdornmentTemplate",w.prototype.hF); -t.defineProperty(w,{hF:"resizeAdornmentTemplate"},function(){return this.Gr},function(a){var b=this.Gr;b!==a&&(f&&t.l(a,We,w,"resizeAdornmentTemplate"),this.Gr=a,this.i("resizeAdornmentTemplate",b,a))});t.g(w,"resizeObjectName",w.prototype.kF);t.defineProperty(w,{kF:"resizeObjectName"},function(){return this.Ir},function(a){var b=this.Ir;b!==a&&(f&&t.j(a,"string",w,"resizeObjectName"),this.Ir=a,this.lo=null,this.i("resizeObjectName",b,a))}); -t.A(w,{jF:"resizeObject"},function(){if(null===this.lo){var a=this.kF;null!==a&&""!==a?(a=this.le(a),this.lo=null!==a?a:this):this.lo=this}return this.lo});t.g(w,"resizeCellSize",w.prototype.iF);t.defineProperty(w,{iF:"resizeCellSize"},function(){return this.Hr},function(a){var b=this.Hr;b.N(a)||(f&&t.l(a,pa,w,"resizeCellSize"),this.Hr=a=a.Z(),this.i("resizeCellSize",b,a))});t.g(w,"rotateAdornmentTemplate",w.prototype.mF); -t.defineProperty(w,{mF:"rotateAdornmentTemplate"},function(){return this.Jr},function(a){var b=this.Jr;b!==a&&(f&&t.l(a,We,w,"rotateAdornmentTemplate"),this.Jr=a,this.i("rotateAdornmentTemplate",b,a))});t.g(w,"rotateObjectName",w.prototype.oF);t.defineProperty(w,{oF:"rotateObjectName"},function(){return this.Kr},function(a){var b=this.Kr;b!==a&&(f&&t.j(a,"string",w,"rotateObjectName"),this.Kr=a,this.mo=null,this.i("rotateObjectName",b,a))}); -t.A(w,{nF:"rotateObject"},function(){if(null===this.mo){var a=this.oF;null!==a&&""!==a?(a=this.le(a),this.mo=null!==a?a:this):this.mo=this}return this.mo});t.g(w,"text",w.prototype.text);t.defineProperty(w,{text:"text"},function(){return this.ge},function(a){var b=this.ge;b!==a&&(f&&t.j(a,"string",w,"text"),this.ge=a,this.i("text",b,a))});t.g(w,"containingGroup",w.prototype.fb); -t.defineProperty(w,{fb:"containingGroup"},function(){return this.Ck},function(a){if(this.Ud()){var b=this.Ck;if(b!==a){f&&null!==a&&t.l(a,z,w,"containingGroup");null===a||this!==a&&!a.Us(this)||(this===a&&t.m("Cannot make a Group a member of itself: "+this.toString()),t.m("Cannot make a Group indirectly contain itself: "+this.toString()+" already contains "+a.toString()));this.K(Mi);var c=this.h;null!==b?gm(b,this):this instanceof z&&null!==c&&c.Vk.remove(this);this.Ck=a;null!==a?hm(a,this):this instanceof -z&&null!==c&&c.Vk.add(this);this.K(Hi);if(null!==c){var d=this.data,e=c.fa;null!==d&&e instanceof V&&e.$A(d,e.Nb(null!==a?a.data:null))}d=this.Lz;null!==d&&(e=!0,null!==c&&(e=c.Wa,c.Wa=!0),d(this,b,a),null!==c&&(c.Wa=e));if(this instanceof z)for(c=new ua(w),Ve(c,this,!0,0),c=c.k;c.next();)if(d=c.value,d instanceof y)for(d=d.Dd;d.next();)e=d.value,$i(e);if(this instanceof y)for(d=this.Dd;d.next();)e=d.value,$i(e);this.i("containingGroup",b,a);null!==a&&a.Pw()}}else t.m("cannot set the Part.containingGroup of a Link or Adornment")}); -function Wj(a){a=a.fb;null!==a&&(a.aa(),null!==a.wb&&a.wb.aa(),a.Wg())}w.prototype.Ps=function(){var a=this.Ck;null!==a&&hm(a,this)};w.prototype.Qs=function(){var a=this.Ck;null!==a&&gm(a,this)};w.prototype.Jm=function(){var a=this.data;if(null!==a){var b=this.h;null!==b&&(b=b.fa,null!==b&&b.Iw(a))}};t.g(w,"containingGroupChanged",w.prototype.Lz); -t.defineProperty(w,{Lz:"containingGroupChanged"},function(){return this.lq},function(a){var b=this.lq;b!==a&&(null!==a&&t.j(a,"function",w,"containingGroupChanged"),this.lq=a,this.i("containingGroupChanged",b,a))});w.prototype.findTopLevelPart=function(){return im(this,this)};function im(a,b){var c=b.fb;return null!==c?im(a,c):b instanceof y&&(c=b.Sc,null!==c)?im(a,c):b}t.A(w,{ep:"isTopLevel"},function(){return null!==this.fb||this instanceof y&&this.Ih?!1:!0}); -w.prototype.isMemberOf=w.prototype.Us=function(a){return a instanceof z?jm(this,this,a):!1};function jm(a,b,c){if(b===c||null===c)return!1;var d=b.fb;return null===d||d!==c&&!jm(a,d,c)?b instanceof y&&(b=b.Sc,null!==b)?jm(a,b,c):!1:!0}w.prototype.findCommonContainingGroup=w.prototype.UH=function(a){return km(this,this,a)}; -function km(a,b,c){if(null===b||null===c)return null;var d=b.fb;if(null===d)return null;if(b===c)return d;var e=c.fb;return null===e?null:d===e?e:jm(a,c,d)?d:jm(a,b,e)?e:km(a,d,e)}t.g(w,"layoutConditions",w.prototype.GE);t.defineProperty(w,{GE:"layoutConditions"},function(){return this.Xq},function(a){var b=this.Xq;b!==a&&(f&&t.j(a,"number",w,"layoutConditions"),this.Xq=a,this.i("layoutConditions",b,a))}); -w.prototype.canLayout=function(){if(!this.tw||!this.zb())return!1;var a=this.layer;return null!==a&&a.pc||this instanceof y&&this.Ih?!1:!0};w.prototype.invalidateLayout=w.prototype.K=function(a){void 0===a&&(a=16777215);var b;this.tw&&0!==(a&this.GE)?(b=this.layer,null!==b&&b.pc||this instanceof y&&this.Ih?b=!1:(b=this.h,b=null!==b&&b.Aa.qb?!1:!0)):b=!1;if(b)if(b=this.Ck,null!==b){var c=b.Tb;null!==c?c.K():b.K(a)}else a=this.h,null!==a&&(c=a.Tb,null!==c&&c.K())};t.g(w,"dragComputation",w.prototype.Sz); -t.defineProperty(w,{Sz:"dragComputation"},function(){return this.vq},function(a){var b=this.vq;b!==a&&(null!==a&&t.j(a,"function",w,"dragComputation"),this.vq=a,this.i("dragComputation",b,a))});t.g(w,"shadowOffset",w.prototype.zF);t.defineProperty(w,{zF:"shadowOffset"},function(){return this.pm},function(a){var b=this.pm;b.N(a)||(f&&t.l(a,C,w,"shadowOffset"),this.pm=a=a.Z(),this.pa(),this.i("shadowOffset",b,a))});t.g(w,"shadowColor",w.prototype.shadowColor); -t.defineProperty(w,{shadowColor:"shadowColor"},function(){return this.om},function(a){var b=this.om;b!==a&&(f&&t.j(a,"string",w,"shadowColor"),this.om=a,this.pa(),this.i("shadowColor",b,a))});t.g(w,"shadowBlur",w.prototype.shadowBlur);t.defineProperty(w,{shadowBlur:"shadowBlur"},function(){return this.nm},function(a){var b=this.nm;b!==a&&(f&&t.j(a,"number",w,"shadowBlur"),this.nm=a,this.pa(),this.i("shadowBlur",b,a))}); -function We(a){0===arguments.length?w.call(this,bh):w.call(this,a);this.Xd="Adornment";this.La=null;this.ca&=-257;this.li=new C(NaN,NaN);this.Zh=new H(D);this.wb=null;this.yy=!1}t.ia("Adornment",We);t.Oa(We,w);aa=We.prototype;aa.toString=function(){var a=this.Dh;return"Adornment("+this.Oc+")"+(null!==a?a.toString():"")};aa.oj=function(){return this.La&&this.La.S instanceof A?this.La.S.oj():null};aa.Gq=function(){return null}; -aa.zw=function(){var a=this.Nc.S,b=this.Nc;if(a instanceof A&&b instanceof Y){var c=a.path,b=c.Ra;a.zw();for(var b=c.Ra,a=this.za,c=a.length,d=0;da&&(a=1);var b=this.h;if(null!==b&&!b.Sd){b.Sd=!0;var c=b.fd,d=new ua(y);d.add(this);sm(this,d,c,a,this.Gc);b.Sd=!1;b.pa()}}; -function sm(a,b,c,d,e){if(1a&&(a=2);var b=this.h;if(null!==b&&!b.Sd){b.Sd=!0;var c=b.fd,d=new ua(y);d.add(this);um(this,d,c,a,this.Gc);b.Sd=!1}};function um(a,b,c,d,e){a.Gc=!0;for(var g=c?a.fw():a.mg();g.next();){var h=g.value;h.xc&&(e||(h.Sg||h.$b(),h.updateAdornments()),h=h.bA(a),null!==h&&h!==a&&!b.contains(h)&&(b.add(h),e||(h.pa(),h.updateAdornments(),Wj(h),h.K(Kh)),2a&&(a=2),null===c||c.Sd||(c.Sd=!0,b=c.fd,d=new ua(y),d.add(this),um(this,d,b,a,!1),c.Sd=!1)):(a=1,1>a&&(a=1),null===c||c.Sd||(c.Sd=!0,b=c.fd,d=new ua(y),d.add(this),sm(this,d,b,a,!0),c.Sd=!1)))}}); -t.g(y,"wasTreeExpanded",y.prototype.jn);t.defineProperty(y,{jn:"wasTreeExpanded"},function(){return this.os},function(a){var b=this.os;b!==a&&(f&&t.j(a,"boolean",y,"wasTreeExpanded"),this.os=a,this.i("wasTreeExpanded",b,a))});t.g(y,"treeExpandedChanged",y.prototype.VF);t.defineProperty(y,{VF:"treeExpandedChanged"},function(){return this.js},function(a){var b=this.js;b!==a&&(null!==a&&t.j(a,"function",y,"treeExpandedChanged"),this.js=a,this.i("treeExpandedChanged",b,a))});t.g(y,"isTreeLeaf",y.prototype.Mh); -t.defineProperty(y,{Mh:"isTreeLeaf"},function(){return this.Sq},function(a){var b=this.Sq;b!==a&&(f&&t.j(a,"boolean",y,"isTreeLeaf"),this.Sq=a,this.i("isTreeLeaf",b,a))}); -function A(){w.call(this,wg);this.Wf=null;this.nh="";this.fg=this.Eq=null;this.Ah="";this.is=null;this.Fr=this.Er=this.Dr=!1;this.Tq=!0;this.$p=Jg;this.mq=0;this.pq=Jg;this.qq=NaN;this.im=Gk;this.$r=0.5;this.ui=this.ff=null;this.mc=(new H(C)).freeze();this.ue=null;this.Sg=!1;this.Uy=null;this.fz=!1;this.rn=this.gi=this.Ra=null;this.cf=0;this.Bn=this.xn=null;this.Zh=new H(D);this.kz=new C;this.RC=this.PC=null;this.Ix=!1;this.V=null}t.ia("Link",A);t.Oa(A,w); -A.prototype.cloneProtected=function(a){w.prototype.cloneProtected.call(this,a);a.nh=this.nh;a.Eq=this.Eq;a.Ah=this.Ah;a.is=this.is;a.Dr=this.Dr;a.Er=this.Er;a.Fr=this.Fr;a.Tq=this.Tq;a.$p=this.$p;a.mq=this.mq;a.pq=this.pq;a.qq=this.qq;a.im=this.im;a.$r=this.$r};A.prototype.Gh=function(a){w.prototype.Gh.call(this,a);this.nh=a.nh;this.Ah=a.Ah;a.ui=null;a.ue=null;a.$b();a.rn=this.rn;a.cf=this.cf};var Gk;A.Normal=Gk=t.w(A,"Normal",1);A.Orthogonal=t.w(A,"Orthogonal",2); -A.AvoidsNodes=t.w(A,"AvoidsNodes",6);var vm;A.AvoidsNodesStraight=vm=t.w(A,"AvoidsNodesStraight",7);var Jg;A.None=Jg=t.w(A,"None",0);var Rg;A.Bezier=Rg=t.w(A,"Bezier",9);var Ig;A.JumpGap=Ig=t.w(A,"JumpGap",10);var Gg;A.JumpOver=Gg=t.w(A,"JumpOver",11);var Dk;A.End=Dk=t.w(A,"End",17);var Ek;A.Scale=Ek=t.w(A,"Scale",18);var Fk;A.Stretch=Fk=t.w(A,"Stretch",19);var Ml;A.OrientAlong=Ml=t.w(A,"OrientAlong",21);var wm;A.OrientPlus90=wm=t.w(A,"OrientPlus90",22);var xm; -A.OrientMinus90=xm=t.w(A,"OrientMinus90",23);var ym;A.OrientOpposite=ym=t.w(A,"OrientOpposite",24);var zm;A.OrientUpright=zm=t.w(A,"OrientUpright",25);var Am;A.OrientPlus90Upright=Am=t.w(A,"OrientPlus90Upright",26);var Bm;A.OrientMinus90Upright=Bm=t.w(A,"OrientMinus90Upright",27);var Cm;A.OrientUpright45=Cm=t.w(A,"OrientUpright45",28);A.prototype.Ge=function(){this.V={nj:Pb,Pj:Pb,lj:NaN,Nj:NaN,kj:lm,Mj:lm,mj:NaN,Oj:NaN}}; -A.prototype.nl=function(){var a=this.da;if(null!==a&&(yi(a)||zi(a)))return!1;a=this.ja;return null!==a&&(yi(a)||zi(a))?!1:!0};A.prototype.Ud=function(){return!1}; -A.prototype.computeAngle=function(a,b,c){switch(b){default:case Jg:a=0;break;case Ml:a=c;break;case wm:a=c+90;break;case xm:a=c-90;break;case ym:a=c+180;break;case zm:a=J.jt(c);90a&&(a-=180);break;case Am:a=J.jt(c+90);90a&&(a-=180);break;case Bm:a=J.jt(c-90);90a&&(a-=180);break;case Cm:a=J.jt(c);if(45a||225a)return 0;90a&&(a-=180)}return J.jt(a)};t.g(A,"fromNode",A.prototype.da); -t.defineProperty(A,{da:"fromNode"},function(){return this.Wf},function(a){var b=this.Wf;if(b!==a){f&&null!==a&&t.l(a,y,A,"fromNode");var c=this.Qc;null!==b&&(this.fg!==b&&qm(b,this,c),null!==c&&(c.ee=null),Dm(this),b.K(Mi));this.Wf=a;this.gi=null;this.$b();var d=this.h;if(null!==d){var e=this.data,g=d.fa;if(null!==e)if(g instanceof V){var h=null!==a?a.data:null;g.YA(e,g.Nb(h))}else g instanceof Zd&&(h=null!==a?a.data:null,d.fd?g.Qh(e,g.Nb(h)):(null!==b&&g.Qh(b.data,void 0),g.Qh(h,g.Nb(null!==this.fg? -this.fg.data:null))))}e=this.Qc;g=this.aA;null!==g&&(h=!0,null!==d&&(h=d.Wa,d.Wa=!0),g(this,c,e),null!==d&&(d.Wa=h));null!==a&&(this.fg!==a&&pm(a,this,e),null!==e&&(e.ee=null),Em(this),a.K(Hi));this.i("fromNode",b,a);$i(this)}});t.g(A,"fromPortId",A.prototype.nf); -t.defineProperty(A,{nf:"fromPortId"},function(){return this.nh},function(a){var b=this.nh;if(b!==a){f&&t.j(a,"string",A,"fromPortId");var c=this.Qc;null!==c&&(c.ee=null);Dm(this);this.nh=a;var d=this.Qc;null!==d&&(d.ee=null);var e=this.h;if(null!==e){var g=this.data,h=e.fa;null!==g&&h instanceof V&&h.ZA(g,a)}c!==d&&(this.gi=null,this.$b(),g=this.aA,null!==g&&(h=!0,null!==e&&(h=e.Wa,e.Wa=!0),g(this,c,d),null!==e&&(e.Wa=h)));Em(this);this.i("fromPortId",b,a)}}); -t.A(A,{Qc:"fromPort"},function(){var a=this.Wf;return null===a?null:a.Js(this.nh)});t.g(A,"fromPortChanged",A.prototype.aA);t.defineProperty(A,{aA:"fromPortChanged"},function(){return this.Eq},function(a){var b=this.Eq;b!==a&&(null!==a&&t.j(a,"function",A,"fromPortChanged"),this.Eq=a,this.i("fromPortChanged",b,a))});t.g(A,"toNode",A.prototype.ja); -t.defineProperty(A,{ja:"toNode"},function(){return this.fg},function(a){var b=this.fg;if(b!==a){f&&null!==a&&t.l(a,y,A,"toNode");var c=this.Ed;null!==b&&(this.Wf!==b&&qm(b,this,c),null!==c&&(c.ee=null),Dm(this),b.K(Mi));this.fg=a;this.gi=null;this.$b();var d=this.h;if(null!==d){var e=this.data,g=d.fa;if(null!==e)if(g instanceof V){var h=null!==a?a.data:null;g.cB(e,g.Nb(h))}else g instanceof Zd&&(h=null!==a?a.data:null,d.fd?(null!==b&&g.Qh(b.data,void 0),g.Qh(h,g.Nb(null!==this.Wf?this.Wf.data:null))): -g.Qh(e,g.Nb(h)))}e=this.Ed;g=this.lB;null!==g&&(h=!0,null!==d&&(h=d.Wa,d.Wa=!0),g(this,c,e),null!==d&&(d.Wa=h));null!==a&&(this.Wf!==a&&pm(a,this,e),null!==e&&(e.ee=null),Em(this),a.K(Hi));this.i("toNode",b,a);$i(this)}});t.g(A,"toPortId",A.prototype.Qf); -t.defineProperty(A,{Qf:"toPortId"},function(){return this.Ah},function(a){var b=this.Ah;if(b!==a){f&&t.j(a,"string",A,"toPortId");var c=this.Ed;null!==c&&(c.ee=null);Dm(this);this.Ah=a;var d=this.Ed;null!==d&&(d.ee=null);var e=this.h;if(null!==e){var g=this.data,h=e.fa;null!==g&&h instanceof V&&h.dB(g,a)}c!==d&&(this.gi=null,this.$b(),g=this.lB,null!==g&&(h=!0,null!==e&&(h=e.Wa,e.Wa=!0),g(this,c,d),null!==e&&(e.Wa=h)));Em(this);this.i("toPortId",b,a)}}); -t.A(A,{Ed:"toPort"},function(){var a=this.fg;return null===a?null:a.Js(this.Ah)});t.g(A,"toPortChanged",A.prototype.lB);t.defineProperty(A,{lB:"toPortChanged"},function(){return this.is},function(a){var b=this.is;b!==a&&(null!==a&&t.j(a,"function",A,"toPortChanged"),this.is=a,this.i("toPortChanged",b,a))}); -t.defineProperty(A,{lb:"fromSpot"},function(){return null!==this.V?this.V.nj:Pb},function(a){null===this.V&&this.Ge();var b=this.V.nj;b.N(a)||(f&&t.l(a,K,A,"fromSpot"),a=a.Z(),this.V.nj=a,this.i("fromSpot",b,a),this.$b())}); -t.defineProperty(A,{ek:"fromEndSegmentLength"},function(){return null!==this.V?this.V.lj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.lj;b!==a&&(f&&t.j(a,"number",A,"fromEndSegmentLength"),0>a&&t.ha(a,">= 0",A,"fromEndSegmentLength"),this.V.lj=a,this.i("fromEndSegmentLength",b,a),this.$b())}); -t.defineProperty(A,{So:"fromEndSegmentDirection"},function(){return null!==this.V?this.V.kj:lm},function(a){null===this.V&&this.Ge();var b=this.V.kj;b!==a&&(f&&t.tb(a,y,A,"fromEndSegmentDirection"),this.V.kj=a,this.i("fromEndSegmentDirection",b,a),this.$b())});t.defineProperty(A,{To:"fromShortLength"},function(){return null!==this.V?this.V.mj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.mj;b!==a&&(f&&t.j(a,"number",A,"fromShortLength"),this.V.mj=a,this.i("fromShortLength",b,a),this.$b())}); -t.defineProperty(A,{mb:"toSpot"},function(){return null!==this.V?this.V.Pj:Pb},function(a){null===this.V&&this.Ge();var b=this.V.Pj;b.N(a)||(f&&t.l(a,K,A,"toSpot"),a=a.Z(),this.V.Pj=a,this.i("toSpot",b,a),this.$b())}); -t.defineProperty(A,{mk:"toEndSegmentLength"},function(){return null!==this.V?this.V.Nj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.Nj;b!==a&&(f&&t.j(a,"number",A,"toEndSegmentLength"),0>a&&t.ha(a,">= 0",A,"toEndSegmentLength"),this.V.Nj=a,this.i("toEndSegmentLength",b,a),this.$b())}); -t.defineProperty(A,{Lp:"toEndSegmentDirection"},function(){return null!==this.V?this.V.Mj:lm},function(a){null===this.V&&this.Ge();var b=this.V.Mj;b!==a&&(f&&t.tb(a,y,A,"toEndSegmentDirection"),this.V.Mj=a,this.i("toEndSegmentDirection",b,a),this.$b())});t.defineProperty(A,{Mp:"toShortLength"},function(){return null!==this.V?this.V.Oj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.Oj;b!==a&&(f&&t.j(a,"number",A,"toShortLength"),this.V.Oj=a,this.i("toShortLength",b,a),this.$b())}); -function $i(a){var b=a.da,c=a.ja;null!==b&&null!==c?Fm(a,b.UH(c)):Fm(a,null)}function Fm(a,b){var c=a.Ck;if(c!==b){null!==c&&gm(c,a);a.Ck=b;null!==b&&hm(b,a);var d=a.Lz;if(null!==d){var e=!0,g=a.h;null!==g&&(e=g.Wa,g.Wa=!0);d(a,c,b);null!==g&&(g.Wa=e)}!a.Sg||a.PC!==c&&a.RC!==c||a.$b()}}A.prototype.getOtherNode=A.prototype.bA=function(a){f&&t.l(a,y,A,"getOtherNode:node");var b=this.da;return a===b?this.ja:b}; -A.prototype.getOtherPort=function(a){f&&t.l(a,X,A,"getOtherPort:port");var b=this.Qc;return a===b?this.Ed:b};t.A(A,{uJ:"isLabeledLink"},function(){return null===this.ff?!1:0=d&&(l=d-1),k=this.n(l-1),g=this.n(l),J.Eo(e.x,e.y,h.x,h.y,k.x,k.y,g.x,g.y,0.5,a),b=Math.min(g.x,b),c=Math.min(g.y,c),e=g;else for(e=this.n(0),g=this.n(1),b=Math.min(e.x,g.x),c=Math.min(e.y,g.y),a.q(e.x,e.y,0,0),a.$i(g),l=2;lc&&(c=-c)):J.Ka(c.y,d.y)?(c=d.x-c.x,0>c&&(c=-c)):c=Math.sqrt(c.$j(d)),g.push(c),e+=c;for(d=h=c=0;ce/2)break;c+=d;h++}t.Da(g);b=this.n(h);g=this.n(h+1);b.x===g.x?b.y>g.y?a.q(b.x,b.y-(e/2-c)):a.q(b.x,b.y+(e/2-c)):b.y===g.y?b.x>g.x?a.q(b.x-(e/2-c),b.y):a.q(b.x+(e/2-c),b.y):(e=(e/2-c)/d,a.q(b.x+e*(g.x-b.x),b.y+e*(g.y-b.y)));return a};t.A(A,{RE:"midAngle"},function(){this.updateRoute();return this.computeMidAngle()}); -A.prototype.computeMidAngle=function(){var a=this.ma;if(2>a)return NaN;if(this.computeCurve()===Rg&&4<=a&&!this.ac){var b=(a-1)/3|0,c=3*(b/2|0);if(1===b%2){var c=Math.floor(c),a=this.n(c),b=this.n(c+1),d=this.n(c+2),c=this.n(c+3);return J.jH(a.x,a.y,b.x,b.y,d.x,d.y,c.x,c.y)}if(0e?a.Li(b):b.Li(d)};t.g(A,"points",A.prototype.points); -t.defineProperty(A,{points:"points"},function(){return this.mc},function(a){f&&(Array.isArray(a)||a instanceof H||t.m("Link.points value is not an instance of List or Array"));var b=this.mc;if(b!==a){if(Array.isArray(a)){for(var c=0===a.length%2,d=0;dp&&(v-=180));0>v?v+=360:360<=v&&(v-=360);k&&(x+=Math.abs(p));0===v?r=x:90===v?s=x:180===v?r=-x:270===v?s=-x:(r=x*Math.cos(v*Math.PI/180),s=x*Math.sin(v*Math.PI/180));if(g.qd()&&k){var E=c.gb(Wb,t.O()),F=t.ic(E.x+1E3*r,E.y+1E3*s);this.getLinkPointFromPoint(b,c,E,F,!0,q);t.B(E);t.B(F)}}var x=this.getLinkPoint(d,e,h,!1,l,b,c),G=0,L=0,N=0;if(l||h!==Ob||k)E=this.computeEndSegmentLength(d,e,h, -!1),N=this.getLinkDirection(d,e,x,h,!1,l,b,c),k&&(N+=l?0:30,0>p&&(N+=180)),0>N?N+=360:360<=N&&(N-=360),k&&(E+=Math.abs(p)),0===N?G=E:90===N?L=E:180===N?G=-E:270===N?L=-E:(G=E*Math.cos(N*Math.PI/180),L=E*Math.sin(N*Math.PI/180)),h.qd()&&k&&(E=e.gb(Wb,t.O()),F=t.ic(E.x+1E3*G,E.y+1E3*L),this.getLinkPointFromPoint(d,e,E,F,!1,x),t.B(E),t.B(F));e=q;if(l||g!==Ob||k)e=new C(q.x+r,q.y+s);c=x;if(l||h!==Ob||k)c=new C(x.x+G,x.y+L);!n&&!l&&g.qd()&&3k&&(m=-m),r=(0>h?-1:1)*m+q,s=l*(r-q)+v),q=a.x+2*g/3,v=a.y+2*h/3,x=q,G=v,J.I(h,0)?G=0h?-1:1)*m+q,G=l*(x-q)+v),this.Fo(),this.Ch(a),this.Yk(r,s),this.Yk(x,G),this.Ch(n),this.uf(0,this.getLinkPoint(b,c,Ob,!0,!1,d,e)),this.uf(3,this.getLinkPoint(d,e,Ob,!1,!1,b,c))):(a=d,d=this.getLinkPoint(b,c,Ob,!0,!1,a,e),e=this.getLinkPoint(a, -e,Ob,!1,!1,b,c),this.hasCurviness()?(h=e.x-d.x,b=e.y-d.y,c=this.computeCurviness(),a=d.x+h/2,n=d.y+b/2,g=a,k=n,J.I(b,0)?k=0c&&(g=-g),g=(0>b?-1:1)*g+a,k=h*(g-a)+n),this.Ch(d),this.Yk(g,k)):this.Ch(d),this.Ch(e)));return!0};function Lm(a,b){Math.abs(b.x-a.x)>Math.abs(b.y-a.y)?(b.x=b.x>=a.x?a.x+9E9:a.x-9E9,b.y=a.y):(b.y=b.y>=a.y?a.y+9E9:a.y-9E9,b.x=a.x);return b} -A.prototype.getLinkPointFromPoint=function(a,b,c,d,e,g){void 0===g&&(g=new C);if(null===a||null===b)return g.assign(c),g;a.zb()||(e=dm(a),null!==e&&e!==a&&(b=e.port));var h;a=null;if(null===b.ga)e=d.x,d=d.y,h=c.x,c=c.y;else{a=b.ga.he;e=1/(a.m11*a.m22-a.m12*a.m21);h=a.m22*e;var k=-a.m12*e,l=-a.m21*e,m=a.m11*e,n=e*(a.m21*a.dy-a.m22*a.dx),p=e*(a.m12*a.dx-a.m11*a.dy);e=d.x*h+d.y*l+n;d=d.x*k+d.y*m+p;h=c.x*h+c.y*l+n;c=c.x*k+c.y*m+p}b.Wo(e,d,h,c,g);a&&g.transform(a);return g}; -function Mm(a,b){var c=b.ee;null===c&&(c=new Nm,c.port=b,c.Ic=b.S,b.ee=c);return Om(c,a)} -A.prototype.getLinkPoint=function(a,b,c,d,e,g,h,k){void 0===k&&(k=new C);if(c.rd())return b.gb(c,k),k;if(c.dp()&&(c=Mm(this,b),null!==c)){k.assign(c.kp);if(e&&this.st===vm){var l=Mm(this,h);if(c.Gm=m.x&&a.x<=m.x+m.width?k.x=a.x:a.y>=m.y&&a.y<=m.y+m.height&&(k.y=a.y);t.B(c);t.B(l)}}return k}g=b.gb(Wb,t.O());c=null;this.ma>(e?6:2)?(h=d?this.n(1):this.n(this.ma-2),e&&(h=Lm(g,h.copy()))): -(c=t.O(),h=h.gb(Wb,c),e&&(h=Lm(g,h)));this.getLinkPointFromPoint(a,b,g,h,d,k);t.B(g);null!==c&&t.B(c);return k}; -A.prototype.getLinkDirection=function(a,b,c,d,e,g,h,k){a:if(d.rd())c=d.x>d.y?d.x>1-d.y?0:d.x<1-d.y?270:315:d.x1-d.y?90:d.x<1-d.y?180:135:0.5>d.x?225:0.5(g?6:2)?(k=e?this.n(1):this.n(this.ma-2),k=g?Lm(a,k.copy()):c):(d=t.O(),k=k.gb(Wb,d));c=Math.abs(k.x-a.x)>Math.abs(k.y-a.y)?k.x>=a.x?0:180:k.y>= -a.y?90:270;t.B(a);null!==d&&t.B(d)}g=lm;g=e?this.So:this.Lp;g===lm&&(g=e?b.So:b.Lp);switch(g){case mm:b=b.jl();c+=b;360<=c&&(c-=360);break;case lm:case Kj:b=b.jl();if(0===b)break;45<=b&&135>b?c+=90:135<=b&&225>b?c+=180:225<=b&&315>b&&(c+=270);360<=c&&(c-=360)}return c};A.prototype.computeEndSegmentLength=function(a,b,c,d){if(c.dp()&&(a=Mm(this,b),null!==a))return a.cw;a=NaN;a=d?this.ek:this.mk;isNaN(a)&&(a=d?b.ek:b.mk);isNaN(a)&&(a=10);return a}; -A.prototype.computeSpot=function(a){return a?Jm(this,this.Qc):Km(this,this.Ed)};function Jm(a,b){var c=a.lb;c.Fc()&&(void 0===b&&(b=a.Qc),null!==b&&(c=b.lb));return c===Pb?Ob:c}function Km(a,b){var c=a.mb;c.Fc()&&(void 0===b&&(b=a.Ed),null!==b&&(c=b.mb));return c===Pb?Ob:c}A.prototype.computeOtherPoint=function(a,b){var c=b.gb(Wb),d;d=b.ee;d=null!==d?Om(d,this):null;null!==d&&(c=d.kp);return c};A.prototype.computeShortLength=function(a){return a?Pm(this):Qm(this)}; -function Pm(a){var b=a.To;isNaN(b)&&(a=a.Qc,null!==a&&(b=a.To));return isNaN(b)?0:b}function Qm(a){var b=a.Mp;isNaN(b)&&(a=a.Ed,null!==a&&(b=a.Mp));return isNaN(b)?0:b} -A.prototype.ck=function(a,b,c,d,e,g){if(!1===this.Ze)return!1;void 0===b&&(b=null);void 0===c&&(c=null);var h=g;void 0===g&&(h=t.bh(),h.reset());h.multiply(this.transform);if(this.Fm(a,h))return Dl(this,b,c,e),void 0===g&&t.Se(h),!0;if(this.If(a,h)){var k=!1;if(!this.Jg)for(var l=this.za.length;l--;){var m=this.za.p[l];if(m.visible||m===this.Ub){var n=m.wa,p=this.Ga;if(!(n.x>p.width||n.y>p.height||0>n.x+n.width||0>n.y+n.height)){n=t.bh();n.set(h);if(m instanceof B)k=m.ck(a,b,c,d,e,n);else if(this.path=== -m){var k=m,q=a,r=d,p=n;if(!1===k.Ze)k=!1;else if(p.multiply(k.transform),r)b:{var s=q,v=p;if(k.Fm(s,v))k=!0;else{if(void 0===v&&(v=k.transform,s.Wj(k.wa))){k=!0;break b}var p=s.left,q=s.right,r=s.top,s=s.bottom,x=t.O(),E=t.O(),F=t.O(),G=t.bh();G.set(v);G.yA(k.transform);G.jA();E.x=q;E.y=r;E.transform(G);x.x=p;x.y=r;x.transform(G);v=!1;Kl(k,x,E,F)?v=!0:(x.x=q,x.y=s,x.transform(G),Kl(k,x,E,F)?v=!0:(E.x=p,E.y=s,E.transform(G),Kl(k,x,E,F)?v=!0:(x.x=p,x.y=r,x.transform(G),Kl(k,x,E,F)&&(v=!0))));t.Se(G); -t.B(x);t.B(E);t.B(F);k=v}}else k=k.Fm(q,p)}else k=Pj(m,a,d,n);k&&(null!==b&&(m=b(m)),m&&(null===c||c(m))&&e.add(m));t.Se(n)}}}void 0===g&&t.Se(h);return k||null!==this.background||null!==this.Tj}void 0===g&&t.Se(h);return!1};t.A(A,{ac:"isOrthogonal"},function(){return 2===(this.im.value&2)});t.A(A,{Si:"isAvoiding"},function(){return 4===(this.im.value&4)});A.prototype.computeCurve=function(){if(null===this.gi){var a=this.ac;this.gi=this.Qc===this.Ed&&!a}return this.gi?Rg:this.Ee}; -A.prototype.computeCorner=function(){if(this.Ee===Rg)return 0;var a=this.Wv;if(isNaN(a)||0>a)a=10;return a};A.prototype.computeCurviness=function(){var a=this.Ds;if(isNaN(a)){var b=this.cf;if(0!==b){var a=10,c=this.h;null!==c&&(a=c.lp);c=Math.abs(b);a=a/2+((c-1)/2|0)*a;0===c%2&&(a=-a);0>b&&(a=-a)}else a=10}return a};A.prototype.hasCurviness=function(){return!isNaN(this.Ds)||0!==this.cf&&!this.ac}; -A.prototype.adjustPoints=function(a,b,c,d){var e=this.xo;if(this.ac){if(e===Ek)return!1;e===Fk&&(e=Dk)}switch(e){case Ek:var g=this.n(a),h=this.n(c);if(!g.N(b)||!h.N(d)){var e=g.x,g=g.y,k=h.x-e,l=h.y-g,m=Math.sqrt(k*k+l*l);if(!J.I(m,0)){var n;J.I(k,0)?n=0>l?-Math.PI/2:Math.PI/2:(n=Math.atan(l/Math.abs(k)),0>k&&(n=Math.PI-n));var h=b.x,p=b.y,k=d.x-h,q=d.y-p,l=Math.sqrt(k*k+q*q);J.I(k,0)?q=0>q?-Math.PI/2:Math.PI/2:(q=Math.atan(q/Math.abs(k)),0>k&&(q=Math.PI-q));m=l/m;n=q-n;this.uf(a,b);for(a+=1;al?-Math.PI/2:Math.PI/2:(l=Math.atan(l/Math.abs(k)),0>k&&(l=Math.PI-l)),k=l+n,b*=m,this.Y(a,h+b*Math.cos(k),p+b*Math.sin(k)));this.uf(c,d)}}return!0;case Fk:g=this.n(a);p=this.n(c);if(!g.N(b)||!p.N(d)){e=g.x;g=g.y;h=p.x;p=p.y;m=(h-e)*(h-e)+(p-g)*(p-g);k=b.x;n=b.y;var l=d.x,q=d.y,r=0,s=1,r=0!==l-k?(q-n)/(l-k):9E9;0!==r&&(s=Math.sqrt(1+1/(r*r)));this.uf(a,b);for(a+=1;ab?0:45<=b&&135>b?90:135<=b&&225>b?180:270;d=-45<=d&&45>d?0:45<=d&&135>d?90:135<=d&&225>d?180:270;var h=e.wa.copy(),k=g.wa.copy();if(h.Q()&&k.Q()){h.Vg(8,8);k.Vg(8,8);h.$i(a);k.$i(c);var l,m;if(0===b)if(c.x>a.x||270===d&&c.ya.x||90===d&&c.y>a.y&&k.right>a.x)l=new C(c.x,a.y),m=new C(c.x,(a.y+c.y)/2),180===d?(l.x=this.computeMidOrthoPosition(a.x,c.x,!1),m.x=l.x,m.y=c.y):270===d&&c.ya.y?(l.x=a.xk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.right,m.x=l.x,m.y=c.y):0===d&&a.xk.top&&a.yh.bottom)180===d&&(k.Ia(a)||h.Ia(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(180===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=h.left&&c.x<=a.x||a.x<=k.right&&a.x>=c.x){if(90===d||270===d)l=new C(Math.max((a.x+c.x)/2,a.x),a.y),m=new C(l.x,c.y)}else l.y=270===d||(0===d||180===d)&&c.ya.y&&k.lefta.y?(l.x=a.x>k.right?this.computeMidOrthoPosition(a.x,k.right,!1):a.x>k.left&&(270===d&&a.yk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.left,m.x=l.x,m.y=c.y):180===d&&a.x>k.right&&a.y>k.top&&a.yh.bottom)0===d&&(k.Ia(a)||h.Ia(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(0===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=a.x||a.x>=k.left&&a.x<=c.x){if(90===d||270===d)l=new C(Math.min((a.x+c.x)/2,a.x),a.y),m=new C(l.x,c.y)}else l.y=270=== -d||(0===d||180===d)&&c.ya.y||180===d&&c.xa.y||0===d&&c.x>a.x&&k.bottom>a.y)l=new C(a.x,c.y),m=new C((a.x+c.x)/2,c.y),270===d?(l.y=this.computeMidOrthoPosition(a.y,c.y,!0),m.x=c.x,m.y=l.y):180===d&&c.xa.x?(l.y=a.yk.right)? -this.computeMidOrthoPosition(a.y,c.y,!0):k.bottom,m.x=c.x,m.y=l.y):90===d&&a.yk.left&&a.xh.right)270===d&&(k.Ia(a)||h.Ia(c))?l.x=this.computeMidOrthoPosition(a.x,c.x,!1):c.xa.x&&(270===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right, -Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=h.top&&c.y<=a.y||a.y<=k.bottom&&a.y>=c.y){if(0===d||180===d)l=new C(a.x,Math.max((a.y+c.y)/2,a.y)),m=new C(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xa.x&&k.top=a.x?(l.y=a.y>k.bottom?this.computeMidOrthoPosition(a.y,k.bottom,!0):a.y>k.top&&(180===d&&a.xk.right)?this.computeMidOrthoPosition(a.y,c.y,!0):k.top,m.x=c.x,m.y=l.y):270===d&&a.y>k.bottom&&a.x>k.left&&a.xh.right)90===d&&(k.Ia(a)||h.Ia(c))?l.x=this.computeMidOrthoPosition(a.x, -c.x,!1):c.xa.x&&(90===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right,Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=a.y||a.y>=k.top&&a.y<=c.y){if(0===d||180===d)l=new C(a.x,Math.min((a.y+c.y)/2,a.y)),m=new C(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xthis.ma)0===b||180===b?(d.x=a.x,d.y=c.y):(d.x=c.x,d.y=a.y),this.Y(2,d.x,d.y),this.C(3,d.x,d.y);else if(c=this.n(3),0===b||180===b)J.I(d.x,c.x)?(b=0===b?Math.max(d.x,a.x):Math.min(d.x,a.x),this.Y(2,b,a.y),this.Y(3,b,c.y)):J.I(d.y,c.y)? -(Math.abs(a.y-d.y)<=e.Bm/2&&(this.Y(2,d.x,a.y),this.Y(3,c.x,a.y)),this.C(2,d.x,a.y)):this.Y(2,a.x,d.y);else if(90===b||270===b)J.I(d.y,c.y)?(b=90===b?Math.max(d.y,a.y):Math.min(d.y,a.y),this.Y(2,a.x,b),this.Y(3,c.x,b)):J.I(d.x,c.x)?(Math.abs(a.x-d.x)<=e.Cm/2&&(this.Y(2,a.x,d.y),this.Y(3,a.x,c.y)),this.C(2,a.x,d.y)):this.Y(2,d.x,a.y);a=!0}else a=!1}else a=!1;a||(this.Ch(l),this.Ch(m))}}; -A.prototype.computeMidOrthoPosition=function(a,b){if(this.hasCurviness()){var c=this.computeCurviness();return(a+b)/2+c}return(a+b)/2};function Ef(a){if(!a.Si)return!1;var b=a.points.p,c=b.length;if(4>c)return!1;a=ia(a.h,!0,a);for(var d=1;dVm&&Tm(b,m,n)===l-Wm;)c=m,d=n,0===e?m+=h:90===e?n+=k:180===e?m-=h:n-=k,l-=Wm;if(g){if(l>Vm)if(180===e||0===e)c=Math.floor(c/h)*h+h/2;else if(90===e||270===e)d=Math.floor(d/k)*k+k/2}else c=Math.floor(c/h)*h+h/2,d=Math.floor(d/k)*k+k/2;l>Vm&&(g=e,m=c,n=d,0===e?(g=90,n+=k):90===e?(g=180,m-=h):180===e?(g=270,n-=k):270===e&&(g=0,m+=h),Tm(b,m,n)===l-Wm?Um(a,b,m,n,g,!1):(m=c,n=d,0===e?(g=270,n-= -k):90===e?(g=0,m+=h):180===e?(g=90,n+=k):270===e&&(g=180,m-=h),Tm(b,m,n)===l-Wm&&Um(a,b,m,n,g,!1)));a.Yk(c,d)}A.prototype.findClosestSegment=function(a){f&&t.l(a,C,A,"findClosestSegment:p");var b=a.x;a=a.y;for(var c=this.n(0),d=this.n(1),e=cb(b,a,c.x,c.y,d.x,d.y),g=0,h=1;ha){var b=new M(Oc),c=new Pc(0,0);b.ub.add(c);return b}var d=this.n(0).copy(),e=d.copy(),g=this.computeCurve();if(g===Rg&&3<=a&&!J.Ka(this.en,0))if(3===a)var h=this.n(1),b=Math.min(d.x,h.x),c=Math.min(d.y,h.y),h=this.n(2),b=Math.min(b,h.x),c=Math.min(c,h.y);else{if(this.ac)for(h=0;h=a&&(h=a-1),k=this.n(h),e.x=Math.min(k.x,e.x),e.y=Math.min(k.y,e.y); -b=e.x;c=e.y}else{for(h=0;hE?r>q?(v.x=F-L,v.y=q-L,x.x=F+s,x.y=q+s):(v.x=F-L,v.y=q+L,x.x=F+s,x.y=q-s):r>q?(v.x=F+L,v.y=q-L,x.x= -F-s,x.y=q+s):(v.x=F+L,v.y=q+L,x.x=F-s,x.y=q-s));J.Ka(E,F)&&J.Ka(q,r)&&(q>p?(G>F?(v.x=F-L,v.y=q-L,x.x=F+s):(v.x=F+L,v.y=q-L,x.x=F-s),x.y=q+s):(G>F?(v.x=F-L,v.y=q+L,x.x=F+s):(v.x=F+L,v.y=q+L,x.x=F-s),x.y=q-s));if(J.Ka(E,F)&&J.Ka(F,G)||J.Ka(p,q)&&J.Ka(q,r))E=0.5*(E+G),p=0.5*(p+r),v.x=E,v.y=p,x.x=E,x.y=p;1===h?(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y)):2===h&&J.Ka(e.x,this.n(0).x)&&J.Ka(e.y,this.n(0).y)&&(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y));P(l,g.x-b,g.y-c,k.x-b,k.y-c,m.x-b,m.y-c);d.set(k);g.set(a);e=m}}h= -e.x;e=e.y;d=this.n(this.ma-1);h=0.5*(h+d.x);e=0.5*(e+d.y);P(l,a.x-b,a.y-c,h-b,e-c,d.x-b,d.y-c)}else for(h=3;h=a&&(h=a-1),d=this.n(h-1),k=this.n(h),h===a-1&&0!==Qm(this)&&(k=k.copy(),Xm(this,k,!1,J.ok)),P(l,e.x-b,e.y-c,d.x-b,d.y-c,k.x-b,k.y-c);else{e=t.O();e.assign(this.n(0));for(h=1;h=a-1){e!==n&&(0!==Qm(this)&&(n=n.copy(),Xm(this,n,!1,J.ok)),$m(this,l,-b,-c,e,n));break}h=Ym(this,n,h+1,hm.x?n.x-E:n.x+E,G=v.y>n.y?n.y+p:n.y-p,$m(this,d,g,k,m,new C(s,F)),cd(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):J.I(m.x,n.x)&&J.I(n.y,v.y)?(E=this.computeCorner(),p=Math.min(E,Math.abs(n.y-m.y)/2),p=E=Math.min(p,Math.abs(v.x-n.x)/2),J.I(E,0)?($m(this,d,g,k,m,n),x.assign(n)):(s=n.x,G=F=n.y,F=n.y>m.y?n.y-p:n.y+p,q=v.x>n.x?n.x+E: -n.x-E,$m(this,d,g,k,m,new C(s,F)),cd(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):($m(this,d,g,k,m,n),x.assign(n))}t.B(e)}b=l.s;t.v(l)}return b};function Zm(a,b,c,d){a=c-a;if(isNaN(a)||Infinity===a||-Infinity===a)return NaN;0>a&&(a=-a);b=d-b;if(isNaN(b)||Infinity===b||-Infinity===b)return NaN;0>b&&(b=-b);return J.Ka(a,0)?b:J.Ka(b,0)?a:Math.sqrt(a*a+b*b)} -function Xm(a,b,c,d){var e=a.ma;if(!(2>e))if(c){var g=a.n(1);c=g.x-d.x;d=g.y-d.y;g=Zm(b.x,b.y,c,d);0!==g&&(e=2===e?0.5*g:g,a=Pm(a),a>e&&(a=e),c=a*(c-b.x)/g,a=a*(d-b.y)/g,b.x+=c,b.y+=a)}else g=a.n(e-2),c=g.x-d.x,d=g.y-d.y,g=Zm(b.x,b.y,c,d),0!==g&&(e=2===e?0.5*g:g,a=Qm(a),a>e&&(a=e),c=a*(b.x-c)/g,a=a*(b.y-d)/g,b.x-=c,b.y-=a)} -function Ym(a,b,c,d){for(var e=a.ma,g=b;J.Ka(b.x,g.x)&&J.Ka(b.y,g.y);){if(c>=e)return e-1;g=a.n(c++)}if(!J.Ka(b.x,g.x)&&!J.Ka(b.y,g.y))return c-1;for(var h=g;J.Ka(b.x,g.x)&&J.Ka(g.x,h.x)&&(!d||(b.y>=g.y?g.y>=h.y:g.y<=h.y))||J.Ka(b.y,g.y)&&J.Ka(g.y,h.y)&&(!d||(b.x>=g.x?g.x>=h.x:g.x<=h.x));){if(c>=e)return e-1;h=a.n(c++)}return c-2} -function $m(a,b,c,d,e,g){if(Gm(a)){var h=new H("number"),k=an(a,e,g,h),l=e.x,l=e.y;if(0p-10)m--,p=Math.max(q-5,g.x);else break;q=g.y-10+d;n=p+c;p=g.y+d;a.Ee===Ig?O(b,n,p,!1,!1):P(b,l,q,n,q,n,p)}else if(J.I(e.x,g.x))if(e.yp-10)m--,p=Math.max(q-5,g.y);else break;q=g.x-10+c;n=g.x+c;p+=d;a.Ee===Ig?O(b,n,p,!1,!1):P(b,q,l,q,p,n,p)}}b.lineTo(g.x+c,g.y+d)} -function an(a,b,c,d){var e=a.h;if(null===e)return 0;Math.min(b.x,c.x);Math.min(b.y,c.y);Math.max(b.x,c.x);Math.max(b.y,c.y);for(e=e.Um;e.next();){var g=e.value;if(null!==g&&g.visible)for(var g=g.cb.p,h=g.length,k=0;k=h.x&&Math.min(h.y,k.y)<=m.y&&Math.max(h.y,k.y)>=m.y&&!J.I(h.y,k.y)){p.x=h.x;p.y=m.y;m=!0;break a}}else if(J.I(h.y,k.y)&&Math.min(m.y,n.y)<=h.y&&Math.max(m.y,n.y)>=h.y&&Math.min(h.x,k.x)<=m.x&&Math.max(h.x,k.x)>=m.x&&!J.I(h.x,k.x)){p.x=m.x;p.y=h.y;m=!0;break a}p.x=0;p.y=0;m=!1}m&&(J.I(a.y,b.y)?c.add(l.x):c.add(l.y));t.B(l)}} -t.A(A,{Ls:"firstPickIndex"},function(){return 2>=this.ma?0:this.ac||Jm(this)!==Ob?1:0});t.A(A,{ww:"lastPickIndex"},function(){var a=this.ma;return 0===a?0:2>=a?a-1:this.ac||Km(this)!==Ob?a-2:a-1});function Gm(a){a=a.Ee;return a===Gg||a===Ig}function Im(a,b){if(b||Gm(a)){var c=a.h;null===c||c.En.contains(a)||null===a.Uy||c.En.add(a,a.Uy)}} -function Kg(a,b){var c=a.layer;if(null!==c&&c.visible&&!c.pc){var d=c.h;if(null!==d)for(var e=!1,d=d.Um;d.next();){var g=d.value;if(g.visible)if(g===c)for(var e=!0,h=!1,g=g.cb.p,k=g.length,l=0;lb.links.count)1===b.links.count&&(c=b.links.p[0],c.rn=null,c.cf=0,c.$b()),c=b.tp,null!==b&&null!==c.fh&&c.fh.remove(b),c=b.gt,null!==b&&null!==c.fh&&c.fh.remove(b);else for(c=Math.abs(c),a=0===c%2,b=b.links.k;b.next();){var d=b.value,e=Math.abs(d.cf),g=0===e%2;e>c&&a===g&&(d.cf=0=a.width||0>=a.height)){var b=a.y,c=a.x+a.width,d=a.y+a.height;this.Bf=Math.floor((a.x-this.vd)/this.vd)*this.vd;this.Cf=Math.floor((b-this.kd)/this.kd)*this.kd;this.hr=Math.ceil((c+2*this.vd)/this.vd)*this.vd;this.ir=Math.ceil((d+2*this.kd)/this.kd)*this.kd;a=1+(Math.ceil((this.hr-this.Bf)/this.vd)|0);b=1+(Math.ceil((this.ir-this.Cf)/this.kd)|0);if(null===this.bc||this.sm=Vm&&(a.bc[b][c]|=la)} -function Rm(a,b,c,d,e){if(b>a.hr||b+da.ir||c+eb&&(d+=b,b=0);0>c&&(g+=c,c=0);if(0>d||0>g)return!0;e=Math.min(b+d-1,a.sm)|0;for(d=Math.min(c+g-1,a.tm)|0;b<=e;b++)for(g=c;g<=d;g++)if(a.bc[b][g]===ja)return!1;return!0} -function fn(a,b,c,d,e,g,h,k,l){if(!(bh||cl)){var m,n;m=b|0;n=c|0;var p=a.bc[m][n];if(p>=Vm&&p=a.bc[m][n]);)a.bc[m][n]=p,p+=Wm,e?n+=d:m+=d;m=e?n:m;if(e)if(0m;c+=d)fn(a,b,c,1,!e,g,h,k,l),fn(a,b,c,-1,!e,g,h,k,l);else if(0m;b+=d)fn(a,b,c,1,!e,g,h,k,l),fn(a,b,c,-1,!e,g,h, -k,l)}}function gn(a,b,c,d,e,g,h,k,l,m,n){for(var p=b|0,q=c|0,r=a.bc[p][q];0===r&&p>k&&pm&&q=Math.abs(p-d)&&1>=Math.abs(q-e))return a.abort=!0,0;p=b|0;q=c|0;r=a.bc[p][q];b=Vm;for(a.bc[p][q]=b;0===r&&p>k&&pm&&q=Math.abs(h-l)&&1>=Math.abs(k-m))a.abort=!0;else{var n=g.x;b=g.y;d=g.x+g.width;var p=g.y+g.height,n=n-a.Bf,n=n/a.vd;b-=a.Cf;b/=a.kd;d-=a.Bf;d/=a.vd;p-=a.Cf;p/=a.kd;g=Math.max(0,Math.min(a.sm,n|0));d=Math.min(a.sm,Math.max(0,d|0));b=Math.max(0,Math.min(a.tm,b|0));var p=Math.min(a.tm,Math.max(0,p|0)),h=h|0,k=k|0,l=l|0, -m=m|0,n=h,q=k,r=0===c||90===c?1:-1;(c=90===c||270===c)?q=gn(a,h,k,l,m,r,c,g,d,b,p):n=gn(a,h,k,l,m,r,c,g,d,b,p);if(!a.abort){a:{c=0===e||90===e?1:-1;e=90===e||270===e;for(var r=l|0,s=m|0,v=a.bc[r][s];0===v&&r>g&&rb&&s=Math.abs(r-h)&&1>=Math.abs(s-k)){a.abort=!0;break a}r=l|0;s=m|0;v=a.bc[r][s];for(a.bc[r][s]=dn;0===v&&r>g&&rb&&s=c?180:0}a=180*Math.atan2(a.height,a.width)/Math.PI;switch(b){case t.hd|t.Fd:return c>a&&c<=180+a?180:270;case t.Fd|t.ud:return c>180-a&&c<=360-a?270:0;case t.ud|t.td:return c>a&&c<=180+a?90:0;case t.td|t.hd:return c>180-a&&c<=360-a?180:90;case t.hd|t.Fd|t.ud:return 90180+a&&c<=360- -a?270:0;case t.Fd|t.ud|t.td:return 180a&&180>=c?90:0;case t.ud|t.td|t.hd:return c>a&&c<=180-a?90:c>180-a&&270>=c?180:0;case t.td|t.hd|t.Fd:return c>180-a&&c<=180+a?180:c>180+a?270:90}d&&b!==(t.hd|t.Fd|t.ud|t.td)&&(c-=15,0>c&&(c+=360));return c>a&&c<180-a?90:c>=180-a&&c<=180+a?180:c>180+a&&c<360-a?270:0} -function Om(a,b){var c=a.rg;if(0===c.length){if(!a.ft){c=a.ft;a.ft=!0;var d=a.Ic.Dd,e=a.rg.length=0,g=a.port.gb(Tb,t.O()),h=a.port.gb($b,t.O()),k=t.lk(g.x,g.y,0,0);k.$i(h);t.B(g);t.B(h);g=t.ic(k.x+k.width/2,k.y+k.height/2);for(d=d.k;d.next();)if(h=d.value,h.zb()){var l=Ob,l=h.Qc===a.port?Jm(h,a.port):Km(h,a.port);if(l.dp()){var m;m=h.Qc===a.port?h.Ed:h.Qc;if(null!==m){var n=m.S;if(null!==n){m=h.computeOtherPoint(n,m);var n=g.Li(m),l=hn(k,l,n,h.ac),p;0===l?(p=t.ud,180b.Ie?1:a.angleb.angle?1:0}; -Nm.prototype.computeEndSegmentLength=function(a){var b=a.link,c=b.computeEndSegmentLength(this.Ic,this.port,Ob,b.Qc===this.port),d=a.Zo;if(0>d)return c;var e=a.Gm;if(1>=e||!b.ac)return c;var b=a.Cw,g=a.kp;if(a.Ie===t.hd||a.Ie===t.td)d=e-1-d;return((a=a.Ie===t.hd||a.Ie===t.ud)?b.ye&&(e=k.right);k.bottom>g&&(g=k.bottom)}}isFinite(c)&&isFinite(d)?a.q(c,d,e-c,g-d):(b=b.location,c=this.padding,a.q(b.x+c.left,b.y+c.top,0,0));return a}; -t.g(Wg,"padding",Wg.prototype.padding);t.defineProperty(Wg,{padding:"padding"},function(){return this.Le},function(a){"number"===typeof a?(0>a&&t.ha(a,">= 0",Wg,"padding"),a=new pb(a)):(t.l(a,pb,Wg,"padding"),0>a.left&&t.ha(a.left,">= 0",Wg,"padding:val.left"),0>a.right&&t.ha(a.right,">= 0",Wg,"padding:val.right"),0>a.top&&t.ha(a.top,">= 0",Wg,"padding:val.top"),0>a.bottom&&t.ha(a.bottom,">= 0",Wg,"padding:val.bottom"));var b=this.Le;b.N(a)||(this.Le=a=a.Z(),this.i("padding",b,a))}); -function xe(){0=c-1?(h=0,e=d,g+=k+20,k=0):h++}null!==a&&a.De("Layout")}this.of=!0};xe.prototype.zA=function(a){return!a.location.Q()||a instanceof z&&a.zC?!0:!1};function nn(a,b,c,d,e,g,h,k){for(c=c.k;c.next();){var l=c.value;d&&!l.ep||e&&!e(l)||l.canLayout()&&(g&&l instanceof y?l.Ih||(l instanceof z&&null===l.Tb?nn(a,b,l.Hc,!1,e,g,h,k):b.add(l)):h&&l instanceof A?b.add(l):!k||!l.Ud()||l instanceof y||b.add(l))}} -t.g(xe,"arrangementOrigin",xe.prototype.zd);t.defineProperty(xe,{zd:"arrangementOrigin"},function(){return this.bq},function(a){this.bq.N(a)||(t.l(a,C,xe,"arrangementOrigin"),this.bq.assign(a),this.K())});xe.prototype.initialOrigin=xe.prototype.iA=function(a){var b=this.group;if(null!==b){var c=b.location;if(isNaN(c.x)||isNaN(c.y))return a;a=b.placeholder;null!==a?(c=a.gb(Tb),c.x+=a.padding.left,c.y+=a.padding.top):c=b.position.copy();return c}return a}; -function Ca(){t.zc(this);this.Ld=null;this.clear()}t.ia("LayoutNetwork",Ca);Ca.prototype.clear=function(){if(this.vertexes)for(var a=this.vertexes.k;a.next();){var b=a.value;b.clear();b.network=null}if(this.edges)for(a=this.edges.k;a.next();)b=a.value,b.clear(),b.network=null;this.vertexes=new ua(Da);this.edges=new ua(Ea);this.CA=new sa(y,Da);this.pA=new sa(A,Ea)};Ca.prototype.toString=function(){return"LayoutNetwork"+(null!==this.Tb?"("+this.Tb.toString()+")":"")};t.A(Ca,{Tb:"layout"},function(){return this.Ld}); -function mn(a,b){f&&null!==b&&t.l(b,xe,Ca,"setLayout");a.Ld=b}Ca.prototype.createVertex=function(){return new Da};Ca.prototype.createEdge=function(){return new Ea}; -Ca.prototype.addParts=Ca.prototype.ss=function(a,b){if(null!==a){void 0===b&&(b=!1);t.j(b,"boolean",Ca,"addParts:toplevelonly");for(var c=a.k;c.next();){var d=c.value;if(d instanceof y&&(!b||d.ep)&&d.canLayout()&&!d.Ih)if(d instanceof z&&null===d.Tb)this.ss(d.Hc,!1);else if(null===this.Nm(d)){var e=this.createVertex();e.Ic=d;this.Zk(e)}}for(c.reset();c.next();)if(d=c.value,d instanceof A&&(!b||d.ep)&&d.canLayout()&&null===this.dw(d)){var g=d.da,e=d.ja;g!==e&&(g=this.ew(g),e=this.ew(e),null!==g&&null!== -e&&this.Vm(g,e,d))}}};Ca.prototype.findGroupVertex=Ca.prototype.ew=function(a){if(null===a)return null;a=dm(a);if(null===a)return null;var b=this.Nm(a);if(null!==b)return b;a=a.fb;return null!==a&&(b=this.Nm(a),null!==b)?b:null};Ca.prototype.addVertex=Ca.prototype.Zk=function(a){if(null!==a){f&&t.l(a,Da,Ca,"addVertex:vertex");this.vertexes.add(a);var b=a.Ic;null!==b&&this.CA.add(b,a);a.network=this}}; -Ca.prototype.addNode=Ca.prototype.wo=function(a){if(null===a)return null;f&&t.l(a,y,Ca,"addNode:node");var b=this.Nm(a);null===b&&(b=this.createVertex(),b.Ic=a,this.Zk(b));return b};Ca.prototype.deleteVertex=Ca.prototype.LD=function(a){if(null!==a&&(f&&t.l(a,Da,Ca,"deleteVertex:vertex"),on(this,a))){for(var b=a.$e,c=b.count-1;0<=c;c--){var d=b.qa(c);this.Ko(d)}b=a.Qe;for(c=b.count-1;0<=c;c--)d=b.qa(c),this.Ko(d)}}; -function on(a,b){if(null===b)return!1;var c=a.vertexes.remove(b);c&&(a.CA.remove(b.Ic),b.network=null);return c}Ca.prototype.deleteNode=function(a){null!==a&&(f&&t.l(a,y,Ca,"deleteNode:node"),a=this.Nm(a),null!==a&&this.LD(a))};Ca.prototype.findVertex=Ca.prototype.Nm=function(a){if(null===a)return null;f&&t.l(a,y,Ca,"findVertex:node");return this.CA.Ba(a)}; -Ca.prototype.addEdge=Ca.prototype.vo=function(a){if(null!==a){f&&t.l(a,Ea,Ca,"addEdge:edge");this.edges.add(a);var b=a.link;null!==b&&null===this.dw(b)&&this.pA.add(b,a);b=a.toVertex;null!==b&&b.dD(a);b=a.fromVertex;null!==b&&b.bD(a);a.network=this}}; -Ca.prototype.addLink=function(a){if(null===a)return null;f&&t.l(a,A,Ca,"addLink:link");var b=a.da,c=a.ja,d=this.dw(a);null===d?(d=this.createEdge(),d.link=a,null!==b&&(d.fromVertex=this.wo(b)),null!==c&&(d.toVertex=this.wo(c)),this.vo(d)):(d.fromVertex=null!==b?this.wo(b):null,d.toVertex=null!==c?this.wo(c):null);return d};Ca.prototype.deleteEdge=Ca.prototype.Ko=function(a){if(null!==a){f&&t.l(a,Ea,Ca,"deleteEdge:edge");var b=a.toVertex;null!==b&&b.KD(a);b=a.fromVertex;null!==b&&b.JD(a);pn(this,a)}}; -function pn(a,b){null!==b&&a.edges.remove(b)&&(a.pA.remove(b.link),b.network=null)}Ca.prototype.deleteLink=function(a){null!==a&&(f&&t.l(a,A,Ca,"deleteLink:link"),a=this.dw(a),null!==a&&this.Ko(a))};Ca.prototype.findEdge=Ca.prototype.dw=function(a){if(null===a)return null;f&&t.l(a,A,Ca,"findEdge:link");return this.pA.Ba(a)}; -Ca.prototype.linkVertexes=Ca.prototype.Vm=function(a,b,c){if(null===a||null===b)return null;f&&(t.l(a,Da,Ca,"linkVertexes:fromVertex"),t.l(b,Da,Ca,"linkVertexes:toVertex"),null!==c&&t.l(c,A,Ca,"linkVertexes:link"));if(a.network===this&&b.network===this){var d=this.createEdge();d.link=c;d.fromVertex=a;d.toVertex=b;this.vo(d);return d}return null}; -Ca.prototype.reverseEdge=Ca.prototype.Jw=function(a){if(null!==a){f&&t.l(a,Ea,Ca,"reverseEdge:edge");var b=a.fromVertex,c=a.toVertex;null!==b&&null!==c&&(b.JD(a),c.KD(a),a.Jw(),b.dD(a),c.bD(a))}};Ca.prototype.deleteSelfEdges=Ca.prototype.$v=function(){for(var a=t.Cb(),b=this.edges.k;b.next();){var c=b.value;c.fromVertex===c.toVertex&&a.push(c)}b=a.length;for(c=0;cd?1:0):1:null!==d?-1:0}; -Da.smartComparer=function(a,b){f&&t.l(a,Da,Da,"smartComparer:m");f&&t.l(b,Da,Da,"smartComparer:n");if(null!==a){if(null!==b){var c=a.nd,d=b.nd;if(null!==c){if(null!==d){var c=c.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=d.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=d&&0>=a&&(d=1);var e=this.spacing.width;isFinite(e)||(e=0);var g=this.spacing.height;isFinite(g)||(g=0);b.rc("Layout");switch(this.alignment){case Pk:var h= -Math.max(this.bl.width,1);if(!isFinite(h))for(var k=h=0;kd-1||0a)v=0,r=q,s+=x,x=0;x=Math.max(x,F);switch(p){case Nk:m=-m.width;break;default:m=0}l.moveTo(r+m,s);switch(p){case Nk:r-=E;break;default:r+=E}v++}break;case Ok:h=Math.max(this.bl.width,1);k=x=v=0;l=t.O();for(n=0;nd-1||0a){for(L=0;Ld?1:0}; -Dj.smartComparer=function(a,b){f&&t.l(a,w,Dj,"standardComparer:a");f&&t.l(b,w,Dj,"standardComparer:b");if(null!==a){if(null!==b){var c=a.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=b.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=a.count)1===a.count&&(a=a.eb(),a.Fa=0,a.Sa=0);else{var b=new H(wn);b.Me(a.k);a=new H(wn);var c=new H(wn),b=this.sort(b);a=new H(wn);var c=new H(wn),d=this.$x,e=this.ZB,g=this.wd,h=this.Gn,k=this.ay,l=this.xq,m=this.Ek,n=this.UC,p=this.jg,q=this.bu,d=this.Oe,e=this.ht,g= -this.bF;if(!isFinite(g)||0>=g)g=NaN;h=this.iD;if(!isFinite(h)||0>=h)h=1;k=this.yg;isFinite(k)||(k=0);l=this.Th;if(!isFinite(l)||360l)l=360;m=this.spacing;isFinite(m)||(m=NaN);d===cl&&e===dl?d=bl:d===cl&&e!==dl&&(e=dl,d=this.Oe);if((this.direction===Wk||this.direction===Xk)&&this.sorting!==Vk){for(var r=0;!(r>=b.length);r+=2){a.add(b.qa(r));if(r+1>=b.length)break;c.add(b.qa(r+1))}this.direction===Wk?(this.Oe===cl&&a.reverse(),b=new H(wn),b.Me(a),b.Me(c)):(this.Oe===cl&&c.reverse(),b=new H(wn), -b.Me(c),b.Me(a))}for(var s=b.length,v=n=0,r=0;rl&&(0===r||r===b.length-1)&&(x/=2);n+=x;v++}if(isNaN(g)||d===cl){isNaN(m)&&(m=6);if(d!==bl&&d!==cl){x=-Infinity;for(r=0;rg?(g=r,p=g*h):q=v/(360<=l?s:s-1)}this.$x=d;this.ZB=e;this.wd=g;this.Gn=h;this.ay=k;this.xq=l;this.Ek=m;this.UC=n;this.jg=p;this.bu=q;c=[b,a,c];b=c[0];a=c[1];c=c[2];d=this.$x;e=this.wd;h=this.ay;k=this.xq;l=this.Ek;m=this.jg;n=this.bu;if(this.direction!==Wk&&this.direction!==Xk||d!==cl)if(this.direction===Wk||this.direction===Xk){g=0;switch(d){case al:g=180*An(this,e,m,h,n)/Math.PI;break;case bl:n=b=0;g=a.eb();null!==g&&(b=xn(g,Math.PI/2));g=c.eb();null!== -g&&(n=xn(g,Math.PI/2));g=180*An(this,e,m,h,l+(b+n)/2)/Math.PI;break;case $k:g=k/b.length}if(this.direction===Wk){switch(d){case al:Bn(this,a,h,Zk);break;case bl:Cn(this,a,h,Zk);break;case $k:Dn(this,a,k/2,h,Zk)}switch(d){case al:Bn(this,c,h+g,Yk);break;case bl:Cn(this,c,h+g,Yk);break;case $k:Dn(this,c,k/2,h+g,Yk)}}else{switch(d){case al:Bn(this,c,h,Zk);break;case bl:Cn(this,c,h,Zk);break;case $k:Dn(this,c,k/2,h,Zk)}switch(d){case al:Bn(this,a,h+g,Yk);break;case bl:Cn(this,a,h+g,Yk);break;case $k:Dn(this, -a,k/2,h+g,Yk)}}}else switch(d){case al:Bn(this,b,h,this.direction);break;case bl:Cn(this,b,h,this.direction);break;case $k:Dn(this,b,k,h,this.direction);break;case cl:En(this,b,k,h,this.direction)}else En(this,b,k,h-k/2,Yk)}this.updateParts();this.network=null;this.of=!0}; -function Dn(a,b,c,d,e){var g=a.xq,h=a.wd;a=a.jg;d=d*Math.PI/180;c=c*Math.PI/180;for(var k=b.length,l=0;lc){for(g=d+(e===Yk?g:-g);0>g;)g+=360;g%=360;180=n.length-1)break;var p=Hn(a,l,m,n,g,e);p[0]||(p=In(a,l,m,n,g,e));l=p[1];m=p[2]}a.fm++;if(!(23Math.abs(r)?Math.abs(l-g)<(n[0].width+n[n.length-1].width)/2&&(h=0):h=0Math.abs(q)?0:q;q=!1;q=Math.abs(g)>Math.abs(p)?0p:0l.Uo||Math.abs(h)h&&0a.fm?a.wd-h/(2*Math.PI):5>n.length&&10=n.length-1)break;var q=Hn(a,l,m,n,p,e);q[0]||(q=In(a,l,m,n,p,e));l=q[1];m=q[2]}a.fm++;if(!(23a.fm?a.wd-g/(2*Math.PI):a.wd-(0h){l=b-a;if(l<-h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(l=b-a,l<-h){l=b+a;if(l>h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}m=Math.sqrt(1-Math.min(1,l*l/(h*h)))*k;0>c!==n&&(m=-m);b=Math.abs(c-m)>(d[e].height+d[e+1].height)/2?[!1]:[!0];b[1]=l;b[2]=m;return b} -function In(a,b,c,d,e,g){var h=a.wd,k=a.jg,l=0,m=0;a=(d[e].height+d[e+1].height)/2+a.Ek;var n=!1;if(0<=b!==(g===Yk)){if(m=c-a,m<-k){m=c+a;if(m>k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(m=c+a,m>k){m=c-a;if(m<-k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}l=Math.sqrt(1-Math.min(1,m*m/(k*k)))*h;0>b!==n&&(l=-l);b=Math.abs(b-l)>(d[e].width+d[e+1].width)/2?[!1]:[!0];b[1]=l;b[2]=m;return b}function un(){this.Uo=-Infinity;this.Op=this.kn=null} -un.prototype.commit=function(a){if(null!==this.kn&&null!==this.Op)for(var b=0;bMath.abs(a.Gn-1))return void 0!==d&&void 0!==e?e*b:2*Math.PI*b;a=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c;var h=0,k;k=void 0!==d&&void 0!==e?e/(g+1):Math.PI/(2*(g+1));for(var l=0;l<=g;l++)var m=Math.sin(void 0!==d&&void 0!==e?d+l*e/g:l*Math.PI/(2*g)),h=h+Math.sqrt(1-a*a*m*m)*k;return void 0!==d&&void 0!==e?(b>c?b:c)*h:4*(b>c?b:c)*h}function yn(a,b,c,d,e){a=void 0!==d&&void 0!==e?zn(a,1,c,d,e):zn(a,1,c);return b/a} -function An(a,b,c,d,e){if(0.001>Math.abs(a.Gn-1))return e/b;var g=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c,h=0;a=2*Math.PI/(700*a.network.vertexes.count);b>c&&(d+=Math.PI/2);for(var k=0;;k++){var l=Math.sin(d+k*a),h=h+(b>c?b:c)*Math.sqrt(1-g*g*l*l)*a;if(h>=e)return k*a}return 0} -Qk.prototype.sort=function(a){switch(this.sorting){case Tk:break;case Uk:a.reverse();break;case Rk:a.sort(this.comparer);break;case Sk:a.sort(this.comparer);a.reverse();break;case Vk:for(var b=[],c=0;ce&&(e=k,g=h)}else for(h=0;he&&(e=k,g=h);d.add(a.qa(g));b[g]=-1;g=a.qa(g);e=g.hc;for(g=g.Zb;e.next();)h=e.value,h=h.fromVertex,h=a.indexOf(h),0> -h||0<=b[h]&&b[h]++;for(;g.next();)h=g.value,h=h.toVertex,h=a.indexOf(h),0>h||0<=b[h]&&b[h]++}a=[];for(b=0;ba[b].indexOf(m)&&a[b].push(m);for(;e.next();)l=e.value,m=d.indexOf(l.fromVertex),m!==b&&0>a[b].indexOf(m)&&a[b].push(m)}k=[];for(b=0;ba[c[q]].indexOf(c[q===c.length-1?0:q+1])&&x.push(q===c.length-1?0:q+1);if(0===x.length)for(q=0;qN.indexOf(da)||RN.indexOf(da)||R=E?m+1:m)),G+=m=E&&m++,L>=E&&L++,m>L&&(N=L,L=m,m=N),L-m<(c.length+2)/2===(mr||r===m||(v=r>m?r-m:m-r,s+=rp-v?1:-1);c.splice(0>s?m:m+1,0,b);e.splice(k,1);k--}else n=!1;if(n)break;else c.push(e[0]),e.splice(0,1)}for(b=0;b=a?a:360,this.K())});t.g(Qk,"arrangement",Qk.prototype.Oe);t.defineProperty(Qk,{Oe:"arrangement"},function(){return this.jd},function(a){this.jd!==a&&(f&&t.l(a,oa,Qk,"arrangement"),a===cl||a===bl||a===al||a===$k)&&(this.jd=a,this.K())});t.g(Qk,"direction",Qk.prototype.direction); -t.defineProperty(Qk,{direction:"direction"},function(){return this.sa},function(a){this.sa!==a&&(f&&t.l(a,oa,Qk,"direction"),a===Yk||a===Zk||a===Wk||a===Xk)&&(this.sa=a,this.K())});t.g(Qk,"sorting",Qk.prototype.sorting);t.defineProperty(Qk,{sorting:"sorting"},function(){return this.xh},function(a){this.xh!==a&&(f&&t.l(a,oa,Qk,"sorting"),a===Tk||a===Uk||a===Rk||Sk||a===Vk)&&(this.xh=a,this.K())});t.g(Qk,"comparer",Qk.prototype.comparer); -t.defineProperty(Qk,{comparer:"comparer"},function(){return this.ih},function(a){this.ih!==a&&(f&&t.j(a,"function",Qk,"comparer"),this.ih=a,this.K())});t.g(Qk,"spacing",Qk.prototype.spacing);t.defineProperty(Qk,{spacing:"spacing"},function(){return this.yh},function(a){this.yh!==a&&(this.yh=a,this.K())});t.g(Qk,"nodeDiameterFormula",Qk.prototype.ht); -t.defineProperty(Qk,{ht:"nodeDiameterFormula"},function(){return this.vr},function(a){this.vr!==a&&(f&&t.l(a,oa,Qk,"nodeDiameterFormula"),a===el||a===dl)&&(this.vr=a,this.K())});t.A(Qk,{MG:"actualXRadius"},function(){return this.wd});t.A(Qk,{NG:"actualYRadius"},function(){return this.jg});t.A(Qk,{nJ:"actualSpacing"},function(){return this.Ek});t.A(Qk,{LG:"actualCenter"},function(){return isNaN(this.zd.x)||isNaN(this.zd.y)?new C(0,0):new C(this.zd.x+this.MG,this.zd.y+this.NG)});var bl; -Qk.ConstantSpacing=bl=t.w(Qk,"ConstantSpacing",0);var al;Qk.ConstantDistance=al=t.w(Qk,"ConstantDistance",1);var $k;Qk.ConstantAngle=$k=t.w(Qk,"ConstantAngle",2);var cl;Qk.Packed=cl=t.w(Qk,"Packed",3);var Yk;Qk.Clockwise=Yk=t.w(Qk,"Clockwise",4);var Zk;Qk.Counterclockwise=Zk=t.w(Qk,"Counterclockwise",5);var Wk;Qk.BidirectionalLeft=Wk=t.w(Qk,"BidirectionalLeft",6);var Xk;Qk.BidirectionalRight=Xk=t.w(Qk,"BidirectionalRight",7);var Tk;Qk.Forwards=Tk=t.w(Qk,"Forwards",8);var Uk; -Qk.Reverse=Uk=t.w(Qk,"Reverse",9);var Rk;Qk.Ascending=Rk=t.w(Qk,"Ascending",10);var Sk;Qk.Descending=Sk=t.w(Qk,"Descending",11);var Vk;Qk.Optimized=Vk=t.w(Qk,"Optimized",12);var el;Qk.Pythagorean=el=t.w(Qk,"Pythagorean",13);var dl;Qk.Circular=dl=t.w(Qk,"Circular",14);function vn(){Ca.call(this)}t.ia("CircularNetwork",vn);t.Oa(vn,Ca);vn.prototype.createVertex=function(){return new wn};vn.prototype.createEdge=function(){return new Jn};function wn(){Da.call(this);this.actualAngle=this.diameter=NaN} -t.ia("CircularVertex",wn);t.Oa(wn,Da);function xn(a,b){var c=a.network;if(null===c)return NaN;c=c.Tb;if(null===c)return NaN;if(c.Oe===cl)if(c.ht===dl)a.diameter=Math.max(a.width,a.height);else{var c=Math.abs(Math.sin(b)),d=Math.abs(Math.cos(b));if(0===c)return a.width;if(0===d)return a.height;a.diameter=Math.min(a.height/c,a.width/d)}else a.diameter=c.ht===dl?Math.max(a.width,a.height):Math.sqrt(a.width*a.width+a.height*a.height);return a.diameter}function Jn(){Ea.call(this)}t.ia("CircularEdge",Jn); -t.Oa(Jn,Ea);function Kn(){0k?(e=l.x+l.width/2,g=l.y+l.height/2,h[0]=new C(l.x+l.width+c.width,l.y),h[1]=new C(l.x,l.y+ -l.height+c.height),k=2):(p=Nn(h,k,e,g,l.width,l.height,c),q=h[p],r=new C(q.x+l.width+c.width,q.y),s=new C(q.x,q.y+l.height+c.height),p+1this.network.vertexes.count)return!1;var a=0,b=0,c=this.network.vertexes.k;c.next();for(var d=c.value.T;c.next();){if(c.value.T.If(d)&&(a++,1a.network.vertexes.count)return!1;null===a.ig?a.ig=new H(Tn):a.ig.clear();a.ig.Me(a.network.vertexes);var c=a.ig;c.sort(function(a,b){return null===a||null===b||a===b?0:b.Lf-a.Lf});for(var d=c.count-1;0<=d&&1>=c.p[d].Lf;)d--;return 1=h))){for(var n=0,p=0,q=m.count-h;qs&&(s=1);n=J.sqrt((n+s+p*p*4/(h*h))/s);h=(n-1)*l/2;n=(n-1)*q/2;g.Mb=new D(m-r.x-h,k-r.y-n,l+2*h,q+2*n);g.focus=new C(r.x+h,r.y+n)}a.network=d;return c} -function Sn(a,b,c){f&&(t.l(b,Ln,Kn,"popNetwork:oldnet"),t.o(c,Kn,"popNetwork:level"));for(c=a.network.vertexes.k;c.next();){var d=c.value;d.network=b;if(null!==d.ah){var e=d.ah.p[d.UA];d.Lf=e.wB;var g=e.kG,h=e.lG;d.Mb=new D(d.Fa-g,d.Sa-h,e.yB,e.vB);d.focus=new C(g,h);d.UA--}}for(c=a.network.edges.k;c.next();)c.value.network=b;a.network=b} -function Un(a,b,c){f&&(t.l(b,Tn,Kn,"surroundNode:oldnet"),t.o(c,Kn,"surroundNode:level"));var d=b.Em;if(null!==d&&0!==d.count){c=b.Fa;var e=b.Sa,g=b.width,h=b.height;null!==b.ah&&0=p.Lf?l++:(k=!0,m++,h+=Math.atan2(b.Sa-p.Sa,b.Fa-p.Fa))}if(0!==l)for(0>1)+m)*(0==k%2?1:-1);p.Fa=c+d*Math.cos(l);p.Sa=e+d*Math.sin(l);k++}}} -function Nn(a,b,c,d,e,g,h){var k=9E19,l=-1,m=0;a:for(;mn.y&&a[q].x-n.xn.x&&a[q].y-n.yl+h?(d=d+g-k,e=e-l-h,J.sqrt(d*d+e*e)):e+ck+m?e>l+h?(d=d-k-m,e=e-l-h,J.sqrt(d*d+e*e)):e+cl+h?e-(l+h):e+c=b.length)return!1;var c=b[0];c.forceX=0;c.forceY=0;for(var d=c.Fa,e=d,g=c.Sa,h=g,c=1;ch-g)?b.sort(function(a,b){return null===a||null===b||a===b?0:a.Fa-b.Fa}):b.sort(function(a,b){return null===a||null===b||a===b?0:a.Sa-b.Sa});for(var h=a.oh,m=0,n=0,p=0,c=0;ch||p-d>h){if(g)break}else if(l-r>h||r-l>h){if(!g)break}else{var s=Vn(k,e);1>s?(d>p?(n=Math.abs(e.T.right-k.T.x),n=(1+n)*Math.random()):dr?(p=Math.abs(e.T.bottom-k.T.y),p=(1+p)*Math.random()):ds?(n=(d>p?1:-1)*(1+(e.width>k.width)?e.width: -k.width)*Math.random(),p=(l>r?1:-1)*(1+(e.height>k.height)?e.height:k.height)*Math.random()):(m=g.stiffness*(s-g.length),n=(p-d)/s*m,p=(r-l)/s*m),k.forceX+=n,k.forceY+=p,e.forceX-=n,e.forceY-=p;c=0;d=Math.max(a.oh/20,50);for(e=0;ed&&(g=d),h<-d?h=-d:h>d&&(h=d),k.Fa+=g,k.Sa+=h,c=Math.max(c,g*g+h*h));return c>a.Vz*a.Vz}Kn.prototype.moveFixedVertex=function(){}; -Kn.prototype.commitLayout=function(){this.bB();this.commitNodes();this.Vs&&this.commitLinks()};Kn.prototype.bB=function(){if(this.wl)for(var a=this.network.edges.k;a.next();){var b=a.value.link;null!==b&&(b.lb=Pb,b.mb=Pb)}};Kn.prototype.commitNodes=function(){var a=0,b=0;if(this.gD){var c=t.wf();this.kf(this.network,c);b=this.zd;a=b.x-c.x;b=b.y-c.y;t.Pc(c)}for(var c=t.wf(),d=this.network.vertexes.k;d.next();){var e=d.value;if(0!==a||0!==b)c.assign(e.T),c.x+=a,c.y+=b,e.Mb=c;e.commit()}t.Pc(c)}; -Kn.prototype.commitLinks=function(){for(var a=this.network.edges.k;a.next();)a.value.commit()};Kn.prototype.springStiffness=function(a){a=a.stiffness;return isNaN(a)?this.An:a};Kn.prototype.springLength=function(a){a=a.length;return isNaN(a)?this.zn:a};Kn.prototype.electricalCharge=function(a){a=a.charge;return isNaN(a)?this.wn:a};Kn.prototype.electricalFieldX=function(){return 0};Kn.prototype.electricalFieldY=function(){return 0}; -Kn.prototype.gravitationalMass=function(a){a=a.mass;return isNaN(a)?this.yn:a};Kn.prototype.gravitationalFieldX=function(){return 0};Kn.prototype.gravitationalFieldY=function(){return 0};Kn.prototype.isFixed=function(a){return a.isFixed};t.A(Kn,{oJ:"currentIteration"},function(){return this.Vq});t.g(Kn,"arrangementSpacing",Kn.prototype.Jv);t.defineProperty(Kn,{Jv:"arrangementSpacing"},function(){return this.Rf},function(a){this.Rf.N(a)||(this.Rf.assign(a),this.K())});t.g(Kn,"arrangesToOrigin",Kn.prototype.gD); -t.defineProperty(Kn,{gD:"arrangesToOrigin"},function(){return this.cq},function(a){this.cq!==a&&(this.cq=a,this.K())});t.g(Kn,"setsPortSpots",Kn.prototype.wl);t.defineProperty(Kn,{wl:"setsPortSpots"},function(){return this.wh},function(a){this.wh!==a&&(this.wh=a,this.K())});t.g(Kn,"comments",Kn.prototype.comments);t.defineProperty(Kn,{comments:"comments"},function(){return this.hh},function(a){this.hh!==a&&(this.hh=a,this.K())});t.g(Kn,"maxIterations",Kn.prototype.Aw); -t.defineProperty(Kn,{Aw:"maxIterations"},function(){return this.ao},function(a){this.ao!==a&&0<=a&&(this.ao=a,this.K())});t.g(Kn,"epsilonDistance",Kn.prototype.Vz);t.defineProperty(Kn,{Vz:"epsilonDistance"},function(){return this.zq},function(a){this.zq!==a&&0b.toVertex.index&&(this.network.Jw(b),b.rev=!0);break;case Yn:for(b=this.network.vertexes.k;b.next();)b.value.Lo=-1,b.value.finish=-1;for(a=this.network.edges.k;a.next();)a.value.forest=!1;this.sr=0;for(b.reset();b.next();)0===b.value.hc.count&&jo(this,b.value);for(b.reset();b.next();)-1===b.value.Lo&&jo(this,b.value);for(a.reset();a.next();)b=a.value,b.forest|| -(c=b.fromVertex,d=c.finish,e=b.toVertex,g=e.finish,e.Los&&0s&&0b[this.Af]&&(this.Gu=b[c]-1,this.Af=c),b[c]k)for(p=k+1;pl;p--)n=d[p],n.near===m&&n.zm===m.zm||h++;var q,r,s,v,x,E;if(0<=c)for(l=d[k].$e,m=0;mv||n===v&&q>s)&&h++,xn||v===n&&s>q)&&h++);if(0>=c)for(l=d[k].Qe,m=0;mv||n===v&&p>x)&&h++,sn||v===n&&x>p)&&h++);g[k*e+k]=h;for(l= -k+1;l=c)for(h=d[k].Qe,E=d[l].Qe,m=0;m=c&&(l=k.$e);var m=null;0<=c&&(m=k.Qe);var n=0,p=0,q=k.near;null!==q&&q.layer===k.layer&&(n+=q.column-1,p++);if(null!==l)for(q=0;q=c&&(l=k.$e);var m=null;0<=c&&(m=k.Qe);var n=0,p=[],q=k.near;null!==q&&q.layer===k.layer&&(p[n]=q.column-1,n++);if(null!==l)for(q=0;q>1,g[h]=n&1?p[m]:p[m-1]+p[m]>>1)}Bo(a,b,d);return g}function Ko(a,b,c,d,e,g){if(b.component===d){b.component=c;var h,k;if(e)for(var l=b.Zb;l.next();){var m=l.value.toVertex;h=b.layer-m.layer;k=Co(l.value);h===k&&Ko(a,m,c,d,e,g)}if(g)for(l=b.hc;l.next();)m=l.value.fromVertex,h=m.layer-b.layer,k=Co(l.value),h===k&&Ko(a,m,c,d,e,g)}} -function Lo(a,b,c,d,e,g){if(b.component===d){b.component=c;if(e)for(var h=b.Zb,k;h.next();)k=h.value.toVertex,Lo(a,k,c,d,e,g);if(g)for(b=b.hc;b.next();)h=b.value.fromVertex,Lo(a,h,c,d,e,g)}}function fo(a){for(a=a.vertexes.k;a.next();){var b=a.value;if(b.valid)return b}return null}function ho(a){for(a=a.vertexes.k;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.Zb;d.next();)if(d.value.toVertex.valid){c=!1;break}if(c)return b}}return null} -function io(a){for(a=a.vertexes.k;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.hc;d.next();)if(d.value.fromVertex.valid){c=!1;break}if(c)return b}}return null}function jo(a,b){b.Lo=a.sr;a.sr++;for(var c=b.Zb;c.next();){var d=c.value,e=d.toVertex;-1===e.Lo&&(d.forest=!0,jo(a,e))}b.finish=a.sr;a.sr++} -Hk.prototype.assignLayers=function(){switch(this.Yn){case Mo:No(this);break;case Oo:for(var a,b=this.network.vertexes.k;b.next();)a=Po(this,b.value),this.ob=Math.max(a,this.ob);for(b.reset();b.next();)a=b.value,a.layer=this.ob-a.layer;break;default:case Zn:No(this);for(b=this.network.vertexes.k;b.next();)b.value.valid=!1;for(b.reset();b.next();)0===b.value.hc.count&&Qo(this,b.value);a=Infinity;for(b.reset();b.next();)a=Math.min(a,b.value.layer);this.ob=-1;for(b.reset();b.next();)b.value.layer-=a, -this.ob=Math.max(this.ob,b.value.layer)}};function No(a){for(var b=a.network.vertexes.k;b.next();){var c=Ro(a,b.value);a.ob=Math.max(c,a.ob)}}function Ro(a,b){var c=0;if(-1===b.layer){for(var d=b.Zb;d.next();)var e=d.value,g=Co(e),c=Math.max(c,Ro(a,e.toVertex)+g);b.layer=c}else c=b.layer;return c}function Po(a,b){var c=0;if(-1===b.layer){for(var d,e,g=b.hc;g.next();)e=g.value,d=Co(e),c=Math.max(c,Po(a,e.fromVertex)+d);b.layer=c}else c=b.layer;return c} -function Qo(a,b){if(!b.valid){b.valid=!0;for(var c=b.Zb;c.next();)Qo(a,c.value.toVertex);for(c=a.network.vertexes.k;c.next();)c.value.component=-1;for(var d=b.$e.p,e=d.length,g=0;gk&&Ko(a,h.fromVertex,0,-1,!0,!1)}for(Ko(a,b,1,-1,!0,!0);0!==b.component;){for(var k=0,d=Infinity,l=0,m=null,n=a.network.vertexes.k;n.next();){var p=n.value;if(1===p.component){for(var q=0,r=!1,s=p.$e.p,e=s.length,g=0;gd)&&!p&&(k=m,d=n)}if(0>g){for(c.reset();c.next();)g=c.value,1===g.component&&(g.layer-=e);b.component=0}else k.component=0}}}function zo(a,b,c){return 90===a.sa?c&&!b.rev||!c&&b.rev?270:90:180===a.sa?c&&!b.rev||!c&&b.rev?0:180:270===a.sa?c&&!b.rev||!c&&b.rev?90:270:c&&!b.rev||!c&&b.rev?180:0} -Hk.prototype.initializeIndices=function(){switch(this.On){default:case So:for(var a,b=this.network.vertexes.k;b.next();){var c=b.value;a=c.layer;c.index=this.Hd[a];this.Hd[a]++}break;case $n:b=this.network.vertexes.k;for(a=this.ob;0<=a;a--){for(;b.next();)b.value.layer===a&&-1===b.value.index&&To(this,b.value);b.reset()}break;case Uo:for(b=this.network.vertexes.k,a=0;a<=this.ob;a++){for(;b.next();)b.value.layer===a&&-1===b.value.index&&Vo(this,b.value);b.reset()}}}; -function To(a,b){var c=b.layer;b.index=a.Hd[c];a.Hd[c]++;for(var c=b.Qe.af(),d=!0,e;d;)for(d=!1,e=0;eh.portFromColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;eh.portToColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;e=h;d--)g=Xo(this,d,-1)||g;e=this.countCrossings();e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,1)||g;e=this.countCrossings();e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g= -Xo(this,d,-1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this))}break;default:case ao:for(c=this.ob,h=0,k=a+1;(d=this.countCrossings())=h;d--)g=Xo(this,d,-1)||g;e=this.countCrossings();e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,1)||g;e=this.countCrossings();e>=a?Fo(this,b): -(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,-1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this))}}Fo(this,b)}; -function Wo(a,b,c){f&&(t.o(b,Hk,"medianBarycenterCrossingReduction:unfixedLayer"),t.o(c,Hk,"medianBarycenterCrossingReduction:direction"));var d=Ao(a,b),e=a.Hd[b],g=Jo(a,b,c),h=Io(a,b,c);for(c=0;cg+1&&(q+=4*(F-g),r+=4*(F-(g+1)))}L=d[g].Zb.k;for(L.reset();L.next();)if(G=L.value,G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g+1&&(r+=1)}L=d[g+1].hc.k;for(L.reset();L.next();)if(G=L.value,G.valid&&G.fromVertex.layer===b){G=G.fromVertex;for(F=0;d[F]!==G;)F++;Fg+1&&(q+=4*(F-(g+1)),r+=4*(F-g))}L=d[g+1].Zb.k;for(L.reset();L.next();)if(G=L.value, -G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g&&(q+=1)}var F=G=0,L=h[d[g].index],N=k[d[g].index],W=h[d[g+1].index],T=k[d[g+1].index];-1!==L&&(G+=Math.abs(L-s),F+=Math.abs(L-E));-1!==N&&(G+=Math.abs(N-s),F+=Math.abs(N-E));-1!==W&&(G+=Math.abs(W-v),F+=Math.abs(W-x));-1!==T&&(G+=Math.abs(T-v),F+=Math.abs(T-x));if(r>1)+8*g;this.Hb*=8}if(0!==(this.si&ap))for(b=!0;b;){b=!1;for(a=this.Af+1;a<=this.ob;a++)b=bp(this,a,1)||b;for(a=this.Af- -1;0<=a;a--)b=bp(this,a,-1)||b;b=bp(this,this.Af,0)||b}if(0!==(this.si&cp)){for(a=this.Af+1;a<=this.ob;a++)dp(this,a,1);for(a=this.Af-1;0<=a;a--)dp(this,a,-1);dp(this,this.Af,0)}c&&(ep(this,-1),ep(this,1));if(0!==(this.si&ap))for(b=!0;b;){b=!1;b=bp(this,this.Af,0)||b;for(a=this.Af+1;a<=this.ob;a++)b=bp(this,a,0)||b;for(a=this.Af-1;0<=a;a--)b=bp(this,a,0)||b}};function bp(a,b,c){f&&(t.o(b,Hk,"bendStraighten:unfixedLayer"),t.o(c,Hk,"bendStraighten:direction"));for(var d=!1;fp(a,b,c);)d=!0;return d} -function fp(a,b,c){f&&(t.o(b,Hk,"shiftbendStraighten:unfixedLayer"),t.o(c,Hk,"shiftbendStraighten:direction"));var d,e=Ao(a,b),g=a.Hd[b],h=Io(a,b,-1);if(0c)for(d=0;dd-1||n-e[d-1].column-1>p+a.nodeMinColumnSpace(e[d-1],!1)?n-1:n,q=d+1>=g||e[d+1].column-n-1>q+a.nodeMinColumnSpace(e[d+1],!0)?n+1:n,r=0,s=0,v=0,x, -E,F,G;if(0>=c)for(var L=e[d].hc.k;L.next();)x=L.value,x.valid&&x.fromVertex.layer!==b&&(E=Do(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.fromVertex.column,r+=(Math.abs(n+G-(x+F))+1)*E,s+=(Math.abs(p+G-(x+F))+1)*E,v+=(Math.abs(q+G-(x+F))+1)*E);if(0<=c)for(L=e[d].Zb.k;L.next();)x=L.value,x.valid&&x.toVertex.layer!==b&&(E=Do(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.toVertex.column,r+=(Math.abs(n+F-(x+G))+1)*E,s+=(Math.abs(p+F-(x+G))+1)*E,v+=(Math.abs(q+F-(x+G))+1)*E);G=F=E=0;x=h[e[d].index]; -L=k[e[d].index];-1!==x&&(E+=Math.abs(x-n),F+=Math.abs(x-p),G+=Math.abs(x-q));-1!==L&&(E+=Math.abs(L-n),F+=Math.abs(L-p),G+=Math.abs(L-q));if(s=h[c]?n=l:m<=h[c]&&(n=m));n!==k&&(g=!0,d[c].column=n)}Bo(a,b,d);a.normalize()} -function gp(a,b){f&&(t.o(b,Hk,"packAux:column"),t.o(1,Hk,"packAux:direction"));for(var c=!0,d=a.network.vertexes.k,e;d.next();){e=d.value;var g=a.nodeMinColumnSpace(e,!0),h=a.nodeMinColumnSpace(e,!1);if(e.column-g<=b&&e.column+h>=b){c=!1;break}}g=!1;if(c)for(d.reset();d.next();)e=d.value,e.column>b&&(e.column-=1,g=!0);return g} -function hp(a,b){f&&(t.o(b,Hk,"tightPackAux:column"),t.o(1,Hk,"tightPackAux:direction"));var c=b,c=b+1,d,e=[],g=[];for(d=0;d<=a.ob;d++)e[d]=!1,g[d]=!1;for(var h=a.network.vertexes.k;h.next();){d=h.value;var k=d.column-a.nodeMinColumnSpace(d,!0),l=d.column+a.nodeMinColumnSpace(d,!1);k<=b&&l>=b&&(e[d.layer]=!0);k<=c&&l>=c&&(g[d.layer]=!0)}k=!0;c=!1;for(d=0;d<=a.ob;d++)k=k&&!(e[d]&&g[d]);if(k)for(h.reset();h.next();)d=h.value,d.column>b&&(d.column-=1,c=!0);return c} -function ep(a,b){f&&t.o(b,Hk,"componentPack:direction");for(var c=0;c<=a.Hb;c++)for(;gp(a,c););a.normalize();for(c=0;ce?Fo(a,d):hb)for(c=a.Hb;0<=c;c--)for(d=Eo(a),e=Ho(a),g=e+1;ee?Fo(a,d):hc)for(d.reset();d.next();)e=d.value,e.column+a.nodeMinColumnSpace(e,!1)>=b&&(e.component=a.ag);a.ag++;for(d.reset();d.next();)e=d.value,-1===e.component&&(Lo(a,e,a.ag,-1,!0,!0),a.ag++);b=[];for(e=0;ec)for(k=a.Hb;0c)for(d.reset();d.next();)e=d.value,g[e.component]&&(e.column+=1)}Hk.prototype.commitLayout=function(){if(this.wl)for(var a=to(this,!0),b=to(this,!1),c=this.network.edges.k,d;c.next();)d=c.value.link,null!==d&&(d.lb=a,d.mb=b);this.commitNodes();this.Vs&&this.commitLinks()}; -function to(a,b){return 270===a.sa?b?ac:dc:90===a.sa?b?dc:ac:180===a.sa?b?bc:cc:b?cc:bc} -Hk.prototype.commitNodes=function(){this.th=[];this.Lg=[];this.yf=[];this.Kd=[];for(var a=0;a<=this.ob;a++)this.th[a]=0,this.Lg[a]=0,this.yf[a]=0,this.Kd[a]=0;for(var a=this.network.vertexes.k,b,c;a.next();)b=a.value,c=b.layer,this.th[c]=Math.max(this.th[c],this.nodeMinLayerSpace(b,!0)),this.Lg[c]=Math.max(this.Lg[c],this.nodeMinLayerSpace(b,!1));b=0;for(var d=this.Xn,e=0;e<=this.ob;e++)c=d,0>=this.th[e]+this.Lg[e]&&(c=0),0=Ja.T.y&&Zb<=Ja.T.bottom&&(za=Ja.Fa+jf,Zb=Zb=Ja.T.x&&Zb<=Ja.T.right&&(za=Ja.Sa+jf,Zb=Zbqb.y&&(jd=Rc.y>qb.y?0:Ya.xsb.x&&(Cc=se.x>sb.x?0:Sc.yb.layer?1:a.Ceb.Ce?1:a.Qdb.Qd?1:0:0}; -Hk.prototype.rF=function(a,b){return a instanceof jp&&b instanceof jp&&a!==b?a.ebb.eb||a.Uhb.Uh||a.Ceb.Ce?1:a.Qdb.Qd?1:0:0};Hk.prototype.Lw=function(a,b){return a instanceof jp&&b instanceof jp&&a!==b?a.Wdb.Wd||a.Uhb.Uh||a.Ceb.Ce?1:a.Qdb.Qd?1:0:0};Hk.prototype.I=function(a,b){f&&(t.o(a,Hk,"isApprox:a"),t.o(b,Hk,"isApprox:b"));var c=a-b;return-1c}; -function kp(a,b,c,d){f&&(t.o(a,Hk,"isUnoccupied2:px"),t.o(b,Hk,"isUnoccupied2:py"),t.o(c,Hk,"isUnoccupied2:qx"),t.o(d,Hk,"isUnoccupied2:qy"));return!0}function Ao(a,b){var c,d=a.Hd[b];if(d>=a.Ng.length){c=[];var e;for(e=0;ea&&(this.si=a,this.K())});t.g(Hk,"setsPortSpots",Hk.prototype.wl);t.defineProperty(Hk,{wl:"setsPortSpots"},function(){return this.wh},function(a){this.wh!==a&&"boolean"===typeof a&&(this.wh=a,this.K())});t.g(Hk,"linkSpacing",Hk.prototype.lp);t.defineProperty(Hk,{lp:"linkSpacing"},function(){return this.uj},function(a){this.uj!==a&&(this.uj=a,this.K())});t.A(Hk,{zJ:"maxLayer"},function(){return this.ob}); -t.A(Hk,{xJ:"maxIndex"},function(){return this.Gu});t.A(Hk,{wJ:"maxColumn"},function(){return this.Hb});t.A(Hk,{AJ:"minIndexLayer"},function(){return this.mr});t.A(Hk,{yJ:"maxIndexLayer"},function(){return this.Af});var Yn;Hk.CycleDepthFirst=Yn=t.w(Hk,"CycleDepthFirst",0);var eo;Hk.CycleGreedy=eo=t.w(Hk,"CycleGreedy",1);var Zn;Hk.LayerOptimalLinkLength=Zn=t.w(Hk,"LayerOptimalLinkLength",0);var Mo;Hk.LayerLongestPathSink=Mo=t.w(Hk,"LayerLongestPathSink",1);var Oo; -Hk.LayerLongestPathSource=Oo=t.w(Hk,"LayerLongestPathSource",2);var $n;Hk.InitDepthFirstOut=$n=t.w(Hk,"InitDepthFirstOut",0);var Uo;Hk.InitDepthFirstIn=Uo=t.w(Hk,"InitDepthFirstIn",1);var So;Hk.InitNaive=So=t.w(Hk,"InitNaive",2);var Yo;Hk.AggressiveNone=Yo=t.w(Hk,"AggressiveNone",0);var ao;Hk.AggressiveLess=ao=t.w(Hk,"AggressiveLess",1);var Zo;Hk.AggressiveMore=Zo=t.w(Hk,"AggressiveMore",2);Hk.PackNone=0;var $o;Hk.PackExpand=$o=1;var ap;Hk.PackStraighten=ap=2;var cp;Hk.PackMedian=cp=4;var bo; -Hk.PackAll=bo=7;function co(){Ca.call(this)}t.ia("LayeredDigraphNetwork",co);t.Oa(co,Ca);co.prototype.createVertex=function(){return new lp};co.prototype.createEdge=function(){return new mp};function lp(){Da.call(this);this.index=this.column=this.layer=-1;this.component=NaN;this.near=null;this.valid=!1;this.finish=this.Lo=NaN;this.zm=0;this.AA=this.BA=void 0}t.ia("LayeredDigraphVertex",lp);t.Oa(lp,Da); -function mp(){Ea.call(this);this.forest=this.rev=this.valid=!1;this.portToPos=this.portFromPos=NaN;this.portToColOffset=this.portFromColOffset=0}t.ia("LayeredDigraphEdge",mp);t.Oa(mp,Ea);function Z(){0b.level)return!1;a.removeChild(c.parent,c)}return!0} -Z.prototype.removeChild=function(a,b){f&&t.l(a,rp,Z,"removeChild:p");f&&t.l(b,rp,Z,"removeChild:c");if(null!==a&&null!==b){for(var c=a.children,d=0,e=0;eh?$p(b,l,ab,L,N):aq(b,l,ab,L,N);ab=R[0];L=R[1];N=R[2];break;case Op:for(n=0;nv&&(yaKb&&(fq(b,-Kb,0,va,n-1),gq(T,-Kb,0),gq(U,-Kb,0),Kb=0);p.la.q(Kb,Na);L=Math.max(L,da);N=Math.max(N,W+(0===Ja?0:F)+za.height);ya=da}else{0v&&(NaKb&&(fq(b,0,-Kb,va,n-1),gq(T,0,-Kb),gq(U,0,-Kb),Kb=0);p.la.q(ya,Kb);N=Math.max(N,R);L=Math.max(L,W+(0===Ja?0:F)+za.width);Na=R}Ka++}0k&&(k=0),135r&&(r=0), -q===Pp&&(m+=x/2+b.P.y),l+=e+d):c?(null===b.comments?e>L&&(q=kq(q,e-L,0),l=q[0],m=q[1],L=e,k=0):L=iq(b,L,k),0>k&&(l-=k,k=0),135N&&(q=kq(q,0,g-N),l=q[0],m=q[1],N=g,r=0):N=jq(b,N,r),0>r&&(m-=r,r=0),l+=e+d);if(0h[0].x?h[2].assign(h[1]):h[1].assign(h[2])),h[3].yh[0].x?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(k+e,0),q[1].q(q[0].x,g),q[2].yh[0].y?h[2].assign(h[1]):h[1].assign(h[2])),h[3].xh[0].y?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(0,r+g),q[1].q(e,q[0].y),q[2].xc?$p(b,e,Ja,N,W):aq(b,e,Ja,N,W);Ja=W[0];N=W[1];W=W[2];break;case Op:for(k=0;kr&&(Ur&&(dap&&(p=0),135G&&(G=0));b.Ma.q(p,G);b.Ya.q(N,W)}} -function $p(a,b,c,d,e){f&&t.l(a,rp,Z,"layoutBusChildrenPosDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ya.width;e=h.Ya.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=90===Vp(a),n=0,p=0,q=0,r=0;rm&&(d-=m),e=Math.max(e,Math.max(F,q)+b+s.height),0>h.la.x&&(c=tq(a,h.la.x,!1,c,k))):(h.la.q(d+b,c+k/2-h.P.y-h.Ma.y),d=Math.max(d,Math.max(E,p)+b+s.width),m=c+k/2-h.P.y-h.Ma.y,e=Math.max(e,m+s.height),0>m&&(e-=m),0>h.la.y&&(c=tq(a,h.la.y,!0,c,k))));a=[];a[0]=c;a[1]=d;a[2]=e;return a} -function aq(a,b,c,d,e){f&&t.l(a,rp,Z,"layoutBusChildrenNegDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ya.width;e=h.Ya.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=270===Vp(a),n=0,p=0,q=0,r=0;rp&&(d-=p),e=Math.max(e,Math.abs(Math.min(F,q))+l+s.height),0>h.la.x&&(c=tq(a,h.la.x,!1,c,k))):(h.la.q(-d-s.width-l,c+k/2-h.P.y-h.Ma.y),d=Math.max(d,Math.abs(Math.min(E,p))+l+s.width),p=c+k/2-h.P.y-h.Ma.y,e=Math.max(e,p+s.height),0>p&&(e-=p),0>h.la.y&&(c=tq(a,h.la.y,!0,c,k))));for(r=0;rd&&(d=c+a.width);0>c&&(d-=c);return d;case Wp:return a.width>b?a.width:b;case Xp:return 2*a.P.x>b?a.width:b+a.width-2*a.P.x;case Np:case Cp:return d=Math.min(0,c),c=Math.max(b,c+a.width),Math.max(a.width,c-d);case Op:return a.width-a.P.x+a.nodeSpacing/2+b;case Pp:return Math.max(a.width,a.P.x+a.nodeSpacing/2+b);default:return b}} -function jq(a,b,c){f&&t.l(a,rp,Z,"calculateSubheight:v");switch(a.alignment){case Lp:case hq:var d=b;c+a.height>d&&(d=c+a.height);0>c&&(d-=c);return d;case Wp:return a.height>b?a.height:b;case Xp:return 2*a.P.y>b?a.height:b+a.height-2*a.P.y;case Np:case Cp:return d=Math.min(0,c),c=Math.max(b,c+a.height),Math.max(a.height,c-d);case Op:return a.height-a.P.y+a.nodeSpacing/2+b;case Pp:return Math.max(a.height,a.P.y+a.nodeSpacing/2+b);default:return b}} -function kq(a,b,c){f&&t.l(a,oa,Z,"alignOffset:align");switch(a){case hq:b/=2;c/=2;break;case Lp:b/=2;c/=2;break;case Wp:c=b=0;break;case Xp:break;default:t.m("Unhandled alignment value "+a.toString())}a=[];a[0]=b;a[1]=c;return a}function cq(a,b,c,d,e,g){f&&t.l(a,rp,Z,"shiftRelPosAlign:v");f&&t.l(b,oa,Z,"shiftRelPosAlign:align");b=kq(b,c,d);fq(a,b[0],b[1],e,g)}function fq(a,b,c,d,e){f&&t.l(a,rp,Z,"shiftRelPos:v");if(0!==b||0!==c)for(a=a.children;d<=e;d++){var g=a[d].la;g.x+=b;g.y+=c}} -function dq(a,b,c,d){f&&(t.l(b,rp,Z,"recordMidPoints:v"),t.j(c,"number",Z,"recordMidPoints:x"),t.j(d,"number",Z,"recordMidPoints:y"));var e=b.parent;switch(a.xf){case op:for(a=b.hc;a.next();)b=a.value,b.fromVertex===e&&b.Cr.q(c,d);break;case vp:for(a=b.Zb;a.next();)b=a.value,b.toVertex===e&&b.Cr.q(c,d);break;default:t.m("Unhandled path value "+a.xf.toString())}}function gq(a,b,c){for(var d=0;dn.length||null===p||2>p.length))for(g= -e=0;ev&&k.yk.y&&vb.length||null===e||2>e.length)d=null;else{m=bq(a,b.length+e.length);for(d=l=k=0;lk;)v=e[l++],m[d++].q(v.x+g,v.y);e=bq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=bq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x, -k.y);k=bq(a,g);for(e=0;en.length||null===p||2>p.length))for(g=e=0;el&&k.xk.x&&lb.length||null===e||2>e.length)d=null;else{m=bq(a,b.length+e.length);for(d=l=k=0;lk;)v=e[l++],m[d++].q(v.x,v.y+g);e=bq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=bq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x,k.y);k=bq(a,g);for(e=0;e=a?0:135>=a?90:225>=a?180:315>=a?270:0} -function Yp(a){f&&t.l(a,rp,Z,"computeLayerSpacing:v");var b=Vp(a),b=90===b||270===b,c=a.layerSpacing;if(0=a&&(this.ua.nodeIndentPastParent=a,this.K())});t.g(Z,"nodeSpacing",Z.prototype.nodeSpacing); -t.defineProperty(Z,{nodeSpacing:"nodeSpacing"},function(){return this.ua.nodeSpacing},function(a){this.ua.nodeSpacing!==a&&(this.ua.nodeSpacing=a,this.K())});t.g(Z,"layerSpacing",Z.prototype.layerSpacing);t.defineProperty(Z,{layerSpacing:"layerSpacing"},function(){return this.ua.layerSpacing},function(a){this.ua.layerSpacing!==a&&(this.ua.layerSpacing=a,this.K())});t.g(Z,"layerSpacingParentOverlap",Z.prototype.layerSpacingParentOverlap); -t.defineProperty(Z,{layerSpacingParentOverlap:"layerSpacingParentOverlap"},function(){return this.ua.layerSpacingParentOverlap},function(a){this.ua.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.ua.layerSpacingParentOverlap=a,this.K())});t.g(Z,"compaction",Z.prototype.compaction);t.defineProperty(Z,{compaction:"compaction"},function(){return this.ua.compaction},function(a){this.ua.compaction!==a&&(f&&t.l(a,oa,Z,"compaction"),a===Sp||a===Up)&&(this.ua.compaction=a,this.K())}); -t.g(Z,"breadthLimit",Z.prototype.breadthLimit);t.defineProperty(Z,{breadthLimit:"breadthLimit"},function(){return this.ua.breadthLimit},function(a){this.ua.breadthLimit!==a&&0<=a&&(this.ua.breadthLimit=a,this.K())});t.g(Z,"rowSpacing",Z.prototype.rowSpacing);t.defineProperty(Z,{rowSpacing:"rowSpacing"},function(){return this.ua.rowSpacing},function(a){this.ua.rowSpacing!==a&&(this.ua.rowSpacing=a,this.K())});t.g(Z,"rowIndent",Z.prototype.rowIndent); -t.defineProperty(Z,{rowIndent:"rowIndent"},function(){return this.ua.rowIndent},function(a){this.ua.rowIndent!==a&&0<=a&&(this.ua.rowIndent=a,this.K())});t.g(Z,"commentSpacing",Z.prototype.commentSpacing);t.defineProperty(Z,{commentSpacing:"commentSpacing"},function(){return this.ua.commentSpacing},function(a){this.ua.commentSpacing!==a&&(this.ua.commentSpacing=a,this.K())});t.g(Z,"commentMargin",Z.prototype.commentMargin); -t.defineProperty(Z,{commentMargin:"commentMargin"},function(){return this.ua.commentMargin},function(a){this.ua.commentMargin!==a&&(this.ua.commentMargin=a,this.K())});t.g(Z,"setsPortSpot",Z.prototype.setsPortSpot);t.defineProperty(Z,{setsPortSpot:"setsPortSpot"},function(){return this.ua.setsPortSpot},function(a){this.ua.setsPortSpot!==a&&(this.ua.setsPortSpot=a,this.K())});t.g(Z,"portSpot",Z.prototype.portSpot); -t.defineProperty(Z,{portSpot:"portSpot"},function(){return this.ua.portSpot},function(a){this.ua.portSpot.N(a)||(this.ua.portSpot=a,this.K())});t.g(Z,"setsChildPortSpot",Z.prototype.setsChildPortSpot);t.defineProperty(Z,{setsChildPortSpot:"setsChildPortSpot"},function(){return this.ua.setsChildPortSpot},function(a){this.ua.setsChildPortSpot!==a&&(this.ua.setsChildPortSpot=a,this.K())});t.g(Z,"childPortSpot",Z.prototype.childPortSpot); -t.defineProperty(Z,{childPortSpot:"childPortSpot"},function(){return this.ua.childPortSpot},function(a){this.ua.childPortSpot.N(a)||(this.ua.childPortSpot=a,this.K())});t.g(Z,"alternateSorting",Z.prototype.iH);t.defineProperty(Z,{iH:"alternateSorting"},function(){return this.ta.sorting},function(a){this.ta.sorting!==a&&(f&&t.l(a,oa,Z,"alternateSorting"),a===Hp||a===Ip||a===Jp||Kp)&&(this.ta.sorting=a,this.K())});t.g(Z,"alternateComparer",Z.prototype.XG); -t.defineProperty(Z,{XG:"alternateComparer"},function(){return this.ta.comparer},function(a){this.ta.comparer!==a&&(f&&t.j(a,"function",Z,"alternateComparer"),this.ta.comparer=a,this.K())});t.g(Z,"alternateAngle",Z.prototype.RG);t.defineProperty(Z,{RG:"alternateAngle"},function(){return this.ta.angle},function(a){this.ta.angle===a||0!==a&&90!==a&&180!==a&&270!==a||(this.ta.angle=a,this.K())});t.g(Z,"alternateAlignment",Z.prototype.QG); -t.defineProperty(Z,{QG:"alternateAlignment"},function(){return this.ta.alignment},function(a){this.ta.alignment!==a&&(f&&t.tb(a,Z,Z,"alternateAlignment"),this.ta.alignment=a,this.K())});t.g(Z,"alternateNodeIndent",Z.prototype.aH);t.defineProperty(Z,{aH:"alternateNodeIndent"},function(){return this.ta.nodeIndent},function(a){this.ta.nodeIndent!==a&&0<=a&&(this.ta.nodeIndent=a,this.K())});t.g(Z,"alternateNodeIndentPastParent",Z.prototype.bH); -t.defineProperty(Z,{bH:"alternateNodeIndentPastParent"},function(){return this.ta.nodeIndentPastParent},function(a){this.ta.nodeIndentPastParent!==a&&0<=a&&1>=a&&(this.ta.nodeIndentPastParent=a,this.K())});t.g(Z,"alternateNodeSpacing",Z.prototype.cH);t.defineProperty(Z,{cH:"alternateNodeSpacing"},function(){return this.ta.nodeSpacing},function(a){this.ta.nodeSpacing!==a&&(this.ta.nodeSpacing=a,this.K())});t.g(Z,"alternateLayerSpacing",Z.prototype.ZG); -t.defineProperty(Z,{ZG:"alternateLayerSpacing"},function(){return this.ta.layerSpacing},function(a){this.ta.layerSpacing!==a&&(this.ta.layerSpacing=a,this.K())});t.g(Z,"alternateLayerSpacingParentOverlap",Z.prototype.$G);t.defineProperty(Z,{$G:"alternateLayerSpacingParentOverlap"},function(){return this.ta.layerSpacingParentOverlap},function(a){this.ta.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.ta.layerSpacingParentOverlap=a,this.K())});t.g(Z,"alternateCompaction",Z.prototype.WG); -t.defineProperty(Z,{WG:"alternateCompaction"},function(){return this.ta.compaction},function(a){this.ta.compaction!==a&&(f&&t.l(a,oa,Z,"alternateCompaction"),a===Sp||a===Up)&&(this.ta.compaction=a,this.K())});t.g(Z,"alternateBreadthLimit",Z.prototype.SG);t.defineProperty(Z,{SG:"alternateBreadthLimit"},function(){return this.ta.breadthLimit},function(a){this.ta.breadthLimit!==a&&0<=a&&(this.ta.breadthLimit=a,this.K())});t.g(Z,"alternateRowSpacing",Z.prototype.fH); -t.defineProperty(Z,{fH:"alternateRowSpacing"},function(){return this.ta.rowSpacing},function(a){this.ta.rowSpacing!==a&&(this.ta.rowSpacing=a,this.K())});t.g(Z,"alternateRowIndent",Z.prototype.eH);t.defineProperty(Z,{eH:"alternateRowIndent"},function(){return this.ta.rowIndent},function(a){this.ta.rowIndent!==a&&0<=a&&(this.ta.rowIndent=a,this.K())});t.g(Z,"alternateCommentSpacing",Z.prototype.VG); -t.defineProperty(Z,{VG:"alternateCommentSpacing"},function(){return this.ta.commentSpacing},function(a){this.ta.commentSpacing!==a&&(this.ta.commentSpacing=a,this.K())});t.g(Z,"alternateCommentMargin",Z.prototype.UG);t.defineProperty(Z,{UG:"alternateCommentMargin"},function(){return this.ta.commentMargin},function(a){this.ta.commentMargin!==a&&(this.ta.commentMargin=a,this.K())});t.g(Z,"alternateSetsPortSpot",Z.prototype.hH); -t.defineProperty(Z,{hH:"alternateSetsPortSpot"},function(){return this.ta.setsPortSpot},function(a){this.ta.setsPortSpot!==a&&(this.ta.setsPortSpot=a,this.K())});t.g(Z,"alternatePortSpot",Z.prototype.dH);t.defineProperty(Z,{dH:"alternatePortSpot"},function(){return this.ta.portSpot},function(a){this.ta.portSpot.N(a)||(this.ta.portSpot=a,this.K())});t.g(Z,"alternateSetsChildPortSpot",Z.prototype.gH); -t.defineProperty(Z,{gH:"alternateSetsChildPortSpot"},function(){return this.ta.setsChildPortSpot},function(a){this.ta.setsChildPortSpot!==a&&(this.ta.setsChildPortSpot=a,this.K())});t.g(Z,"alternateChildPortSpot",Z.prototype.TG);t.defineProperty(Z,{TG:"alternateChildPortSpot"},function(){return this.ta.childPortSpot},function(a){this.ta.childPortSpot.N(a)||(this.ta.childPortSpot=a,this.K())});var np;Z.PathDefault=np=t.w(Z,"PathDefault",-1);var op;Z.PathDestination=op=t.w(Z,"PathDestination",0);var vp; -Z.PathSource=vp=t.w(Z,"PathSource",1);var Hp;Z.SortingForwards=Hp=t.w(Z,"SortingForwards",10);var Ip;Z.SortingReverse=Ip=t.w(Z,"SortingReverse",11);var Jp;Z.SortingAscending=Jp=t.w(Z,"SortingAscending",12);var Kp;Z.SortingDescending=Kp=t.w(Z,"SortingDescending",13);var hq;Z.AlignmentCenterSubtrees=hq=t.w(Z,"AlignmentCenterSubtrees",20);var Lp;Z.AlignmentCenterChildren=Lp=t.w(Z,"AlignmentCenterChildren",21);var Wp;Z.AlignmentStart=Wp=t.w(Z,"AlignmentStart",22);var Xp; -Z.AlignmentEnd=Xp=t.w(Z,"AlignmentEnd",23);var Np;Z.AlignmentBus=Np=t.w(Z,"AlignmentBus",24);var Cp;Z.AlignmentBusBranching=Cp=t.w(Z,"AlignmentBusBranching",25);var Op;Z.AlignmentTopLeftBus=Op=t.w(Z,"AlignmentTopLeftBus",26);var Pp;Z.AlignmentBottomRightBus=Pp=t.w(Z,"AlignmentBottomRightBus",27);var Sp;Z.CompactionNone=Sp=t.w(Z,"CompactionNone",30);var Up;Z.CompactionBlock=Up=t.w(Z,"CompactionBlock",31);var pp;Z.StyleLayered=pp=t.w(Z,"StyleLayered",40);var Gp; -Z.StyleLastParents=Gp=t.w(Z,"StyleLastParents",41);var Fp;Z.StyleAlternating=Fp=t.w(Z,"StyleAlternating",42);var Ep;Z.StyleRootOnly=Ep=t.w(Z,"StyleRootOnly",43);var qp;Z.ArrangementVertical=qp=t.w(Z,"ArrangementVertical",50);var vq;Z.ArrangementHorizontal=vq=t.w(Z,"ArrangementHorizontal",51);var up;Z.ArrangementFixedRoots=up=t.w(Z,"ArrangementFixedRoots",52);function sp(){Ca.call(this)}t.ia("TreeNetwork",sp);t.Oa(sp,Ca);sp.prototype.createVertex=function(){return new rp};sp.prototype.createEdge=function(){return new xq}; -function rp(){Da.call(this);this.initialized=!1;this.parent=null;this.children=[];this.maxGenerationCount=this.maxChildrenCount=this.descendantCount=this.level=0;this.comments=null;this.la=new C(0,0);this.Ya=new pa(0,0);this.Ma=new C(0,0);this.Cp=this.Bp=this.aJ=!1;this.qt=this.Ys=null;this.sorting=Hp;this.comparer=sn;this.angle=0;this.alignment=Lp;this.nodeIndentPastParent=this.nodeIndent=0;this.nodeSpacing=20;this.layerSpacing=50;this.layerSpacingParentOverlap=0;this.compaction=Up;this.breadthLimit= -0;this.rowSpacing=25;this.commentSpacing=this.rowIndent=10;this.commentMargin=20;this.setsPortSpot=!0;this.portSpot=Pb;this.setsChildPortSpot=!0;this.childPortSpot=Pb}t.ia("TreeVertex",rp);t.Oa(rp,Da); -rp.prototype.copyInheritedPropertiesFrom=function(a){null!==a&&(this.sorting=a.sorting,this.comparer=a.comparer,this.angle=a.angle,this.alignment=a.alignment,this.nodeIndent=a.nodeIndent,this.nodeIndentPastParent=a.nodeIndentPastParent,this.nodeSpacing=a.nodeSpacing,this.layerSpacing=a.layerSpacing,this.layerSpacingParentOverlap=a.layerSpacingParentOverlap,this.compaction=a.compaction,this.breadthLimit=a.breadthLimit,this.rowSpacing=a.rowSpacing,this.rowIndent=a.rowIndent,this.commentSpacing=a.commentSpacing, -this.commentMargin=a.commentMargin,this.setsPortSpot=a.setsPortSpot,this.portSpot=a.portSpot,this.setsChildPortSpot=a.setsChildPortSpot,this.childPortSpot=a.childPortSpot)};t.A(rp,{Dm:"childrenCount"},function(){return this.children.length});t.g(rp,"relativePosition",rp.prototype.VI);t.defineProperty(rp,{VI:"relativePosition"},function(){return this.la},function(a){t.l(a,C,rp,"relativePosition");this.la.set(a)});t.g(rp,"subtreeSize",rp.prototype.iJ); -t.defineProperty(rp,{iJ:"subtreeSize"},function(){return this.Ya},function(a){t.l(a,pa,rp,"subtreeSize");this.Ya.set(a)});t.g(rp,"subtreeOffset",rp.prototype.hJ);t.defineProperty(rp,{hJ:"subtreeOffset"},function(){return this.Ma},function(a){t.l(a,C,rp,"subtreeOffset");this.Ma.set(a)});function xq(){Ea.call(this);this.Cr=new C(0,0)}t.ia("TreeEdge",xq);t.Oa(xq,Ea); -xq.prototype.commit=function(){var a=this.link;if(null!==a&&!a.Si){var b=this.network.Tb,c=null,d=null;switch(b.xf){case op:c=this.fromVertex;d=this.toVertex;break;case vp:c=this.toVertex;d=this.fromVertex;break;default:t.m("Unhandled path value "+b.xf.toString())}if(null!==c&&null!==d)if(b=this.Cr,0!==b.x||0!==b.y||c.aJ){var d=c.Mb,e=Vp(c),g=Yp(c),h=c.rowSpacing;a.updateRoute();var k=a.Ee===Rg,l=a.ac,m,n,p,q;a.xl();if(l||k){for(m=2;4q.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Zp(c))))):c.alignment===Wp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Zp(c))))):c.alignment===Wp?(e=d.left+b.x,0===b.x&&n.xq.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Zp(c))))):c.alignment===Wp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Zp(c))))):c.alignment===Wp?(e=d.left+b.x,0===b.x&&n.xl?h=null:(m=parseFloat(n.getAttribute("cx")),isNaN(m)&&(m=0),n=parseFloat(n.getAttribute("cy")),isNaN(n)&&(n=0),p=new M(Xc),p.na=0,p.oa=0,p.D=2*l,p.F=2*l,h.position=new C(m-l,n-l),h.ed=p);break;case "ellipse":p=g;h=new Y;l=parseFloat(p.getAttribute("rx"));isNaN(l)||0>l?h=null:(m=parseFloat(p.getAttribute("ry")),isNaN(m)||0>m?h=null:(n=parseFloat(p.getAttribute("cx")),isNaN(n)&&(n=0),p=parseFloat(p.getAttribute("cy")), -isNaN(p)&&(p=0),q=new M(Xc),q.na=0,q.oa=0,q.D=2*l,q.F=2*m,h.position=new C(n-l,p-m),h.ed=q));break;case "rect":q=g;h=new Y;l=parseFloat(q.getAttribute("width"));if(isNaN(l)||0>l)h=null;else if(m=parseFloat(q.getAttribute("height")),isNaN(m)||0>m)h=null;else{n=parseFloat(q.getAttribute("x"));isNaN(n)&&(n=0);p=parseFloat(q.getAttribute("y"));isNaN(p)&&(p=0);var r=q.getAttribute("rx"),s=q.getAttribute("ry"),q=parseFloat(r);if(isNaN(q)||0>q)q=0;var v=parseFloat(s);if(isNaN(v)||0>v)v=0;!r&&s?q=v:r&&!s&& -(v=q);q=Math.min(q,l/2);v=Math.min(v,m/2);s=void 0;0===q&&0===v?(s=new M(Wc),s.na=0,s.oa=0,s.D=l,s.F=m):(s=J.va/2,r=t.u(),O(r,q,0,!0),r.lineTo(l-q,0),P(r,l-q*s,0,l,v*s,l,v),r.lineTo(l,m-v),P(r,l,m-v*s,l-q*s,m,l-q,m),r.lineTo(q,m),P(r,q*s,m,0,m-v*s,0,m-v),r.lineTo(0,v),P(r,0,v*s,q*s,0,q,0),Q(r),s=r.s,t.v(r));h.position=new C(n,p);h.ed=s}break;case "polygon":h=Cq(g);break;case "polyline":h=Cq(g)}if(null!==h){if(h instanceof Y){l=zq(a,g,"fill");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+ -1,l.length-1),l=a["_brush"+l],h.fill=l instanceof ke?l:"black"):h.fill=null===l?"black":"none"===l?null:l;l=zq(a,g,"stroke");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+1,l.length-1),l=a["_brush"+l],h.stroke=l instanceof ke?l:"black"):h.stroke="none"===l?null:l;l=parseFloat(zq(a,g,"stroke-width"));isNaN(l)||(h.ib=l);l=zq(a,g,"stroke-linecap");null!==l&&(h.HF=l);if(l=zq(a,g,"stroke-dasharray")){m=l.split(",");n=[];for(l=0;lg.length)return null;for(var h,d=new H(S),k,l,m=1;m=la||(e%=10,a.fillStyle="blue",a.fillText(e.toString(),g,h+b.kd))}}}},RH:function(a){if(a instanceof u)for(a=a.Um;a.next();){var b=a.value;t.trace(b.toString());for(b=b.sl;b.next();)f.RH(b.value)}else if(a instanceof +w){t.trace("References for "+a);a.layer&&t.trace(" "+a.layer.toString()+' LayerName: "'+a.Xd+'"');a.bn!==a&&t.trace(" SelectionObject: "+a.bn.toString()+' SelectionObjectName: "'+a.vt+'"');a.Ub!==a&&t.trace(" LocationObject: "+a.Ub.toString()+' LocationObjectName: "'+a.Zs+'"');if(a.Cg){for(var c="",b=a.Cg.k;b.next();)c+=b.key+" ";t.trace(" Adornments: "+c)}a.fb&&t.trace(" ContainingGroup: "+a.fb.toString());if(a instanceof y){if(a.yd)for(b=a.yd.k;b.next(););if(0=a.length?a.push(c):a.splice(b,0,c):t.m("Cannot insert an object into an HTMLCollection or NodeList: "+c+" at "+b)},Fi:function(a,b){t.qc&&t.qc(a)&&(a=a());Array.isArray(a)?b>=a.length?a.pop():a.splice(b,1):t.m("Cannot remove an object from an HTMLCollection or NodeList at "+b)},xx:[],O:function(){var a=t.xx.pop();return void 0===a?new C:a},ic:function(a,b){var c=t.xx.pop();if(void 0===c)return new C(a,b);c.x=a;c.y=b;return c},B:function(a){t.xx.push(a)}, +AB:[],yl:function(){var a=t.AB.pop();return void 0===a?new pa:a},dk:function(a){t.AB.push(a)},yx:[],wf:function(){var a=t.yx.pop();return void 0===a?new D:a},lk:function(a,b,c,d){var e=t.yx.pop();if(void 0===e)return new D(a,b,c,d);e.x=a;e.y=b;e.width=c;e.height=d;return e},Pc:function(a){t.yx.push(a)},BB:[],bh:function(){var a=t.BB.pop();return void 0===a?new qa:a},Se:function(a){t.BB.push(a)},zx:null,u:function(){var a=t.zx;return null!==a?(t.zx=null,a):new ra},v:function(a){a.reset();t.zx=a},zB:[], +Cb:function(){var a=t.zB.pop();return void 0===a?[]:a},Da:function(a){a.length=0;t.zB.push(a)},CB:1,zc:function(a){a.__gohashid=t.CB++},Os:function(a){var b=a.__gohashid;void 0===b&&(b=t.CB++,a.__gohashid=b);return b},oc:function(a){return a.__gohashid},g:function(a,b,c){"name"!==b&&"length"!==b&&(a[b]=c)},ia:function(a,b){b.Gx=a;ba[a]=b},Oa:function(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a},Fh:function(a){a.EG=!0},defineProperty:function(a,b,c,d,e){t.j(a, +"function","Util.defineProperty:classfunc");t.j(b,"object","Util.defineProperty:propobj");t.j(c,"function","Util.defineProperty:getter");t.j(d,"function","Util.defineProperty:setter");for(var g in b){var h=b[g];b={get:c,set:d};if(void 0!==e)for(var k in e)b[k]=e[k];Object.defineProperty(a.prototype,g,b);e=Object.getOwnPropertyDescriptor(a.prototype,g);h&&e&&Object.defineProperty(a.prototype,h,e);if(f&&h){var l=h.charAt(0).toUpperCase()+h.slice(1);h==l&&t.m('Defining capitalized property "'+l+'"!?'); +Object.defineProperty(a.prototype,l,{get:function(){t.m('Getting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')},set:function(){t.m('Setting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')}})}break}},A:function(a,b,c,d){t.j(a,"function","Util.defineReadOnlyProperty:classfunc");t.j(b,"object","Util.defineReadOnlyProperty:propobj");t.j(c,"function","Util.defineReadOnlyProperty:getter");for(var e in b){var g= +b[e];b={get:c,set:function(a){t.m('The property "'+g+'" is read-only and cannot be set to '+a)}};if(void 0!==d)for(var h in d)b[h]=d[h];Object.defineProperty(a.prototype,e,b);d=Object.getOwnPropertyDescriptor(a.prototype,e);g&&d&&Object.defineProperty(a.prototype,g,d);if(f&&g){var k=g.charAt(0).toUpperCase()+g.slice(1);Object.defineProperty(a.prototype,k,{get:function(){t.m('Getting the property "'+k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'"')},set:function(){t.m('Setting the read-only property "'+ +k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'", and cannot be set anyway')}})}break}},je:function(a,b){for(var c in b)b[c]=!0;a.prototype.EC=b},Hh:function(a){return void 0===a?"":"string"===typeof a?a:"function"===typeof a?t.Ug(a):null===a?"*":""},Ug:function(a){if("function"===typeof a){if(a.Gx)return a.Gx;if(a.name)return a.name;var b=a.toString(),c=b.indexOf("(");if(b=b.substring(9,c).trim())return a.Gx=b}else if("object"===typeof a&&a.constructor)return t.Ug(a.constructor); +return typeof a},w:function(a,b,c){t.j(a,"function","Util.defineEnumValue:classfunc");t.j(b,"string","Util.defineEnumValue:name");t.j(c,"number","Util.defineEnumValue:num");c=new oa(a,b,c);Object.freeze(c);a[b]=c;var d=a.Jt;d||(d=new sa("string",oa),a.Jt=d);d.add(b,c);return c},Lm:function(a,b){if(!b)return null;t.j(a,"function","Util.findEnumValueForName:classfunc");t.j(b,"string","Util.findEnumValueForName:name");var c=a.Jt;return c?c.Ba(b):null},qH:function(a,b,c,d){var e={},g;for(g in a){for(var h= +!1,k=1;k=d.length)){var e=t.hb(b,d);null===e||"function"===typeof e||t.mw(b,d)||(""===c&&(c=b+"\n"),c+=' unknown property "'+d+'" has value: '+e+" at "+a+"\n")}return c},Ov:function(a,b){if(b&&"number"!==typeof b&&"string"!==typeof b&&"boolean"!==typeof b&&"function"!==typeof b)if(void 0!==t.oc(b)){if(!t.jv.contains(b))if(t.jv.add(b), +t.Ku.add(t.nD(a,b)),b instanceof H||b instanceof ua||b instanceof sa)for(var c=b.k;c.next();)t.Ov(a+"["+c.key+"]",c.value);else for(c in b){var d=t.hb(b,c);if(void 0!==d&&null!==d&&t.pb(d)&&d!==b.EC){if(b instanceof wa){if(d===b.Zn)continue}else if(b instanceof B){if("data"===c||d===b.Ll)continue;if("itemArray"===c||d===b.sj)continue;if(b instanceof w&&d===b.Aj)continue}else if(!(b instanceof u))if(b instanceof xa){if("archetypeGroupData"===c||d===b.Cx)continue}else if(b instanceof Aa){if("archetypeLinkData"=== +c||d===b.Vt)continue;if("archetypeLabelNodeData"===c||d===b.Ut)continue}else if(b instanceof Ba){if("archetypeNodeData"===c||d===b.bj)continue}else if(b instanceof I){if("nodeDataArray"===c||d===b.Ke)continue;if("linkDataArray"===c||d===b.Mg||d===b.Zl)continue;if(d===b.uc)continue;if(d===b.Uf)continue}else if(b instanceof Ca||b instanceof Da||b instanceof Ea)continue;t.Ov(a+"."+c,d)}}}else if(Array.isArray(b))for(c=0;cc;c++)b[c]=c;for(var d=0,e,c=0;256>c;c++)d=(d+b[c]+119)%256,e=b[c],b[c]=b[d],b[d]=e;for(var d=c=0,g="",h=0;hc;c++)b["0123456789abcdef".charAt(c>>4)+"0123456789abcdef".charAt(c&15)]=String.fromCharCode(c); +a.length%2&&(a="0"+a);for(var d=[],e=0,c=0;cd;d++)b[t.Qa("7ca11abfd7330390")](t.Qa(c[d-1]),10,15*d+0);b[t.Qa("7ca11abfd022028846")]=t.Qa("39f046ebb36e4b");for(d=1;5>d;d++)b[t.Qa("7ca11abfd7330390")](t.Qa(c[d- +1]),10,15*d+0);if(4!==c.length||"5"!==c[0][0]||"7"!==c[3][0])t.w=function(a,b){var c=new oa(a,b,2);Object.freeze(c);a[b]=c;var d=a.Jt;d||(d=new sa("string",oa),a.Jt=d);d.add(b,c);return c};return a}();function oa(a,b,c){t.zc(this);this.GB=a;this.Rb=b;this.JG=c}oa.prototype.toString=function(){return t.Ug(this.GB)+"."+this.Rb};t.A(oa,{Pe:"classType"},function(){return this.GB});t.A(oa,{name:"name"},function(){return this.Rb});t.A(oa,{value:"value"},function(){return this.JG}); +function Fa(){this.FB=[]}Fa.prototype.toString=function(){return this.FB.join("")};Fa.prototype.add=function(a){a&&this.FB.push(a)};function Ia(){}t.A(Ia,{k:"iterator"},function(){return this});Ia.prototype.reset=Ia.prototype.reset=function(){};Ia.prototype.next=Ia.prototype.hasNext=Ia.prototype.next=function(){return!1};Ia.prototype.first=Ia.prototype.eb=function(){return null};t.A(Ia,{count:"count"},function(){return 0});Ia.prototype.Gg=function(){};Ia.prototype.toString=function(){return"EmptyIterator"}; +t.dh=new Ia;function La(a){this.key=-1;this.value=a}t.je(La,{key:!0,value:!0});t.A(La,{k:"iterator"},function(){return this});La.prototype.reset=La.prototype.reset=function(){this.key=-1};La.prototype.next=La.prototype.hasNext=La.prototype.next=function(){return-1===this.key?(this.key=0,!0):!1};La.prototype.first=La.prototype.eb=function(){this.key=0;return this.value};t.A(La,{count:"count"},function(){return 1});La.prototype.Gg=function(){this.value=null}; +La.prototype.toString=function(){return"SingletonIterator("+this.value+")"};function Ma(a){this.zf=a;this.io=null;this.reset()}t.je(Ma,{key:!0,value:!0});t.A(Ma,{k:"iterator"},function(){return this});t.g(Ma,"predicate",Ma.prototype.tl);t.defineProperty(Ma,{tl:"predicate"},function(){return this.io},function(a){this.io=a});Ma.prototype.reset=Ma.prototype.reset=function(){var a=this.zf;a.qh=null;this.kb=a.Wb;this.te=-1}; +Ma.prototype.next=Ma.prototype.hasNext=Ma.prototype.next=function(){var a=this.zf;a.Wb!==this.kb&&t.m("the List has been modified during iteration");var a=a.p,b=a.length,c=++this.te,d=this.io;if(null!==d)for(;ca||a>=b.length)&&t.ha(a,"0 <= i < length",H,"elt:i");return b[a]}; +H.prototype.setElt=H.prototype.set=H.prototype.xg=function(a,b){f&&(this.Dg(b),t.o(a,H,"setElt:i"));var c=this.p;(0>a||a>=c.length)&&t.ha(a,"0 <= i < length",H,"setElt:i");t.J(this,a);c[a]=b};H.prototype.first=H.prototype.eb=function(){var a=this.p;return 0===a.length?null:a[0]};H.prototype.insertAt=H.prototype.Ad=function(a,b){f&&(this.Dg(b),t.o(a,H,"insertAt:i"));0>a&&t.ha(a,">= 0",H,"insertAt:i");t.J(this,a);var c=this.p;a>=c.length?c.push(b):c.splice(a,0,b);this.Nd();return!0}; +H.prototype.remove=H.prototype["delete"]=H.prototype.remove=function(a){if(null===a)return!1;f&&this.Dg(a);t.J(this,a);var b=this.p;a=b.indexOf(a);if(-1===a)return!1;a===b.length-1?b.pop():b.splice(a,1);this.Nd();return!0};H.prototype.removeAt=H.prototype.gd=function(a){f&&t.o(a,H,"removeAt:i");var b=this.p;(0>a||a>=b.length)&&t.ha(a,"0 <= i < length",H,"removeAt:i");t.J(this,a);a===b.length-1?b.pop():b.splice(a,1);this.Nd()}; +H.prototype.removeRange=H.prototype.removeRange=function(a,b){f&&(t.o(a,H,"removeRange:from"),t.o(b,H,"removeRange:to"));var c=this.p;(0>a||a>=c.length)&&t.ha(a,"0 <= from < length",H,"elt:from");(0>b||b>=c.length)&&t.ha(b,"0 <= to < length",H,"elt:to");t.J(this,a);var d=c.slice((b||a)+1||c.length);c.length=0>a?c.length+a:a;c.push.apply(c,d);this.Nd()};H.prototype.copy=function(){for(var a=new H(this.ba),b=this.p,c=this.count,d=0;d=g)return this;(0>b||b>=e-1)&&t.ha(b,"0 <= from < length",H,"sortRange:from");if(2===g)return c=d[b],e=d[b+1],0=e)d.sort(a);else for(g=d.slice(0,c),g.sort(a),a=0;a=e)for(g=d.slice(b),g.sort(a), +a=b;a=this.p.length)return t.dh;var a=this.qh;return null!==a?(a.reset(),a):new Ma(this)}); +t.A(H,{Sm:"iteratorBackwards"},function(){if(0>=this.p.length)return t.dh;var a=this.Cy;return null!==a?(a.reset(),a):new Oa(this)});function Pa(a){this.q=a;this.reset()}t.je(Pa,{key:!0,value:!0});t.A(Pa,{k:"iterator"},function(){return this});Pa.prototype.reset=Pa.prototype.reset=function(){var a=this.q;a.qh=null;this.kb=a.Wb;this.ce=null}; +Pa.prototype.next=Pa.prototype.hasNext=Pa.prototype.next=function(){var a=this.q;a.Wb!==this.kb&&t.m("the Set has been modified during iteration");var b=this.ce,b=null===b?a.se:b.Bj;if(null!==b)return this.ce=b,this.value=b.value,this.key=b.key,!0;this.Gg();return!1};Pa.prototype.first=Pa.prototype.eb=function(){var a=this.q;this.kb=a.Wb;a=a.se;if(null!==a){this.ce=a;var b=a.value;this.key=a.key;return this.value=b}return null};t.A(Pa,{count:"count"},function(){return this.q.ld}); +Pa.prototype.Gg=function(){this.value=null;this.kb=-1;this.q.qh=this};Pa.prototype.toString=function(){return null!==this.ce?"SetIterator@"+this.ce.value:"SetIterator"}; +function ua(a){t.zc(this);this.jb=!1;void 0===a||null===a?this.ba=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.ba=a:t.ha(a,"the string 'object', 'number' or 'string'","Set constructor: type"):"function"===typeof a?this.ba=a===Object?"object":a===String?"string":a===Number?"number":a:t.ha(a,"null, a primitive type name, or a class type","Set constructor: type");this.Wc={};this.ld=0;this.qh=null;this.Wb=0;this.sh=this.se=null}t.ia("Set",ua); +ua.prototype.Dg=function(a){null!==this.ba&&("string"===typeof this.ba?typeof a===this.ba&&null!==a||t.Vb(a,this.ba):a instanceof this.ba||t.Vb(a,this.ba))};ua.prototype.Nd=function(){var a=this.Wb;a++;999999999=this.ld)return t.dh;var a=this.qh;return null!==a?(a.reset(),a):new Pa(this)});function Ra(a){this.Cc=a;this.reset()}t.je(Ra,{key:!0,value:!0});t.A(Ra,{k:"iterator"},function(){return this});Ra.prototype.reset=Ra.prototype.reset=function(){this.kb=this.Cc.Wb;this.ce=null}; +Ra.prototype.next=Ra.prototype.hasNext=Ra.prototype.next=function(){var a=this.Cc;a.Wb!==this.kb&&t.m("the Map has been modified during iteration");var b=this.ce,b=null===b?a.se:b.Bj;if(null!==b)return this.ce=b,this.value=this.key=a=b.key,!0;this.Gg();return!1};Ra.prototype.first=Ra.prototype.eb=function(){var a=this.Cc;this.kb=a.Wb;a=a.se;return null!==a?(this.ce=a,this.value=this.key=a=a.key):null};t.A(Ra,{count:"count"},function(){return this.Cc.ld}); +Ra.prototype.Gg=function(){this.value=null;this.kb=-1};Ra.prototype.toString=function(){return null!==this.ce?"MapKeySetIterator@"+this.ce.value:"MapKeySetIterator"};function Sa(a){t.zc(this);this.jb=!0;this.Cc=a}t.Oa(Sa,ua);Sa.prototype.freeze=function(){return this};Sa.prototype.Ua=function(){return this};Sa.prototype.toString=function(){return"MapKeySet("+this.Cc.toString()+")"};Sa.prototype.add=Sa.prototype.set=Sa.prototype.add=function(){t.m("This Set is read-only: "+this.toString());return!1}; +Sa.prototype.contains=Sa.prototype.has=Sa.prototype.contains=function(a){return this.Cc.contains(a)};Sa.prototype.remove=Sa.prototype["delete"]=Sa.prototype.remove=function(){t.m("This Set is read-only: "+this.toString());return!1};Sa.prototype.clear=Sa.prototype.clear=function(){t.m("This Set is read-only: "+this.toString())};Sa.prototype.first=Sa.prototype.eb=function(){var a=this.Cc.se;return null!==a?a.key:null};Sa.prototype.copy=function(){return new Sa(this.Cc)}; +Sa.prototype.toSet=function(){var a=new ua(this.Cc.rh),b=this.Cc.Wc,c;for(c in b)a.add(b[c].key);return a};Sa.prototype.toArray=Sa.prototype.af=function(){var a=this.Cc.Wc,b=Array(this.Cc.ld),c=0,d;for(d in a)b[c]=a[d].key,c++;return b};Sa.prototype.toList=function(){var a=new H(this.ba),b=this.Cc.Wc,c;for(c in b)a.add(b[c].key);return a};t.A(Sa,{count:"count"},function(){return this.Cc.ld});t.A(Sa,{size:"size"},function(){return this.Cc.ld}); +t.A(Sa,{k:"iterator"},function(){return 0>=this.Cc.ld?t.dh:new Ra(this.Cc)});function Qa(a,b){this.key=a;this.value=b;this.jo=this.Bj=null}t.je(Qa,{key:!0,value:!0});Qa.prototype.toString=function(){return"{"+this.key+":"+this.value+"}"};function Ua(a){this.Cc=a;this.reset()}t.je(Ua,{key:!0,value:!0});t.A(Ua,{k:"iterator"},function(){return this});Ua.prototype.reset=Ua.prototype.reset=function(){var a=this.Cc;a.qh=null;this.kb=a.Wb;this.ce=null}; +Ua.prototype.next=Ua.prototype.hasNext=Ua.prototype.next=function(){var a=this.Cc;a.Wb!==this.kb&&t.m("the Map has been modified during iteration");var b=this.ce,b=null===b?a.se:b.Bj;if(null!==b)return this.ce=b,this.key=b.key,this.value=b.value,!0;this.Gg();return!1};Ua.prototype.first=Ua.prototype.eb=function(){var a=this.Cc;this.kb=a.Wb;a=a.se;if(null!==a){this.ce=a;var b=a.key;this.key=b;this.value=a.value;return b}return null};t.A(Ua,{count:"count"},function(){return this.Cc.ld}); +Ua.prototype.Gg=function(){this.value=this.key=null;this.kb=-1;this.Cc.qh=this};Ua.prototype.toString=function(){return null!==this.ce?"MapIterator@"+this.ce:"MapIterator"}; +function sa(a,b){t.zc(this);this.jb=!1;void 0===a||null===a?this.rh=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.rh=a:t.ha(a,"the string 'object', 'number' or 'string'","Map constructor: keytype"):"function"===typeof a?this.rh=a===Object?"object":a===String?"string":a===Number?"number":a:t.ha(a,"null, a primitive type name, or a class type","Map constructor: keytype");void 0===b||null===b?this.Ci=null:"string"===typeof b?"object"===b||"string"===b||"boolean"===b||"number"=== +b||"function"===b?this.Ci=b:t.ha(b,"the string 'object', 'number', 'string', 'boolean', or 'function'","Map constructor: valtype"):"function"===typeof b?this.Ci=b===Object?"object":b===String?"string":b===Number?"number":b===Boolean?"boolean":b===Function?"function":b:t.ha(b,"null, a primitive type name, or a class type","Map constructor: valtype");this.Wc={};this.ld=0;this.qh=null;this.Wb=0;this.sh=this.se=null}t.ia("Map",sa); +function Va(a,b){null!==a.rh&&("string"===typeof a.rh?typeof b===a.rh&&null!==b||t.Vb(b,a.rh):b instanceof a.rh||t.Vb(b,a.rh))}sa.prototype.Nd=function(){var a=this.Wb;a++;999999999=this.count)return t.dh;var a=this.qh;return null!==a?(a.reset(),a):new Ua(this)});function C(a,b){void 0===a?this.M=this.L=0:"number"===typeof a&&"number"===typeof b?(this.L=a,this.M=b):t.m("Invalid arguments to Point constructor")}t.ia("Point",C);t.Fh(C);t.je(C,{x:!0,y:!0});C.prototype.assign=function(a){this.L=a.L;this.M=a.M};C.prototype.q=function(a,b){this.L=a;this.M=b}; +C.prototype.setTo=C.prototype.Fp=function(a,b){f&&(t.j(a,"number",C,"setTo:x"),t.j(b,"number",C,"setTo:y"));t.J(this);this.L=a;this.M=b;return this};C.prototype.set=C.prototype.set=function(a){f&&t.l(a,C,C,"set:p");t.J(this);this.L=a.L;this.M=a.M;return this};C.prototype.copy=function(){var a=new C;a.L=this.L;a.M=this.M;return a};C.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};C.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; +C.prototype.freeze=function(){this.jb=!0;return this};C.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this};C.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new C(c,e)}return new C};C.stringify=function(a){return a instanceof C?a.x.toString()+" "+a.y.toString():a.toString()}; +C.prototype.toString=function(){return"Point("+this.x+","+this.y+")"};C.prototype.equals=C.prototype.N=function(a){return a instanceof C?this.L===a.x&&this.M===a.y:!1};C.prototype.equalTo=function(a,b){return this.L===a&&this.M===b};C.prototype.bk=function(a){return J.Ka(this.L,a.x)&&J.Ka(this.M,a.y)};C.prototype.Oi=function(a){return J.I(this.L,a.x)&&J.I(this.M,a.y)};C.prototype.add=C.prototype.add=function(a){f&&t.l(a,C,C,"add:p");t.J(this);this.L+=a.x;this.M+=a.y;return this}; +C.prototype.subtract=C.prototype.At=function(a){f&&t.l(a,C,C,"subtract:p");t.J(this);this.L-=a.x;this.M-=a.y;return this};C.prototype.offset=C.prototype.offset=function(a,b){f&&(t.o(a,C,"offset:dx"),t.o(b,C,"offset:dy"));t.J(this);this.L+=a;this.M+=b;return this}; +C.prototype.rotate=C.prototype.rotate=function(a){f&&t.o(a,C,"rotate:angle");t.J(this);if(0===a)return this;var b=this.L,c=this.M;if(0===b&&0===c)return this;var d;90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));this.L=a*b-d*c;this.M=d*b+a*c;return this};C.prototype.scale=C.prototype.scale=function(a,b){f&&(t.o(a,C,"scale:sx"),t.o(b,C,"scale:sy"));this.L*=a;this.M*=b;return this}; +C.prototype.distanceSquaredPoint=C.prototype.$j=function(a){f&&t.l(a,C,C,"distanceSquaredPoint:p");var b=a.x-this.L;a=a.y-this.M;return b*b+a*a};C.prototype.distanceSquared=C.prototype.Fs=function(a,b){f&&(t.o(a,C,"distanceSquared:px"),t.o(b,C,"distanceSquared:py"));var c=a-this.L,d=b-this.M;return c*c+d*d};C.prototype.normalize=C.prototype.normalize=function(){t.J(this);var a=this.L,b=this.M,c=Math.sqrt(a*a+b*b);0b?270:0;if(0===b)return 0a?c=0>b?c+180:180-c:0>b&&(c=360-c);return c} +C.prototype.projectOntoLineSegment=function(a,b,c,d){f&&(t.o(a,C,"projectOntoLineSegment:px"),t.o(b,C,"projectOntoLineSegment:py"),t.o(c,C,"projectOntoLineSegment:qx"),t.o(d,C,"projectOntoLineSegment:qy"));J.Zm(a,b,c,d,this.L,this.M,this);return this};C.prototype.projectOntoLineSegmentPoint=function(a,b){f&&(t.l(a,C,C,"projectOntoLineSegmentPoint:p"),t.l(b,C,C,"projectOntoLineSegmentPoint:q"));J.Zm(a.x,a.y,b.x,b.y,this.L,this.M,this);return this}; +C.prototype.snapToGrid=function(a,b,c,d){f&&(t.o(a,C,"snapToGrid:originx"),t.o(b,C,"snapToGrid:originy"),t.o(c,C,"snapToGrid:cellwidth"),t.o(d,C,"snapToGrid:cellheight"));J.Hs(this.L,this.M,a,b,c,d,this);return this};C.prototype.snapToGridPoint=function(a,b){f&&(t.l(a,C,C,"snapToGridPoint:p"),t.l(b,pa,C,"snapToGridPoint:q"));J.Hs(this.L,this.M,a.x,a.y,b.width,b.height,this);return this}; +C.prototype.setRectSpot=C.prototype.wt=function(a,b){f&&(t.l(a,D,C,"setRectSpot:r"),t.l(b,K,C,"setRectSpot:spot"));t.J(this);this.L=a.x+b.x*a.width+b.offsetX;this.M=a.y+b.y*a.height+b.offsetY;return this}; +C.prototype.setSpot=C.prototype.xt=function(a,b,c,d,e){f&&(t.o(a,C,"setSpot:x"),t.o(b,C,"setSpot:y"),t.o(c,C,"setSpot:w"),t.o(d,C,"setSpot:h"),(0>c||0>d)&&t.m("Point.setSpot:Width and height cannot be negative"),t.l(e,K,C,"setSpot:spot"));t.J(this);this.L=a+e.x*c+e.offsetX;this.M=b+e.y*d+e.offsetY;return this};C.prototype.transform=function(a){f&&t.l(a,qa,C,"transform:t");a.Va(this);return this};function $a(a,b){f&&t.l(b,qa,C,"transformInverted:t");b.Ri(a);return a}var cb; +C.distanceLineSegmentSquared=cb=function(a,b,c,d,e,g){f&&(t.o(a,C,"distanceLineSegmentSquared:px"),t.o(b,C,"distanceLineSegmentSquared:py"),t.o(c,C,"distanceLineSegmentSquared:ax"),t.o(d,C,"distanceLineSegmentSquared:ay"),t.o(e,C,"distanceLineSegmentSquared:bx"),t.o(g,C,"distanceLineSegmentSquared:by"));var h=e-c,k=g-d,l=h*h+k*k;c-=a;d-=b;var m=-c*h-d*k;if(0>=m||m>=l)return h=e-a,k=g-b,Math.min(c*c+d*d,h*h+k*k);a=h*d-k*c;return a*a/l};var eb; +C.distanceSquared=eb=function(a,b,c,d){f&&(t.o(a,C,"distanceSquared:px"),t.o(b,C,"distanceSquared:py"),t.o(c,C,"distanceSquared:qx"),t.o(d,C,"distanceSquared:qy"));a=c-a;b=d-b;return a*a+b*b};var kb; +C.direction=kb=function(a,b,c,d){f&&(t.o(a,C,"direction:px"),t.o(b,C,"direction:py"),t.o(c,C,"direction:qx"),t.o(d,C,"direction:qy"));a=c-a;b=d-b;if(0===a)return 0b?270:0;if(0===b)return 0a?d=0>b?d+180:180-d:0>b&&(d=360-d);return d};t.g(C,"x",C.prototype.x);t.defineProperty(C,{x:"x"},function(){return this.L},function(a){t.J(this,a);f&&t.j(a,"number",C,"x");this.L=a});t.g(C,"y",C.prototype.y); +t.defineProperty(C,{y:"y"},function(){return this.M},function(a){t.J(this,a);f&&t.j(a,"number",C,"y");this.M=a});C.prototype.isReal=C.prototype.Q=function(){return isFinite(this.x)&&isFinite(this.y)};function pa(a,b){void 0===a?this.xa=this.ya=0:"number"===typeof a&&(0<=a||isNaN(a))&&"number"===typeof b&&(0<=b||isNaN(b))?(this.ya=a,this.xa=b):t.m("Invalid arguments to Size constructor")}t.ia("Size",pa);t.Fh(pa);t.je(pa,{width:!0,height:!0});pa.prototype.assign=function(a){this.ya=a.ya;this.xa=a.xa}; +pa.prototype.q=function(a,b){this.ya=a;this.xa=b};pa.prototype.setTo=pa.prototype.Fp=function(a,b){f&&(t.j(a,"number",pa,"setTo:w"),t.j(b,"number",pa,"setTo:h"));0>a&&t.ha(a,">= 0",pa,"setTo:w");0>b&&t.ha(b,">= 0",pa,"setTo:h");t.J(this);this.ya=a;this.xa=b;return this};pa.prototype.set=pa.prototype.set=function(a){f&&t.l(a,pa,pa,"set:s");t.J(this);this.ya=a.ya;this.xa=a.xa;return this};pa.prototype.copy=function(){var a=new pa;a.ya=this.ya;a.xa=this.xa;return a}; +pa.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};pa.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()};pa.prototype.freeze=function(){this.jb=!0;return this};pa.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this}; +pa.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new pa(c,e)}return new pa};pa.stringify=function(a){return a instanceof pa?a.width.toString()+" "+a.height.toString():a.toString()};pa.prototype.toString=function(){return"Size("+this.width+","+this.height+")"}; +pa.prototype.equals=pa.prototype.N=function(a){return a instanceof pa?this.ya===a.width&&this.xa===a.height:!1};pa.prototype.equalTo=function(a,b){return this.ya===a&&this.xa===b};pa.prototype.bk=function(a){return J.Ka(this.ya,a.width)&&J.Ka(this.xa,a.height)};pa.prototype.Oi=function(a){return J.I(this.ya,a.width)&&J.I(this.xa,a.height)};t.g(pa,"width",pa.prototype.width); +t.defineProperty(pa,{width:"width"},function(){return this.ya},function(a){t.J(this,a);f&&t.j(a,"number",pa,"width");0>a&&t.ha(a,">= 0",pa,"width");this.ya=a});t.g(pa,"height",pa.prototype.height);t.defineProperty(pa,{height:"height"},function(){return this.xa},function(a){t.J(this,a);f&&t.j(a,"number",pa,"height");0>a&&t.ha(a,">= 0",pa,"height");this.xa=a});pa.prototype.isReal=pa.prototype.Q=function(){return isFinite(this.width)&&isFinite(this.height)}; +function D(a,b,c,d){void 0===a?this.xa=this.ya=this.M=this.L=0:a instanceof C?b instanceof C?(this.L=Math.min(a.L,b.L),this.M=Math.min(a.M,b.M),this.ya=Math.abs(a.L-b.L),this.xa=Math.abs(a.M-b.M)):b instanceof pa?(this.L=a.L,this.M=a.M,this.ya=b.ya,this.xa=b.xa):t.m("Incorrect arguments supplied"):"number"===typeof a&&"number"===typeof b&&"number"===typeof c&&(0<=c||isNaN(c))&&"number"===typeof d&&(0<=d||isNaN(d))?(this.L=a,this.M=b,this.ya=c,this.xa=d):t.m("Invalid arguments to Rect constructor")} +t.ia("Rect",D);t.Fh(D);t.je(D,{x:!0,y:!0,width:!0,height:!0});D.prototype.assign=function(a){this.L=a.L;this.M=a.M;this.ya=a.ya;this.xa=a.xa};D.prototype.q=function(a,b,c,d){this.L=a;this.M=b;this.ya=c;this.xa=d};function nb(a,b,c){a.ya=b;a.xa=c} +D.prototype.setTo=D.prototype.Fp=function(a,b,c,d){f&&(t.j(a,"number",D,"setTo:x"),t.j(b,"number",D,"setTo:y"),t.j(c,"number",D,"setTo:w"),t.j(d,"number",D,"setTo:h"));0>c&&t.ha(c,">= 0",D,"setTo:w");0>d&&t.ha(d,">= 0",D,"setTo:h");t.J(this);this.L=a;this.M=b;this.ya=c;this.xa=d;return this};D.prototype.set=D.prototype.set=function(a){f&&t.l(a,D,D,"set:r");t.J(this);this.L=a.L;this.M=a.M;this.ya=a.ya;this.xa=a.xa;return this}; +D.prototype.setPoint=D.prototype.uf=function(a){f&&t.l(a,C,D,"setPoint:p");t.J(this);this.L=a.L;this.M=a.M;return this};D.prototype.setSize=function(a){f&&t.l(a,pa,D,"setSize:s");t.J(this);this.ya=a.ya;this.xa=a.xa;return this};D.prototype.copy=function(){var a=new D;a.L=this.L;a.M=this.M;a.ya=this.ya;a.xa=this.xa;return a};D.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};D.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; +D.prototype.freeze=function(){this.jb=!0;return this};D.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this};D.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new D(c,e,g,h)}return new D}; +D.stringify=function(a){return a instanceof D?a.x.toString()+" "+a.y.toString()+" "+a.width.toString()+" "+a.height.toString():a.toString()};D.prototype.toString=function(){return"Rect("+this.x+","+this.y+","+this.width+","+this.height+")"};D.prototype.equals=D.prototype.N=function(a){return a instanceof D?this.L===a.x&&this.M===a.y&&this.ya===a.width&&this.xa===a.height:!1};D.prototype.equalTo=function(a,b,c,d){return this.L===a&&this.M===b&&this.ya===c&&this.xa===d}; +D.prototype.bk=function(a){return J.Ka(this.L,a.x)&&J.Ka(this.M,a.y)&&J.Ka(this.ya,a.width)&&J.Ka(this.xa,a.height)};D.prototype.Oi=function(a){return J.I(this.L,a.x)&&J.I(this.M,a.y)&&J.I(this.ya,a.width)&&J.I(this.xa,a.height)};D.prototype.containsPoint=D.prototype.Ia=function(a){f&&t.l(a,C,D,"containsPoint:p");return this.L<=a.x&&this.L+this.ya>=a.x&&this.M<=a.y&&this.M+this.xa>=a.y}; +D.prototype.containsRect=D.prototype.Wj=function(a){f&&t.l(a,D,D,"containsRect:r");return this.L<=a.x&&a.x+a.width<=this.L+this.ya&&this.M<=a.y&&a.y+a.height<=this.M+this.xa}; +D.prototype.contains=D.prototype.contains=function(a,b,c,d){f?(t.o(a,D,"contains:x"),t.o(b,D,"contains:y"),void 0===c?c=0:t.o(c,D,"contains:w"),void 0===d?d=0:t.o(d,D,"contains:h"),(0>c||0>d)&&t.m("Rect.contains:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return this.L<=a&&a+c<=this.L+this.ya&&this.M<=b&&b+d<=this.M+this.xa};D.prototype.reset=function(){t.J(this);this.xa=this.ya=this.M=this.L=0}; +D.prototype.offset=D.prototype.offset=function(a,b){f&&(t.o(a,D,"offset:dx"),t.o(b,D,"offset:dy"));t.J(this);this.L+=a;this.M+=b;return this};D.prototype.inflate=D.prototype.Vg=function(a,b){f&&(t.o(a,D,"inflate:w"),t.o(b,D,"inflate:h"));return ob(this,b,a,b,a)};D.prototype.addMargin=D.prototype.Ev=function(a){f&&t.l(a,pb,D,"addMargin:m");return ob(this,a.top,a.right,a.bottom,a.left)}; +D.prototype.subtractMargin=D.prototype.gJ=function(a){f&&t.l(a,pb,D,"subtractMargin:m");return ob(this,-a.top,-a.right,-a.bottom,-a.left)};D.prototype.grow=function(a,b,c,d){f&&(t.o(a,D,"grow:t"),t.o(b,D,"grow:r"),t.o(c,D,"grow:b"),t.o(d,D,"grow:l"));return ob(this,a,b,c,d)};function ob(a,b,c,d,e){t.J(a);var g=a.ya;c+e<=-g?(a.L+=g/2,a.ya=0):(a.L-=e,a.ya+=c+e);c=a.xa;b+d<=-c?(a.M+=c/2,a.xa=0):(a.M-=b,a.xa+=b+d);return a} +D.prototype.intersectRect=function(a){f&&t.l(a,D,D,"intersectRect:r");return ub(this,a.x,a.y,a.width,a.height)};D.prototype.intersect=function(a,b,c,d){f&&(t.o(a,D,"intersect:x"),t.o(b,D,"intersect:y"),t.o(c,D,"intersect:w"),t.o(d,D,"intersect:h"),(0>c||0>d)&&t.m("Rect.intersect:Width and height cannot be negative"));return ub(this,a,b,c,d)}; +function ub(a,b,c,d,e){t.J(a);var g=Math.max(a.L,b),h=Math.max(a.M,c);b=Math.min(a.L+a.ya,b+d);c=Math.min(a.M+a.xa,c+e);a.L=g;a.M=h;a.ya=Math.max(0,b-g);a.xa=Math.max(0,c-h);return a}D.prototype.intersectsRect=D.prototype.If=function(a){f&&t.l(a,D,D,"intersectsRect:r");return this.wE(a.x,a.y,a.width,a.height)}; +D.prototype.intersects=D.prototype.wE=function(a,b,c,d){f&&(t.o(a,D,"intersects:x"),t.o(b,D,"intersects:y"),t.o(a,D,"intersects:w"),t.o(b,D,"intersects:h"),(0>c||0>d)&&t.m("Rect.intersects:Width and height cannot be negative"));var e=this.ya,g=this.L;if(Infinity!==e&&Infinity!==c&&(e+=g,c+=a,isNaN(c)||isNaN(e)||g>c||a>e))return!1;a=this.xa;c=this.M;return Infinity!==a&&Infinity!==d&&(a+=c,d+=b,isNaN(d)||isNaN(a)||c>d||b>a)?!1:!0}; +function vb(a,b){var c=a.ya,d=b.width+10+10,e=a.L,g=b.x-10;if(e>d+g||g>c+e)return!1;c=a.xa;d=b.height+10+10;e=a.M;g=b.y-10;return e>d+g||g>c+e?!1:!0}D.prototype.unionPoint=D.prototype.$i=function(a){f&&t.l(a,C,D,"unionPoint:p");return wb(this,a.x,a.y,0,0)};D.prototype.unionRect=D.prototype.nk=function(a){f&&t.l(a,D,D,"unionRect:r");return wb(this,a.L,a.M,a.ya,a.xa)}; +D.prototype.union=D.prototype.YF=function(a,b,c,d){t.J(this);f?(t.o(a,D,"union:x"),t.o(b,D,"union:y"),void 0===c?c=0:t.o(c,D,"union:w"),void 0===d?d=0:t.o(d,D,"union:h"),(0>c||0>d)&&t.m("Rect.union:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return wb(this,a,b,c,d)};function wb(a,b,c,d,e){var g=Math.min(a.L,b),h=Math.min(a.M,c);b=Math.max(a.L+a.ya,b+d);c=Math.max(a.M+a.xa,c+e);a.L=g;a.M=h;a.ya=b-g;a.xa=c-h;return a} +D.prototype.setSpot=D.prototype.xt=function(a,b,c){f&&(t.o(a,D,"setSpot:x"),t.o(b,D,"setSpot:y"),t.l(c,K,D,"setSpot:spot"));t.J(this);this.L=a-c.offsetX-c.x*this.ya;this.M=b-c.offsetY-c.y*this.xa;return this};var Db; +D.contains=Db=function(a,b,c,d,e,g,h,k){f?(t.o(a,D,"contains:rx"),t.o(b,D,"contains:ry"),t.o(c,D,"contains:rw"),t.o(d,D,"contains:rh"),t.o(e,D,"contains:x"),t.o(g,D,"contains:y"),void 0===h?h=0:t.o(h,D,"contains:w"),void 0===k?k=0:t.o(k,D,"contains:h"),(0>c||0>d||0>h||0>k)&&t.m("Rect.contains:Width and height cannot be negative")):(void 0===h&&(h=0),void 0===k&&(k=0));return a<=e&&e+h<=a+c&&b<=g&&g+k<=b+d}; +D.intersects=function(a,b,c,d,e,g,h,k){f&&(t.o(a,D,"intersects:rx"),t.o(b,D,"intersects:ry"),t.o(c,D,"intersects:rw"),t.o(d,D,"intersects:rh"),t.o(e,D,"intersects:x"),t.o(g,D,"intersects:y"),t.o(h,D,"intersects:w"),t.o(k,D,"intersects:h"),(0>c||0>d||0>h||0>k)&&t.m("Rect.intersects:Width and height cannot be negative"));c+=a;h+=e;if(a>h||e>c)return!1;a=d+b;k+=g;return b>k||g>a?!1:!0};t.g(D,"x",D.prototype.x); +t.defineProperty(D,{x:"x"},function(){return this.L},function(a){t.J(this,a);f&&t.j(a,"number",D,"x");this.L=a});t.g(D,"y",D.prototype.y);t.defineProperty(D,{y:"y"},function(){return this.M},function(a){t.J(this,a);f&&t.j(a,"number",D,"y");this.M=a});t.g(D,"width",D.prototype.width);t.defineProperty(D,{width:"width"},function(){return this.ya},function(a){t.J(this,a);f&&t.j(a,"number",D,"width");0>a&&t.ha(a,">= 0",D,"width");this.ya=a});t.g(D,"height",D.prototype.height); +t.defineProperty(D,{height:"height"},function(){return this.xa},function(a){t.J(this,a);f&&t.j(a,"number",D,"height");0>a&&t.ha(a,">= 0",D,"height");this.xa=a});t.g(D,"left",D.prototype.left);t.defineProperty(D,{left:"left"},function(){return this.L},function(a){t.J(this,a);f&&t.j(a,"number",D,"left");this.L=a});t.g(D,"top",D.prototype.top);t.defineProperty(D,{top:"top"},function(){return this.M},function(a){t.J(this,a);f&&t.j(a,"number",D,"top");this.M=a});t.g(D,"right",D.prototype.right); +t.defineProperty(D,{right:"right"},function(){return this.L+this.ya},function(a){t.J(this,a);f&&t.o(a,D,"right");this.L+=a-(this.L+this.ya)});t.g(D,"bottom",D.prototype.bottom);t.defineProperty(D,{bottom:"bottom"},function(){return this.M+this.xa},function(a){t.J(this,a);f&&t.o(a,D,"top");this.M+=a-(this.M+this.xa)});t.g(D,"position",D.prototype.position); +t.defineProperty(D,{position:"position"},function(){return new C(this.L,this.M)},function(a){t.J(this,a);f&&t.l(a,C,D,"position");this.L=a.x;this.M=a.y});t.g(D,"size",D.prototype.size);t.defineProperty(D,{size:"size"},function(){return new pa(this.ya,this.xa)},function(a){t.J(this,a);f&&t.l(a,pa,D,"size");this.ya=a.width;this.xa=a.height});t.g(D,"center",D.prototype.Iz); +t.defineProperty(D,{Iz:"center"},function(){return new C(this.L+this.ya/2,this.M+this.xa/2)},function(a){t.J(this,a);f&&t.l(a,C,D,"center");this.L=a.x-this.ya/2;this.M=a.y-this.xa/2});t.g(D,"centerX",D.prototype.Fa);t.defineProperty(D,{Fa:"centerX"},function(){return this.L+this.ya/2},function(a){t.J(this,a);f&&t.o(a,D,"centerX");this.L=a-this.ya/2});t.g(D,"centerY",D.prototype.Sa); +t.defineProperty(D,{Sa:"centerY"},function(){return this.M+this.xa/2},function(a){t.J(this,a);f&&t.o(a,D,"centerY");this.M=a-this.xa/2});D.prototype.isReal=D.prototype.Q=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)};D.prototype.isEmpty=function(){return 0===this.width&&0===this.height}; +function pb(a,b,c,d){void 0===a?this.$f=this.Sf=this.dg=this.gg=0:void 0===b?this.left=this.bottom=this.right=this.top=a:void 0===c?(d=b,this.top=a,this.right=b,this.bottom=a,this.left=d):void 0!==d?(this.top=a,this.right=b,this.bottom=c,this.left=d):t.m("Invalid arguments to Margin constructor")}t.ia("Margin",pb);t.Fh(pb);t.je(pb,{top:!0,right:!0,bottom:!0,left:!0});pb.prototype.assign=function(a){this.gg=a.gg;this.dg=a.dg;this.Sf=a.Sf;this.$f=a.$f}; +pb.prototype.setTo=pb.prototype.Fp=function(a,b,c,d){f&&(t.j(a,"number",pb,"setTo:t"),t.j(b,"number",pb,"setTo:r"),t.j(c,"number",pb,"setTo:b"),t.j(d,"number",pb,"setTo:l"));t.J(this);this.gg=a;this.dg=b;this.Sf=c;this.$f=d;return this};pb.prototype.set=pb.prototype.set=function(a){f&&t.l(a,pb,pb,"assign:m");t.J(this);this.gg=a.gg;this.dg=a.dg;this.Sf=a.Sf;this.$f=a.$f;return this};pb.prototype.copy=function(){var a=new pb;a.gg=this.gg;a.dg=this.dg;a.Sf=this.Sf;a.$f=this.$f;return a}; +pb.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this};pb.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()};pb.prototype.freeze=function(){this.jb=!0;return this};pb.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this}; +pb.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=void 0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=void 0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=void 0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new pb(c,e,g,h)}return new pb};pb.stringify=function(a){return a instanceof pb?a.top.toString()+" "+a.right.toString()+" "+a.bottom.toString()+" "+a.left.toString():a.toString()}; +pb.prototype.toString=function(){return"Margin("+this.top+","+this.right+","+this.bottom+","+this.left+")"};pb.prototype.equals=pb.prototype.N=function(a){return a instanceof pb?this.gg===a.top&&this.dg===a.right&&this.Sf===a.bottom&&this.$f===a.left:!1};pb.prototype.equalTo=function(a,b,c,d){return this.gg===a&&this.dg===b&&this.Sf===c&&this.$f===d};pb.prototype.bk=function(a){return J.Ka(this.gg,a.top)&&J.Ka(this.dg,a.right)&&J.Ka(this.Sf,a.bottom)&&J.Ka(this.$f,a.left)}; +pb.prototype.Oi=function(a){return J.I(this.gg,a.top)&&J.I(this.dg,a.right)&&J.I(this.Sf,a.bottom)&&J.I(this.$f,a.left)};t.g(pb,"top",pb.prototype.top);t.defineProperty(pb,{top:"top"},function(){return this.gg},function(a){t.J(this,a);f&&t.o(a,pb,"top");this.gg=a});t.g(pb,"right",pb.prototype.right);t.defineProperty(pb,{right:"right"},function(){return this.dg},function(a){t.J(this,a);f&&t.o(a,pb,"right");this.dg=a});t.g(pb,"bottom",pb.prototype.bottom); +t.defineProperty(pb,{bottom:"bottom"},function(){return this.Sf},function(a){t.J(this,a);f&&t.o(a,pb,"bottom");this.Sf=a});t.g(pb,"left",pb.prototype.left);t.defineProperty(pb,{left:"left"},function(){return this.$f},function(a){t.J(this,a);f&&t.o(a,pb,"left");this.$f=a});pb.prototype.isReal=pb.prototype.Q=function(){return isFinite(this.top)&&isFinite(this.right)&&isFinite(this.bottom)&&isFinite(this.left)};function qa(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}t.Fh(qa); +t.je(qa,{m11:!0,m12:!0,m21:!0,m22:!0,dx:!0,dy:!0});qa.prototype.set=qa.prototype.set=function(a){f&&t.l(a,qa,qa,"set:t");this.m11=a.m11;this.m12=a.m12;this.m21=a.m21;this.m22=a.m22;this.dx=a.dx;this.dy=a.dy;return this};qa.prototype.copy=function(){var a=new qa;a.m11=this.m11;a.m12=this.m12;a.m21=this.m21;a.m22=this.m22;a.dx=this.dx;a.dy=this.dy;return a};qa.prototype.toString=function(){return"Transform("+this.m11+","+this.m12+","+this.m21+","+this.m22+","+this.dx+","+this.dy+")"}; +qa.prototype.equals=qa.prototype.N=function(a){return a instanceof qa?this.m11===a.m11&&this.m12===a.m12&&this.m21===a.m21&&this.m22===a.m22&&this.dx===a.dx&&this.dy===a.dy:!1};qa.prototype.reset=qa.prototype.reset=function(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}; +qa.prototype.multiply=qa.prototype.multiply=function(a){f&&t.l(a,qa,qa,"multiply:matrix");var b=this.m12*a.m11+this.m22*a.m12,c=this.m11*a.m21+this.m21*a.m22,d=this.m12*a.m21+this.m22*a.m22,e=this.m11*a.dx+this.m21*a.dy+this.dx,g=this.m12*a.dx+this.m22*a.dy+this.dy;this.m11=this.m11*a.m11+this.m21*a.m12;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g;return this}; +qa.prototype.multiplyInverted=qa.prototype.yA=function(a){f&&t.l(a,qa,qa,"multiplyInverted:matrix");var b=1/(a.m11*a.m22-a.m12*a.m21),c=a.m22*b,d=-a.m12*b,e=-a.m21*b,g=a.m11*b,h=b*(a.m21*a.dy-a.m22*a.dx),k=b*(a.m12*a.dx-a.m11*a.dy);a=this.m12*c+this.m22*d;b=this.m11*e+this.m21*g;e=this.m12*e+this.m22*g;g=this.m11*h+this.m21*k+this.dx;h=this.m12*h+this.m22*k+this.dy;this.m11=this.m11*c+this.m21*d;this.m12=a;this.m21=b;this.m22=e;this.dx=g;this.dy=h;return this}; +qa.prototype.invert=qa.prototype.jA=function(){var a=1/(this.m11*this.m22-this.m12*this.m21),b=-this.m12*a,c=-this.m21*a,d=this.m11*a,e=a*(this.m21*this.dy-this.m22*this.dx),g=a*(this.m12*this.dx-this.m11*this.dy);this.m11=this.m22*a;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g}; +qa.prototype.rotate=qa.prototype.rotate=function(a,b,c){f&&(t.o(a,qa,"rotate:angle"),t.o(b,qa,"rotate:rx"),t.o(c,qa,"rotate:ry"));this.translate(b,c);var d;0===a?(a=1,d=0):90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));var e=this.m12*a+this.m22*d,g=this.m11*-d+this.m21*a,h=this.m12*-d+this.m22*a;this.m11=this.m11*a+this.m21*d;this.m12=e;this.m21=g;this.m22=h;this.translate(-b,-c)}; +qa.prototype.translate=qa.prototype.translate=function(a,b){f&&(t.o(a,qa,"translate:x"),t.o(b,qa,"translate:y"));this.dx+=this.m11*a+this.m21*b;this.dy+=this.m12*a+this.m22*b};qa.prototype.scale=qa.prototype.scale=function(a,b){void 0===b&&(b=a);f&&(t.o(a,qa,"translate:sx"),t.o(b,qa,"translate:sy"));this.m11*=a;this.m12*=a;this.m21*=b;this.m22*=b}; +qa.prototype.transformPoint=qa.prototype.Va=function(a){f&&t.l(a,C,qa,"transformPoint:p");var b=a.L,c=a.M;a.L=b*this.m11+c*this.m21+this.dx;a.M=b*this.m12+c*this.m22+this.dy;return a};qa.prototype.invertedTransformPoint=qa.prototype.Ri=function(a){f&&t.l(a,C,qa,"invertedTransformPoint:p");var b=1/(this.m11*this.m22-this.m12*this.m21),c=-this.m12*b,d=this.m11*b,e=b*(this.m12*this.dx-this.m11*this.dy),g=a.L,h=a.M;a.L=g*this.m22*b+h*-this.m21*b+b*(this.m21*this.dy-this.m22*this.dx);a.M=g*c+h*d+e;return a}; +qa.prototype.transformRect=qa.prototype.TF=function(a){f&&t.l(a,D,qa,"transformRect:rect");var b=a.L,c=a.M,d=b+a.ya,e=c+a.xa,g=this.m11,h=this.m12,k=this.m21,l=this.m22,m=this.dx,n=this.dy,p=b*g+c*k+m,q=b*h+c*l+n,r=d*g+c*k+m,c=d*h+c*l+n,s=b*g+e*k+m,b=b*h+e*l+n,g=d*g+e*k+m,d=d*h+e*l+n,e=p,h=q,p=Math.min(p,r),e=Math.max(e,r),h=Math.min(h,c),q=Math.max(q,c),p=Math.min(p,s),e=Math.max(e,s),h=Math.min(h,b),q=Math.max(q,b),p=Math.min(p,g),e=Math.max(e,g),h=Math.min(h,d),q=Math.max(q,d);a.L=p;a.M=h;a.ya= +e-p;a.xa=q-h};qa.prototype.isIdentity=qa.prototype.Ts=function(){return 1===this.m11&&0===this.m12&&0===this.m21&&1===this.m22&&0===this.dx&&0===this.dy};function K(a,b,c,d){void 0===a?this.cg=this.bg=this.M=this.L=0:(void 0===b&&(b=0),void 0===c&&(c=0),void 0===d&&(d=0),this.x=a,this.y=b,this.offsetX=c,this.offsetY=d)}t.ia("Spot",K);t.Fh(K);t.je(K,{x:!0,y:!0,offsetX:!0,offsetY:!0});K.prototype.assign=function(a){this.L=a.L;this.M=a.M;this.bg=a.bg;this.cg=a.cg}; +K.prototype.setTo=K.prototype.Fp=function(a,b,c,d){f&&(Eb(a,"setTo:x"),Eb(b,"setTo:y"),Fb(c,"setTo:offx"),Fb(d,"setTo:offy"));t.J(this);this.L=a;this.M=b;this.bg=c;this.cg=d;return this};K.prototype.set=K.prototype.set=function(a){f&&t.l(a,K,K,"set:s");t.J(this);this.L=a.L;this.M=a.M;this.bg=a.bg;this.cg=a.cg;return this};K.prototype.copy=function(){var a=new K;a.L=this.L;a.M=this.M;a.bg=this.bg;a.cg=this.cg;return a};K.prototype.Na=function(){this.jb=!0;Object.freeze(this);return this}; +K.prototype.Z=function(){return Object.isFrozen(this)?this:this.copy().freeze()};K.prototype.freeze=function(){this.jb=!0;return this};K.prototype.Ua=function(){Object.isFrozen(this)&&t.m("cannot thaw constant: "+this);this.jb=!1;return this};function Jb(a,b){a.L=NaN;a.M=NaN;a.bg=b;return a}function Eb(a,b){(isNaN(a)||1a)&&t.ha(a,"0 <= "+b+" <= 1",K,b)}function Fb(a,b){(isNaN(a)||Infinity===a||-Infinity===a)&&t.ha(a,"real number, not NaN or Infinity",K,b)}var Nb; +K.parse=Nb=function(a){if("string"===typeof a){a=a.trim();if("None"===a)return t.NONE;if("TopLeft"===a)return t.sx;if("Top"===a||"TopCenter"===a||"MiddleTop"===a)return t.Tp;if("TopRight"===a)return t.ux;if("Left"===a||"LeftCenter"===a||"MiddleLeft"===a)return t.Qp;if("Center"===a)return t.ex;if("Right"===a||"RightCenter"===a||"MiddleRight"===a)return t.Rp;if("BottomLeft"===a)return t.Yw;if("Bottom"===a||"BottomCenter"===a||"MiddleBottom"===a)return t.Pp;if("BottomRight"===a)return t.$w;if("TopSide"=== +a)return t.wx;if("LeftSide"===a)return t.jx;if("RightSide"===a)return t.px;if("BottomSide"===a)return t.bx;if("TopBottomSides"===a)return t.qx;if("LeftRightSides"===a)return t.ix;if("TopLeftSides"===a)return t.tx;if("TopRightSides"===a)return t.vx;if("BottomLeftSides"===a)return t.Zw;if("BottomRightSides"===a)return t.ax;if("NotTopSide"===a)return t.nx;if("NotLeftSide"===a)return t.lx;if("NotRightSide"===a)return t.mx;if("NotBottomSide"===a)return t.kx;if("AllSides"===a)return t.Xw;if("Default"=== +a)return t.gx;a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new K(c,e,g,h)}return new K};K.stringify=function(a){return a instanceof K?a.rd()?a.x.toString()+" "+a.y.toString()+" "+a.offsetX.toString()+" "+a.offsetY.toString():a.toString():a.toString()}; +K.prototype.toString=function(){return this.rd()?0===this.bg&&0===this.cg?"Spot("+this.x+","+this.y+")":"Spot("+this.x+","+this.y+","+this.offsetX+","+this.offsetY+")":this.N(t.NONE)?"None":this.N(t.sx)?"TopLeft":this.N(t.Tp)?"Top":this.N(t.ux)?"TopRight":this.N(t.Qp)?"Left":this.N(t.ex)?"Center":this.N(t.Rp)?"Right":this.N(t.Yw)?"BottomLeft":this.N(t.Pp)?"Bottom":this.N(t.$w)?"BottomRight":this.N(t.wx)?"TopSide":this.N(t.jx)?"LeftSide":this.N(t.px)?"RightSide":this.N(t.bx)?"BottomSide":this.N(t.qx)? +"TopBottomSides":this.N(t.ix)?"LeftRightSides":this.N(t.tx)?"TopLeftSides":this.N(t.vx)?"TopRightSides":this.N(t.Zw)?"BottomLeftSides":this.N(t.ax)?"BottomRightSides":this.N(t.nx)?"NotTopSide":this.N(t.lx)?"NotLeftSide":this.N(t.mx)?"NotRightSide":this.N(t.kx)?"NotBottomSide":this.N(t.Xw)?"AllSides":this.N(t.gx)?"Default":"None"}; +K.prototype.equals=K.prototype.N=function(a){return a instanceof K?(this.L===a.x||isNaN(this.L)&&isNaN(a.x))&&(this.M===a.y||isNaN(this.M)&&isNaN(a.y))&&this.bg===a.offsetX&&this.cg===a.offsetY:!1};K.prototype.opposite=function(){return new K(0.5-(this.L-0.5),0.5-(this.M-0.5),-this.bg,-this.cg)};K.prototype.includesSide=function(a){if(!this.dp()||!a.dp())return!1;a=a.offsetY;return(this.cg&a)===a};t.g(K,"x",K.prototype.x); +t.defineProperty(K,{x:"x"},function(){return this.L},function(a){t.J(this,a);f&&Eb(a,"x");this.L=a});t.g(K,"y",K.prototype.y);t.defineProperty(K,{y:"y"},function(){return this.M},function(a){t.J(this,a);f&&Eb(a,"y");this.M=a});t.g(K,"offsetX",K.prototype.offsetX);t.defineProperty(K,{offsetX:"offsetX"},function(){return this.bg},function(a){t.J(this,a);f&&Fb(a,"offsetX");this.bg=a});t.g(K,"offsetY",K.prototype.offsetY); +t.defineProperty(K,{offsetY:"offsetY"},function(){return this.cg},function(a){t.J(this,a);f&&Fb(a,"offsetY");this.cg=a});K.prototype.isSpot=K.prototype.rd=function(){return!isNaN(this.x)&&!isNaN(this.y)};K.prototype.isNoSpot=K.prototype.qd=function(){return isNaN(this.x)||isNaN(this.y)};K.prototype.isSide=K.prototype.dp=function(){return this.qd()&&1===this.offsetX&&0!==this.offsetY};K.prototype.isDefault=K.prototype.Fc=function(){return isNaN(this.x)&&isNaN(this.y)&&-1===this.offsetX&&0===this.offsetY}; +t.Fd=1;t.hd=2;t.ud=4;t.td=8;t.NONE=Jb(new K(0,0,0,0),0).Na();t.gx=Jb(new K(0,0,-1,0),-1).Na();t.sx=(new K(0,0,0,0)).Na();t.Tp=(new K(0.5,0,0,0)).Na();t.ux=(new K(1,0,0,0)).Na();t.Qp=(new K(0,0.5,0,0)).Na();t.ex=(new K(0.5,0.5,0,0)).Na();t.Rp=(new K(1,0.5,0,0)).Na();t.Yw=(new K(0,1,0,0)).Na();t.Pp=(new K(0.5,1,0,0)).Na();t.$w=(new K(1,1,0,0)).Na();t.wx=Jb(new K(0,0,1,t.Fd),1).Na();t.jx=Jb(new K(0,0,1,t.hd),1).Na();t.px=Jb(new K(0,0,1,t.ud),1).Na();t.bx=Jb(new K(0,0,1,t.td),1).Na(); +t.qx=Jb(new K(0,0,1,t.Fd|t.td),1).Na();t.ix=Jb(new K(0,0,1,t.hd|t.ud),1).Na();t.tx=Jb(new K(0,0,1,t.Fd|t.hd),1).Na();t.vx=Jb(new K(0,0,1,t.Fd|t.ud),1).Na();t.Zw=Jb(new K(0,0,1,t.td|t.hd),1).Na();t.ax=Jb(new K(0,0,1,t.td|t.ud),1).Na();t.nx=Jb(new K(0,0,1,t.hd|t.ud|t.td),1).Na();t.lx=Jb(new K(0,0,1,t.Fd|t.ud|t.td),1).Na();t.mx=Jb(new K(0,0,1,t.Fd|t.hd|t.td),1).Na();t.kx=Jb(new K(0,0,1,t.Fd|t.hd|t.ud),1).Na();t.Xw=Jb(new K(0,0,1,t.Fd|t.hd|t.ud|t.td),1).Na();var Ob;K.None=Ob=t.NONE;var Pb; +K.Default=Pb=t.gx;var Tb;K.TopLeft=Tb=t.sx;var Ub;K.TopCenter=Ub=t.Tp;var Vb;K.TopRight=Vb=t.ux;K.LeftCenter=t.Qp;var Wb;K.Center=Wb=t.ex;K.RightCenter=t.Rp;var Xb;K.BottomLeft=Xb=t.Yw;var Yb;K.BottomCenter=Yb=t.Pp;var $b;K.BottomRight=$b=t.$w;var ac;K.MiddleTop=ac=t.Tp;var bc;K.MiddleLeft=bc=t.Qp;var cc;K.MiddleRight=cc=t.Rp;var dc;K.MiddleBottom=dc=t.Pp;K.Top=t.Tp;var ic;K.Left=ic=t.Qp;var nc;K.Right=nc=t.Rp;K.Bottom=t.Pp;var oc;K.TopSide=oc=t.wx;var pc;K.LeftSide=pc=t.jx;var tc; +K.RightSide=tc=t.px;var uc;K.BottomSide=uc=t.bx;K.TopBottomSides=t.qx;K.LeftRightSides=t.ix;K.TopLeftSides=t.tx;K.TopRightSides=t.vx;K.BottomLeftSides=t.Zw;K.BottomRightSides=t.ax;K.NotTopSide=t.nx;K.NotLeftSide=t.lx;K.NotRightSide=t.mx;K.NotBottomSide=t.kx;var vc;K.AllSides=vc=t.Xw;function xc(){this.Xe=[1,0,0,1,0,0]}xc.prototype.copy=function(){var a=new xc;a.Xe[0]=this.Xe[0];a.Xe[1]=this.Xe[1];a.Xe[2]=this.Xe[2];a.Xe[3]=this.Xe[3];a.Xe[4]=this.Xe[4];a.Xe[5]=this.Xe[5];return a}; +function yc(a){this.type=a;this.r2=this.y2=this.x2=this.r1=this.y1=this.x1=0;this.rD=[]}yc.prototype.addColorStop=function(a,b){this.rD.push({offset:a,color:b})}; +function zc(a){this.fillStyle="#000000";this.font="10px sans-serif";this.globalAlpha=1;this.lineCap="butt";this.xw=0;this.lineJoin="miter";this.lineWidth=1;this.miterLimit=10;this.shadowBlur=0;this.shadowColor="rgba(0, 0, 0, 0)";this.shadowOffsetY=this.shadowOffsetX=0;this.strokeStyle="#000000";this.textAlign="start";this.path=[];this.Ki=new xc;this.stack=[];this.og=[];this.AF=this.hE=this.Rv=0;this.bw=a;this.II="http://www.w3.org/2000/svg";this.Bt=Ac(this,"svg",{width:this.bw.width+"px",height:this.bw.height+ +"px",KJ:"0 0 "+this.bw.width+" "+this.bw.height})}aa=zc.prototype;aa.arc=function(a,b,c,d,e,g){Ic(this,a,b,c,d,e,g)};aa.beginPath=function(){this.path=[]};aa.bezierCurveTo=function(a,b,c,d,e,g){this.path.push(["C",a,b,c,d,e,g])};aa.clearRect=function(){};aa.clip=function(){Jc(this,"clipPath",this.path,new xc)};aa.closePath=function(){this.path.push(["z"])};aa.createLinearGradient=function(a,b,c,d){var e=new yc("linear");e.x1=a;e.y1=b;e.x2=c;e.y2=d;return e};aa.createPattern=function(){}; +aa.createRadialGradient=function(a,b,c,d,e,g){var h=new yc("radial");h.x1=a;h.y1=b;h.r1=c;h.x2=d;h.y2=e;h.r2=g;return h}; +aa.drawImage=function(a,b,c,d,e,g,h,k,l){a=[b,c,d,e,g,h,k,l,a];b=this.Ki;e=a[8];c={x:0,y:0,width:e.naturalWidth,height:e.naturalHeight,href:e.src};d="";g=a[6]/a[2];h=a[7]/a[3];if(0!==a[4]||0!==a[5])d+=" translate("+a[4]+", "+a[5]+")";if(1!==g||1!==h)d+=" scale("+g+", "+h+")";if(0!==a[0]||0!==a[1])d+=" translate("+-a[0]+", "+-a[1]+")";if(0!==a[0]||0!==a[1]||a[2]!==e.naturalWidth||a[3]!==e.naturalHeight)e="CLIP"+this.Rv,this.Rv++,g=Ac(this,"clipPath",{id:e}),g.appendChild(Ac(this,"rect",{x:a[0],y:a[1], +width:a[2],height:a[3]})),this.Bt.appendChild(g),c["clip-path"]="url(#"+e+")";Kc(this,"image",c,b,d);this.addElement("image",c)};aa.fill=function(){Jc(this,"fill",this.path,this.Ki)};aa.fillRect=function(a,b,c,d){Lc(this,"fill",[a,b,c,d],this.Ki)};aa.fillText=function(a,b,c){a=[a,b,c];b=this.textAlign;"left"===b?b="start":"right"===b?b="end":"center"===b&&(b="middle");b={x:a[1],y:a[2],style:"font: "+this.font,"text-anchor":b};Kc(this,"fill",b,this.Ki);this.addElement("text",b,a[0])}; +aa.lineTo=function(a,b){this.path.push(["L",a,b])};aa.moveTo=function(a,b){this.path.push(["M",a,b])};aa.quadraticCurveTo=function(a,b,c,d){this.path.push(["Q",a,b,c,d])};aa.rect=function(a,b,c,d){this.path.push(["M",a,b],["L",a+c,b],["L",a+c,b+d],["L",a,b+d],["z"])}; +aa.restore=function(){this.Ki=this.stack.pop();this.path=this.stack.pop();var a=this.stack.pop();this.fillStyle=a.fillStyle;this.font=a.font;this.globalAlpha=a.globalAlpha;this.lineCap=a.lineCap;this.xw=a.xw;this.lineJoin=a.lineJoin;this.lineWidth=a.lineWidth;this.miterLimit=a.miterLimit;this.shadowBlur=a.shadowBlur;this.shadowColor=a.shadowColor;this.shadowOffsetX=a.shadowOffsetX;this.shadowOffsetY=a.shadowOffsetY;this.strokeStyle=a.strokeStyle;this.textAlign=a.textAlign}; +aa.save=function(){this.stack.push({fillStyle:this.fillStyle,font:this.font,globalAlpha:this.globalAlpha,lineCap:this.lineCap,xw:this.xw,lineJoin:this.lineJoin,lineWidth:this.lineWidth,miterLimit:this.miterLimit,shadowBlur:this.shadowBlur,shadowColor:this.shadowColor,shadowOffsetX:this.shadowOffsetX,shadowOffsetY:this.shadowOffsetY,strokeStyle:this.strokeStyle,textAlign:this.textAlign});for(var a=[],b=0;bb.offset?1:-1});for(k=0;k=2*Math.PI?(Ic(a,b,c,d,e,e+Math.PI,h),Ic(a,b,c,d,e+Math.PI,e+2*Math.PI,h),a.path.push(["M",l,g])):(b+=d*Math.cos(e),c+=d*Math.sin(e),k=180*k/Math.PI,e=h?0:1,h=180<=k==!!h?0:1,0!=a.path.length?a.path.push(["L",b,c]):a.path.push(["M",b,c]),a.path.push(["A",d,d,k,h,e,l,g]))}} +function Mc(a,b,c,d,e,g,h){var k=new xc;k.Xe=[b,c,d,e,g,h];b={};Kc(a,"g",b,k);k=a.addElement("g",b);a.og.push(k)} +aa.ab=function(){var a="SHADOW"+this.AF;this.AF++;var b=this.addElement("filter",{id:a,width:"250%",height:"250%"},null),c,d,e,g,h;if(0!=this.shadowOffsetX||0!=this.shadowOffsetY)c=Ac(this,"feGaussianBlur",{"in":"SourceAlpha",result:"blur",IJ:this.shadowBlur/2}),d=Ac(this,"feFlood",{"in":"blur",result:"flood","flood-color":this.shadowColor}),e=Ac(this,"feComposite",{"in":"flood",in2:"blur",operator:"in",result:"comp"}),g=Ac(this,"feOffset",{"in":"comp",result:"offsetBlur",dx:this.shadowOffsetX,dy:this.shadowOffsetY}), +h=Ac(this,"feMerge",{}),h.appendChild(Ac(this,"feMergeNode",{"in":"offsetBlur"})),h.appendChild(Ac(this,"feMergeNode",{"in":"SourceGraphic"})),b.appendChild(c),b.appendChild(d),b.appendChild(e),b.appendChild(g),b.appendChild(h);0=a)return 0;var b=J.xB;if(null===b){for(var b=[],c=0;2E3>=c;c++)b[c]=Math.sqrt(c);J.xB=b}return 1>a?(c=1/a,2E3>=c?1/b[c| +0]:Math.sqrt(a)):2E3>=a?b[a|0]:Math.sqrt(a)},I:function(a,b){var c=a-b;return 0.5>c&&-0.5c&&-5E-8=e&&(e=1E-6);var k,l,m,n;am-n)if(a-c>e||c-a>e){if(g=(d-b)/(c-a)*(g-a)+b,g-e<=h&&h<=g+e)return!0}else return!0;else if(b-d>e||d-b>e){if(h=(c- +a)/(d-b)*(h-b)+a,h-e<=g&&g<=h+e)return!0}else return!0;return!1},Mv:function(a,b,c,d,e,g,h,k,l,m,n,p){if(J.Cd(a,b,h,k,p,c,d)&&J.Cd(a,b,h,k,p,e,g))return J.Cd(a,b,h,k,p,m,n);var q=(a+c)/2,r=(b+d)/2,s=(c+e)/2,v=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(q+s)/2;c=(r+v)/2;var s=(s+e)/2,v=(v+g)/2,x=(d+s)/2,E=(c+v)/2;return J.Mv(a,b,q,r,d,c,x,E,l,m,n,p)||J.Mv(x,E,s,v,e,g,h,k,l,m,n,p)},kH:function(a,b,c,d,e,g,h,k,l){var m=(c+e)/2,n=(d+g)/2;l.x=(((a+c)/2+m)/2+(m+(e+h)/2)/2)/2;l.y=(((b+d)/2+n)/2+(n+(g+k)/2)/2)/2;return l}, +jH:function(a,b,c,d,e,g,h,k){var l=(c+e)/2,m=(d+g)/2;return kb(((a+c)/2+l)/2,((b+d)/2+m)/2,(l+(e+h)/2)/2,(m+(g+k)/2)/2)},Eo:function(a,b,c,d,e,g,h,k,l,m){if(J.Cd(a,b,h,k,l,c,d)&&J.Cd(a,b,h,k,l,e,g))wb(m,a,b,0,0),wb(m,h,k,0,0);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,v=(c+r)/2;J.Eo(a,b,n,p,d,c,s,v,l,m);J.Eo(s,v,q,r,e,g,h,k,l,m)}return m},ze:function(a,b,c,d,e,g,h,k,l,m){if(J.Cd(a,b,h,k,l,c,d)&&J.Cd(a,b,h,k,l,e,g))0=== +m.length&&m.push([a,b]),m.push([h,k]);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,v=(c+r)/2;J.ze(a,b,n,p,d,c,s,v,l,m);J.ze(s,v,q,r,e,g,h,k,l,m)}return m},JA:function(a,b,c,d,e,g,h,k,l,m){if(J.Cd(a,b,e,g,m,c,d))return J.Cd(a,b,e,g,m,k,l);var n=(a+c)/2,p=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var q=(n+c)/2,r=(p+d)/2;return J.JA(a,b,n,p,q,r,h,k,l,m)||J.JA(q,r,c,d,e,g,h,k,l,m)},HJ:function(a,b,c,d,e,g,h){h.x=((a+c)/2+(c+e)/2)/2;h.y=((b+ +d)/2+(d+g)/2)/2;return h},IA:function(a,b,c,d,e,g,h,k){if(J.Cd(a,b,e,g,h,c,d))wb(k,a,b,0,0),wb(k,e,g,0,0);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;J.IA(a,b,l,m,n,p,h,k);J.IA(n,p,c,d,e,g,h,k)}return k},xp:function(a,b,c,d,e,g,h,k){if(J.Cd(a,b,e,g,h,c,d))0===k.length&&k.push([a,b]),k.push([e,g]);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;J.xp(a,b,l,m,n,p,h,k);J.xp(n,p,c,d,e,g,h,k)}return k},ws:function(a,b,c,d,e,g,h,k,l,m,n,p,q,r){0>=q&& +(q=1E-6);if(J.Cd(a,b,h,k,q,c,d)&&J.Cd(a,b,h,k,q,e,g)){var s=(a-h)*(m-p)-(b-k)*(l-n);if(!s)return!1;q=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/s;s=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/s;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(bh)return!1}else if(ah)return!1;r.x=q;r.y=s;return!0}var s=(a+c)/2,v=(b+d)/2;c=(c+e)/2;d=(d+g)/2;e=(e+h)/2;g=(g+k)/2;var x=(s+c)/2,E=(v+d)/2;c=(c+e)/2;d=(d+g)/2;var F=(x+c)/2,G=(E+d)/2,L=(n-l)*(n-l)+(p-m)*(p-m),N=!1;J.ws(a,b,s,v,x,E,F,G, +l,m,n,p,q,r)&&(a=(r.x-l)*(r.x-l)+(r.y-m)*(r.y-m),a=q&&(q=1E-6);if(J.Cd(a,b,h,k,q,c,d)&&J.Cd(a,b,h,k,q,e,g)){q=(a-h)*(m-p)-(b-k)*(l-n);if(!q)return r;var s=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/q,v=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/q;if(s>=n)return r;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(ba)return r}else if(a< +h?(l=a,a=h):l=h,sa)return r;0q&&r--}else{var s=(a+c)/2,v=(b+d)/2,x=(c+e)/2,E=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(s+x)/2;c=(v+E)/2;var x=(x+e)/2,E=(E+g)/2,F=(d+x)/2,G=(c+E)/2,r=r+J.xs(a,b,s,v,d,c,F,G,l,m,n,p,q),r=r+J.xs(F,G,x,E,e,g,h,k,l,m,n,p,q)}return r},Zm:function(a,b,c,d,e,g,h){if(J.Ka(a,c)){var k;bc)return h.x=a,h.y=c,!1;h.x=a;h.y=d;return!0}if(J.Ka(b,d)){ac)return h.x= +c,h.y=b,!1;h.x=d;h.y=b;return!0}k=((a-e)*(a-c)+(b-g)*(b-d))/((c-a)*(c-a)+(d-b)*(d-b));if(-5E-6>k)return h.x=a,h.y=b,!1;if(1.000005c)return l.x=a,l.y=c,!1;l.x=a; +l.y=g;return!0}h=(d-b)/(c-a);if(J.Ka(k,h))return J.Zm(a,b,c,d,e,g,l),!1;e=(h*a-k*e+g-b)/(h-k);if(J.Ka(h,0)){ac)return l.x=c,l.y=b,!1;l.x=e;l.y=b;return!0}g=h*(e-a)+b;return J.Zm(a,b,c,d,e,g,l)},vJ:function(a,b,c,d,e){return J.$g(c.x,c.y,d.x,d.y,a.x,a.y,b.x,b.y,e)},tJ:function(a,b,c,d,e,g,h,k,l,m){function n(c,d){var e=(c-a)*(c-a)+(d-b)*(d-b);e(c>a?c-a:a-c)){q=1-(c-e)*(c-e)/(q*q);if(0>q)return l;q=Math.sqrt(q);d=-m*q+g;n(c,m*q+g);n(c,d)}else{c=(d-b)/(c-a);d=1/(q*q)+c*c/(m*m);k=2*c*(b-c*a)/(m*m)-2*c*g/(m*m)-2*e/(q*q);q=k*k-4*d*(2*c*a*g/(m*m)-2*b*g/(m*m)+g*g/(m*m)+e*e/(q*q)-1+(b-c*a)*(b-c*a)/(m*m));if(0>q)return l;q=Math.sqrt(q);m=(-k+q)/(2*d);n(m,c*m-c*a+b);q=(-k-q)/(2*d);n(q,c*q-c*a+b)}return l},ml:function(a,b,c,d,e,g,h,k,l){var m=1E21,n=a,p=b;if(J.$g(a,b,a, +d,e,g,h,k,l)){var q=(l.x-e)*(l.x-e)+(l.y-g)*(l.y-g);qm},ow:function(a,b,c){var d=b.x,e=b.y,g=c.x,h=c.y,k=a.left,l=a.right,m=a.top,n=a.bottom;return d===g?(e=m): +e===h?(d=k):a.Ia(b)||a.Ia(c)||J.nw(k,m,l,m,d,e,g,h)||J.nw(l,m,l,n,d,e,g,h)||J.nw(l,n,k,n,d,e,g,h)||J.nw(k,n,k,m,d,e,g,h)?!0:!1},nw:function(a,b,c,d,e,g,h,k){return 0>=J.Tv(a,b,c,d,e,g)*J.Tv(a,b,c,d,h,k)&&0>=J.Tv(e,g,h,k,a,b)*J.Tv(e,g,h,k,c,d)},Tv:function(a,b,c,d,e,g){c-=a;d-=b;a=e-a;b=g-b;g=a*d-b*c;0===g&&(g=a*c+b*d,0g&&(g=0)));return 0>g?-1:0a&&(a+=360);360<=a&&(a-=360);return a},AD:function(a,b,c,d,e,g){var h= +Math.PI;g||(d*=h/180,e*=h/180);g=dc,g=0>d,h,k;am;++m){b=0.5*(k+l);if(b===k||b===l)break;var n=a/(b+g),p=h/(b+e),n=n*n+p*p-1;if(0n)l=b;else break}c=g*c/(b+g)-c;d=e*d/(b+e)-d;c=Math.sqrt(c*c+d*d)}else c=Math.abs(d-b);else d=a*a-b*b,e=a*c,e=x-1?!0:null!==m[n+1].match(/[A-Za-z]/)}function d(){n++;return m[n]}function e(){var a=new C(parseFloat(d()),parseFloat(d()));p===p.toLowerCase()&&(a.x=v.x+a.x,a.y=v.y+a.y);return a}function g(){return v=e()}function h(){return s=e()}function k(){var a=[parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d())];c()||(a.push(parseFloat(d())),c()||a.push(parseFloat(d())));p===p.toLowerCase()&&(a[2]+=v.x,a[3]+=v.y);return a}function l(){return"c"!== +q.toLowerCase()&&"s"!==q.toLowerCase()?v:new C(2*v.x-s.x,2*v.y-s.y)}void 0===b&&(b=!1);"string"!==typeof a&&t.Vb(a,"string",M,"parse:str");a=a.replace(/,/gm," ");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([^\s])/gm,"$1 $2");a=a.replace(/([^\s])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([0-9])([+\-])/gm,"$1 $2");a= +a.replace(/(\.[0-9]*)(\.)/gm,"$1 $2");a=a.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,"$1 $3 $4 ");a=a.replace(/[\s\r\t\n]+/gm," ");a=a.replace(/^\s+|\s+$/g,"");for(var m=a.split(" "),n=-1,p="",q="",r=new C(0,0),s=new C(0,0),v=new C(0,0),x=m.length,E=t.u(),F,G=!1,L=!1,N=!0;!(n>=x-1);)if(q=p,p=d(),""!==p)switch(p.toUpperCase()){case "X":N=!0;L=G=!1;break;case "M":F=g();null===E.Qb||!0===N?(O(E,F.x,F.y,G,!1,!L),N=!1):E.moveTo(F.x,F.y);for(r=v;!c();)F=g(),E.lineTo(F.x,F.y);break;case "L":for(;!c();)F= +g(),E.lineTo(F.x,F.y);break;case "H":for(;!c();)v=F=new C((p===p.toLowerCase()?v.x:0)+parseFloat(d()),v.y),E.lineTo(v.x,v.y);break;case "V":for(;!c();)v=F=new C(v.x,(p===p.toLowerCase()?v.y:0)+parseFloat(d())),E.lineTo(v.x,v.y);break;case "C":for(;!c();){var W=e(),T=h();F=g();P(E,W.x,W.y,T.x,T.y,F.x,F.y)}break;case "S":for(;!c();)W=l(),T=h(),F=g(),P(E,W.x,W.y,T.x,T.y,F.x,F.y);break;case "Q":for(;!c();)T=h(),F=g(),cd(E,T.x,T.y,F.x,F.y);break;case "T":for(;!c();)s=T=l(),F=g(),cd(E,T.x,T.y,F.x,F.y); +break;case "B":for(;!c();)F=k(),E.arcTo(F[0],F[1],F[2],F[3],F[4],F[5],F[6]);break;case "A":for(;!c();){var W=Math.abs(parseFloat(d())),T=Math.abs(parseFloat(d())),U=parseFloat(d()),da=!!parseFloat(d()),R=!!parseFloat(d());F=g();dd(E,W,T,U,da,R,F.x,F.y)}break;case "Z":Q(E);v=r;break;case "F":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Uu]/))W++;else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?G=!0:ed(E);break;case "U":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Ff]/))W++; +else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?L=!0:E.ab(!1)}r=E.s;t.v(E);if(b)for(E=r.ub.k;E.next();)E.value.bp=!0;return r};function fd(a,b){for(var c=a.length,d=t.O(),e=0;e=a&&t.ha(a,"scale must be greater than zero",M,"scale:x"),0>=b&&t.ha(b,"scale must be greater than zero",M,"scale:y"));this.transform(a,0,0,b,0,0)}; +M.prototype.rotate=M.prototype.rotate=function(a,b,c){t.J(this);void 0===b&&(b=0);void 0===c&&(c=0);f&&(t.o(a,M,"rotate:angle"),t.o(b,M,"rotate:x"),t.o(c,M,"rotate:y"));var d=t.bh();d.reset();d.rotate(a,b,c);this.transform(d.m11,d.m12,d.m21,d.m22,d.dx,d.dy);t.Se(d)}; +M.prototype.transform=M.prototype.transform=function(a,b,c,d,e,g){var h,k;switch(this.type){case Vc:case Wc:case Xc:h=this.ec;k=this.nc;this.ec=h*a+k*c+e;this.nc=h*b+k*d+g;h=this.md;k=this.xd;this.md=h*a+k*c+e;this.xd=h*b+k*d+g;break;case Oc:for(var l=this.ub,m=l.length,n=0;n=a)return 0;if((e>h?e-h:h-e)<(g>k?g-k:k-g)){if(ge)return 0}else if(ee)return 0;return 0a||1a)return n=(a-m)/l,t.Da(c),new C(b[0]+(d[0]-b[0])*n,b[1]+(d[1]-b[1])*n);m+=l}b=d}t.Da(c);return null};t.g(M,"type",M.prototype.type);t.defineProperty(M,{type:"type"},function(){return this.ba},function(a){this.ba!==a&&(f&&t.tb(a,M,M,"type"),t.J(this,a),this.ba=a,this.Xa=!0)});t.g(M,"startX",M.prototype.na);t.defineProperty(M,{na:"startX"},function(){return this.ec},function(a){this.ec!==a&&(f&&t.o(a,M,"startX"),t.J(this,a),this.ec=a,this.Xa=!0)}); +t.g(M,"startY",M.prototype.oa);t.defineProperty(M,{oa:"startY"},function(){return this.nc},function(a){this.nc!==a&&(f&&t.o(a,M,"startY"),t.J(this,a),this.nc=a,this.Xa=!0)});t.g(M,"endX",M.prototype.D);t.defineProperty(M,{D:"endX"},function(){return this.md},function(a){this.md!==a&&(f&&t.o(a,M,"endX"),t.J(this,a),this.md=a,this.Xa=!0)});t.g(M,"endY",M.prototype.F);t.defineProperty(M,{F:"endY"},function(){return this.xd},function(a){this.xd!==a&&(f&&t.o(a,M,"endY"),t.J(this,a),this.xd=a,this.Xa=!0)}); +t.g(M,"figures",M.prototype.ub);t.defineProperty(M,{ub:"figures"},function(){return this.Fk},function(a){this.Fk!==a&&(f&&t.l(a,H,M,"figures"),t.J(this,a),this.Fk=a,this.Xa=!0)});t.defineProperty(M,{G:"spot1"},function(){return this.xi},function(a){f&&t.l(a,K,M,"spot1");t.J(this,a);this.xi=a.Z()});t.defineProperty(M,{H:"spot2"},function(){return this.yi},function(a){f&&t.l(a,K,M,"spot2");t.J(this,a);this.yi=a.Z()});t.A(M,{Mb:"bounds"},function(){this.mA()&&(this.pB(),this.kf());return this.au}); +t.g(M,"minSize",M.prototype.Ye);t.defineProperty(M,{Ye:"minSize"},function(){return this.de},function(a){this.de.N(a)||(f&&t.l(a,pa,M,"minSize"),a=a.Z(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.de=a)});function Pc(a,b,c){t.zc(this);void 0===c&&(c=!0);this.Ql=c;this.Rn=!0;void 0!==a?(f&&t.o(a,Pc,"sx"),this.ec=a):this.ec=0;void 0!==b?(f&&t.o(b,Pc,"sy"),this.nc=b):this.nc=0;this.Sr=new H(S);this.kv=this.Sr.Wb;this.Xa=!0}t.ia("PathFigure",Pc);t.Fh(Pc); +Pc.prototype.copy=function(){var a=new Pc;a.Ql=this.Ql;a.Rn=this.Rn;a.ec=this.ec;a.nc=this.nc;for(var b=this.Sr,c=b.length,d=a.Sr,e=0;ea&&(a+=360),this.uo=a):(void 0!==b?(f&&t.o(b,S,"ex"),this.ve=b):this.ve=0,void 0!==c?(f&&t.o(c,S,"ey"),this.we=c):this.we=0,void 0!==d&&(f&&t.o(d,S,"x1"),this.Pg=d),void 0!==e&&(f&&t.o(e,S,"y1"),this.Qg=e),void 0!==g&&(f&&t.o(g,S,"x2"),this.Tk=g),void 0!==h&&"number"===typeof h&&(f&&t.o(h,S,"y2"),this.Uk=h));this.Xa=!0;this.ph= +!1;this.cj=null}t.ia("PathSegment",S);t.Fh(S);S.prototype.copy=function(){var a=new S;a.ba=this.ba;this.ba===qd?(a.xe=this.xe,a.ye=this.ye,a.sn=this.sn,a.tn=this.tn,a.Ej=this.Ej,a.Fj=this.Fj):this.ba===rd?(a.xe=this.xe,a.ye=this.ye,a.ve=this.ve,a.we=this.we,a.Ej=this.Ej,a.Fj=this.Fj,a.uo=this.uo):(a.ve=this.ve,a.we=this.we,a.Pg=this.Pg,a.Qg=this.Qg,a.Tk=this.Tk,a.Uk=this.Uk);a.Xa=this.Xa;a.ph=this.ph;return a}; +S.prototype.equalsApprox=S.prototype.bk=function(a){if(!(a instanceof S)||this.type!==a.type||this.Ss!==a.Ss)return!1;switch(this.type){case md:case Zc:return J.I(this.D,a.D)&&J.I(this.F,a.F);case od:return J.I(this.D,a.D)&&J.I(this.F,a.F)&&J.I(this.vb,a.vb)&&J.I(this.Lb,a.Lb)&&J.I(this.oe,a.oe)&&J.I(this.pe,a.pe);case pd:return J.I(this.D,a.D)&&J.I(this.F,a.F)&&J.I(this.vb,a.vb)&&J.I(this.Lb,a.Lb);case qd:return J.I(this.yg,a.yg)&&J.I(this.Th,a.Th)&&J.I(this.Fa,a.Fa)&&J.I(this.Sa,a.Sa)&&J.I(this.radiusX, +a.radiusX)&&J.I(this.radiusY,a.radiusY);case rd:return this.pw===a.pw&&this.sw===a.sw&&J.I(this.Ww,a.Ww)&&J.I(this.D,a.D)&&J.I(this.F,a.F)&&J.I(this.radiusX,a.radiusX)&&J.I(this.radiusY,a.radiusY);default:return!1}}; +S.prototype.toString=function(a){switch(this.type){case md:a=void 0===a?"M"+this.D.toString()+" "+this.F.toString():"M"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case Zc:a=void 0===a?"L"+this.D.toString()+" "+this.F.toString():"L"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case od:a=void 0===a?"C"+this.vb.toString()+" "+this.Lb.toString()+" "+this.oe.toString()+" "+this.pe.toString()+" "+this.D.toString()+" "+this.F.toString():"C"+this.vb.toFixed(a)+" "+this.Lb.toFixed(a)+" "+this.oe.toFixed(a)+ +" "+this.pe.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case pd:a=void 0===a?"Q"+this.vb.toString()+" "+this.Lb.toString()+" "+this.D.toString()+" "+this.F.toString():"Q"+this.vb.toFixed(a)+" "+this.Lb.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case qd:a=void 0===a?"B"+this.yg.toString()+" "+this.Th.toString()+" "+this.Fa.toString()+" "+this.Sa.toString()+" "+this.radiusX:"B"+this.yg.toFixed(a)+" "+this.Th.toFixed(a)+" "+this.Fa.toFixed(a)+" "+this.Sa.toFixed(a)+ +" "+this.radiusX;break;case rd:a=void 0===a?"A"+this.radiusX.toString()+" "+this.radiusY.toString()+" "+this.Ww.toString()+" "+(this.sw?1:0)+" "+(this.pw?1:0)+" "+this.D.toString()+" "+this.F.toString():"A"+this.radiusX.toFixed(a)+" "+this.radiusY.toFixed(a)+" "+this.Ww.toFixed(a)+" "+(this.sw?1:0)+" "+(this.pw?1:0)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;default:a=this.type.toString()}return a+(this.ph?"z":"")};var md;S.Move=md=t.w(S,"Move",0);var Zc;S.Line=Zc=t.w(S,"Line",1);var od; +S.Bezier=od=t.w(S,"Bezier",2);var pd;S.QuadraticBezier=pd=t.w(S,"QuadraticBezier",3);var qd;S.Arc=qd=t.w(S,"Arc",4);var rd;S.SvgArc=rd=t.w(S,"SvgArc",4);S.prototype.freeze=function(){this.jb=!0;return this};S.prototype.Ua=function(){this.jb=!1;return this};S.prototype.close=S.prototype.close=function(){this.ph=!0;return this}; +function sd(a,b){if(null!==a.cj&&!1===b.Xa)return a.cj;var c=a.radiusX,d=a.radiusY;void 0===d&&(d=c);var e=a.sn,g=a.tn,h=J.AD(0,0,c=g(p,r)&&(q=Math.PI);1<=g(p,r)&&(q=0);0===m&&0q&&(q+=2*Math.PI);m=b>h?1:b/h; +r=b>h?h/b:1;b=J.AD(0,0,b>h?b:h,k,k+q,!0);h=t.bh();h.reset();h.translate(c,d);h.rotate(a.uo,0,0);h.scale(m,r);fd(b,h);t.Se(h);a.cj=b;return a.cj}t.g(S,"isClosed",S.prototype.Ss);t.defineProperty(S,{Ss:"isClosed"},function(){return this.ph},function(a){this.ph!==a&&(this.ph=a,this.Xa=!0)});t.g(S,"type",S.prototype.type);t.defineProperty(S,{type:"type"},function(){return this.ba},function(a){f&&t.tb(a,S,S,"type");t.J(this,a);this.ba=a;this.Xa=!0});t.g(S,"endX",S.prototype.D); +t.defineProperty(S,{D:"endX"},function(){return this.ve},function(a){f&&t.o(a,S,"endX");t.J(this,a);this.ve=a;this.Xa=!0});t.g(S,"endY",S.prototype.F);t.defineProperty(S,{F:"endY"},function(){return this.we},function(a){f&&t.o(a,S,"endY");t.J(this,a);this.we=a;this.Xa=!0});t.defineProperty(S,{vb:"point1X"},function(){return this.Pg},function(a){f&&t.o(a,S,"point1X");t.J(this,a);this.Pg=a;this.Xa=!0}); +t.defineProperty(S,{Lb:"point1Y"},function(){return this.Qg},function(a){f&&t.o(a,S,"point1Y");t.J(this,a);this.Qg=a;this.Xa=!0});t.defineProperty(S,{oe:"point2X"},function(){return this.Tk},function(a){f&&t.o(a,S,"point2X");t.J(this,a);this.Tk=a;this.Xa=!0});t.defineProperty(S,{pe:"point2Y"},function(){return this.Uk},function(a){f&&t.o(a,S,"point2Y");t.J(this,a);this.Uk=a;this.Xa=!0}); +t.defineProperty(S,{Fa:"centerX"},function(){return this.sn},function(a){f&&t.o(a,S,"centerX");t.J(this,a);this.sn=a;this.Xa=!0});t.defineProperty(S,{Sa:"centerY"},function(){return this.tn},function(a){f&&t.o(a,S,"centerY");t.J(this,a);this.tn=a;this.Xa=!0});t.defineProperty(S,{radiusX:"radiusX"},function(){return this.Ej},function(a){f&&t.o(a,S,"radiusX");0>a&&t.ha(a,">= zero",S,"radiusX");t.J(this,a);this.Ej=a;this.Xa=!0}); +t.defineProperty(S,{radiusY:"radiusY"},function(){return this.Fj},function(a){f&&t.o(a,S,"radiusY");0>a&&t.ha(a,">= zero",S,"radiusY");t.J(this,a);this.Fj=a;this.Xa=!0});t.defineProperty(S,{yg:"startAngle"},function(){return this.xe},function(a){this.xe!==a&&(t.J(this,a),f&&t.o(a,S,"startAngle"),a%=360,0>a&&(a+=360),this.xe=a,this.Xa=!0)}); +t.defineProperty(S,{Th:"sweepAngle"},function(){return this.ye},function(a){f&&t.o(a,S,"sweepAngle");t.J(this,a);360a&&(a=-360);this.ye=a;this.Xa=!0});t.defineProperty(S,{pw:"isClockwiseArc"},function(){return!!this.ye},function(a){t.J(this,a);this.ye=a?1:0;this.Xa=!0});t.defineProperty(S,{sw:"isLargeArc"},function(){return!!this.xe},function(a){t.J(this,a);this.xe=a?1:0;this.Xa=!0}); +t.defineProperty(S,{Ww:"xAxisRotation"},function(){return this.uo},function(a){f&&t.o(a,S,"xAxisRotation");a%=360;0>a&&(a+=360);t.J(this,a);this.uo=a;this.Xa=!0});function wd(){this.ea=null;this.sz=(new C(0,0)).freeze();this.Yx=(new C(0,0)).freeze();this.Yt=this.Nu=0;this.Bu="";this.yv=this.lu=!1;this.iu=this.$t=0;this.dj=this.su=!1;this.Aq=null;this.wv=0;this.eg=this.uv=null}t.ia("InputEvent",wd); +wd.prototype.copy=function(){var a=new wd;a.ea=this.ea;a.sz=this.Ac.copy().freeze();a.Yx=this.W.copy().freeze();a.Nu=this.Nu;a.Yt=this.Yt;a.Bu=this.Bu;a.lu=this.lu;a.yv=this.yv;a.$t=this.$t;a.iu=this.iu;a.su=this.su;a.dj=this.dj;a.Aq=this.Aq;a.wv=this.wv;a.uv=this.uv;a.eg=this.eg;return a}; +wd.prototype.toString=function(){var a="^";this.Tc&&(a+="M:"+this.Tc);this.button&&(a+="B:"+this.button);this.key&&(a+="K:"+this.key);this.Be&&(a+="C:"+this.Be);this.Zj&&(a+="D:"+this.Zj);this.Fe&&(a+="h");this.bubbles&&(a+="b");null!==this.W&&(a+="@"+this.W.toString());return a};t.g(wd,"diagram",wd.prototype.h);t.defineProperty(wd,{h:"diagram"},function(){return this.ea},function(a){this.ea=a});t.g(wd,"viewPoint",wd.prototype.Ac); +t.defineProperty(wd,{Ac:"viewPoint"},function(){return this.sz},function(a){t.l(a,C,wd,"viewPoint");this.sz.assign(a)});t.g(wd,"documentPoint",wd.prototype.W);t.defineProperty(wd,{W:"documentPoint"},function(){return this.Yx},function(a){t.l(a,C,wd,"documentPoint");this.Yx.assign(a)});t.g(wd,"modifiers",wd.prototype.Tc);t.defineProperty(wd,{Tc:"modifiers"},function(){return this.Nu},function(a){this.Nu=a});t.g(wd,"button",wd.prototype.button); +t.defineProperty(wd,{button:"button"},function(){return this.Yt},function(a){this.Yt=a});t.g(wd,"key",wd.prototype.key);t.defineProperty(wd,{key:"key"},function(){return this.Bu},function(a){this.Bu=a});t.g(wd,"down",wd.prototype.ak);t.defineProperty(wd,{ak:"down"},function(){return this.lu},function(a){this.lu=a});t.g(wd,"up",wd.prototype.aj);t.defineProperty(wd,{aj:"up"},function(){return this.yv},function(a){this.yv=a});t.g(wd,"clickCount",wd.prototype.Be); +t.defineProperty(wd,{Be:"clickCount"},function(){return this.$t},function(a){this.$t=a});t.g(wd,"delta",wd.prototype.Zj);t.defineProperty(wd,{Zj:"delta"},function(){return this.iu},function(a){this.iu=a});t.g(wd,"handled",wd.prototype.Fe);t.defineProperty(wd,{Fe:"handled"},function(){return this.su},function(a){this.su=a});t.g(wd,"bubbles",wd.prototype.bubbles);t.defineProperty(wd,{bubbles:"bubbles"},function(){return this.dj},function(a){this.dj=a});t.g(wd,"event",wd.prototype.event); +t.defineProperty(wd,{event:"event"},function(){return this.Aq},function(a){this.Aq=a});t.A(wd,{vw:"isTouchEvent"},function(){var a=window.TouchEvent;return a&&this.event instanceof a});t.g(wd,"timestamp",wd.prototype.timestamp);t.defineProperty(wd,{timestamp:"timestamp"},function(){return this.wv},function(a){this.wv=a});t.g(wd,"targetDiagram",wd.prototype.zg);t.defineProperty(wd,{zg:"targetDiagram"},function(){return this.uv},function(a){this.uv=a});t.g(wd,"targetObject",wd.prototype.Yd); +t.defineProperty(wd,{Yd:"targetObject"},function(){return this.eg},function(a){this.eg=a});t.g(wd,"control",wd.prototype.control);t.defineProperty(wd,{control:"control"},function(){return 0!==(this.Tc&1)},function(a){this.Tc=a?this.Tc|1:this.Tc&-2});t.g(wd,"shift",wd.prototype.shift);t.defineProperty(wd,{shift:"shift"},function(){return 0!==(this.Tc&4)},function(a){this.Tc=a?this.Tc|4:this.Tc&-5});t.g(wd,"alt",wd.prototype.alt); +t.defineProperty(wd,{alt:"alt"},function(){return 0!==(this.Tc&2)},function(a){this.Tc=a?this.Tc|2:this.Tc&-3});t.g(wd,"meta",wd.prototype.Xm);t.defineProperty(wd,{Xm:"meta"},function(){return 0!==(this.Tc&8)},function(a){this.Tc=a?this.Tc|8:this.Tc&-9});t.g(wd,"left",wd.prototype.left);t.defineProperty(wd,{left:"left"},function(){return 0===this.button},function(a){this.button=a?0:2});t.g(wd,"middle",wd.prototype.EI); +t.defineProperty(wd,{EI:"middle"},function(){return 1===this.button},function(a){this.button=a?1:0});t.g(wd,"right",wd.prototype.right);t.defineProperty(wd,{right:"right"},function(){return 2===this.button},function(a){this.button=a?2:0});function Fd(){this.ea=null;this.Rb="";this.$u=this.qv=null;this.Zt=!1}t.ia("DiagramEvent",Fd);Fd.prototype.copy=function(){var a=new Fd;a.ea=this.ea;a.Rb=this.Rb;a.qv=this.qv;a.$u=this.$u;a.Zt=this.Zt;return a}; +Fd.prototype.toString=function(){var a="*"+this.name;this.cancel&&(a+="x");null!==this.Sw&&(a+=":"+this.Sw.toString());null!==this.Fw&&(a+="("+this.Fw.toString()+")");return a};t.g(Fd,"diagram",Fd.prototype.h);t.defineProperty(Fd,{h:"diagram"},function(){return this.ea},function(a){this.ea=a});t.g(Fd,"name",Fd.prototype.name);t.defineProperty(Fd,{name:"name"},function(){return this.Rb},function(a){this.Rb=a});t.g(Fd,"subject",Fd.prototype.Sw); +t.defineProperty(Fd,{Sw:"subject"},function(){return this.qv},function(a){this.qv=a});t.g(Fd,"parameter",Fd.prototype.Fw);t.defineProperty(Fd,{Fw:"parameter"},function(){return this.$u},function(a){this.$u=a});t.g(Fd,"cancel",Fd.prototype.cancel);t.defineProperty(Fd,{cancel:"cancel"},function(){return this.Zt},function(a){this.Zt=a});function Gd(){this.clear()}t.ia("ChangedEvent",Gd);var Hd;Gd.Transaction=Hd=t.w(Gd,"Transaction",-1);var Id;Gd.Property=Id=t.w(Gd,"Property",0);var Jd; +Gd.Insert=Jd=t.w(Gd,"Insert",1);var Td;Gd.Remove=Td=t.w(Gd,"Remove",2);Gd.prototype.clear=Gd.prototype.clear=function(){this.gq=Id;this.hm=this.Mu="";this.Qu=this.Ru=this.Xu=this.co=this.Wu=this.ea=this.Md=null}; +Gd.prototype.copy=function(){var a=new Gd;a.Md=this.Md;a.ea=this.ea;a.gq=this.gq;a.Mu=this.Mu;a.hm=this.hm;a.Wu=this.Wu;var b=this.co;a.co=t.pb(b)&&"function"===typeof b.Z?b.Z():b;b=this.Xu;a.Xu=t.pb(b)&&"function"===typeof b.Z?b.Z():b;b=this.Ru;a.Ru=t.pb(b)&&"function"===typeof b.Z?b.Z():b;b=this.Qu;a.Qu=t.pb(b)&&"function"===typeof b.Z?b.Z():b;return a}; +Gd.prototype.toString=function(){var a="",a=this.od===Hd?a+"* ":this.od===Id?a+(null!==this.fa?"!m":"!d"):a+((null!==this.fa?"!m":"!d")+this.od);this.propertyName&&"string"===typeof this.propertyName&&(a+=" "+this.propertyName);this.rf&&this.rf!==this.propertyName&&(a+=" "+this.rf);a+=": ";this.od===Hd?null!==this.oldValue&&(a+=" "+this.oldValue):(null!==this.object&&(a+=ma(this.object)),null!==this.oldValue&&(a+=" old: "+ma(this.oldValue)),null!==this.Mf&&(a+=" "+this.Mf),null!==this.newValue&& +(a+=" new: "+ma(this.newValue)),null!==this.Kf&&(a+=" "+this.Kf));return a};Gd.prototype.getValue=Gd.prototype.Ba=function(a){return a?this.oldValue:this.newValue};Gd.prototype.getParam=function(a){return a?this.Mf:this.Kf};Gd.prototype.canUndo=Gd.prototype.canUndo=function(){return null!==this.fa||null!==this.h?!0:!1};Gd.prototype.undo=Gd.prototype.undo=function(){this.canUndo()&&(null!==this.fa?this.fa.changeState(this,!0):null!==this.h&&this.h.changeState(this,!0))}; +Gd.prototype.canRedo=Gd.prototype.canRedo=function(){return null!==this.fa||null!==this.h?!0:!1};Gd.prototype.redo=Gd.prototype.redo=function(){this.canRedo()&&(null!==this.fa?this.fa.changeState(this,!1):null!==this.h&&this.h.changeState(this,!1))};t.g(Gd,"model",Gd.prototype.fa);t.defineProperty(Gd,{fa:"model"},function(){return this.Md},function(a){this.Md=a});t.g(Gd,"diagram",Gd.prototype.h);t.defineProperty(Gd,{h:"diagram"},function(){return this.ea},function(a){this.ea=a});t.g(Gd,"change",Gd.prototype.od); +t.defineProperty(Gd,{od:"change"},function(){return this.gq},function(a){f&&t.tb(a,Gd,Gd,"change");this.gq=a});t.g(Gd,"modelChange",Gd.prototype.rf);t.defineProperty(Gd,{rf:"modelChange"},function(){return this.Mu},function(a){f&&t.j(a,"string",Gd,"modelChange");this.Mu=a});t.g(Gd,"propertyName",Gd.prototype.propertyName);t.defineProperty(Gd,{propertyName:"propertyName"},function(){return this.hm},function(a){f&&"string"!==typeof a&&t.l(a,Function,Gd,"propertyName");this.hm=a}); +t.g(Gd,"isTransactionFinished",Gd.prototype.rI);t.A(Gd,{rI:"isTransactionFinished"},function(){return this.gq===Hd&&("CommittedTransaction"===this.hm||"FinishedUndo"===this.hm||"FinishedRedo"===this.hm)});t.g(Gd,"object",Gd.prototype.object);t.defineProperty(Gd,{object:"object"},function(){return this.Wu},function(a){this.Wu=a});t.g(Gd,"oldValue",Gd.prototype.oldValue);t.defineProperty(Gd,{oldValue:"oldValue"},function(){return this.co},function(a){this.co=a});t.g(Gd,"oldParam",Gd.prototype.Mf); +t.defineProperty(Gd,{Mf:"oldParam"},function(){return this.Xu},function(a){this.Xu=a});t.g(Gd,"newValue",Gd.prototype.newValue);t.defineProperty(Gd,{newValue:"newValue"},function(){return this.Ru},function(a){this.Ru=a});t.g(Gd,"newParam",Gd.prototype.Kf);t.defineProperty(Gd,{Kf:"newParam"},function(){return this.Qu},function(a){this.Qu=a}); +function I(a){1b||(t.Fi(this.Ke,b),ze(this,"nodeDataArray",Td,"nodeDataArray",this,a,null,b,null),this.Ft(a)))}};I.prototype.removeNodeDataCollection=function(a){if(t.isArray(a))for(var b=t.yb(a),c=0;cb&&(b=t.yb(a));t.Ei(a,b,c);ze(this,"",Jd,"",a,null,c,null,b)}; +I.prototype.removeArrayItem=function(a,b){void 0===b&&(b=-1);f&&(t.ys(a,I,"removeArrayItem:arr"),t.o(b,I,"removeArrayItem:idx"));a===this.Ke&&t.m("Model.removeArrayItem should not be called on the Model.nodeDataArray");-1===b&&(b=t.yb(a)-1);var c=t.sb(a,b);t.Fi(a,b);ze(this,"",Td,"",a,c,null,b,null)};t.g(I,"nodeCategoryProperty",I.prototype.rl); +t.defineProperty(I,{rl:"nodeCategoryProperty"},function(){return this.ur},function(a){var b=this.ur;b!==a&&(Ae(a,I,"nodeCategoryProperty"),this.ur=a,this.i("nodeCategoryProperty",b,a))});I.prototype.getCategoryForNodeData=I.prototype.getCategoryForNodeData=function(a){if(null===a)return"";var b=this.ur;if(""===b)return"";b=t.hb(a,b);if(void 0===b)return"";if("string"===typeof b)return b;t.m("getCategoryForNodeData found a non-string category for "+a+": "+b);return""}; +I.prototype.setCategoryForNodeData=I.prototype.Mw=function(a,b){t.j(b,"string",I,"setCategoryForNodeData:cat");if(null!==a){var c=this.ur;if(""!==c)if(this.ie(a)){var d=t.hb(a,c);void 0===d&&(d="");d!==b&&(t.Ta(a,c,b),ze(this,"nodeCategory",Id,c,a,d,b))}else t.Ta(a,c,b)}}; +function V(a,b){2e||(t.Fi(d,e),this.Ji(a)&&(Ee(this,b,a),ze(this,"linkLabelKeys",Td,c,a,b,null)))}else void 0!==d&&t.m(c+" property is not an Array; cannot removeLabelKeyforLinkData: "+a)}}};t.g(V,"linkDataArray",V.prototype.Vi); +t.defineProperty(V,{Vi:"linkDataArray"},function(){return this.Mg},function(a){var b=this.Mg;if(b!==a){t.ys(a,V,"linkDataArray");this.Vd&&t.qc&&(null!==b&&t.Tm(b,"linkDataArray",this,!0),a=t.Tm(a,"linkDataArray",this,!1));for(var c=t.yb(a),d=0;db)){t.Fi(this.Mg,b);ze(this,"linkDataArray",Td,"linkDataArray",this,a,null,b,null);b=this.Om(a);Ee(this,b,a);b=this.Pm(a);Ee(this,b,a);var c=this.ll(a);if(t.isArray(c))for(var d=t.yb(c),e=0;ea.Cl&&t.trace("Ending transaction without having started a transaction: "+c);var d=1===a.Cl;d&&b&&a.isEnabled&&a.Lc("CommittingTransaction",c,a.gl);var e=0;if(0a.gk;e--)g=d.qa(e),null!==g&&g.clear(), +d.gd(e);e=a.rA;0===e&&(e=1);0=e&&(g=d.qa(0),null!==g&&g.clear(),d.gd(0),a.Jk--);d.add(b);a.Jk++;d.freeze();g=b}a.Lc("CommittedTransaction",c,g)}else{a.ji=!0;try{a.isEnabled&&null!==g&&(g.ap=!0,g.undo())}finally{a.Lc("RolledBackTransaction",c,g),a.ji=!1}null!==g&&g.clear()}a.hu=null;return!0}if(a.isEnabled&&!b&&null!==g){a=e;c=g.Eh;for(b=c.count-1;b>=a;b--)d=c.qa(b),null!==d&&d.undo(),c.Ua(),c.gd(b);c.freeze()}return!1} +Ud.prototype.canUndo=Ud.prototype.canUndo=function(){if(!this.isEnabled||0=this.Cl&&!this.hy&&(a=a.h,null!==a&&!1===a.Xf||t.trace("Change not within a transaction: "+c.toString()))}}; +Ud.prototype.skipsEvent=function(a){if(null===a||0>a.od.value)return!0;a=a.object;if(a instanceof X){if(a=a.layer,null!==a&&a.pc)return!0}else if(a instanceof pe&&a.pc)return!0;return!1};t.A(Ud,{FI:"models"},function(){return this.Iy.k});t.g(Ud,"isEnabled",Ud.prototype.isEnabled);t.defineProperty(Ud,{isEnabled:"isEnabled"},function(){return this.ii},function(a){this.ii=a});t.A(Ud,{SF:"transactionToUndo"},function(){return 0<=this.gk&&this.gk<=this.history.count-1?this.history.qa(this.gk):null}); +t.A(Ud,{RF:"transactionToRedo"},function(){return this.gkb.pg||(b.scale=a))};xa.prototype.canDecreaseZoom=function(a){void 0===a&&(a=1/this.It);t.o(a,xa,"canDecreaseZoom:factor");var b=this.h;if(null===b||b.Am!==$e)return!1;a*=b.scale;return ab.pg?!1:b.us}; +xa.prototype.increaseZoom=function(a){void 0===a&&(a=this.It);t.o(a,xa,"increaseZoom:factor");var b=this.h;null!==b&&b.Am===$e&&(a*=b.scale,ab.pg||(b.scale=a))};xa.prototype.canIncreaseZoom=function(a){void 0===a&&(a=this.It);t.o(a,xa,"canIncreaseZoom:factor");var b=this.h;if(null===b||b.Am!==$e)return!1;a*=b.scale;return ab.pg?!1:b.us};xa.prototype.resetZoom=function(a){void 0===a&&(a=this.GD);t.o(a,xa,"resetZoom:newscale");var b=this.h;null===b||ab.pg||(b.scale=a)}; +xa.prototype.canResetZoom=function(a){void 0===a&&(a=1);t.o(a,xa,"canResetZoom:newscale");var b=this.h;return null===b||ab.pg?!1:b.us};xa.prototype.zoomToFit=function(){var a=this.h;if(null!==a){var b=a.scale,c=a.position;b!==this.$C||isNaN(this.Dy)?(this.Dy=b,this.oC=c.copy(),a.zoomToFit(),a.Nh(),this.$C=a.scale):(a.scale=this.Dy,a.position=this.oC)}};xa.prototype.canZoomToFit=function(){var a=this.h;return null===a?!1:a.us}; +xa.prototype.collapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b)return!1;b.rc("Collapse Tree");var c=new H(y);if(a instanceof y&&a.Gc)a.collapseTree(),c.add(a);else for(a=b.selection.k;a.next();){var d=a.value;d instanceof y&&d.Gc&&(d.collapseTree(),c.add(d))}b.Ja("TreeCollapsed",c);b.De("Collapse Tree")}; +xa.prototype.canCollapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b||b.$a)return!1;if(a instanceof y){if(!a.Gc)return!1;if(0c||Math.abs(b.y-a.y)>d};t.A(qe,{h:"diagram"},function(){return this.ea}); +t.g(qe,"name",qe.prototype.name);t.defineProperty(qe,{name:"name"},function(){return this.Rb},function(a){this.Rb=a});t.g(qe,"isEnabled",qe.prototype.isEnabled);t.defineProperty(qe,{isEnabled:"isEnabled"},function(){return this.ii},function(a){this.ii=a});t.g(qe,"isActive",qe.prototype.ra);t.defineProperty(qe,{ra:"isActive"},function(){return this.eC},function(a){this.eC=a});t.g(qe,"transactionResult",qe.prototype.bf); +t.defineProperty(qe,{bf:"transactionResult"},function(){return this.WC},function(a){this.WC=a}); +function gf(){0e&&(e=k),l>g&&(g=l))}}Infinity===c?b.q(0,0,0,0):b.q(c,d,e-c,g-d)} +function Gf(a,b){if(null===a.pd){var c=a.h;if(null!==c&&!c.$a&&!c.Ue&&null!==a.wc){Df(a);c.Bb=!b;a.Zp=!b;a.Zi=c.Ec.W;for(var c=a.xD?c.copyParts(a.wc.Bl(),c,!0):c.copyParts(c.selection,c,!0),d=c.k;d.next();)d.value.location=d.key.location;d=t.wf();Ff(c,d);t.Pc(d);for(var d=new sa(w,Object),e=a.wc.k;e.next();){var g=e.key;g.Ud()&&g.canCopy()&&(g=c.Ba(g),null!==g&&(a.Zp&&(g.Xd="Tool"),g.Gf(),d.add(g,wf(g.location))))}for(c=c.k;c.next();)e=c.value,e instanceof A&&e.canCopy()&&d.add(e,wf());a.pd=d;hf(a, +d.Bl());null!==a.dd&&(c=a.dd,d=c.oj(),c.ql(a.Zi.x-(d.x+d.width/2),a.Zi.y-(d.y+d.height/2)))}}}function Cf(a){var b=a.h;null!==b&&(null!==a.pd&&(b.PA(a.pd.Bl(),!1),a.pd=null),b.Bb=!1,a.Zp=!1,a.Zi=b.Ec.W)}function Bf(a){if(null!==a.dd){if(a.Ni&&null!==a.vi){var b=a.vi;b.h.remove(b.Zd);b.h.remove(b.$d)}a.dd=null;a.vi=null}}function Qf(a,b,c){var d=a.h;if(null!==d){var e=a.Zi,g=t.O();g.assign(d.U.W);a.moveParts(b,g.At(e),c);t.B(g)}} +gf.prototype.moveParts=function(a,b,c){if(null!==a&&(t.l(a,sa,gf,"moveParts:parts"),0!==a.count)){var d=t.O(),e=t.O();e.assign(b);isNaN(e.x)&&(e.x=0);isNaN(e.y)&&(e.y=0);var g=this.rv;g||rf(this,a);for(var h=new H,k=new H(Qa),l=a.k;l.next();){var m=l.key;if(m.Ud()){var n=Rf(this,m,a);if(null!==n)h.add({Ic:m,info:l.value,cI:n});else if(!c||m.canMove()){n=l.value.point;d.assign(n);var p=this.computeMove(m,d.add(e),a);m.location=p;l.value.Zy=p.At(n)}}else l.key instanceof A&&k.add(l.ce)}for(c=h.k;c.next();)h= +c.value,n=h.info.point,d.assign(n),h.Ic.location=d.add(h.cI.Zy);n=t.O();c=t.O();for(k=k.k;k.next();)if(p=k.value,h=p.key,h instanceof A)if(h.Kp)if(l=h.da,m=h.ja,null!==this.dd&&this.Ni)p=p.value.point,a.add(h,wf(e)),l=b.x-p.x,m=b.y-p.y,h.ql(l,m);else{if(null!==l){n.assign(l.location);var q=a.Ba(l);null!==q&&n.At(q.point)}null!==m&&(c.assign(m.location),q=a.Ba(m),null!==q&&c.At(q.point));null!==l&&null!==m?n.Oi(c)?(p=p.value.point,l=d,l.assign(n),l.At(p),a.add(h,wf(n)),h.ql(l.x,l.y)):(h.Kp=!1,h.$b()): +(p=p.value.point,a.add(h,wf(null!==l?n:null!==m?c:b)),l=e.x-p.x,m=e.y-p.y,h.ql(l,m))}else if(null===h.da||null===h.ja)p=p.value.point,a.add(h,wf(b)),l=e.x-p.x,m=e.y-p.y,h.ql(l,m);t.B(d);t.B(e);t.B(n);t.B(c);g||zf(this,a)}};function Rf(a,b,c){b=b.fb;if(null!==b){a=Rf(a,b,c);if(null!==a)return a;a=c.Ba(b);if(null!==a)return a}return null} +function Df(a){if(null!==a.wc){for(var b=a.h,c=a.wc.k;c.next();){var d=c.key;d.Ud()&&(d.location=c.value.point)}for(c=a.wc.k;c.next();)if(d=c.key,d instanceof A&&d.Kp){var e=c.value.point;a.wc.add(d,wf());d.ql(-e.x,-e.y)}b.Nh()}} +gf.prototype.computeMove=function(a,b,c,d){void 0===d&&(d=new C);d.assign(b);if(null===a)return d;void 0===c&&(c=null);var e=b;if(this.cp&&(this.yE||null===c||this.h.U.aj)&&(e=t.O(),c=e,c.assign(b),null!==a)){var g=this.h;if(null!==g){var h=g.Yo,k=this.dA,g=k.width,k=k.height,l=this.jE,m=l.x,l=l.y,n=this.iE;if(null!==h){var p=h.Ms;isNaN(g)&&(g=p.width);isNaN(k)&&(k=p.height);h=h.cA;isNaN(m)&&(m=h.x);isNaN(l)&&(l=h.y)}h=t.ic(0,0);h.xt(0,0,g,k,n);J.Hs(b.x,b.y,m+h.x,l+h.y,g,k,c);t.B(h)}}c=null!==a.Sz? +a.Sz(a,b,e):e;k=a.TE;g=k.x;isNaN(g)&&(g=a.location.x);k=k.y;isNaN(k)&&(k=a.location.y);h=a.NE;m=h.x;isNaN(m)&&(m=a.location.x);h=h.y;isNaN(h)&&(h=a.location.y);d.q(Math.max(g,Math.min(c.x,m)),Math.max(k,Math.min(c.y,h)));e!==b&&t.B(e);return d};function Sf(a,b){if(null===b)return!0;var c=b.S;return null===c||c instanceof We||c.layer.pc||a.wc&&a.wc.contains(c)||a.pd&&a.pd.contains(c)?!0:!1} +function Tf(a,b,c,d){var e=a.h;if(null!==e){a.Ni&&(null!==a.dd&&(a.dd.da=null,a.dd.ja=null),Uf(a,!1));var g=!1;!1===a.mv&&(g=e.Bb,e.Bb=!0);var h=!1,k=Vf(e,b,null,function(b){return!Sf(a,b)}),l=e.U;l.Yd=k;var m=e.Bb;e.Bb=!0;if(k!==a.Kl){var n=a.Kl;a.bv=n;for(a.Kl=k;null!==n;){var p=n.uA;if(null!==p){if(k===n)break;if(null!==k&&k.Ti(n))break;p(l,n,k);h=!0;if(l.Fe)break}n=n.ga}for(n=a.bv;null!==k;){p=k.UE;if(null!==p){if(n===k)break;if(null!==n&&n.Ti(k))break;p(l,k,n);h=!0;if(l.Fe)break}k=k.ga}k=a.Kl}null=== +k&&(p=e.VE,null!==p&&(p(l),h=!0));a.doDragOver(b,k);e.Bb=m;h&&e.Nh();!1===a.mv&&(e.Bb=g);(e.hf||e.jf)&&(c||d)&&Wf(e,b)}}function Xf(a,b,c){var d=a.vi;if(null===d)return null;var e=a.h.Mm(b,d.FA,function(a){return d.findValidLinkablePort(a,c)});a=t.O();for(var g=Infinity,h=null,e=e.k;e.next();){var k=e.value;if(null!==k.S){var l=k.gb(Wb,a),l=b.$j(l);lc.ma)){var d=a.h;if(null!==d&&!d.$a&&(d=a.vi,null!==d)){var e=null,g=null;null===c.da&&(e=Xf(a,c.n(0),!1),null!==e&&(g=e.S));var h=null,k=null;null===c.ja&&(h=Xf(a,c.n(c.ma-1),!0),null!==h&&(k=h.S));if((null===g||g instanceof y)&&(null===k||k instanceof y)){var l=d.isValidLink(g,e,k,h);b?(c.xn=c.n(0).copy(),c.Bn=c.n(c.ma-1).copy(),c.Kp=!1,c.da=g,null!==e&&(c.nf=e.sd),c.ja=k,null!==h&&(c.Qf=h.sd)):l?Yf(d,g,e,k,h):Yf(d,null,null,null,null)}}}} +gf.prototype.doDragOver=function(){};function Zf(a,b){var c=a.h;if(null!==c&&null!==c.fa){a.Ni&&Uf(a,!0);yf(a);var d=Vf(c,b,null,function(b){return!Sf(a,b)}),e=c.U;e.Yd=d;if(null!==d)for(var g=d;null!==g;){var h=g.bt;if(null!==h&&(h(e,g),e.Fe))break;g=g.ga}else h=c.bt,null!==h&&h(e);a.doDropOnto(b,d);for(d=c.selection.k;d.next();)e=d.value,e instanceof y&&$f(c,e.wa)}}gf.prototype.doDropOnto=function(){}; +gf.prototype.doMouseMove=function(){if(this.ra){var a=this.h;if(null!==a&&null!==this.Jo&&null!==this.wc){var b=!1,c=!1;this.mayCopy()?(b=!0,Gf(this,!1),Qf(this,this.pd,!0)):this.mayMove()?(c=!0,Cf(this),Qf(this,this.wc,!0)):Cf(this);Tf(this,a.U.W,c,b)}}}; +gf.prototype.doMouseUp=function(){if(this.ra){this.wq=!0;var a=this.h;if(null!==a){var b=!1,c=this.mayCopy();c&&null!==this.pd?(Df(this),Cf(this),Gf(this,!0),Qf(this,this.pd,!0),null!==this.pd&&a.tF(this.pd.Bl())):(b=!0,Cf(this),this.mayMove()&&(Qf(this,this.wc,!0),this.mv=!1,Tf(this,a.U.W,!0,!1),this.mv=!0));Zf(this,a.U.W);if(this.ra){this.pd=null;if(b&&null!==this.wc)for(b=this.wc.k;b.next();){var d=b.key;d instanceof y&&(d=d.fb,null===d||null===d.placeholder||this.wc.contains(d)||d.Kz&&d.aa())}a.Rc(); +zf(this,this.wc);this.bf=c?"Copy":"Move";a.Ja(c?"SelectionCopied":"SelectionMoved",a.selection)}this.stopTool()}}};gf.prototype.mayCopy=function(){var a=this.h;if(null===a||a.$a||a.Ue||!a.wm||!a.Rj||(a.Sl?!a.U.Xm:!a.U.control))return!1;for(a=a.selection.k;a.next();){var b=a.value;if(b.Ud()&&b.canCopy())return!0}return null!==this.dd&&this.Ni&&this.dd.canCopy()?!0:!1}; +gf.prototype.mayMove=function(){var a=this.h;if(null===a||a.$a||!a.al)return!1;for(a=a.selection.k;a.next();){var b=a.value;if(b.Ud()&&b.canMove())return!0}return null!==this.dd&&this.Ni&&this.dd.canMove()?!0:!1};var Af=new H(gf),sf=null,tf=null;gf.prototype.mayCopyExternal=function(){var a=this.h;return null===a||!a.Bz||a.$a||a.Ue||!a.wm||null===a.fa?!1:!0}; +gf.prototype.doSimulatedDragEnter=function(){if(this.mayCopyExternal()){var a=sf;if(null!==a){Cf(a);Df(a);var b=a.h;null!==b&&a.oo.Q()&&(b.position=a.oo);null!==b&&xf(b)}Af.contains(this)||Af.add(this)}};gf.prototype.doSimulatedDragLeave=function(){sf.qw=!1;this.doCancel()};gf.prototype.doSimulatedDragOver=function(){if(this.mayCopyExternal()){var a=this.h;if(null!==a){var b=sf;null!==b&&null!==b.wc&&(ag(this,b.wc.Bl(),!1),Qf(this,this.pd,!1),Tf(this,a.U.W,!1,!0))}}}; +gf.prototype.doSimulatedDrop=function(){var a=sf;if(null!==a&&(a.wq=!0,Cf(this),this.mayCopyExternal())){var b=this.h;null!==b&&(this.rc("Drop"),ag(this,a.wc.Bl(),!0),Qf(this,this.pd,!0),null!==this.pd&&b.tF(this.pd.Bl()),this.bf="ExternalCopy",Zf(this,b.U.W),this.pd=null,b.Ja("ExternalObjectsDropped",b.selection),this.kk(),b.Rc())}}; +function ag(a,b,c){if(null===a.pd){var d=a.h;if(null!==d&&!d.$a&&!d.Ue&&null!==d.fa){d.Bb=!c;a.Zp=!c;a.Zi=d.U.W;d=d.copyParts(b,d,!0);c=t.wf();Ff(b,c);var e=c.x+c.width/2,g=c.y+c.height/2;t.Pc(c);var h=a.ov;c=new sa(w,Object);var k=t.O();for(b=b.k;b.next();){var l=b.value;if(l.Ud()&&l.canCopy()){var m=l.location,l=d.Ba(l);k.q(h.x-(e-m.x),h.y-(g-m.y));l.location=k;a.Zp&&(l.Xd="Tool");l.Gf();c.add(l,wf(k))}}t.B(k);for(d=d.k;d.next();)e=d.value,e instanceof A&&e.canCopy()&&c.add(e,wf());a.pd=c;hf(a, +c.Bl());null!==a.dd&&(c=a.dd,d=c.oj(),c.ql(a.Zi.x-(d.x+d.width/2),a.Zi.y-(d.y+d.height/2)))}}} +function bg(){0=d&&(d=0.1);for(var e=this,g=b.Mm(c,d,function(b){return e.findValidLinkablePort(b,a)},null,!0),d=Infinity,b=null,g=g.k;g.next();){var h=g.value,k=h.S;if(k instanceof y){var l=h.gb(Wb,t.O()),m=c.x-l.x,n=c.y-l.y;t.B(l);l=m*m+n*n;lc){if(null!==this.fc&&a===this.tg&&b===this.ug)return!0;var d=b.sd;null===d&&(d="");if(a.fw(d).count>=c)return!1}return!0}; +bg.prototype.isValidTo=function(a,b){if(null===a||null===b)return this.Rm;if(this.h.Za===this&&(null!==a.layer&&!a.layer.xm||!0!==b.kB))return!1;var c=b.NF;if(Infinity>c){if(null!==this.fc&&a===this.vg&&b===this.wg)return!0;var d=b.sd;null===d&&(d="");if(a.mg(d).count>=c)return!1}return!0};bg.prototype.isInSameNode=function(a,b){if(null===a||null===b)return!1;if(a===b)return!0;var c=a.S,d=b.S;return null!==c&&c===d}; +bg.prototype.isLinked=function(a,b){if(null===a||null===b)return!1;var c=a.S;if(!(c instanceof y))return!1;var d=a.sd;null===d&&(d="");var e=b.S;if(!(e instanceof y))return!1;var g=b.sd;null===g&&(g="");for(e=e.mg(g);e.next();)if(g=e.value,g.da===c&&g.nf===d)return!0;return!1}; +bg.prototype.isValidLink=function(a,b,c,d){if(!this.isValidFrom(a,b)||!this.isValidTo(c,d)||!(null===b||null===d||(b.cE&&d.MF||!this.isInSameNode(b,d))&&(b.bE&&d.LF||!this.isLinked(b,d)))||null!==this.fc&&(null!==a&&cg(this,a,this.fc)||null!==c&&cg(this,c,this.fc))||null!==a&&null!==c&&(null===a.data&&null!==c.data||null!==a.data&&null===c.data)||!ig(this,a,c,this.fc))return!1;if(null!==a){var e=a.op;if(null!==e&&!e(a,b,c,d,this.fc))return!1}if(null!==c&&(e=c.op,null!==e&&!e(a,b,c,d,this.fc)))return!1; +e=this.op;return null!==e?e(a,b,c,d,this.fc):!0};function cg(a,b,c){if(null===b)return!1;var d=b.Sc;if(null===d)return!1;if(d===c)return!0;var e=new ua(y);e.add(b);return jg(a,d,c,e)}function jg(a,b,c,d){if(b===c)return!0;var e=b.da;if(null!==e&&e.Ih&&(d.add(e),jg(a,e.Sc,c,d)))return!0;b=b.ja;return null!==b&&b.Ih&&(d.add(b),jg(a,b.Sc,c,d))?!0:!1} +function ig(a,b,c,d){if(null===b||null===c)return a.Rm;var e=a.h.aG;if(e!==kg){if(e===lg){if(null!==d&&!d.xc)return!0;for(e=c.Dd;e.next();){var g=e.value;if(g!==d&&g.xc&&g.ja===c)return!1}return!mg(a,b,c,d,!0)}if(e===ng){if(null!==d&&!d.xc)return!0;for(e=b.Dd;e.next();)if(g=e.value,g!==d&&g.xc&&g.da===b)return!1;return!mg(a,b,c,d,!0)}if(e===og)return b===c?a=!0:(e=new ua(y),e.add(c),a=pg(a,e,b,c,d)),!a;if(e===qg)return!mg(a,b,c,d,!1);if(e===rg)return b===c?a=!0:(e=new ua(y),e.add(c),a=sg(a,e,b,c, +d)),!a}return!0}function mg(a,b,c,d,e){if(b===c)return!0;if(null===b||null===c)return!1;for(var g=b.Dd;g.next();){var h=g.value;if(h!==d&&(!e||h.xc)&&h.ja===b&&(h=h.da,h!==b&&mg(a,h,c,d,e)))return!0}return!1}function pg(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.Dd;g.next();){var h=g.value;if(h!==e&&h.ja===c&&(h=h.da,h!==c&&pg(a,b,h,d,e)))return!0}return!1} +function sg(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.Dd;g.next();){var h=g.value;if(h!==e){var k=h.da,h=h.ja,k=k===c?h:k;if(k!==c&&sg(a,b,k,d,e))return!0}}return!1}t.g(bg,"linkValidation",bg.prototype.op);t.defineProperty(bg,{op:"linkValidation"},function(){return this.Nk},function(a){null!==a&&t.j(a,"function",bg,"linkValidation");this.Nk=a});t.g(bg,"portTargeted",bg.prototype.mt); +t.defineProperty(bg,{mt:"portTargeted"},function(){return this.FC},function(a){null!==a&&t.j(a,"function",bg,"portTargeted");this.FC=a});function Aa(){0b.Ls+1&&ch.$j(e)&&(k=b.points.copy(),k.gd(c), +b.points=k,b.Ae(),b.updateAdornments()),t.B(h)}a.Rc();this.bf=this.name;a.Ja("LinkReshaped",this.ts)}this.stopTool()};function Sg(a,b,c,d,e,g){return g?Math.abs(b.y-c.y)=a.x)c=0>=a.y?c+225:1<=a.y?c+135:c+180;else if(1<=a.x)0>=a.y?c+=315:1<=a.y&&(c+=45);else if(0>=a.y)c+=270;else if(1<=a.y)c+=90;else break a;0>c?c+=360:360<=c&&(c-=360);b.cursor=22.5>c?"e-resize":67.5>c?"se-resize":112.5>c?"s-resize":157.5>c?"sw-resize":202.5>c?"w-resize":247.5>c?"nw-resize":292.5>c?"n-resize":337.5>c?"ne-resize":"e-resize"}else if(b instanceof B)for(b=b.elements;b.next();)Ug(a, +b.value,c)}t.defineProperty(Tg,{Ns:"handleArchetype"},function(){return this.Hk},function(a){a&&t.l(a,X,Tg,"handleArchetype");this.Hk=a});t.A(Tg,{handle:"handle"},function(){return this.Xb});t.defineProperty(Tg,{Nc:"adornedObject"},function(){return this.La},function(a){a&&t.l(a,X,Tg,"adornedObject");this.La=a});Tg.prototype.canStart=function(){if(!this.isEnabled)return!1;var a=this.h;return null!==a&&!a.$a&&a.Ao&&a.U.left?null!==this.findToolHandleAt(a.Ec.W,this.name)?!0:!1:!1}; +Tg.prototype.doActivate=function(){var a=this.h;null!==a&&(this.Xb=this.findToolHandleAt(a.Ec.W,this.name),null!==this.Xb&&(this.La=this.Xb.S.Nc,this.eo=this.La.angle,this.CG.set(this.La.Ga),this.Oy.set(this.La.S.location),this.Yu.set(this.La.Ca),this.by=this.computeCellSize(),this.gy=this.computeMinSize(),this.ey=this.computeMaxSize(),a.Bd=!0,this.rc(this.name),this.ra=!0))};Tg.prototype.doDeactivate=function(){var a=this.h;null!==a&&(this.kk(),this.La=this.Xb=null,this.ra=a.Bd=!1)}; +Tg.prototype.doCancel=function(){this.La.Ca=this.Yu;this.La.S.location=this.Oy;this.stopTool()};Tg.prototype.doMouseMove=function(){var a=this.h;if(this.ra&&null!==a){var b=this.gy,c=this.ey,d=this.by,e=this.La.gE(a.U.W,t.O()),g=Xg;this.La instanceof Y&&(g=this.La.kw,g===Yg&&(g=this.La.Ra.kc));b=this.computeResize(e,this.Xb.alignment,b,c,d,!(g===Zg||g===$g||a.U.shift));this.resize(b);a.Nh();t.B(e)}}; +Tg.prototype.doMouseUp=function(){var a=this.h;if(this.ra&&null!==a){var b=this.gy,c=this.ey,d=this.by,e=this.La.gE(a.U.W,t.O()),g=Xg;this.La instanceof Y&&(g=this.La.kw,g===Yg&&(g=this.La.Ra.kc));b=this.computeResize(e,this.Xb.alignment,b,c,d,!(g===Zg||g===$g||a.U.shift));this.resize(b);t.B(e);a.Rc();this.bf=this.name;a.Ja("PartResized",this.La,this.Yu)}this.stopTool()}; +Tg.prototype.resize=function(a){if(null!==this.h){var b=this.La.S,c=b.position.copy(),d=this.La.Ga.copy(),e=this.La.jl(),g=this.La.fk();360<=e?e-=360:0>e&&(e+=360);var h=Math.PI*e/180,k=Math.cos(h),h=Math.sin(h),l=a.width-d.width,d=a.height-d.height,m=90e?1:0;c.x+=g*((a.x+l*m)*k-(a.y+d*(0e?1:0))*h);c.y+=g*((a.x+l*(180e?1:0))*h+(a.y+d*m)*k);this.La.Ca=a.size;b.Gf();b.move(c)}}; +Tg.prototype.computeResize=function(a,b,c,d,e,g){b.qd()&&(b=Wb);var h=this.La.Ga,k=h.x,l=h.y,m=h.x+h.width,n=h.y+h.height,p=1;if(!g){var p=h.width,q=h.height;0>=p&&(p=1);0>=q&&(q=1);p=q/p}q=t.O();J.Hs(a.x,a.y,k,l,e.width,e.height,q);a=h.copy();0>=b.x?0>=b.y?(a.x=Math.max(q.x,m-d.width),a.x=Math.min(a.x,m-c.width),a.width=Math.max(m-a.x,c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.width=Math.max(Math.min(q.x-k,d.width),c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y, +n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=n-a.y,g||(a.width= +a.height/p,a.x=k+0.5*(m-k-a.width))):1<=b.y&&(a.height=Math.max(Math.min(q.y-l,d.height),c.height),g||(a.width=a.height/p,a.x=k+0.5*(m-k-a.width)));t.B(q);return a};Tg.prototype.computeMinSize=function(){var a=this.La.Ye.copy(),b=this.Ye;!isNaN(b.width)&&b.width>a.width&&(a.width=b.width);!isNaN(b.height)&&b.height>a.height&&(a.height=b.height);return a}; +Tg.prototype.computeMaxSize=function(){var a=this.La.He.copy(),b=this.He;!isNaN(b.width)&&b.widtha&&(a+=360));var b=Math.min(Math.abs(this.FF),180),c=Math.min(Math.abs(this.EF),b/2);!this.h.U.shift&&0b-c&&(a=(Math.floor(a/b)+1)*b));360<=a?a-=360:0>a&&(a+=360);return a};t.g(ah,"snapAngleMultiple",ah.prototype.FF); +t.defineProperty(ah,{FF:"snapAngleMultiple"},function(){return this.bz},function(a){this.bz!==a&&(f&&t.j(a,"number",ah,"snapAngleMultiple"),this.bz=a)});t.g(ah,"snapAngleEpsilon",ah.prototype.EF);t.defineProperty(ah,{EF:"snapAngleEpsilon"},function(){return this.az},function(a){this.az!==a&&(f&&t.j(a,"number",ah,"snapAngleEpsilon"),this.az=a)});t.g(ah,"originalAngle",ah.prototype.KI);t.A(ah,{KI:"originalAngle"},function(){return this.eo}); +function ch(){0e.right&&(c.x-=d.width+5);c.xe.bottom&&(c.y-=d.height+5);c.ye.right&&(c.x-=d.width+5);c.xe.bottom?c.y-(d.height+5):c.y+20;c.y=a)return b;for(var c=0,d=0,e=0,g=0,h=0,k=this.cb.k;k.next();){var l=k.value;l instanceof z?e++:l instanceof y?d++:l instanceof A?g++:l instanceof We?h++:c++}k="";0=d.count)a=d.count;else if(d.qa(a)===b)return-1;d.Ad(a,b);b.Ps();d=this.h;null!==d&&(c?d.pa():d.Qm(b));b instanceof z&&this.Pw(b);return a};aa.Te=function(a,b,c){var d=this.cb;if(0>a||a>=d.length){if(a=d.indexOf(b),0>a)return-1}else if(d.qa(a)!==b&&(a=d.indexOf(b),0>a))return-1;b.Qs();d.gd(a);d=this.h;null!==d&&(c?d.pa():d.Te(b));b.Vn=null;return a}; +aa.Pw=function(a){for(;null!==a;){if(a.layer===this){var b=a;if(b.Hc.next()){for(var c=-1,d=-1,e=this.cb.p,g=e.length,h=0;hd&&k.fb===b&&(d=h,0<=c))break}!(0>d)&&da||1=a)return b;for(var c=this.Kb.k;c.next();)b+="\n "+c.value.toString(a-1);return b};u.prototype.checkProperties=function(){return t.lH(this)};u.fromDiv=function(a){var b=a;"string"===typeof a&&(b=document.getElementById(a));return b instanceof HTMLDivElement&&b.ea instanceof u?b.ea:null};t.g(u,"div",u.prototype.Mi); +t.defineProperty(u,{Mi:"div"},function(){return this.Ab},function(a){null!==a&&t.l(a,HTMLDivElement,u,"div");if(this.Ab!==a){var b=this.Ab;if(null!==b){delete b.ea;b.innerHTML="";null!==this.Pa&&(this.Pa.ea=null,this.Pa.removeEventListener("touchstart",this.QF,!1),this.Pa.removeEventListener("touchmove",this.PF,!1),this.Pa.removeEventListener("touchend",this.OF,!1));b=this.xv;if(null!==b){for(var c=b.vC.p,d=c.length,e=0;e=d&&t.Qa(t.Gv)!==t.Qa("7da71ca0ad381e90")&&(d=a[t.Qa("73a612b6fb191d")](t.Qa("76a715b2ef3e149757")));if(this.jj=!(0a.scale&&h.canIncreaseZoom()||gc)b.preventDefault();else{a.em=null;return}if(null!==a.em){var d=a.Pa,e=d.getBoundingClientRect();b=new C(b.pageX-window.scrollX-d.width/e.width*e.left,b.pageY-window.scrollY-d.height/e.height*e.top);d=a.Wh;c*=a.em;e=a.lg;if(c>a.scale&&e.canIncreaseZoom()||cl&&(a.position= +new C(-(a.Hj.scrollWidth-a.tc)+this.scrollLeft-a.tc/r+a.vc.right,a.position.y))),this.KC&&a.jf&&(bn&&(a.position=new C(a.position.x,-(a.Ij.scrollHeight-a.sc)+this.scrollTop-a.sc/r+a.vc.bottom))),t.B(s),ai(a),a.gv=!1,a.rj=!1,b=a.vc,c=a.nb,k=b.right,l=c.right,m=b.bottom,n=c.bottom,p=b.x,q=c.x,b=b.y,c=c.y,e>=d&&p>=q&&k<=l&&(a.Xy.style.width="1px"),h>=g&&b>=c&&m<=n&&(a.Yy.style.height="1px")}}else bi(this.ea)}; +u.prototype.BC=function(){this.ea.isEnabled?this.ea.Wy=!0:bi(this.ea)};u.prototype.computeBounds=u.prototype.kf=function(){0a.pg&&(l=a.pg),l):b===oi?(l=k>h?(g-a.gf)/c:(e-a.gf)/d,1a.pg&&(l=a.pg),l):a.scale}}u.prototype.zoomToFit=u.prototype.zoomToFit=function(){this.scale=fi(this,ni)}; +u.prototype.zoomToRect=function(a,b){void 0===b&&(b=ni);var c=a.width,d=a.height;if(!(0===c||0===d||isNaN(c)&&isNaN(d))){var e=1;if(b===ni||b===oi)if(isNaN(c))e=this.nb.height*this.scale/d;else if(isNaN(d))e=this.nb.width*this.scale/c;else var e=this.tc,g=this.sc,e=b===oi?g/d>e/c?(g-(this.Ol?this.gf:0))/d:(e-(this.Pl?this.gf:0))/c:Math.min(g/d,e/c);this.scale=e;this.position=new C(a.x,a.y)}}; +u.prototype.alignDocument=function(a,b){this.qj&&hi(this,this.kf());var c=this.vc,d=this.nb,e=this.lc;this.lc=!0;this.position=new C(c.x+(a.x*c.width+a.offsetX)-(b.x*d.width-b.offsetX),c.y+(a.y*c.height+a.offsetY)-(b.y*d.height-b.offsetY));this.lc=e;this.pa()}; +function gi(a,b,c,d,e,g){g.rd()&&(d>c.width&&(b.x=c.x+(g.x*c.width+g.offsetX)-(g.x*d-g.offsetX)),e>c.height&&(b.y=c.y+(g.y*c.height+g.offsetY)-(g.y*e-g.offsetY)));dc.left?b.x=c.left:b.xc.top?b.y=c.top:b.yc.touches.length)&&c.preventDefault();c.cancelBubble=!0;return!1} +u.prototype.xI=function(a){if(this.ea.isEnabled){var b=this.ea.cc;Wh(this.ea,this.ea,a,b,!1);b.key=String.fromCharCode(a.which);b.ak=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del";break;case 48:b.key="0";break;case 187:b.key="Add";break;case 189:b.key="Subtract"; +break;case 107:b.key="Add";break;case 109:b.key="Subtract";break;case 27:b.key="Esc"}this.ea.doKeyDown();return 187!==a.which&&189!==a.which&&48!==a.which&&107!==a.which&&109!==a.which||!0!==a.ctrlKey?ga(this.ea,b,a):(a.cancelBubble=!0,void 0!==a.preventDefault?a.preventDefault():a.returnValue=!1,Event.stop&&(t.m("Event.stop can fire for this browser"),Event.stop(a)),void 0!==a.stopPropagation&&a.stopPropagation(),!1)}}; +u.prototype.yI=function(a){if(this.ea.isEnabled){var b=this.ea.cc;Wh(this.ea,this.ea,a,b,!1);b.key=String.fromCharCode(a.which);b.aj=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del"}this.ea.doKeyUp();return ga(this.ea,b,a)}}; +u.prototype.Ig=function(a){var b=this.Pa;if(null===b)return new C(0,0);var c=b.getBoundingClientRect(),d=a.clientX-b.width/c.width*c.left;a=a.clientY-b.height/c.height*c.top;return null!==this.bd?(d=new C(d,a),$a(d,this.bd),d):new C(d,a)};t.g(u,"renderingHints",u.prototype.gF);t.defineProperty(u,{gF:"renderingHints"},function(){return this.GC},function(a){this.GC=a;this.ot()});u.prototype.invalidateDocumentBounds=u.prototype.Rc=function(){this.qj=!0;this.Nf()}; +function pi(a){a.Jd||ci(a);a.qj&&hi(a,a.kf());ei(a);for(a=a.ho.k;a.next();)pi(a.value)}u.prototype.redraw=u.prototype.ot=function(){this.lc||this.Jd||(this.pa(),qi(this),ai(this),this.Rc(),this.Nh())};u.prototype.isUpdateRequested=function(){return this.hg};u.prototype.delayInitialization=function(a){ri(this);this.Xf=!1;a&&setTimeout(a,1)}; +u.prototype.requestUpdate=u.prototype.Nf=function(a){void 0===a&&(a=!1);if(!0!==this.hg&&!(this.lc||!1===a&&this.Jd)){this.hg=!0;var b=this;requestAnimationFrame(function(){b.hg&&b.Nh()})}};u.prototype.maybeUpdate=u.prototype.Nh=function(){if(!this.Bq||this.hg)this.Bq&&(this.Bq=!1),ri(this)}; +function ri(a){if(!a.Jd&&(a.hg=!1,null!==a.Ab)){a.Jd=!0;a.sA();!a.lc&&a.rj&&(bi(a)||bi(a));null!==a.Xc&&(a.Xc.visible&&!a.qu&&(si(a),a.qu=!0),!a.Xc.visible&&a.qu&&(a.qu=!1));ci(a);var b=!1;if(!a.Xf||a.Tt)a.Xf?ti(a,!a.ju):(a.rc("Initial Layout"),ti(a,!1)),b=!0;a.ju=!1;ci(a);a.$y||pi(a);b&&(a.Xf||(ui(a),si(a)),a.Ja("LayoutCompleted"));vi(a);ci(a);a.lc||!a.rj||bi(a)||(bi(a),ci(a));b&&!a.Xf&&(a.Xf=!0,a.De("Initial Layout"),a.Aa.clear(),setTimeout(function(){a.hk=!1},1));a.Re();a.Jd=!1}} +function ui(a){if(a.Kk!==$e)a.scale=fi(a,a.Kk);else if(a.Fl!==$e)a.scale=fi(a,a.Fl);else{var b=a.tE;isFinite(b)&&0b;b++){var c=a.Yf.k;if(null===c||0===a.Yf.count)break;a.Yf=new ua(X);var d=a,e=a.Yf;for(c.reset();c.next();){var g=c.value;!g.Ud()||g instanceof z||(g.nl()?(Bh(g,Infinity,Infinity),g.Dc()):e.add(g))}for(c.reset();c.next();)g=c.value,g instanceof z&&wi(d,g);for(c.reset();c.next();)d=c.value,d instanceof A&&(d.nl()?(Bh(d,Infinity,Infinity),d.Dc(),d.zw()):e.add(d));for(c.reset();c.next();)d=c.value,d instanceof We&&(d.nl()?(Bh(d,Infinity,Infinity),d.Dc()): +e.add(d))}}function wi(a,b){for(var c=b.Hc,d=t.Cb();c.next();){var e=c.value;e instanceof z?(xi(e)||yi(e)||zi(e))&&wi(a,e):e instanceof A?d.push(e):(Bh(e,Infinity,Infinity),e.Dc())}c=d.length;for(e=0;e=l[0]&&c>=l[1]&&b+d<=l[0]+l[2]&&c+e<=l[1]+l[3])return!1;b<=l[0]&&c<=l[1]&&b+d>=l[0]+l[2]&&c+e>=l[1]+l[3]?(g[k][2]=0,g[k][3]=0):b>=l[0]&&b=l[1]&&c+e<=l[1]+l[3]?(d=b+d-(l[0]+l[2]),b=l[0]+l[2],k=-1):b+d>l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c+e<=l[1]+l[3]?(d=l[0]-b,k=-1):b>=l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c= +l[0]&&b+d<=l[0]+l[2]&&c+e>l[1]&&c+e<=l[1]+l[3]?(e=l[1]-c,k=-1):g[k][0]>=b&&g[k][0]=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]-=b+d-g[k][0],g[k][0]=b+d,k=-1):g[k][0]+g[k][2]>b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]=b-g[k][0],k=-1):g[k][0]>=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]+g[k][3]>c&&g[k][1]+g[k][3]<=c+e&&(g[k][3]=c-g[k][1],k=-1)}for(k=0;kk&&c/W>l||(a.nE&&a.hf&&(q+1E+1&&(n=(x-E)*W+a.tc+"px",a.Hj.scrollLeft=a.position.x*W)),a.oE&&a.jf&&(r+1N+1&&(p=(L-N)*W+a.sc+"px",a.Ij.scrollTop=a.position.y*W)));m="1px"!==n;c="1px"!==p;m!==a.Ol&&(a.sc="1px"===n?a.sc+a.gf:Math.max(a.sc-a.gf,1),b.height=a.sc,h=!0);a.Ol=m;a.Xy.style.width=n;c!==a.Pl&&(a.tc= +"1px"===p?a.tc+a.gf:Math.max(a.tc-a.gf,1),b.width=a.tc,h=!0);a.Pl=c;a.Yy.style.height=p;h&&ca(a);m=a.tc;c=a.sc;a.Ij.style.height=c+"px";a.Ij.style.width=m+(a.Pl?a.gf:0)+"px";a.Hj.style.width=m+"px";a.Hj.style.height=c+(a.Ol?a.gf:0)+"px";a.Wy=!1;return d!==m||e!==c?(n=a.nb,a.kt(g,n,h?!0:void 0),!1):!0}}} +u.prototype.add=u.prototype.add=function(a){t.l(a,w,u,"add:part");var b=a.h;if(b!==this){null!==b&&t.m("Cannot add part "+a.toString()+" to "+this.toString()+". It is already a part of "+b.toString());var c=a.Xd,b=this.il(c);null===b&&(b=this.il(""));null===b&&t.m('Cannot add a Part when unable find a Layer named "'+c+'" and there is no default Layer');a.layer!==b&&(c=a.h===this?b.Qm(99999999,a,!0):b.Qm(99999999,a),0<=c&&this.Uc(Jd,"parts",b,null,a,null,c),b.pc||this.Rc(),a.K(Hi),c=a.fp,null!==c&& +c(a,null,b))}};u.prototype.Qm=function(a){if(a instanceof y){if(this.Vu.add(a),a instanceof z){var b=a.fb;null===b?this.Vk.add(a):b.cm.add(a);b=a.Tb;null!==b&&(b.h=this)}}else a instanceof A?this.Eu.add(a):a instanceof We||this.cb.add(a);a.wb&&a.aa();if(b=a.data){a instanceof We||(a instanceof A?this.Dk.add(b,a):this.di.add(b,a));var c=this;Ii(a,function(a){Ji(c,a)})}!0!==yi(a)&&!0!==zi(a)||this.Yf.add(a);Ki(a,!0,this);a.zb()&&(a.wa.Q()&&this.pa(Jh(a,a.wa)),this.Rc())}; +u.prototype.Te=function(a){a.Ae();if(a instanceof y){if(this.Vu.remove(a),a instanceof z){var b=a.fb;null===b?this.Vk.remove(a):b.cm.remove(a);b=a.Tb;null!==b&&(b.h=null)}}else a instanceof A?this.Eu.remove(a):a instanceof We||this.cb.remove(a);if(b=a.data){a instanceof We||(a instanceof A?this.Dk.remove(b):this.di.remove(b));var c=this;Ii(a,function(a){Li(c,a)})}this.Yf.remove(a);a.zb()&&(a.wa.Q()&&this.pa(Jh(a,a.wa)),this.Rc())}; +u.prototype.remove=u.prototype.remove=function(a){t.l(a,w,u,"remove:part");a.bb=!1;var b=a.layer;if(null!==b&&b.h===this){a.K(Mi);a.Jm();var c=b.Te(-1,a);0<=c&&this.Uc(Td,"parts",b,a,null,c,null);c=a.fp;null!==c&&c(a,b,null);b.pc||this.Rc()}};u.prototype.removeParts=u.prototype.PA=function(a,b){if(a===this.selection){var c=new ua;c.Me(a);a=c}for(c=a.k;c.next();){var d=c.value;d.h===this&&(b&&!d.canDelete()||this.remove(d))}}; +u.prototype.copyParts=u.prototype.copyParts=function(a,b,c){return this.lg.copyParts(a,b,c)};u.prototype.moveParts=u.prototype.moveParts=function(a,b,c){t.l(b,C,u,"moveParts:offset");var d=this.Db;if(null!==d){d=d.ke;null===d&&(d=new gf,d.h=this);var e=new sa(w,Object);if(a)a=a.k;else{for(a=this.sl;a.next();)vf(d,e,a.value,c);for(a=this.Yi;a.next();)vf(d,e,a.value,c);a=this.links}for(;a.next();)vf(d,e,a.value,c);d.moveParts(e,b,c)}}; +function Ni(a,b,c){t.l(b,pe,u,"addLayer:layer");null!==b.h&&b.h!==a&&t.m("Cannot share a Layer with another Diagram: "+b+" of "+b.h);null===c?null!==b.h&&t.m("Cannot add an existing Layer to this Diagram again: "+b):(t.l(c,pe,u,"addLayer:existingLayer"),c.h!==a&&t.m("Existing Layer must be in this Diagram: "+c+" not in "+c.h),b===c&&t.m("Cannot move a Layer before or after itself: "+b));if(b.h!==a){b=b.name;a=a.Kb;c=a.count;for(var d=0;dd&&this.Rc()}; +u.prototype.addLayerAfter=function(a,b){Ni(this,a,b);a.qe(this);var c=this.Kb,d=c.indexOf(a);0<=d&&(c.remove(a),null!==this.Md&&this.Uc(Td,"layers",this,a,null,d,null));for(var e=c.count,g=0;gd&&this.Rc()}; +u.prototype.removeLayer=function(a){t.l(a,pe,u,"removeLayer:layer");a.h!==this&&t.m("Cannot remove a Layer from another Diagram: "+a+" of "+a.h);if(""!==a.name){var b=this.Kb,c=b.indexOf(a);if(b.remove(a)){for(b=a.cb.copy().k;b.next();){var d=b.value,e=d.Xd;d.Xd=e!==a.name?e:""}null!==this.Md&&this.Uc(Td,"layers",this,a,null,c,null);this.pa();this.Rc()}}};u.prototype.findLayer=u.prototype.il=function(a){for(var b=this.Um;b.next();){var c=b.value;if(c.name===a)return c}return null}; +u.prototype.addChangedListener=u.prototype.zz=function(a){t.j(a,"function",u,"addChangedListener:listener");null===this.fj&&(this.fj=new H("function"));this.fj.add(a)};u.prototype.removeChangedListener=u.prototype.NA=function(a){t.j(a,"function",u,"removeChangedListener:listener");null!==this.fj&&(this.fj.remove(a),0===this.fj.count&&(this.fj=null))}; +u.prototype.Nv=function(a){this.Bb||this.Aa.lE(a);a.od!==Hd&&(this.hk=!0);if(null!==this.fj){var b=this.fj,c=b.length;if(1===c)b=b.qa(0),b(a);else if(0!==c)for(var d=b.af(),e=0;em||("LineV"===l.Ib?g=g*m/J.eE(g,m):e=e*m/J.eE(e,m))}h=c.Ms;d.q(g*h.width,e*h.height);if(b)k=b.width,l=b.height,g=b.x,h=b.y;else{e=t.wf();g=a.nb;e.q(g.x,g.y,g.width,g.height);for(h=a.ho.k;h.next();)g=h.value.nb,wb(e,g.x,g.y,g.width,g.height);k=e.width;l=e.height;g=e.x;h=e.y;if(!e.Q())return}c.width=k+2*d.width;c.height=l+2*d.height;e=t.O();J.Hs(g,h,0,0,d.width,d.height, +e);e.offset(-d.width,-d.height);t.dk(d);c.S.location=e;t.B(e)}}u.prototype.clearSelection=u.prototype.Pv=function(){var a=0a&&t.ha(a,">= zero",u,"linkSpacing"),this.uj=a,this.i("linkSpacing",b,a))});t.A(u,{Um:"layers"},function(){return this.Kb.k});t.g(u,"isModelReadOnly",u.prototype.Ue);t.defineProperty(u,{Ue:"isModelReadOnly"},function(){var a=this.Md;return null===a?!1:a.$a},function(a){var b=this.Md;null!==b&&(b.$a=a)});t.g(u,"isReadOnly",u.prototype.$a); +t.defineProperty(u,{$a:"isReadOnly"},function(){return this.Mk},function(a){var b=this.Mk;b!==a&&(t.j(a,"boolean",u,"isReadOnly"),this.Mk=a,this.i("isReadOnly",b,a))});t.g(u,"isEnabled",u.prototype.isEnabled);t.defineProperty(u,{isEnabled:"isEnabled"},function(){return this.ii},function(a){var b=this.ii;b!==a&&(t.j(a,"boolean",u,"isEnabled"),this.ii=a,this.i("isEnabled",b,a))});t.g(u,"allowClipboard",u.prototype.Hv); +t.defineProperty(u,{Hv:"allowClipboard"},function(){return this.Lt},function(a){var b=this.Lt;b!==a&&(t.j(a,"boolean",u,"allowClipboard"),this.Lt=a,this.i("allowClipboard",b,a))});t.g(u,"allowCopy",u.prototype.Rj);t.defineProperty(u,{Rj:"allowCopy"},function(){return this.pk},function(a){var b=this.pk;b!==a&&(t.j(a,"boolean",u,"allowCopy"),this.pk=a,this.i("allowCopy",b,a))});t.g(u,"allowDelete",u.prototype.$k); +t.defineProperty(u,{$k:"allowDelete"},function(){return this.qk},function(a){var b=this.qk;b!==a&&(t.j(a,"boolean",u,"allowDelete"),this.qk=a,this.i("allowDelete",b,a))});t.g(u,"allowDragOut",u.prototype.Iv);t.defineProperty(u,{Iv:"allowDragOut"},function(){return this.Mt},function(a){var b=this.Mt;b!==a&&(t.j(a,"boolean",u,"allowDragOut"),this.Mt=a,this.i("allowDragOut",b,a))});t.g(u,"allowDrop",u.prototype.Bz); +t.defineProperty(u,{Bz:"allowDrop"},function(){return this.Nt},function(a){var b=this.Nt;b!==a&&(t.j(a,"boolean",u,"allowDrop"),this.Nt=a,this.i("allowDrop",b,a))});t.g(u,"allowTextEdit",u.prototype.Co);t.defineProperty(u,{Co:"allowTextEdit"},function(){return this.zk},function(a){var b=this.zk;b!==a&&(t.j(a,"boolean",u,"allowTextEdit"),this.zk=a,this.i("allowTextEdit",b,a))});t.g(u,"allowGroup",u.prototype.yo); +t.defineProperty(u,{yo:"allowGroup"},function(){return this.rk},function(a){var b=this.rk;b!==a&&(t.j(a,"boolean",u,"allowGroup"),this.rk=a,this.i("allowGroup",b,a))});t.g(u,"allowUngroup",u.prototype.Do);t.defineProperty(u,{Do:"allowUngroup"},function(){return this.Ak},function(a){var b=this.Ak;b!==a&&(t.j(a,"boolean",u,"allowUngroup"),this.Ak=a,this.i("allowUngroup",b,a))});t.g(u,"allowInsert",u.prototype.wm); +t.defineProperty(u,{wm:"allowInsert"},function(){return this.Pt},function(a){var b=this.Pt;b!==a&&(t.j(a,"boolean",u,"allowInsert"),this.Pt=a,this.i("allowInsert",b,a))});t.g(u,"allowLink",u.prototype.xm);t.defineProperty(u,{xm:"allowLink"},function(){return this.sk},function(a){var b=this.sk;b!==a&&(t.j(a,"boolean",u,"allowLink"),this.sk=a,this.i("allowLink",b,a))});t.g(u,"allowRelink",u.prototype.Sj); +t.defineProperty(u,{Sj:"allowRelink"},function(){return this.uk},function(a){var b=this.uk;b!==a&&(t.j(a,"boolean",u,"allowRelink"),this.uk=a,this.i("allowRelink",b,a))});t.g(u,"allowMove",u.prototype.al);t.defineProperty(u,{al:"allowMove"},function(){return this.tk},function(a){var b=this.tk;b!==a&&(t.j(a,"boolean",u,"allowMove"),this.tk=a,this.i("allowMove",b,a))});t.g(u,"allowReshape",u.prototype.zo); +t.defineProperty(u,{zo:"allowReshape"},function(){return this.vk},function(a){var b=this.vk;b!==a&&(t.j(a,"boolean",u,"allowReshape"),this.vk=a,this.i("allowReshape",b,a))});t.g(u,"allowResize",u.prototype.Ao);t.defineProperty(u,{Ao:"allowResize"},function(){return this.wk},function(a){var b=this.wk;b!==a&&(t.j(a,"boolean",u,"allowResize"),this.wk=a,this.i("allowResize",b,a))});t.g(u,"allowRotate",u.prototype.Bo); +t.defineProperty(u,{Bo:"allowRotate"},function(){return this.xk},function(a){var b=this.xk;b!==a&&(t.j(a,"boolean",u,"allowRotate"),this.xk=a,this.i("allowRotate",b,a))});t.g(u,"allowSelect",u.prototype.Ne);t.defineProperty(u,{Ne:"allowSelect"},function(){return this.yk},function(a){var b=this.yk;b!==a&&(t.j(a,"boolean",u,"allowSelect"),this.yk=a,this.i("allowSelect",b,a))});t.g(u,"allowUndo",u.prototype.Cz); +t.defineProperty(u,{Cz:"allowUndo"},function(){return this.Qt},function(a){var b=this.Qt;b!==a&&(t.j(a,"boolean",u,"allowUndo"),this.Qt=a,this.i("allowUndo",b,a))});t.g(u,"allowZoom",u.prototype.us);t.defineProperty(u,{us:"allowZoom"},function(){return this.St},function(a){var b=this.St;b!==a&&(t.j(a,"boolean",u,"allowZoom"),this.St=a,this.i("allowZoom",b,a))});t.g(u,"hasVerticalScrollbar",u.prototype.oE); +t.defineProperty(u,{oE:"hasVerticalScrollbar"},function(){return this.uu},function(a){var b=this.uu;b!==a&&(t.j(a,"boolean",u,"hasVerticalScrollbar"),this.uu=a,qi(this),this.pa(),this.i("hasVerticalScrollbar",b,a),ei(this))});t.g(u,"hasHorizontalScrollbar",u.prototype.nE);t.defineProperty(u,{nE:"hasHorizontalScrollbar"},function(){return this.tu},function(a){var b=this.tu;b!==a&&(t.j(a,"boolean",u,"hasHorizontalScrollbar"),this.tu=a,qi(this),this.pa(),this.i("hasHorizontalScrollbar",b,a),ei(this))}); +t.g(u,"allowHorizontalScroll",u.prototype.hf);t.defineProperty(u,{hf:"allowHorizontalScroll"},function(){return this.Ot},function(a){var b=this.Ot;b!==a&&(t.j(a,"boolean",u,"allowHorizontalScroll"),this.Ot=a,this.i("allowHorizontalScroll",b,a),ei(this))});t.g(u,"allowVerticalScroll",u.prototype.jf);t.defineProperty(u,{jf:"allowVerticalScroll"},function(){return this.Rt},function(a){var b=this.Rt;b!==a&&(t.j(a,"boolean",u,"allowVerticalScroll"),this.Rt=a,this.i("allowVerticalScroll",b,a),ei(this))}); +t.g(u,"scrollHorizontalLineChange",u.prototype.Dp);t.defineProperty(u,{Dp:"scrollHorizontalLineChange"},function(){return this.hv},function(a){var b=this.hv;b!==a&&(t.j(a,"number",u,"scrollHorizontalLineChange"),0>a&&t.ha(a,">= 0",u,"scrollHorizontalLineChange"),this.hv=a,this.i("scrollHorizontalLineChange",b,a))});t.g(u,"scrollVerticalLineChange",u.prototype.Ep); +t.defineProperty(u,{Ep:"scrollVerticalLineChange"},function(){return this.iv},function(a){var b=this.iv;b!==a&&(t.j(a,"number",u,"scrollVerticalLineChange"),0>a&&t.ha(a,">= 0",u,"scrollVerticalLineChange"),this.iv=a,this.i("scrollVerticalLineChange",b,a))});t.g(u,"lastInput",u.prototype.U);t.defineProperty(u,{U:"lastInput"},function(){return this.cc},function(a){f&&t.l(a,wd,u,"lastInput");this.cc=a});t.g(u,"firstInput",u.prototype.Ec); +t.defineProperty(u,{Ec:"firstInput"},function(){return this.Hg},function(a){f&&t.l(a,wd,u,"firstInput");this.Hg=a});t.g(u,"currentCursor",u.prototype.cd);t.defineProperty(u,{cd:"currentCursor"},function(){return this.fu},function(a){t.j(a,"string",u,"currentCursor");null===this.Pa||this.fu===a||""===a&&this.fu===this.uq||(this.fu=a,""!==a?(this.Pa.style.cursor=a,this.Ab.style.cursor=a):(this.Pa.style.cursor=this.Pz,this.Ab.style.cursor=this.Pz))});t.g(u,"defaultCursor",u.prototype.Pz); +t.defineProperty(u,{Pz:"defaultCursor"},function(){return this.uq},function(a){t.j(a,"string",u,"defaultCursor");var b=this.uq;b!==a&&(this.uq=a,this.i("defaultCursor",b,a))});t.g(u,"hasGestureZoom",u.prototype.eI);t.defineProperty(u,{eI:"hasGestureZoom"},function(){return this.hi},function(a){var b=this.hi;b!==a&&(t.j(a,"boolean",u,"hasGestureZoom"),this.hi=a,this.i("hasGestureZoom",b,a))});t.g(u,"click",u.prototype.click); +t.defineProperty(u,{click:"click"},function(){return this.$h},function(a){var b=this.$h;b!==a&&(null!==a&&t.j(a,"function",u,"click"),this.$h=a,this.i("click",b,a))});t.g(u,"doubleClick",u.prototype.Km);t.defineProperty(u,{Km:"doubleClick"},function(){return this.fi},function(a){var b=this.fi;b!==a&&(null!==a&&t.j(a,"function",u,"doubleClick"),this.fi=a,this.i("doubleClick",b,a))});t.g(u,"contextClick",u.prototype.Cs); +t.defineProperty(u,{Cs:"contextClick"},function(){return this.bi},function(a){var b=this.bi;b!==a&&(null!==a&&t.j(a,"function",u,"contextClick"),this.bi=a,this.i("contextClick",b,a))});t.g(u,"mouseOver",u.prototype.et);t.defineProperty(u,{et:"mouseOver"},function(){return this.pi},function(a){var b=this.pi;b!==a&&(null!==a&&t.j(a,"function",u,"mouseOver"),this.pi=a,this.i("mouseOver",b,a))});t.g(u,"mouseHover",u.prototype.dt); +t.defineProperty(u,{dt:"mouseHover"},function(){return this.oi},function(a){var b=this.oi;b!==a&&(null!==a&&t.j(a,"function",u,"mouseHover"),this.oi=a,this.i("mouseHover",b,a))});t.g(u,"mouseHold",u.prototype.ct);t.defineProperty(u,{ct:"mouseHold"},function(){return this.ni},function(a){var b=this.ni;b!==a&&(null!==a&&t.j(a,"function",u,"mouseHold"),this.ni=a,this.i("mouseHold",b,a))});t.g(u,"mouseDragOver",u.prototype.VE); +t.defineProperty(u,{VE:"mouseDragOver"},function(){return this.Ou},function(a){var b=this.Ou;b!==a&&(null!==a&&t.j(a,"function",u,"mouseDragOver"),this.Ou=a,this.i("mouseDragOver",b,a))});t.g(u,"mouseDrop",u.prototype.bt);t.defineProperty(u,{bt:"mouseDrop"},function(){return this.mi},function(a){var b=this.mi;b!==a&&(null!==a&&t.j(a,"function",u,"mouseDrop"),this.mi=a,this.i("mouseDrop",b,a))});t.g(u,"toolTip",u.prototype.Et); +t.defineProperty(u,{Et:"toolTip"},function(){return this.zi},function(a){var b=this.zi;b!==a&&(null!==a&&t.l(a,We,u,"toolTip"),this.zi=a,this.i("toolTip",b,a))});t.g(u,"contextMenu",u.prototype.contextMenu);t.defineProperty(u,{contextMenu:"contextMenu"},function(){return this.ci},function(a){var b=this.ci;b!==a&&(null!==a&&t.l(a,We,u,"contextMenu"),this.ci=a,this.i("contextMenu",b,a))});t.g(u,"commandHandler",u.prototype.lg); +t.defineProperty(u,{lg:"commandHandler"},function(){return this.Hx},function(a){var b=this.Hx;b!==a&&(t.l(a,xa,u,"commandHandler"),null!==a.h&&t.m("Cannot share CommandHandlers between Diagrams: "+a.toString()),null!==b&&b.qe(null),this.Hx=a,a.qe(this))});t.g(u,"toolManager",u.prototype.Db); +t.defineProperty(u,{Db:"toolManager"},function(){return this.xv},function(a){var b=this.xv;b!==a&&(t.l(a,Ke,u,"toolManager"),null!==a.h&&t.m("Cannot share ToolManagers between Diagrams: "+a.toString()),null!==b&&b.qe(null),this.xv=a,a.qe(this))});t.g(u,"defaultTool",u.prototype.Yv);t.defineProperty(u,{Yv:"defaultTool"},function(){return this.Vx},function(a){var b=this.Vx;b!==a&&(t.l(a,qe,u,"defaultTool"),this.Vx=a,this.Za===b&&(this.Za=a))});t.g(u,"currentTool",u.prototype.Za); +t.defineProperty(u,{Za:"currentTool"},function(){return this.Qx},function(a){var b=this.Qx;null!==b&&(b.ra&&b.doDeactivate(),b.cancelWaitAfter(),b.doStop());null===a&&(a=this.Yv);null!==a&&(t.l(a,qe,u,"currentTool"),this.Qx=a,a.qe(this),a.doStart())});t.A(u,{selection:"selection"},function(){return this.lv});t.g(u,"maxSelectionCount",u.prototype.OE); +t.defineProperty(u,{OE:"maxSelectionCount"},function(){return this.Ju},function(a){var b=this.Ju;if(b!==a)if(t.j(a,"number",u,"maxSelectionCount"),0<=a&&!isNaN(a)){if(this.Ju=a,this.i("maxSelectionCount",b,a),!this.Aa.qb&&(a=this.selection.count-a,0= 0",u,"maxSelectionCount")});t.g(u,"nodeSelectionAdornmentTemplate",u.prototype.YE); +t.defineProperty(u,{YE:"nodeSelectionAdornmentTemplate"},function(){return this.Uu},function(a){var b=this.Uu;b!==a&&(t.l(a,We,u,"nodeSelectionAdornmentTemplate"),this.Uu=a,this.i("nodeSelectionAdornmentTemplate",b,a))});t.g(u,"groupSelectionAdornmentTemplate",u.prototype.kE);t.defineProperty(u,{kE:"groupSelectionAdornmentTemplate"},function(){return this.ru},function(a){var b=this.ru;b!==a&&(t.l(a,We,u,"groupSelectionAdornmentTemplate"),this.ru=a,this.i("groupSelectionAdornmentTemplate",b,a))}); +t.g(u,"linkSelectionAdornmentTemplate",u.prototype.LE);t.defineProperty(u,{LE:"linkSelectionAdornmentTemplate"},function(){return this.Du},function(a){var b=this.Du;b!==a&&(t.l(a,We,u,"linkSelectionAdornmentTemplate"),this.Du=a,this.i("linkSelectionAdornmentTemplate",b,a))});t.g(u,"isModified",u.prototype.hk); +t.defineProperty(u,{hk:"isModified"},function(){var a=this.Aa;return null===a?this.wy:null!==a.gl?!0:this.wy&&this.Jk!==a.gk},function(a){if(this.wy!==a){t.j(a,"boolean",u,"isModified");this.wy=a;var b=this.Aa;!a&&b&&(this.Jk=b.gk);a||Oi(this)}});function Oi(a){var b=a.hk;a.YC!==b&&(a.YC=b,a.Ja("Modified"))}t.g(u,"model",u.prototype.fa); +t.defineProperty(u,{fa:"model"},function(){return this.Md},function(a){var b=this.Md;if(b!==a){t.l(a,I,u,"model");null!==b&&b.Aa!==a.Aa&&b.Aa.mI&&t.m("Do not replace a Diagram.model while a transaction is in progress.");this.Pv();this.Xf=!1;this.Bq=!0;this.hg=!1;var c=this.Jd;this.Jd=!0;null!==b&&(b.NA(this.tC),b instanceof V&&Pi(this,b.Vi),Pi(this,b.sg));this.Md=a;a.zz(this.sC);Qi(this,a.sg);a instanceof V&&Ri(this,a.Vi);a.NA(this.sC);a.zz(this.tC);this.Jd=c;this.lc||this.pa();null!==b&&(a.Aa.isEnabled= +b.Aa.isEnabled)}});t.defineProperty(u,{Wa:null},function(){return this.mC},function(a){this.mC=a}); +function Ph(a,b){if(b.fa===a.fa&&a.Wa){a.Wa=!1;try{var c=b.od,d=b.rf;if(""!==d)if(c===Id){if("linkFromKey"===d){var e=b.object,g=a.Hf(e);if(null!==g){var h=b.newValue,k=a.ng(h);g.da=k}}else if("linkToKey"===d)e=b.object,g=a.Hf(e),null!==g&&(h=b.newValue,k=a.ng(h),g.ja=k);else if("linkFromPortId"===d){if(e=b.object,g=a.Hf(e),null!==g){var l=b.newValue;"string"===typeof l&&(g.nf=l)}}else if("linkToPortId"===d)e=b.object,g=a.Hf(e),null!==g&&(l=b.newValue,"string"===typeof l&&(g.Qf=l));else if("nodeGroupKey"=== +d){var e=b.object,m=a.Pi(e);if(null!==m){var n=b.newValue;if(void 0!==n){var p=a.ng(n);m.fb=p instanceof z?p:null}else m.fb=null}}else if("linkLabelKeys"===d){if(e=b.object,g=a.Hf(e),null!==g){var q=b.oldValue,r=b.newValue;if(t.isArray(q))for(var s=t.yb(q),v=0;vthis.pg&&(a=this.pg);if(b!==a){var c=this.Sb=a;if(!this.lc&&!this.Jd&&(this.lc=!0,null!==this.Pa)){a=this.nb.copy();var d=this.tc/c,e=this.sc/c;a.width=this.tc/b;a.height=this.sc/b;var g=this.Wh.copy();if(isNaN(g.x))switch(this.Uv){case pc:g.x=0;break;case tc:g.x=d-1;break;case Wb:g.x=d/2;break;case Pb:case vc:g.x=d/2}if(isNaN(g.y))switch(this.Uv){case oc:g.y=0;break;case uc:g.y= +e-1;break;case Wb:g.y=e/2;break;case Pb:case vc:g.y=e/2}var h=this.position,b=new C(h.x+g.x/b-g.x/c,h.y+g.y/b-g.y/c);gi(this,b,this.vc,d,e,this.Il);this.position=b;this.lc=!1;this.kt(a,this.nb)}this.pa();qi(this)}});t.g(u,"autoScale",u.prototype.Am);t.defineProperty(u,{Am:"autoScale"},function(){return this.Fl},function(a){var b=this.Fl;b!==a&&(t.tb(a,u,u,"autoScale"),this.Fl=a,this.i("autoScale",b,a),a!==$e&&ei(this))});t.g(u,"initialAutoScale",u.prototype.iI); +t.defineProperty(u,{iI:"initialAutoScale"},function(){return this.Kk},function(a){var b=this.Kk;b!==a&&(t.tb(a,u,u,"initialAutoScale"),this.Kk=a,this.i("initialAutoScale",b,a))});t.g(u,"initialViewportSpot",u.prototype.uE);t.defineProperty(u,{uE:"initialViewportSpot"},function(){return this.wu},function(a){var b=this.wu;b!==a&&(t.l(a,K,u,"initialViewportSpot"),a.rd()||t.m("initialViewportSpot must be a real Spot: "+a),this.wu=a,this.i("initialViewportSpot",b,a))});t.g(u,"initialDocumentSpot",u.prototype.rE); +t.defineProperty(u,{rE:"initialDocumentSpot"},function(){return this.vu},function(a){var b=this.vu;b!==a&&(t.l(a,K,u,"initialDocumentSpot"),a.rd()||t.m("initialViewportSpot must be a real Spot: "+a),this.vu=a,this.i("initialDocumentSpot",b,a))});t.g(u,"minScale",u.prototype.qg);t.defineProperty(u,{qg:"minScale"},function(){return this.Lu},function(a){t.o(a,u,"minScale");var b=this.Lu;b!==a&&0this.scale&&(this.scale=a)):t.ha(a,"> 0",u,"minScale")}); +t.g(u,"maxScale",u.prototype.pg);t.defineProperty(u,{pg:"maxScale"},function(){return this.Iu},function(a){t.o(a,u,"maxScale");var b=this.Iu;b!==a&&0 0",u,"maxScale")});t.g(u,"zoomPoint",u.prototype.Wh);t.defineProperty(u,{Wh:"zoomPoint"},function(){return this.Cv},function(a){this.Cv.N(a)||(t.l(a,C,u,"zoomPoint"),this.Cv=a=a.Z())});t.g(u,"contentAlignment",u.prototype.Uv); +t.defineProperty(u,{Uv:"contentAlignment"},function(){return this.Il},function(a){var b=this.Il;b.N(a)||(t.l(a,K,u,"contentAlignment"),this.Il=a=a.Z(),this.i("contentAlignment",b,a),ei(this))});t.g(u,"initialContentAlignment",u.prototype.jI);t.defineProperty(u,{jI:"initialContentAlignment"},function(){return this.Nn},function(a){var b=this.Nn;b.N(a)||(t.l(a,K,u,"initialContentAlignment"),this.Nn=a=a.Z(),this.i("initialContentAlignment",b,a))});t.g(u,"padding",u.prototype.padding); +t.defineProperty(u,{padding:"padding"},function(){return this.Le},function(a){"number"===typeof a?a=new pb(a):t.l(a,pb,u,"padding");var b=this.Le;b.N(a)||(this.Le=a=a.Z(),this.Rc(),this.i("padding",b,a))});t.A(u,{Yi:"nodes"},function(){return this.Vu.k});t.A(u,{links:"links"},function(){return this.Eu.k});t.A(u,{sl:"parts"},function(){return this.cb.k});u.prototype.findTopLevelGroups=function(){return this.Vk.k};t.g(u,"layout",u.prototype.Tb); +t.defineProperty(u,{Tb:"layout"},function(){return this.Ld},function(a){var b=this.Ld;b!==a&&(t.l(a,xe,u,"layout"),null!==b&&(b.h=null,b.group=null),this.Ld=a,a.h=this,a.group=null,this.Tt=!0,this.i("layout",b,a),this.Nf())});u.prototype.layoutDiagram=function(a){ci(this);a&&aj(this,!0);ti(this,!1)};function aj(a,b){for(var c=a.Vk.k;c.next();)bj(a,c.value,b);null!==a.Tb&&(b?a.Tb.of=!1:a.Tb.K())} +function bj(a,b,c){if(null!==b){for(var d=b.cm.k;d.next();)bj(a,d.value,c);null!==b.Tb&&(c?b.Tb.of=!1:b.Tb.K())}}function ti(a,b){for(var c=a.Vk.k;c.next();)cj(a,c.value,b);c=a.Tb;if(null!==c&&!c.of){if(b&&!c.nA)return;c.doLayout(a);ci(a);c.of=!0}a.Tt=!1}function cj(a,b,c){if(null!==b){for(var d=b.cm.k;d.next();)cj(a,d.value,c);d=b.Tb;null===d||d.of||c&&!d.nA||(b.zC=!b.location.Q(),d.doLayout(b),b.K(dj),d.of=!0,wi(a,b))}}t.g(u,"isTreePathToChildren",u.prototype.fd); +t.defineProperty(u,{fd:"isTreePathToChildren"},function(){return this.Au},function(a){var b=this.Au;if(b!==a&&(t.j(a,"boolean",u,"isTreePathToChildren"),this.Au=a,this.i("isTreePathToChildren",b,a),!this.Aa.qb))for(a=this.Yi;a.next();)ej(a.value)});u.prototype.findTreeRoots=function(){for(var a=new H(y),b=this.Yi.k;b.next();){var c=b.value;c.ep&&null===c.Ks()&&a.add(c)}return a.k};t.g(u,"isCollapsingExpanding",u.prototype.Sd); +t.defineProperty(u,{Sd:null},function(){return this.fC},function(a){this.fC=a}); +function Nh(a){function b(a){var b=a.toLowerCase(),h=new H("function");c.add(a,h);c.add(b,h);d.add(a,a);d.add(b,a)}var c=new sa("string",H),d=new sa("string","string");b("BackgroundSingleClicked");b("BackgroundDoubleClicked");b("BackgroundContextClicked");b("ClipboardChanged");b("ClipboardPasted");b("DocumentBoundsChanged");b("ExternalObjectsDropped");b("InitialLayoutCompleted");b("LayoutCompleted");b("LinkDrawn");b("LinkRelinked");b("LinkReshaped");b("Modified");b("ObjectSingleClicked");b("ObjectDoubleClicked"); +b("ObjectContextClicked");b("PartCreated");b("PartResized");b("PartRotated");b("SelectionMoved");b("SelectionCopied");b("SelectionDeleting");b("SelectionDeleted");b("SelectionGrouped");b("SelectionUngrouped");b("ChangingSelection");b("ChangedSelection");b("SubGraphCollapsed");b("SubGraphExpanded");b("TextEdited");b("TreeCollapsed");b("TreeExpanded");b("ViewportBoundsChanged");a.Xx=c;a.Wx=d}function ta(a,b){var c=a.Wx.Ba(b);return null!==c?c:a.Wx.Ba(b.toLowerCase())} +function fj(a,b){var c=a.Xx.Ba(b);if(null!==c)return c;c=a.Xx.Ba(b.toLowerCase());if(null!==c)return c;t.m("Unknown DiagramEvent name: "+b);return null}u.prototype.addDiagramListener=u.prototype.Az=function(a,b){t.j(a,"string",u,"addDiagramListener:name");t.j(b,"function",u,"addDiagramListener:listener");var c=fj(this,a);null!==c&&c.add(b)}; +u.prototype.removeDiagramListener=u.prototype.eF=function(a,b){t.j(a,"string",u,"removeDiagramListener:name");t.j(b,"function",u,"addDiagramListener:listener");var c=fj(this,a);null!==c&&c.remove(b)};u.prototype.raiseDiagramEvent=u.prototype.Ja=function(a,b,c){f&&t.j(a,"string",u,"raiseDiagramEvent:name");var d=fj(this,a),e=new Fd;e.h=this;e.name=ta(this,a);void 0!==b&&(e.Sw=b);void 0!==c&&(e.Fw=c);a=d.length;if(1===a)d=d.qa(0),d(e);else if(0!==a)for(b=d.af(),c=0;c=d.top&&0>=d.left&&0>=d.right&&0>=d.bottom)return c;var e=a.nb,g=a.scale,e=t.lk(0,0,e.width*g,e.height*g),h=t.ic(0,0);if(b.x>=e.x&&b.xe.x+e.width-d.right&&(k=Math.max(a.Dp,1),k|=0,h.x+=k,b.x>e.x+e.width-d.right/2&&(h.x+=k),b.x>e.x+e.width-d.right/4&&(h.x+=4*k));b.y>=e.y&&b.ye.y+e.height-d.bottom&&(k=Math.max(a.Ep,1),k|=0,h.y+=k,b.y>e.y+e.height-d.bottom/2&&(h.y+=k),b.y>e.y+e.height-d.bottom/4&&(h.y+=4*k));h.Oi(J.ok)||(c=new C(c.x+h.x/g,c.y+h.y/g));t.Pc(e);t.B(h);return c}u.prototype.makeSVG=function(a){void 0===a&&(a={});a.context="svg";a=Bj(this,a);return null!==a?a.Bt:null}; +u.prototype.makeImage=function(a){var b=document.createElement("img");b.src=this.BI(a);return b instanceof HTMLImageElement?b:null};u.prototype.makeImageData=u.prototype.BI=function(a){void 0===a&&(a={});var b=Bj(this,a);return null!==b?b.toDataURL(a.type,a.details):""}; +function Bj(a,b){a.Nh();if(null===a.Pa)return null;"object"!==typeof b&&t.m("properties argument must be an Object.");var c=!1,d=b.size||null,e=b.scale||null;void 0!==b.scale&&isNaN(b.scale)&&(e="NaN");var g=b.maxSize||new pa(2E3,2E3);void 0===b.maxSize&&(c=!0);var h=b.position||null,k=b.parts||null,l=void 0===b.padding?1:b.padding,m=b.background||null,n=b.omitTemporary;void 0===n&&(n=!0);var p=b.showTemporary;void 0===p&&(p=!n);n=b.showGrid;void 0===n&&(n=p);null!==d&&isNaN(d.width)&&isNaN(d.height)&& +(d=null);l&&"number"===typeof l&&(l=new pb(l));l||(l=new pb(0));l.left=Math.max(l.left,0);l.right=Math.max(l.right,0);l.top=Math.max(l.top,0);l.bottom=Math.max(l.bottom,0);a.Fn=!1;ca(a);var q=document.createElement("canvas"),r=q.getContext("2d"),s=q;if(!(d||e||k||h))return q.width=a.Pa.width+Math.ceil(l.left+l.right),q.height=a.Pa.height+Math.ceil(l.top+l.bottom),"svg"===b.context&&(r=s=new zc(q),r instanceof zc&&(a.Fn=!0)),Ci(a,r,l,new pa(q.width,q.height),a.Sb,a.rb,k,m,p,n),a.Fn=!0,s;var v,x=new C(0, +0);v=a.vc.copy();v.gJ(a.padding);null!==h&&h.Q()?(x=h,e||(e=1)):(x.x=v.x,x.y=v.y);if(k){var E,h=!0,k=k.k;for(k.reset();k.next();){var F=k.value;if(F instanceof w){var G=F.layer;G&&!G.visible||G&&G.pc||!F.zb()||(F=F.wa,F.Q()&&(h?(h=!1,E=F.copy()):E.nk(F)))}}h&&(E=new D(0,0,0,0));v.width=E.width;v.height=E.height;x.x=E.x;x.y=E.y}h=E=0;l&&(E=l.left+l.right,h=l.top+l.bottom);F=G=0;d&&(G=d.width,F=d.height,isFinite(G)&&(G=Math.max(0,G-E)),isFinite(F)&&(F=Math.max(0,F-h)));d&&e?("NaN"===e&&(e=1),d.Q()? +(d=G,v=F):isNaN(F)?(d=G,v=v.height*e):(d=v.width*e,v=F)):d?d.Q()?(e=Math.min(G/v.width,F/v.height),d=G,v=F):isNaN(F)?(e=G/v.width,d=G,v=v.height*e):(e=F/v.height,d=v.width*e,v=F):e?"NaN"===e&&g.Q()?(e=Math.min((g.width-E)/v.width,(g.height-h)/v.height),1E||v>g)&&(t.trace("Diagram.makeImage(data): Diagram width or height is larger than the default max size. ("+ +Math.ceil(d)+"x"+Math.ceil(v)+" vs 2000x2000) Consider increasing the max size."),t.cG=!0),isNaN(E)&&(E=2E3),isNaN(g)&&(g=2E3),isFinite(E)&&(d=Math.min(d,E)),isFinite(g)&&(v=Math.min(v,g)));q.width=Math.ceil(d);q.height=Math.ceil(v);"svg"===b.context&&(r=s=new zc(q),r instanceof zc&&(a.Fn=!0));Ci(a,r,l,new pa(Math.ceil(d),Math.ceil(v)),e,x,k,m,p,n);a.Fn=!0;return s} +u.inherit=function(a,b){t.j(a,"function",u,"inherit");t.j(b,"function",u,"inherit");b.EG&&t.m("Cannot inherit from "+t.Ug(b));t.Oa(a,b)};function Cj(a){1a)&&t.ha(a,"0 <= loc <= 1",ke,"addColorStop:loc");t.j(b,"string",ke,"addColorStop:color");null===this.Eg&&(this.Eg=new sa("number","string"));this.Eg.add(a,b);this.ba===me&&(this.type=ne);this.Fg=null};t.g(ke,"type",ke.prototype.type); +t.defineProperty(ke,{type:"type"},function(){return this.ba},function(a){t.J(this,a);t.tb(a,ke,ke,"type");this.ba=a;this.start.qd()&&(a===ne?this.start=Ub:a===oe&&(this.start=Wb));this.end.qd()&&(a===ne?this.end=Yb:a===oe&&(this.end=Wb));this.Fg=null});t.g(ke,"color",ke.prototype.color);t.defineProperty(ke,{color:"color"},function(){return this.un},function(a){t.J(this,a);t.j(a,"string",ke,"color");this.un=a;this.Fg=null});t.g(ke,"start",ke.prototype.start); +t.defineProperty(ke,{start:"start"},function(){return this.no},function(a){t.J(this,a);a instanceof K||t.Vb(a,"Spot",ke,"start");this.no=a.Z();this.Fg=null});t.g(ke,"end",ke.prototype.end);t.defineProperty(ke,{end:"end"},function(){return this.Hn},function(a){t.J(this,a);a instanceof K||t.Vb(a,"Spot",ke,"end");this.Hn=a.Z();this.Fg=null});t.g(ke,"startRadius",ke.prototype.Jp); +t.defineProperty(ke,{Jp:"startRadius"},function(){return this.pv},function(a){t.J(this,a);t.o(a,ke,"startRadius");0>a&&t.ha(a,">= zero",ke,"startRadius");this.pv=a;this.Fg=null});t.g(ke,"endRadius",ke.prototype.Mo);t.defineProperty(ke,{Mo:"endRadius"},function(){return this.nu},function(a){t.J(this,a);t.o(a,ke,"endRadius");0>a&&t.ha(a,">= zero",ke,"endRadius");this.nu=a;this.Fg=null});t.g(ke,"colorStops",ke.prototype.Go); +t.defineProperty(ke,{Go:"colorStops"},function(){return this.Eg},function(a){t.J(this,a);f&&t.l(a,sa,ke,"colorStops");this.Eg=a;this.Fg=null});t.g(ke,"pattern",ke.prototype.pattern);t.defineProperty(ke,{pattern:"pattern"},function(){return this.av},function(a){t.J(this,a);this.av=a;this.Fg=null}); +ke.randomColor=function(a,b){void 0===a&&(a=128);f&&(t.o(a,ke,"randomColor:min"),(0>a||255d.length&&(d="0"+d);2>e.length&&(e="0"+e);2>c.length&&(c="0"+c);return"#"+ +d+e+c}; +function X(){t.zc(this);this.ka=30723;this.ti=null;this.Rb="";this.jc=this.Gb=null;this.rb=(new C(NaN,NaN)).freeze();this.df=(new pa(NaN,NaN)).freeze();this.de=J.ln;this.zj=J.qG;this.bd=new qa;this.Yh=new qa;this.Ok=new qa;this.Sb=1;this.pn=0;this.zh=Yg;this.fr=J.Up;this.Kc=(new D(NaN,NaN,NaN,NaN)).freeze();this.Fb=(new D(NaN,NaN,NaN,NaN)).freeze();this.Yc=(new D(0,0,NaN,NaN)).freeze();this.gs=this.Cq=this.V=this.Ar=this.ee=null;this.hs=this.Dq=Infinity;this.aq=this.re=Pb;this.Lr=0;this.Gj=1;this.hq= +0;this.gj=1;this.Pr=-Infinity;this.Nr=0;this.Qr=J.ok;this.Rr=Jg;this.oq="";this.gm=this.ai=this.Jl=this.Bc=this.R=null}t.ia("GraphObject",X);t.Fh(X); +X.prototype.cloneProtected=function(a){a.ka=this.ka|6144;a.Rb=this.Rb;a.Gb=this.Gb;a.jc=this.jc;a.rb.assign(this.rb);a.df.assign(this.df);a.de=this.de.Z();a.zj=this.zj.Z();a.Ok=this.Ok.copy();a.Sb=this.Sb;a.pn=this.pn;a.zh=this.zh;a.fr=this.fr.Z();a.Kc.assign(this.Kc);a.Fb.assign(this.Fb);a.Yc.assign(this.Yc);a.Ar=this.Ar;a.re=this.re.Z();a.aq=this.aq.Z();a.Lr=this.Lr;a.Gj=this.Gj;a.hq=this.hq;a.gj=this.gj;a.Pr=this.Pr;a.Nr=this.Nr;a.Qr=this.Qr.Z();a.Rr=this.Rr;a.oq=this.oq;if(null!==this.R){var b= +this.R;a.R={$h:b.$h,fi:b.fi,bi:b.bi,qr:b.qr,rr:b.rr,pi:b.pi,oi:b.oi,ni:b.ni,or:b.or,pr:b.pr,mi:b.mi,Wp:b.Wp,Xp:b.Xp,Yp:b.Yp,Vp:b.Vp,zi:b.zi,ci:b.ci}}null!==this.V&&(b=this.V,a.V={nj:b.nj.Z(),Pj:b.Pj.Z(),lj:b.lj,Nj:b.Nj,kj:b.kj,Mj:b.Mj,mj:b.mj,Oj:b.Oj});a.Cq=this.Cq;a.Dq=this.Dq;a.gs=this.gs;a.hs=this.hs;a.Bc=this.Bc;if(Array.isArray(this.Jl))for(a.Jl=this.Jl.slice(0),b=0;bk;)k+=g[n++%l],p=!p;q=!1}else k=g[n++%l];k>m&&(k=m);var r=Math.sqrt(k*k/(1+e*e));0>d&&(r=-r);b+=r;c+=e*r;p?a.lineTo(b,c):a.moveTo(b,c);m-=k;p=!p}}aa.Uc=function(a,b,c,d,e,g,h){var k=this.S;null!==k&&(k.$m(a,b,c,d,e,g,h),0!==(this.ka&1024)&&c===this&&a===Id&&Mj(this,k,b))}; +function Mj(a,b,c){var d=a.Ro();if(null!==d)for(var e=a.Bc.k;e.next();){var g=e.value,h=d.data,k=g.zt;null!==k&&(h=d.le(k));if(null!==h&&(g.ZF(a,h,c,null!==k?null:b.h),null!==k&&(h=d,""!==k&&(h=d.le(k)),null!==h))){var k=g.fn,l=d;""!==k&&(l=d.le(k));null!==l&&g.$F(l,h,c)}}}aa.i=function(a,b,c){this.Uc(Id,a,this,b,c)};function Nj(a,b,c,d,e){var g=a.Kc,h=a.Ok;h.reset();Oj(a,h,b,c,d,e);a.Ok=h;g.x=b;g.y=c;g.width=d;g.height=e;h.Ts()||h.TF(g)} +function Pj(a,b,c,d){if(!1===a.Ze)return!1;d.multiply(a.transform);return c?a.If(b,d):a.Fm(b,d)}aa.XD=function(a,b,c){if(!1===this.Ze)return!1;var d=this.Ga;b=a.$j(b);var e=!1;c&&(e=cb(a.x,a.y,0,0,0,d.height)d.width*e&&10>d.height*e)return a=Db(c.x-5*g,c.y-5*g,c.width+10*g,c.height+10*g,b.x,b.y),t.B(b),a}if(void 0!==this.Nc||this instanceof Y?Db(c.x-5,c.y-5,c.width+10,c.height+10,b.x,b.y):c.Ia(b)){if(this.ai&&!this.ai.Ia(b))return!1;if(null!==this.jc&&c.Ia(b)||null!== +this.Gb&&this.Yc.Ia(a))return!0;t.B(b);return this.Vj(a)}t.B(b);return!1};X.prototype.Vj=function(a){var b=this.Ga;return Db(0,0,b.width,b.height,a.x,a.y)}; +X.prototype.containsRect=X.prototype.Wj=function(a){f&&t.l(a,D,X,"containsRect:r");if(0===this.angle)return this.wa.Wj(a);var b=this.Ga,b=t.lk(0,0,b.width,b.height),c=this.transform,d=!1,e=t.ic(a.x,a.y);b.Ia(c.Ri(e))&&(e.q(a.x,a.bottom),b.Ia(c.Ri(e))&&(e.q(a.right,a.bottom),b.Ia(c.Ri(e))&&(e.q(a.right,a.y),b.Ia(c.Ri(e))&&(d=!0))));t.B(e);t.Pc(b);return d}; +X.prototype.containedInRect=X.prototype.Fm=function(a,b){f&&t.l(a,D,X,"containedInRect:r");if(void 0===b)return a.Wj(this.wa);var c=this.Ga,d=!1,e=t.ic(0,0);a.Ia(b.Va(e))&&(e.q(0,c.height),a.Ia(b.Va(e))&&(e.q(c.width,c.height),a.Ia(b.Va(e))&&(e.q(c.width,0),a.Ia(b.Va(e))&&(d=!0))));return d}; +X.prototype.intersectsRect=X.prototype.If=function(a,b){f&&t.l(a,D,X,"intersectsRect:r");if(void 0===b&&(b=this.transform,0===this.angle))return a.If(this.wa);var c=this.Ga,d=b,e=t.ic(0,0),g=t.ic(0,c.height),h=t.ic(c.width,c.height),k=t.ic(c.width,0),l=!1;if(a.Ia(d.Va(e))||a.Ia(d.Va(g))||a.Ia(d.Va(h))||a.Ia(d.Va(k)))l=!0;else{var c=t.lk(0,0,c.width,c.height),m=t.ic(a.x,a.y);c.Ia(d.Ri(m))?l=!0:(m.q(a.x,a.bottom),c.Ia(d.Ri(m))?l=!0:(m.q(a.right,a.bottom),c.Ia(d.Ri(m))?l=!0:(m.q(a.right,a.y),c.Ia(d.Ri(m))&& +(l=!0))));t.B(m);t.Pc(c);!l&&(J.ow(a,e,g)||J.ow(a,g,h)||J.ow(a,h,k)||J.ow(a,k,e))&&(l=!0)}t.B(e);t.B(g);t.B(h);t.B(k);return l};X.prototype.getDocumentPoint=X.prototype.gb=function(a,b){void 0===b&&(b=new C);a.qd()&&t.m("Spot must be real");var c=this.Ga;b.q(a.x*c.width+a.offsetX,a.y*c.height+a.offsetY);this.he.Va(b);return b};X.prototype.getDocumentAngle=X.prototype.jl=function(){var a=this.he,a=180/Math.PI*Math.atan2(a.m12,a.m11);0>a&&(a+=360);return a}; +X.prototype.getDocumentScale=X.prototype.fk=function(){var a=this.Sb;return null!==this.ga?a*this.ga.fk():a};X.prototype.getLocalPoint=X.prototype.gE=function(a,b){void 0===b&&(b=new C);b.assign(a);this.he.Ri(b);return b};X.prototype.getNearestIntersectionPoint=X.prototype.ml=function(a,b,c){return this.Wo(a.x,a.y,b.x,b.y,c)};aa=X.prototype; +aa.Wo=function(a,b,c,d,e){var g=this.transform,h=1/(g.m11*g.m22-g.m12*g.m21),k=g.m22*h,l=-g.m12*h,m=-g.m21*h,n=g.m11*h,p=h*(g.m21*g.dy-g.m22*g.dx),q=h*(g.m12*g.dx-g.m11*g.dy);if(null!==this.Tj)return g=this.wa,J.ml(g.left,g.top,g.right,g.bottom,a,b,c,d,e);h=a*k+b*m+p;a=a*l+b*n+q;b=c*k+d*m+p;c=c*l+d*n+q;e.q(0,0);d=this.Ga;c=J.ml(0,0,d.width,d.height,h,a,b,c,e);e.transform(g);return c}; +function Bh(a,b,c,d,e){if(!1!==xi(a)){var g=a.margin,h=g.top+g.bottom;b=Math.max(b-(g.right+g.left),0);c=Math.max(c-h,0);g=a.angle;if(90===g||270===g)g=b,b=c,c=g,g=d,d=e,e=g;g=a.Ca;h=0;a.ib&&(h=a.ib);b=isFinite(g.width)?g.width+h:b;c=isFinite(g.height)?g.height+h:c;var g=d||0,h=e||0,k=a instanceof B;switch(Qj(a)){case Xg:h=g=0;k&&(c=b=Infinity);break;case Qc:isFinite(b)&&b>d&&(g=b);isFinite(c)&&c>e&&(h=c);break;case Ij:isFinite(b)&&b>d&&(g=b);h=0;k&&(c=Infinity);break;case Hj:isFinite(c)&&c>e&&(h= +c),g=0,k&&(b=Infinity)}var k=a.He,l=a.Ye;g>k.width&&l.widthk.height&&l.heighta.height||this.Zn.Wi>a.width))&&(c=!0);this.ka=c?this.ka|256:this.ka&-257;this.Fb.Q()||t.m("Non-real actualBounds has been set. Object "+ +this+", actualBounds: "+this.Fb.toString());Tj(this,g,this.Fb);t.Pc(g)};aa.Uj=function(){};function Uj(a,b,c,d,e){var g=a.wa;g.x=b;g.y=c;g.width=d;g.height=e;if(!a.Ca.Q()){g=a.Kc;c=a.margin;b=c.right+c.left;var h=c.top+c.bottom;c=g.width+b;g=g.height+h;d+=b;e+=h;b=Qj(a);c===d&&g===e&&(b=Xg);switch(b){case Xg:if(c>d||g>e)Rj(a,!0),Bh(a,c>d?d:c,g>e?e:g);break;case Qc:Rj(a,!0);Bh(a,d,e,0,0);break;case Ij:Rj(a,!0);Bh(a,d,g,0,0);break;case Hj:Rj(a,!0),Bh(a,c,e,0,0)}}} +function Tj(a,b,c){Vj(a,!1);var d=a.S;if(null!==d){var e=d.h;if(null!==e)if(Wj(d),a instanceof w){var g=!1,d=b.Q();if(!1===e.qj){var h=e.vc,k=e.padding,l=h.x+k.left,m=h.y+k.top,n=h.width-2*k.right,h=h.height-2*k.bottom;d&&b.x>l&&b.y>m&&b.rightl&&c.y>m&&c.rightc.width+c.x||c.x>h.width+h.x||m>c.height+c.y||c.y>h.height+h.y)break a;h=!0;Mc(a,1,0,0,1,0,0);a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}l=!1;if(this instanceof w&&(l=!0,!this.zb()))break a;m=!1;this.S&&(m=this.S.Lh);a.Ki.Xe=[1,0,0,1,0,0];null!==this.jc&&(dk(this,a,this.jc,!0,!0),this.jc instanceof ke&&this.jc.type===oe?(a.beginPath(),a.rect(c.x,c.y,c.width,c.height),ek(a,this.jc,!0)):a.fillRect(c.x, +c.y,c.width,c.height));l&&this.Lh&&(Mc(a,1,0,0,1,0,0),c=this.pm,a.shadowOffsetX=c.x,a.shadowOffsetY=c.y,a.shadowColor=this.om,a.shadowBlur=this.nm/b.scale,a.ab());this instanceof B?Mc(a,d.m11,d.m12,d.m21,d.m22,d.dx,d.dy):a.Ki.Xe=[d.m11,d.m12,d.m21,d.m22,d.dx,d.dy];if(null!==this.Gb){var k=this.Ga,c=d=0,n=k.width,k=k.height,p=0;this instanceof Y&&(k=this.Ra.Mb,d=k.x,c=k.y,n=k.width,k=k.height,p=this.fe);dk(this,a,this.Gb,!0);this.Gb instanceof ke&&this.Gb.type===oe?(a.beginPath(),a.rect(d-p/2,c-p/ +2,n+p,k+p),ek(a,this.Gb,!0)):a.fillRect(d-p/2,c-p/2,n+p,k+p)}if(m&&(null!==this.Gb||null!==this.jc||null!==e&&0!==(e.ka&512)||null!==e&&e.type===Vh&&e.gw()!==this)){fk(this,!0);var q=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}else fk(this,!1);this.hl(a,b);m&&0!==(this.ka&512)===!0&&(a.shadowOffsetX=q[0],a.shadowOffsetY=q[1],a.shadowBlur=q[2]);l&&m&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);g?(a.restore(),h&&a.og.pop(),ca(b,a)):this instanceof +B&&a.og.pop();l&&m&&a.og.pop()}}}else if(this instanceof B&&(this.type===Zj||this.type===ak))bk(this,a,b);else if(d=this.Fb,0!==d.width&&0!==d.height&&!isNaN(d.x)&&!isNaN(d.y)){!f||!f.Gi||this instanceof We||f.JH(a,this);q=this.transform;g=this.ga;h=this.Yh;h.reset();null!==g&&(g.Bg()?h.multiply(g.he):null!==g.ga&&h.multiply(g.ga.he));h.multiply(this.bd);h=0!==(this.ka&256);this instanceof wa&&ck(this,a);if(h){f&&f.UD&&t.trace("clip"+this.toString());c=g.Bg()?g.Ga:g.wa;this.ai?(k=this.ai,l=k.x,m= +k.y,n=k.width,k=k.height):(l=Math.max(d.x,c.x),m=Math.max(d.y,c.y),n=Math.min(d.right,c.right)-l,k=Math.min(d.bottom,c.bottom)-m);if(l>d.width+d.x||d.x>c.width+c.x||m>d.height+d.y||d.y>c.height+c.y)return;f&&f.UD&&f.LH(a,l,m,n,k);a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}c=!1;if(this instanceof w){c=!0;if(!this.zb())return;this.Lh&&(l=this.pm,a.shadowOffsetX=l.x*b.scale,a.shadowOffsetY=l.y*b.scale,a.shadowColor=this.om,a.shadowBlur=this.nm)}l=!1;this.S&&(l=this.S.Lh);null!==this.jc&&(dk(this, +a,this.jc,!0,!0),this.jc instanceof ke&&this.jc.type===oe?(a.beginPath(),a.rect(d.x,d.y,d.width,d.height),ek(a,this.jc,!0)):a.fillRect(d.x,d.y,d.width,d.height));q.Ts()||a.transform(q.m11,q.m12,q.m21,q.m22,q.dx,q.dy);null!==this.Gb&&(k=this.Ga,m=d=0,n=k.width,k=k.height,p=0,this instanceof Y&&(k=this.Ra.Mb,d=k.x,m=k.y,n=k.width,k=k.height,p=this.fe),dk(this,a,this.Gb,!0),this.Gb instanceof ke&&this.Gb.type===oe?(a.beginPath(),a.rect(d-p/2,m-p/2,n+p,k+p),ek(a,this.Gb,!0)):a.fillRect(d-p/2,m-p/2,n+ +p,k+p));f&&f.Gi&&f.KH(a,this);l&&(null!==this.Gb||null!==this.jc||null!==g&&0!==(g.ka&512)||null!==g&&g.type===Vh&&g.gw()!==this)?(fk(this,!0),e=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0):fk(this,!1);this.hl(a,b);l&&0!==(this.ka&512)===!0&&(a.shadowOffsetX=e[0],a.shadowOffsetY=e[1],a.shadowBlur=e[2]);c&&l&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);h?(a.restore(),this instanceof B?ca(b,a,!0):ca(b,a,!1)):q.Ts()||(e=1/(q.m11*q.m22-q.m12* +q.m21),a.transform(q.m22*e,-q.m12*e,-q.m21*e,q.m11*e,e*(q.m21*q.dy-q.m22*q.dx),e*(q.m12*q.dx-q.m11*q.dy)))}}; +function bk(a,b,c){var d=a.Fb;0===d.width||0===d.height||isNaN(d.x)||isNaN(d.y)||(null!==a.jc&&(dk(a,b,a.jc,!0,!0),a.jc instanceof ke&&a.jc.type===oe?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),ek(b,a.jc,!0)):b.fillRect(d.x,d.y,d.width,d.height)),null!==a.Gb&&(dk(a,b,a.Gb,!0),a.Gb instanceof ke&&a.Gb.type===oe?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),ek(b,a.Gb,!0)):b.fillRect(d.x,d.y,d.width,d.height)),a.hl(b,c))}aa.hl=function(){}; +function ek(a,b,c){if(c)if(a instanceof CanvasRenderingContext2D&&b instanceof ke&&b.type===oe){var d=b.Kx;b=b.Jx;b>d?(a.scale(d/b,1),a.translate((b-d)/2,0),c?a.fill():a.stroke(),a.translate(-(b-d)/2,0),a.scale(1/(d/b),1)):d>b?(a.scale(1,b/d),a.translate(0,(d-b)/2),c?a.fill():a.stroke(),a.translate(0,-(d-b)/2),a.scale(1,1/(b/d))):c?a.fill():a.stroke()}else c?a.fill():a.stroke();else a.stroke()} +function dk(a,b,c,d,e){if(null!==c){var g=1,h=1;if("string"===typeof c)d?b.El!==c&&(b.fillStyle=c,b.El=c):b.mn!==c&&(b.strokeStyle=c,b.mn=c);else if(c.type===me)c=c.color,d?b.El!==c&&(b.fillStyle=c,b.El=c):b.mn!==c&&(b.strokeStyle=c,b.mn=c);else{var k,h=a.Ga,g=h.width,h=h.height;if(e)var l=a.wa,g=l.width,h=l.height;var m=b instanceof CanvasRenderingContext2D;if(m&&(c.Fg&&c.type===Gj||c.Kx===g&&c.Jx===h))k=c.Fg;else{var n,p,q=p=0;e&&(l=a.wa,g=l.width,h=l.height,p=l.x,q=l.y);c.start instanceof C?(a= +c.start.x,e=c.start.y):c.start instanceof K?(a=c.start.x*g,e=c.start.y*h):(a=Wb.x*g,e=Wb.y*h);c.end instanceof C?(l=c.end.x,n=c.end.y):c.end instanceof K?(l=c.end.x*g,n=c.end.y*h):c.type===ne?(l=Yb.x*g,n=Yb.y*h):(l=Wb.x*g,n=Wb.y*h);a+=p;l+=p;e+=q;n+=q;c.type===ne?k=b.createLinearGradient(a,e,l,n):c.type===oe?(p=isNaN(c.Mo)?Math.max(g,h)/2:c.Mo,isNaN(c.Jp)?(k=0,p=Math.max(g,h)/2):k=c.Jp,k=b.createRadialGradient(a,e,k,l,n,p)):c.type===Gj?k=b.createPattern(c.pattern,"repeat"):t.Vb(c.type,"Brush type"); +if(c.type!==Gj&&(p=c.Go))for(p=p.k;p.next();)k.addColorStop(p.key,p.value);m&&(c.Fg=k,c.Kx=g,c.Jx=h)}d?b.El!==k&&(b.fillStyle=k,b.El=k):b.mn!==k&&(b.strokeStyle=k,b.mn=k)}}}X.prototype.isContainedBy=X.prototype.Ti=function(a){if(a instanceof B)a:{if(this!==a&&null!==a)for(var b=this.ga;null!==b;){if(b===a){a=!0;break a}b=b.ga}a=!1}else a=!1;return a};X.prototype.isVisibleObject=X.prototype.pl=function(){if(!this.visible)return!1;var a=this.ga;return null!==a?a.pl():!0}; +function gk(a){if(0!==(a.ka&2048)===!0){var b=a.bd;b.reset();if(!a.Fb.Q()||!a.Kc.Q()){hk(a,!1);return}b.translate(a.Fb.x,a.Fb.y);b.translate(-a.Ea.x,-a.Ea.y);var c=a.Ga;Oj(a,b,c.x,c.y,c.width,c.height);hk(a,!1);ik(a,!0)}0!==(a.ka&4096)===!0&&(null===a.ga?(a.Yh.set(a.bd),ik(a,!1)):null!==a.ga.he&&(b=a.Yh,b.reset(),b.multiply(a.ga.Yh),b.multiply(a.bd),ik(a,!1)))} +function Oj(a,b,c,d,e,g){1!==a.scale&&b.scale(a.scale);if(0!==a.angle){var h=Wb;a.We&&a.We.rd()&&(h=a.We);var k=t.O();if(a instanceof w&&a.Ub!==a)for(c=a.Ub,d=c.Ga,k.xt(d.x,d.y,d.width,d.height,h),c.Ok.Va(k),k.offset(-c.Ea.x,-c.Ea.y),h=c.ga;null!==h&&h!==a;)h.Ok.Va(k),k.offset(-h.Ea.x,-h.Ea.y),h=h.ga;else k.xt(c,d,e,g,h);b.rotate(a.angle,k.x,k.y);t.B(k)}} +X.prototype.aa=function(a){if(!0!==xi(this)){Rj(this,!0);Vj(this,!0);var b=this.ga;null!==b?a||b.aa():(a=this.h,null!==a&&(a.Yf.add(this),this instanceof y&&(a.Aa.qb||this.Wg(),null!==this.Sc&&jk(this.Sc)),a.Nf()));if(this instanceof B){var c=null;a=this.za;b=a.length;this.ba===Vh&&(c=kk(this,a,b))&&c.aa(!0);a=a.p;for(c=0;ca?a=0:1=a&&t.m("GraphObject.scale must be greater than zero"),this.Sb=a,Sj(this),this.aa(),this.i("scale",b,a))});t.g(X,"angle",X.prototype.angle);t.defineProperty(X,{angle:"angle"},function(){return this.pn},function(a){var b=this.pn;b!==a&&(f&&t.o(a,X,"angle"),a%=360,0>a&&(a+=360),b!==a&&(this.pn=a,this.aa(),Sj(this),this.i("angle",b,a)))}); +t.g(X,"desiredSize",X.prototype.Ca);t.defineProperty(X,{Ca:"desiredSize"},function(){return this.df},function(a){var b=this.df;b.N(a)||(f&&t.l(a,pa,X,"desiredSize"),this.df=a=a.Z(),this.aa(),this instanceof Y&&this.Jf(),this.i("desiredSize",b,a),a=this.S,null!==a&&0!==(this.ka&1024)&&(Mj(this,a,"width"),Mj(this,a,"height")))});t.g(X,"width",X.prototype.width); +t.defineProperty(X,{width:"width"},function(){return this.df.width},function(a){if(this.df.width!==a){f&&t.j(a,"number",X,"width");var b=this.df;this.df=a=(new pa(a,this.df.height)).freeze();this.aa();this instanceof Y&&this.Jf();this.i("desiredSize",b,a);b=this.S;null!==b&&0!==(this.ka&1024)&&Mj(this,b,"width")}});t.g(X,"height",X.prototype.height); +t.defineProperty(X,{height:"height"},function(){return this.df.height},function(a){if(this.df.height!==a){f&&t.j(a,"number",X,"height");var b=this.df;this.df=a=(new pa(this.df.width,a)).freeze();this.aa();this instanceof Y&&this.Jf();this.i("desiredSize",b,a);b=this.S;null!==b&&0!==(this.ka&1024)&&Mj(this,b,"height")}});t.g(X,"minSize",X.prototype.Ye); +t.defineProperty(X,{Ye:"minSize"},function(){return this.de},function(a){var b=this.de;b.N(a)||(f&&t.l(a,pa,X,"minSize"),a=a.copy(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.de=a,this.aa(),this.i("minSize",b,a))});t.g(X,"maxSize",X.prototype.He); +t.defineProperty(X,{He:"maxSize"},function(){return this.zj},function(a){var b=this.zj;b.N(a)||(f&&t.l(a,pa,X,"maxSize"),a=a.copy(),isNaN(a.width)&&(a.width=Infinity),isNaN(a.height)&&(a.height=Infinity),a.freeze(),this.zj=a,this.aa(),this.i("maxSize",b,a))});t.A(X,{Ea:"measuredBounds"},function(){return this.Kc});t.A(X,{Ga:"naturalBounds"},function(){return this.Yc},{configurable:!0});t.g(X,"margin",X.prototype.margin); +t.defineProperty(X,{margin:"margin"},function(){return this.fr},function(a){"number"===typeof a?a=new pb(a):f&&t.l(a,pb,X,"margin");var b=this.fr;b.N(a)||(this.fr=a=a.Z(),this.aa(),this.i("margin",b,a))});t.A(X,{transform:null},function(){0!==(this.ka&2048)===!0&&gk(this);return this.bd});t.A(X,{he:null},function(){0!==(this.ka&4096)===!0&&gk(this);return this.Yh});t.g(X,"alignment",X.prototype.alignment); +t.defineProperty(X,{alignment:"alignment"},function(){return this.re},function(a){var b=this.re;b.N(a)||(f?t.l(a,K,X,"alignment"):a.qd()&&!a.Fc()&&t.m("alignment must be a real Spot or Spot.Default"),this.re=a=a.Z(),jk(this),this.i("alignment",b,a))});t.g(X,"column",X.prototype.column);t.defineProperty(X,{column:"column"},function(){return this.hq},function(a){f&&t.o(a,X,"column");a=Math.round(a);var b=this.hq;b!==a&&(0>a&&t.ha(a,">= 0",X,"column"),this.hq=a,this.aa(),this.i("column",b,a))}); +t.g(X,"columnSpan",X.prototype.tD);t.defineProperty(X,{tD:"columnSpan"},function(){return this.gj},function(a){f&&t.o(a,X,"columnSpan");a=Math.round(a);var b=this.gj;b!==a&&(1>a&&t.ha(a,">= 1",X,"columnSpan"),this.gj=a,this.aa(),this.i("columnSpan",b,a))});t.g(X,"row",X.prototype.gc);t.defineProperty(X,{gc:"row"},function(){return this.Lr},function(a){f&&t.o(a,X,"row");a=Math.round(a);var b=this.Lr;b!==a&&(0>a&&t.ha(a,">= 0",X,"row"),this.Lr=a,this.aa(),this.i("row",b,a))});t.g(X,"rowSpan",X.prototype.rowSpan); +t.defineProperty(X,{rowSpan:"rowSpan"},function(){return this.Gj},function(a){f&&t.o(a,X,"rowSpan");a=Math.round(a);var b=this.Gj;b!==a&&(1>a&&t.ha(a,">= 1",X,"rowSpan"),this.Gj=a,this.aa(),this.i("rowSpan",b,a))});t.g(X,"alignmentFocus",X.prototype.Qj); +t.defineProperty(X,{Qj:"alignmentFocus"},function(){return this.aq},function(a){var b=this.aq;b.N(a)||(f?t.l(a,K,X,"alignmentFocus"):a.qd()&&!a.Fc()&&t.m("alignmentFocus must be a real Spot or Spot.Default"),this.aq=a=a.Z(),this.aa(),this.i("alignmentFocus",b,a))});t.g(X,"portId",X.prototype.sd); +t.defineProperty(X,{sd:"portId"},function(){return this.Ar},function(a){var b=this.Ar;if(b!==a){f&&null!==a&&t.j(a,"string",X,"portId");var c=this.S;null===c||c instanceof y||(t.m("portID being set on a Link: "+a),c=null);null!==b&&c&&sk(c,this);this.Ar=a;if(null!==a&&c){c.pj=!0;null===c.yd&&tk(c);var d=this.sd;null!==d&&c.yd.add(d,this)}this.i("portId",b,a)}});function uk(a){var b={value:null};vk(a,b);return b.value} +function vk(a,b){var c=a.ga;return null===c||!vk(c,b)&&a.visible?(b.value=a,!1):!0}function ok(a){var b=a.S;b instanceof y&&(a=a.h)&&!a.Aa.qb&&b.Wg()}t.g(X,"toSpot",X.prototype.mb);t.defineProperty(X,{mb:"toSpot"},function(){return null!==this.V?this.V.Pj:Ob},function(a){null===this.V&&this.Ge();var b=this.V.Pj;b.N(a)||(f&&t.l(a,K,X,"toSpot"),a=a.Z(),this.V.Pj=a,this.i("toSpot",b,a),ok(this))});t.g(X,"toEndSegmentLength",X.prototype.mk); +t.defineProperty(X,{mk:"toEndSegmentLength"},function(){return null!==this.V?this.V.Nj:10},function(a){null===this.V&&this.Ge();var b=this.V.Nj;b!==a&&(f&&t.j(a,"number",X,"toEndSegmentLength"),0>a&&t.ha(a,">= 0",X,"toEndSegmentLength"),this.V.Nj=a,this.i("toEndSegmentLength",b,a),ok(this))});t.g(X,"toEndSegmentDirection",X.prototype.Lp); +t.defineProperty(X,{Lp:"toEndSegmentDirection"},function(){return null!==this.V?this.V.Mj:Kj},function(a){null===this.V&&this.Ge();var b=this.V.Mj;b!==a&&(f&&t.tb(a,y,X,"toEndSegmentDirection"),this.V.Mj=a,this.i("toEndSegmentDirection",b,a),ok(this))});t.g(X,"toShortLength",X.prototype.Mp); +t.defineProperty(X,{Mp:"toShortLength"},function(){return null!==this.V?this.V.Oj:0},function(a){null===this.V&&this.Ge();var b=this.V.Oj;b!==a&&(f&&t.j(a,"number",X,"toShortLength"),this.V.Oj=a,this.i("toShortLength",b,a),ok(this))});t.g(X,"toLinkable",X.prototype.kB);t.defineProperty(X,{kB:"toLinkable"},function(){return this.gs},function(a){var b=this.gs;b!==a&&(f&&null!==a&&t.j(a,"boolean",X,"toLinkable"),this.gs=a,this.i("toLinkable",b,a))});t.g(X,"toMaxLinks",X.prototype.NF); +t.defineProperty(X,{NF:"toMaxLinks"},function(){return this.hs},function(a){var b=this.hs;b!==a&&(f&&t.o(a,X,"toMaxLinks"),0>a&&t.ha(a,">= 0",X,"toMaxLinks"),this.hs=a,this.i("toMaxLinks",b,a))});t.g(X,"fromSpot",X.prototype.lb);t.defineProperty(X,{lb:"fromSpot"},function(){return null!==this.V?this.V.nj:Ob},function(a){null===this.V&&this.Ge();var b=this.V.nj;b.N(a)||(f&&t.l(a,K,X,"fromSpot"),a=a.Z(),this.V.nj=a,this.i("fromSpot",b,a),ok(this))});t.g(X,"fromEndSegmentLength",X.prototype.ek); +t.defineProperty(X,{ek:"fromEndSegmentLength"},function(){return null!==this.V?this.V.lj:10},function(a){null===this.V&&this.Ge();var b=this.V.lj;b!==a&&(f&&t.j(a,"number",X,"fromEndSegmentLength"),0>a&&t.ha(a,">= 0",X,"fromEndSegmentLength"),this.V.lj=a,this.i("fromEndSegmentLength",b,a),ok(this))});t.g(X,"fromEndSegmentDirection",X.prototype.So); +t.defineProperty(X,{So:"fromEndSegmentDirection"},function(){return null!==this.V?this.V.kj:Kj},function(a){null===this.V&&this.Ge();var b=this.V.kj;b!==a&&(f&&t.tb(a,y,X,"fromEndSegmentDirection"),this.V.kj=a,this.i("fromEndSegmentDirection",b,a),ok(this))});t.g(X,"fromShortLength",X.prototype.To); +t.defineProperty(X,{To:"fromShortLength"},function(){return null!==this.V?this.V.mj:0},function(a){null===this.V&&this.Ge();var b=this.V.mj;b!==a&&(f&&t.j(a,"number",X,"fromShortLength"),this.V.mj=a,this.i("fromShortLength",b,a),ok(this))});t.g(X,"fromLinkable",X.prototype.$z);t.defineProperty(X,{$z:"fromLinkable"},function(){return this.Cq},function(a){var b=this.Cq;b!==a&&(f&&null!==a&&t.j(a,"boolean",X,"fromLinkable"),this.Cq=a,this.i("fromLinkable",b,a))});t.g(X,"fromMaxLinks",X.prototype.dE); +t.defineProperty(X,{dE:"fromMaxLinks"},function(){return this.Dq},function(a){var b=this.Dq;b!==a&&(f&&t.o(a,X,"fromMaxLinks"),0>a&&t.ha(a,">= 0",X,"fromMaxLinks"),this.Dq=a,this.i("fromMaxLinks",b,a))});t.g(X,"cursor",X.prototype.cursor);t.defineProperty(X,{cursor:"cursor"},function(){return this.oq},function(a){var b=this.oq;b!==a&&(t.j(a,"string",X,"cursor"),this.oq=a,this.i("cursor",b,a))});t.g(X,"click",X.prototype.click); +t.defineProperty(X,{click:"click"},function(){return null!==this.R?this.R.$h:null},function(a){null===this.R&&Jj(this);var b=this.R.$h;b!==a&&(null!==a&&t.j(a,"function",X,"click"),this.R.$h=a,this.i("click",b,a))});t.g(X,"doubleClick",X.prototype.Km);t.defineProperty(X,{Km:"doubleClick"},function(){return null!==this.R?this.R.fi:null},function(a){null===this.R&&Jj(this);var b=this.R.fi;b!==a&&(null!==a&&t.j(a,"function",X,"doubleClick"),this.R.fi=a,this.i("doubleClick",b,a))}); +t.g(X,"contextClick",X.prototype.Cs);t.defineProperty(X,{Cs:"contextClick"},function(){return null!==this.R?this.R.bi:null},function(a){null===this.R&&Jj(this);var b=this.R.bi;b!==a&&(null!==a&&t.j(a,"function",X,"contextClick"),this.R.bi=a,this.i("contextClick",b,a))});t.g(X,"mouseEnter",X.prototype.vA); +t.defineProperty(X,{vA:"mouseEnter"},function(){return null!==this.R?this.R.qr:null},function(a){null===this.R&&Jj(this);var b=this.R.qr;b!==a&&(null!==a&&t.j(a,"function",X,"mouseEnter"),this.R.qr=a,this.i("mouseEnter",b,a))});t.g(X,"mouseLeave",X.prototype.wA);t.defineProperty(X,{wA:"mouseLeave"},function(){return null!==this.R?this.R.rr:null},function(a){null===this.R&&Jj(this);var b=this.R.rr;b!==a&&(null!==a&&t.j(a,"function",X,"mouseLeave"),this.R.rr=a,this.i("mouseLeave",b,a))}); +t.g(X,"mouseOver",X.prototype.et);t.defineProperty(X,{et:"mouseOver"},function(){return null!==this.R?this.R.pi:null},function(a){null===this.R&&Jj(this);var b=this.R.pi;b!==a&&(null!==a&&t.j(a,"function",X,"mouseOver"),this.R.pi=a,this.i("mouseOver",b,a))});t.g(X,"mouseHover",X.prototype.dt); +t.defineProperty(X,{dt:"mouseHover"},function(){return null!==this.R?this.R.oi:null},function(a){null===this.R&&Jj(this);var b=this.R.oi;b!==a&&(null!==a&&t.j(a,"function",X,"mouseHover"),this.R.oi=a,this.i("mouseHover",b,a))});t.g(X,"mouseHold",X.prototype.ct);t.defineProperty(X,{ct:"mouseHold"},function(){return null!==this.R?this.R.ni:null},function(a){null===this.R&&Jj(this);var b=this.R.ni;b!==a&&(null!==a&&t.j(a,"function",X,"mouseHold"),this.R.ni=a,this.i("mouseHold",b,a))}); +t.g(X,"mouseDragEnter",X.prototype.UE);t.defineProperty(X,{UE:"mouseDragEnter"},function(){return null!==this.R?this.R.or:null},function(a){null===this.R&&Jj(this);var b=this.R.or;b!==a&&(null!==a&&t.j(a,"function",X,"mouseDragEnter"),this.R.or=a,this.i("mouseDragEnter",b,a))});t.g(X,"mouseDragLeave",X.prototype.uA); +t.defineProperty(X,{uA:"mouseDragLeave"},function(){return null!==this.R?this.R.pr:null},function(a){null===this.R&&Jj(this);var b=this.R.pr;b!==a&&(null!==a&&t.j(a,"function",X,"mouseDragLeave"),this.R.pr=a,this.i("mouseDragLeave",b,a))});t.g(X,"mouseDrop",X.prototype.bt);t.defineProperty(X,{bt:"mouseDrop"},function(){return null!==this.R?this.R.mi:null},function(a){null===this.R&&Jj(this);var b=this.R.mi;b!==a&&(null!==a&&t.j(a,"function",X,"mouseDrop"),this.R.mi=a,this.i("mouseDrop",b,a))}); +t.g(X,"actionDown",X.prototype.wz);t.defineProperty(X,{wz:"actionDown"},function(){return null!==this.R?this.R.Wp:null},function(a){null===this.R&&Jj(this);var b=this.R.Wp;b!==a&&(null!==a&&t.j(a,"function",X,"actionDown"),this.R.Wp=a,this.i("actionDown",b,a))});t.g(X,"actionUp",X.prototype.yz); +t.defineProperty(X,{yz:"actionUp"},function(){return null!==this.R?this.R.Yp:null},function(a){null===this.R&&Jj(this);var b=this.R.Yp;b!==a&&(null!==a&&t.j(a,"function",X,"actionUp"),this.R.Yp=a,this.i("actionUp",b,a))});t.g(X,"actionMove",X.prototype.xz);t.defineProperty(X,{xz:"actionMove"},function(){return null!==this.R?this.R.Xp:null},function(a){null===this.R&&Jj(this);var b=this.R.Xp;b!==a&&(null!==a&&t.j(a,"function",X,"actionMove"),this.R.Xp=a,this.i("actionMove",b,a))}); +t.g(X,"actionCancel",X.prototype.vz);t.defineProperty(X,{vz:"actionCancel"},function(){return null!==this.R?this.R.Vp:null},function(a){null===this.R&&Jj(this);var b=this.R.Vp;b!==a&&(null!==a&&t.j(a,"function",X,"actionCancel"),this.R.Vp=a,this.i("actionCancel",b,a))});t.g(X,"toolTip",X.prototype.Et); +t.defineProperty(X,{Et:"toolTip"},function(){return null!==this.R?this.R.zi:null},function(a){null===this.R&&Jj(this);var b=this.R.zi;b!==a&&(null!==a&&t.l(a,We,X,"toolTip"),this.R.zi=a,this.i("toolTip",b,a))});t.g(X,"contextMenu",X.prototype.contextMenu);t.defineProperty(X,{contextMenu:"contextMenu"},function(){return null!==this.R?this.R.ci:null},function(a){null===this.R&&Jj(this);var b=this.R.ci;b!==a&&(null!==a&&t.l(a,We,X,"contextMenu"),this.R.ci=a,this.i("contextMenu",b,a))}); +X.prototype.bind=X.prototype.bind=function(a){a.eg=this;var b=this.Ro();null!==b&&wk(b)&&t.m("Cannot add a Binding to a template that has already been copied: "+a);null===this.Bc&&(this.Bc=new H(Ge));this.Bc.add(a)};X.prototype.findTemplateBinder=X.prototype.Ro=function(){for(var a=this instanceof B?this:this.ga;null!==a;){if(null!==a.Gl&&a instanceof B)return a;a=a.ga}return null};X.fromSvg=function(a){return xk(a)};X.prototype.setProperties=function(a){t.Nw(this,a)};var yk; +X.make=yk=function(a,b){var c=arguments,d=null,e=null;if("function"===typeof a)e=a;else if("string"===typeof a){var g=zk.Ba(a);"function"===typeof g?(c=Array.prototype.slice.call(arguments),d=g(c)):e=ba[a]}null===d&&(void 0===e&&(d=window.$,void 0!==d&&void 0!==d.noop&&t.m("GraphObject.make failed to complete. Is it conflicting with another $ var? (such as jQuery)"),t.m("GraphObject.make failed to complete, it may be conflicting with another var.")),null!==e&&e.constructor||t.m("GraphObject.make requires a class function or class name, not: "+ +a),d=new e);g=1;d instanceof u&&1d)&&t.m("Must specify non-negative integer row for RowColumnDefinition "+b),c.Tl=!0,c.te=d):void 0!==b.column?(d=b.column,(void 0===d||null===d||Infinity===d||isNaN(d)||0>d)&&t.m("Must specify non-negative integer column for RowColumnDefinition "+b),c.Tl=!1,c.te=d):t.m("Must specify row or column value in a RowColumnDefinition "+b),d=t.qH(b,"row","column"),t.Nw(c,d)):t.Nw(c,b);else t.m('Unknown initializer "'+b+'" for object being constructed by GraphObject.make: '+ +a)}var zk;X.Builders=zk=new sa("string","function"); +zk.add("Button",function(){var a=new ke(ne);a.addColorStop(0,"white");a.addColorStop(1,"lightgray");var b=new ke(ne);b.addColorStop(0,"white");b.addColorStop(1,"dodgerblue");var c=yk(B,Vh,{Rs:!0},yk(Y,{name:"ButtonBorder",Ib:"RoundedRectangle",fill:a,stroke:"gray"}));c.vA=function(a,c){var g=c.qa(0),h=c._buttonFillOver;void 0===h&&(h=b);c._buttonFillNormal=g.fill;g.fill=h;h=c._buttonStrokeOver;void 0===h&&(h="blue");c._buttonStrokeNormal=g.stroke;g.stroke=h};c.wA=function(b,c){var g=c.qa(0),h=c._buttonFillNormal; +void 0===h&&(h=a);g.fill=h;h=c._buttonStrokeNormal;void 0===h&&(h="gray");g.stroke=h};return c}); +zk.add("TreeExpanderButton",function(){var a=yk("Button",yk(Y,{name:"ButtonIcon",Ib:"MinusLine",Ca:J.Sp},(new Ge("figure","isTreeExpanded",function(a,c){var d=null,e=c.ga;e&&(d=a?e._treeExpandedFigure:e._treeCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).DA("")),{visible:!1},(new Ge("visible","isTreeLeaf",function(a){return!a})).DA(""));a.click=function(a,c){var d=c.S;d instanceof We&&(d=d.Dh);if(d instanceof y){var e=d.h;if(null!==e){e=e.lg;if(d.Gc){if(!e.canCollapseTree(d))return}else if(!e.canExpandTree(d))return; +a.Fe=!0;d.Gc?e.collapseTree(d):e.expandTree(d)}}};return a}); +zk.add("SubGraphExpanderButton",function(){var a=yk("Button",yk(Y,{name:"ButtonIcon",Ib:"MinusLine",Ca:J.Sp},(new Ge("figure","isSubGraphExpanded",function(a,c){var d=null,e=c.ga;e&&(d=a?e._subGraphExpandedFigure:e._subGraphCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).DA("")));a.click=function(a,c){var d=c.S;d instanceof We&&(d=d.Dh);if(d instanceof z){var e=d.h;if(null!==e){e=e.lg;if(d.Ve){if(!e.canCollapseSubGraph(d))return}else if(!e.canExpandSubGraph(d))return;a.Fe=!0;d.Ve?e.collapseSubGraph(d): +e.expandSubGraph(d)}}};return a});zk.add("ContextMenuButton",function(){var a=yk("Button");a.Sh=Ij;var b=a.le("ButtonBorder");b instanceof Y&&(b.Ib="Rectangle",b.G=new K(0,0,2,2),b.H=new K(1,1,-2,-2));return a}); +function B(a){X.call(this);void 0===a?0===arguments.length?this.ba=bh:t.m("invalid argument to Panel constructor: undefined"):(t.tb(a,B,B,"type"),this.ba=a);this.za=new H(X);this.Le=J.Up;this.Jg=!1;this.ba===$h&&(this.Jg=!0);this.Df=1;this.rq=Pb;this.kc=Yg;this.ba===ea&&fl(this);this.to=Zg;this.Hq=(new pa(10,10)).freeze();this.Iq=J.ok;this.Gl=this.Ll=null;this.By="";this.Kg=this.sj=null;this.Tn="category";this.Zf=null;this.Bi=new D(NaN,NaN,NaN,NaN);this.ro=null;this.pj=!1}t.ia("Panel",B);t.Fh(B); +t.Oa(B,X);function fl(a){a.hj=J.Up;a.lh=1;a.ei=null;a.Nl=null;a.kh=1;a.jh=null;a.Ml=null;a.$c=[];a.Vc=[];a.lm=gl;a.Hl=gl;a.Ai=0;a.ki=0} +B.prototype.cloneProtected=function(a){X.prototype.cloneProtected.call(this,a);a.ba=this.ba;a.Le=this.Le.Z();a.Jg=this.Jg;a.Df=this.Df;a.rq=this.rq.Z();a.kc=this.kc;if(a.ba===ea){a.hj=this.hj.Z();a.lh=this.lh;a.ei=this.ei;a.Nl=this.Nl;a.kh=this.kh;a.jh=this.jh;a.Ml=this.Ml;var b=[];if(0a&&t.ha(a,">= 0",B,"padding"),a=new pb(a)):(t.l(a,pb,B,"padding"),0>a.left&&t.ha(a.left,">= 0",B,"padding:val.left"),0>a.right&&t.ha(a.right,">= 0",B,"padding:val.right"),0>a.top&&t.ha(a.top,">= 0",B,"padding:val.top"),0>a.bottom&&t.ha(a.bottom,">= 0",B,"padding:val.bottom"));var b=this.Le;b.N(a)||(this.Le=a=a.Z(),this.aa(),this.i("padding",b,a))});t.g(B,"defaultAlignment",B.prototype.Yj); +t.defineProperty(B,{Yj:"defaultAlignment"},function(){return this.rq},function(a){var b=this.rq;b.N(a)||(f&&t.l(a,K,B,"defaultAlignment"),this.rq=a=a.Z(),this.aa(),this.i("defaultAlignment",b,a))});t.g(B,"defaultStretch",B.prototype.Qz);t.defineProperty(B,{Qz:"defaultStretch"},function(){return this.kc},function(a){var b=this.kc;b!==a&&(t.tb(a,X,B,"defaultStretch"),this.kc=a,this.aa(),this.i("defaultStretch",b,a))});t.g(B,"defaultSeparatorPadding",B.prototype.CH); +t.defineProperty(B,{CH:"defaultSeparatorPadding"},function(){return void 0===this.hj?J.Up:this.hj},function(a){if(void 0!==this.hj){"number"===typeof a?a=new pb(a):f&&t.l(a,pb,B,"defaultSeparatorPadding");var b=this.hj;b.N(a)||(this.hj=a=a.Z(),this.i("defaultSeparatorPadding",b,a))}});t.g(B,"defaultRowSeparatorStroke",B.prototype.AH); +t.defineProperty(B,{AH:"defaultRowSeparatorStroke"},function(){return void 0===this.ei?null:this.ei},function(a){var b=this.ei;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.ei=a,this.i("defaultRowSeparatorStroke",b,a))});t.g(B,"defaultRowSeparatorStrokeWidth",B.prototype.BH); +t.defineProperty(B,{BH:"defaultRowSeparatorStrokeWidth"},function(){return void 0===this.lh?1:this.lh},function(a){if(void 0!==this.lh){var b=this.lh;b!==a&&(this.lh=a,this.i("defaultRowSeparatorStrokeWidth",b,a))}});t.g(B,"defaultRowSeparatorDashArray",B.prototype.zH); +t.defineProperty(B,{zH:"defaultRowSeparatorDashArray"},function(){return void 0===this.Nl?null:this.Nl},function(a){if(void 0!==this.Nl){var b=this.Nl;b!==a&&(Array.isArray(a)||t.Vb(a,"Array",B,"defaultRowSeparatorDashArray:val"),this.Nl=a,this.i("defaultRowSeparatorDashArray",b,a))}});t.g(B,"defaultColumnSeparatorStroke",B.prototype.vH); +t.defineProperty(B,{vH:"defaultColumnSeparatorStroke"},function(){return void 0===this.jh?null:this.jh},function(a){if(void 0!==this.jh){var b=this.jh;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.jh=a,this.i("defaultColumnSeparatorStroke",b,a))}});t.g(B,"defaultColumnSeparatorStrokeWidth",B.prototype.wH); +t.defineProperty(B,{wH:"defaultColumnSeparatorStrokeWidth"},function(){return void 0===this.kh?1:this.kh},function(a){if(void 0!==this.kh){var b=this.kh;b!==a&&(this.kh=a,this.i("defaultColumnSeparatorStrokeWidth",b,a))}});t.g(B,"defaultColumnSeparatorDashArray",B.prototype.uH); +t.defineProperty(B,{uH:"defaultColumnSeparatorDashArray"},function(){return void 0===this.Ml?null:this.Ml},function(a){if(void 0!==this.Ml){var b=this.Ml;b!==a&&(Array.isArray(a)||t.Vb(a,"Array",B,"defaultColumnSeparatorDashArray:val"),this.Ml=a,this.i("defaultColumnSeparatorDashArray",b,a))}});t.g(B,"viewboxStretch",B.prototype.lJ); +t.defineProperty(B,{lJ:"viewboxStretch"},function(){return this.to},function(a){var b=this.to;b!==a&&(t.tb(a,X,B,"viewboxStretch"),this.to=a,this.i("viewboxStretch",b,a))});t.g(B,"gridCellSize",B.prototype.Ms); +t.defineProperty(B,{Ms:"gridCellSize"},function(){return this.Hq},function(a){var b=this.Hq;b.N(a)||(t.l(a,pa,B,"gridCellSize"),a.Q()&&0!==a.width&&0!==a.height||t.m("Invalid Panel.gridCellSize: "+a),this.Hq=a.Z(),null!==this.h&&this===this.h.Yo&&si(this.h),this.pa(),this.i("gridCellSize",b,a))});t.g(B,"gridOrigin",B.prototype.cA); +t.defineProperty(B,{cA:"gridOrigin"},function(){return this.Iq},function(a){var b=this.Iq;b.N(a)||(t.l(a,C,B,"gridOrigin"),a.Q()||t.m("Invalid Panel.gridOrigin: "+a),this.Iq=a.Z(),this.h&&si(this.h),this.pa(),this.i("gridOrigin",b,a))}); +B.prototype.hl=function(a,b){var c=this.opacity,d=1;1!==c&&(d=a.globalAlpha,a.globalAlpha=d*c);if(this.ba===$h){c=this.fk()*b.scale;0>=c&&(c=1);var e=this.Ms,d=e.width,e=e.height,g=this.Ga,h=g.width,g=g.height,k=Math.ceil(h/d),l=Math.ceil(g/e),m=this.cA;a.save();a.beginPath();a.rect(0,0,h,g);a.clip();for(var n=[],p=this.za.p,q=this.za.length,r=0;rd*v*c))break}else for(L=G=Math.floor(-m.y/e);L<=G+l&&!(N=L*e+m.y,0<=N&&N<=g&&hl(L,v,s)&&(x&&!F?Lj(a,0,N,h,N,E,r.ad):(a.moveTo(0,N),a.lineTo(h,N)),2>e*v*c));L++);a.stroke();x&&(void 0!==a.setLineDash?(a.setLineDash(t.Xh),a.lineDashOffset=0):void 0!==a.webkitLineDash?(a.webkitLineDash=t.Xh,a.webkitLineDashOffset=0):void 0!==a.mozDash&&(a.mozDash=null,a.mozDashOffset=0))}a.restore();ca(b,a,!1)}else{this.ba===ea&&(a.lineCap="butt",il(this,a,!0,this.$c,!0),il(this, +a,!1,this.Vc,!0),nl(this,a,!0,this.$c),nl(this,a,!1,this.Vc),il(this,a,!0,this.$c,!1),il(this,a,!1,this.Vc,!1));F=this.za.length;for(e=0;e +h.height&&(m-=r-h.height):r>h.width&&(m-=r-h.width);g=g.position+m/2;b.lineWidth=m;r=a.padding;c?(g+=r.top,m=r.left,r=h.width-r.right,n&&!q?Lj(b,m,g,r,g,p,0):(b.moveTo(m,g),b.lineTo(r,g))):(g+=r.left,m=r.top,r=h.height-r.bottom,n&&!q?Lj(b,g,m,g,r,p,0):(b.moveTo(g,m),b.lineTo(g,r)));b.stroke();n&&(void 0!==b.setLineDash?(b.setLineDash(t.Xh),b.lineDashOffset=0):void 0!==b.webkitLineDash?(b.webkitLineDash=t.Xh,b.webkitLineDashOffset=0):void 0!==b.mozDash&&(b.mozDash=null,b.mozDashOffset=0))}}} +function il(a,b,c,d,e){for(var g=d.length,h,k=a.wa,l=0;lm)){var n=ol(h),p=h.dn;isNaN(p)&&(p=c?a.lh:a.kh);var q=h.cn;null===q&&(q=c?a.ei:a.jh);null===q&&(p=0);n-=p;p=h.position+p;n+=h.Yb;p+n>m&&(n=m-p);0>=n||(m=a.padding,dk(a,b,h.background,!0),c?b.fillRect(m.left,p+m.top,k.width-(m.left+m.right),n):b.fillRect(p+m.left,m.top,n,k.height-(m.top+m.bottom)))}}} +function hl(a,b,c){if(0!==a%b)return!1;b=c.length;for(var d=0;dGc&&(mc=Gc),sl(ha,ha.Yb+mc),Gc=Math.max(Gc-mc,0));1!==na.gj||!qh&&Od!==Xg&&Od!==Hj||(ha=this.me(rc),mc=Math.max(Qe-ha.Yb,0),mc>wc&&(mc=wc),sl(ha,ha.Yb+mc),wc=Math.max(wc-mc,0));fg&&lk(na)}}}t.Da(ph);for(var ee=0,fe=0,tb=this.Sv,ka=0;ka=this.Kw);hc++)ha=this.ne(na.gc+hc),Qd.height+=Math.max(ha.Oh,isNaN(ha.Ef)?ha.qf:Math.min(ha.Ef,ha.qf));for(hc=1;hc=this.Sv);hc++)ha=this.me(na.column+hc),Qd.width+=Math.max(ha.Oh,isNaN(ha.Ef)?ha.qf:Math.min(ha.Ef,ha.qf));yb.width+=Qd.width;yb.height+=Qd.height;Rb=na.margin;Lf=Rb.right+Rb.left;Mf=Rb.top+Rb.bottom;Bh(na,yb.width,yb.height,mf,bb);for(var te=na.Ea,Qe=Math.max(te.width+Lf,0),Re=Math.max(te.height+Mf,0),Eg=0,hc=0;hcsc&&(sl(ha,Math.min(ha.qf,sc+Rd)),ha.Eb!==sc&&(Rd-=ha.Eb-sc));if(-1===ha.index-1)break;ha=this.ne(ha.index-1)}for(var Se=0,hc=0;hcsc&&(sl(ha,Math.min(ha.qf,sc+Rd)),ha.Eb!==sc&&(Rd-=ha.Eb-sc));if(-1===ha.index-1)break;ha=this.me(ha.index-1)}}t.Da(Ag);t.dk(Qd);t.dk(yb);for(var pf=0,he=0,Od=Qj(this),Fg= +this.Ca,gg=this.He,Hc=fe=ee=0,ie=0,tb=this.Sv,ka=0;kash)Bh(Sb, +Infinity,Infinity),Sd=Sb.Ea,ue.nk(Sd),this.Zh.add(Sd);else{var Pf=Sb.tf,uo=Sb.tt,ll=Sb.Qj;ll.qd()&&(ll=Wb);var uj=Sb.ut,pq=Sb.VA,ki,li,vj=0;if(Pf<-sh||Pf>=sh){var vo=rj.SE,wj=rj.RE;uj!==Jg&&(vj=rj.computeAngle(Sb,uj,wj),Sb.angle=vj);ki=vo.x-Ue.x;li=vo.y-Ue.y}else{var qf,uh;if(0<=Pf)qf=ji.p[Pf],uh=Pfc||q>d)this.aa(),Bh(this,p>c?c:p,q>d?d:q);break;case Qc:Rj(this,!0);Bh(this,c+s,d+v,0,0);break;case Ij:Rj(this,!0);Bh(this,c+s,q+v,0,0);break;case Hj:Rj(this,!0),Bh(this,p+s,d+v,0,0)}}l=this.wa;l.x=a; +l.y=b;l.width=c;l.height=d;var x=this.ba.Rb;switch(x){case "Position":for(var E=e.x-this.padding.left,F=e.y-this.padding.top,G=0;G=this.Kw);ka++){var na=this.ne(Bb+ka);Cb.height+=na.total}for(ka=1;ka=this.Sv);ka++){var kj=this.me(Dd+ka);Cb.width+=kj.total}var zg=fc.Eb+Cb.width,rc=Cd.Eb+Cb.height;k.x=be;k.y=Bc;k.width=zg;k.height=rc;Bc+rc>e.height&&(rc=Math.max(e.height- +Bc,0));be+zg>e.width&&(zg=Math.max(e.width-be,0));var oh=be,gc=Bc,ph=zg,Ag=rc,Dc=bb.alignment,Ec,Fc,wc,Gc;if(Dc.Fc()){Dc=this.Yj;Dc.rd()||(Dc=Wb);Ec=Dc.x;Fc=Dc.y;wc=Dc.offsetX;Gc=Dc.offsetY;var Kf=fc.alignment,ha=Cd.alignment;Kf.rd()&&(Ec=Kf.x,wc=Kf.offsetX);ha.rd()&&(Fc=ha.y,Gc=ha.offsetY)}else Ec=Dc.x,Fc=Dc.y,wc=Dc.offsetX,Gc=Dc.offsetY;if(isNaN(Ec)||isNaN(Fc))Fc=Ec=0.5,Gc=wc=0;var Nd=ce.width,Ed=ce.height,lj=bb.He,mj=bb.Ye,Nd=Math.min(lj.width,Nd),Ed=Math.min(lj.height,Ed),Nd=Math.max(mj.width, +Nd),Ed=Math.max(mj.height,Ed),mc=bb.margin,lb=mc.left+mc.right,mb=mc.top+mc.bottom,Bg=nk(bb,Cd,fc);if(isNaN(bb.Ca.width)&&isNaN(fc.width)&&Bg===Qc||Bg===Ij)Nd=Math.max(zg-lb,0);if(isNaN(bb.Ca.height)&&isNaN(Cd.height)&&Bg===Qc||Bg===Hj)Ed=Math.max(rc-mb,0);var jl=Ed+mb;k.x+=k.width*Ec-(Nd+lb)*Ec+wc+mc.left;k.y+=k.height*Fc-jl*Fc+Gc+mc.top;bb.visible&&(Db(oh,gc,ph,Ag,k.x,k.y,Nd,Ed)?bb.Dc(k.x,k.y,Nd,Ed):bb.Dc(k.x,k.y,Nd,Ed,new D(oh,gc,ph,Ag)))}}}}t.dk(Cb);for(Bb=0;Bb=rh){var Eg=this.SE,Rd=this.RE;ge!==Jg&&(hc= +this.computeAngle(nd,ge,Rd),nd.angle=hc);of=Eg.x;Qd=Eg.y}else{var sc=void 0,Se=void 0;if(0<=Pd)sc=Cg.p[Pd],Se=Pdn.width||m.y>n.height||0>m.x+m.width||0>m.y+m.height)){m=t.bh();m.set(h);if(l instanceof B?l.ck(a,b,c,d,e,m):Pj(l,a,d,m))null!==b&&(l=b(l)),l&& +(null===c||c(l))&&e.add(l);t.Se(m)}}}void 0===g&&t.Se(h);return d}void 0===g&&t.Se(h);return!1};function Dl(a,b,c,d){for(var e=a.za.length;e--;){var g=a.za.p[e];if(g.visible){var h=g.wa,k=a.Ga;h.x>k.width||h.y>k.height||0>h.x+h.width||0>h.y+h.height||(g instanceof B&&Dl(g,b,c,d),null!==b&&(g=b(g)),g&&(null===c||c(g))&&d.add(g))}}} +aa.Mm=function(a,b,c,d,e,g){if(!1===this.Ze)return!1;void 0===c&&(c=null);void 0===d&&(d=null);var h=this.Ga,k=this.Bg(),l=k?a:$a(t.ic(a.x,a.y),this.transform),m=k?b:$a(t.ic(b.x,b.y),this.transform),n=l.$j(m),p=0r.width||q.y>r.height||0>q.x+q.width||0>q.y+q.height||(n.Bg()?(q=n.transform,$a(k.set(a),q),$a(l.set(b),q)):(k.set(a),l.set(b)),n instanceof B?!n.Mm(k,l,c,d,e,g):!n.XD(k,l,e))||(null!==c&&(n=c(n)),n&&(null===d||d(n))&&g.add(n))}t.B(k);t.B(l)}return e?p:h}return!1}; +function pl(a){var b=a.G;if(void 0===b||b===Pb)b=null;null===b&&a instanceof Y&&(a=a.Ra,null!==a&&(b=a.G));null===b&&(b=Tb);return b}function ql(a){var b=a.H;if(void 0===b||b===Pb)b=null;null===b&&a instanceof Y&&(a=a.Ra,null!==a&&(b=a.H));null===b&&(b=$b);return b}B.prototype.add=B.prototype.add=function(a){t.l(a,X,B,"add:element");this.Ad(this.za.count,a)};B.prototype.elt=B.prototype.qa=function(a){return this.za.qa(a)}; +B.prototype.insertAt=B.prototype.Ad=function(a,b){b instanceof w&&t.m("Cannot add a Part to a Panel: "+b);if(this===b||this.Ti(b))this===b&&t.m("Cannot make a Panel contain itself: "+this.toString()),t.m("Cannot make a Panel indirectly contain itself: "+this.toString()+" already contains "+b.toString());var c=b.ga;null!==c&&c!==this&&t.m("Cannot add a GraphObject that already belongs to another Panel to this Panel: "+b.toString()+", already contained by "+c.toString()+", cannot be shared by this Panel: "+ +this.toString());this.ba!==$h||b instanceof Y||t.m("Can only add Shapes to a Grid Panel, not: "+b);b.vl(this);b.gm=null;if(null!==this.Xs){var d=b.data;null!==d&&"object"===typeof d&&(null===this.Zf&&(this.Zf=new sa(Object,B)),this.Zf.add(d,b))}var e=this.za,d=-1;if(c===this){for(var g=-1,h=e.count,k=0;k=e.count&&a>=e.count)return;e.gd(g);d=g}else t.m("element "+b.toString()+" has panel "+c.toString()+" but is not contained by it.")}if(0>a|| +a>e.count)a=e.count;e.Ad(a,b);this.aa();b.aa();null!==b.sd&&(this.pj=!0);b instanceof B&&!0===b.pj&&(this.pj=!0);c=this.S;null!==c&&(c.Aj=null,c.yj=NaN,null!==b.sd&&c instanceof y&&(c.pj=!0),e=this.h,null!==e&&e.Aa.qb||(-1!==d&&c.Uc(Td,"elements",this,b,null,d,null),c.Uc(Jd,"elements",this,null,b,null,a)))};B.prototype.remove=B.prototype.remove=function(a){t.l(a,X,B,"remove:element");for(var b=this.za,c=b.count,d=-1,e=0;ea&&t.ha(a,">= 0",B,"getRowDefinition:idx");a=Math.round(a);var b=this.$c;if(void 0===b[a]){var c=new Ck;c.vl(this);c.Tl=!0;c.te=a;b[a]=c}return b[a]};B.prototype.removeRowDefinition=function(a){if(void 0!==this.$c){f&&t.o(a,B,"removeRowDefinition:idx");0>a&&t.ha(a,">= 0",B,"removeRowDefinition:idx");a=Math.round(a);var b=this.$c;b[a]&&(b[a]=void 0)}}; +t.A(B,{Sv:"columnCount"},function(){return void 0===this.Vc?0:this.Vc.length});B.prototype.getColumnDefinition=B.prototype.me=function(a){if(void 0===this.Vc)return null;f&&t.o(a,B,"getColumnDefinition:idx");0>a&&t.ha(a,">= 0",B,"getColumnDefinition:idx");a=Math.round(a);var b=this.Vc;if(void 0===b[a]){var c=new Ck;c.vl(this);c.Tl=!1;c.te=a;b[a]=c}return b[a]}; +B.prototype.removeColumnDefinition=function(a){if(void 0!==this.Vc){f&&t.o(a,B,"removeColumnDefinition:idx");0>a&&t.ha(a,">= 0",B,"removeColumnDefinition:idx");a=Math.round(a);var b=this.Vc;b[a]&&(b[a]=void 0)}};t.g(B,"rowSizing",B.prototype.qF); +t.defineProperty(B,{qF:"rowSizing"},function(){return void 0===this.lm?gl:this.lm},function(a){if(void 0!==this.lm){var b=this.lm;b!==a&&(a!==gl&&a!==ul&&t.m("rowSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.lm=a,this.aa(),this.i("rowSizing",b,a))}});t.g(B,"columnSizing",B.prototype.sD); +t.defineProperty(B,{sD:"columnSizing"},function(){return void 0===this.Hl?gl:this.Hl},function(a){if(void 0!==this.Hl){var b=this.Hl;b!==a&&(a!==gl&&a!==ul&&t.m("columnSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.Hl=a,this.aa(),this.i("columnSizing",b,a))}});t.g(B,"topIndex",B.prototype.mB); +t.defineProperty(B,{mB:"topIndex"},function(){return void 0===this.Ai?0:this.Ai},function(a){if(void 0!==this.Ai){var b=this.Ai;b!==a&&((!isFinite(a)||0>a)&&t.m("topIndex must be greater than zero and a real number. Was "+a),this.Ai=a,this.aa(),this.i("topIndex",b,a))}});t.g(B,"leftIndex",B.prototype.oA); +t.defineProperty(B,{oA:"leftIndex"},function(){return void 0===this.ki?0:this.ki},function(a){if(void 0!==this.ki){var b=this.ki;b!==a&&((!isFinite(a)||0>a)&&t.m("leftIndex must be greater than zero and a real number. Was "+a),this.ki=a,this.aa(),this.i("leftIndex",b,a))}});B.prototype.findRowForLocalY=function(a){if(0>a)return-1;if(this.type!==ea)return NaN;for(var b=0,c=this.$c,d=c.length,e=this.Ai;ea)return-1;if(this.type!==ea)return NaN;for(var b=0,c=this.Vc,d=c.length,e=this.ki;ea;)this.Te(a);a=this.Xs;if(null!==a)for(var b=t.yb(a),c=0;ca||1a&&t.ha(a,">= 0",Ck,"height"),this.Ef=a,sl(this,this.Eb),this.Lc("size",b,a))});t.g(Ck,"width",Ck.prototype.width);t.defineProperty(Ck,{width:"width"},function(){return this.Ef},function(a){var b=this.Ef;b!==a&&(f&&t.j(a,"number",Ck,"width"),0>a&&t.ha(a,">= 0",Ck,"width"),this.Ef=a,sl(this,this.Eb),this.Lc("size",b,a))});t.g(Ck,"minimum",Ck.prototype.Oh); +t.defineProperty(Ck,{Oh:"minimum"},function(){return this.am},function(a){var b=this.am;b!==a&&(f&&t.j(a,"number",Ck,"minimum"),(0>a||!isFinite(a))&&t.ha(a,">= 0",Ck,"minimum"),this.am=a,sl(this,this.Eb),this.Lc("minimum",b,a))});t.g(Ck,"maximum",Ck.prototype.qf);t.defineProperty(Ck,{qf:"maximum"},function(){return this.$l},function(a){var b=this.$l;b!==a&&(f&&t.j(a,"number",Ck,"maximum"),0>a&&t.ha(a,">= 0",Ck,"maximum"),this.$l=a,sl(this,this.Eb),this.Lc("maximum",b,a))});t.g(Ck,"alignment",Ck.prototype.alignment); +t.defineProperty(Ck,{alignment:"alignment"},function(){return this.re},function(a){var b=this.re;b.N(a)||(f&&t.l(a,K,Ck,"alignment"),this.re=a.Z(),this.Lc("alignment",b,a))});t.g(Ck,"stretch",Ck.prototype.Sh);t.defineProperty(Ck,{Sh:"stretch"},function(){return this.zh},function(a){var b=this.zh;b!==a&&(f&&t.tb(a,X,Ck,"stretch"),this.zh=a,this.Lc("stretch",b,a))});t.g(Ck,"separatorPadding",Ck.prototype.XA); +t.defineProperty(Ck,{XA:"separatorPadding"},function(){return this.Jj},function(a){"number"===typeof a?a=new pb(a):null!==a&&f&&t.l(a,pb,Ck,"separatorPadding");var b=this.Jj;null!==a&&null!==b&&b.N(a)||(null!==a&&(a=a.Z()),this.Jj=a,this.Lc("separatorPadding",b,a))});t.g(Ck,"separatorStroke",Ck.prototype.cn); +t.defineProperty(Ck,{cn:"separatorStroke"},function(){return this.Wr},function(a){var b=this.Wr;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.Wr=a,this.ga&&this.ga.pa(),this.Lc("separatorStroke",b,a))});t.g(Ck,"separatorStrokeWidth",Ck.prototype.dn);t.defineProperty(Ck,{dn:"separatorStrokeWidth"},function(){return this.Xr},function(a){var b=this.Xr;b!==a&&(this.Xr=a,this.ga&&this.ga.pa(),this.Lc("separatorStrokeWidth",b,a))}); +t.g(Ck,"separatorDashArray",Ck.prototype.wF);t.defineProperty(Ck,{wF:"separatorDashArray"},function(){return this.vh},function(a){var b=this.vh;b!==a&&(Array.isArray(a)||t.Vb(a,"Array",Ck,"separatorDashArray:val"),this.vh=a,this.ga&&this.ga.pa(),this.Lc("separatorDashArray",b,a))});t.g(Ck,"background",Ck.prototype.background); +t.defineProperty(Ck,{background:"background"},function(){return this.Gb},function(a){var b=this.Gb;b!==a&&(null===a||"string"===typeof a||a instanceof ke)&&(a instanceof ke&&a.freeze(),this.Gb=a,this.ga&&this.ga.pa(),this.Lc("background",b,a))});t.g(Ck,"coversSeparators",Ck.prototype.Xv);t.defineProperty(Ck,{Xv:"coversSeparators"},function(){return this.nq},function(a){var b=this.nq;b!==a&&(t.j(a,"boolean",Ck,"coversSeparators"),this.nq=a,this.Lc("coversSeparators",b,a))});t.g(Ck,"sizing",Ck.prototype.yt); +t.defineProperty(Ck,{yt:"sizing"},function(){return this.Zr},function(a){var b=this.Zr;b!==a&&(f&&t.tb(a,Ck,Ck,"sizing"),this.Zr=a,this.Lc("sizing",b,a))});function tl(a){if(a.yt===Fl){var b=a.ti;return a.Kh?b.qF:b.sD}return a.yt}t.A(Ck,{Yb:"actual"},function(){return this.Eb});t.A(Ck,{total:"total"},function(){return this.Eb+ol(this)});t.A(Ck,{position:"position"},function(){return this.rb}); +Ck.prototype.bind=Ck.prototype.bind=function(a){a.eg=this;var b=this.ga;null!==b&&(b=b.Ro(),null!==b&&wk(b)&&t.m("Cannot add a Binding to a RowColumnDefinition that is already frozen: "+a));null===this.Bc&&(this.Bc=new H(Ge));this.Bc.add(a)}; +function Y(){X.call(this);this.Ra=null;this.In="None";this.Rg=!1;this.Fq=Yg;this.Bk=null;this.xb=this.Jc="black";this.fe=1;this.po="butt";this.qo="miter";this.rm=10;this.qm=null;this.ad=0;this.yi=this.xi=Pb;this.xr=this.wr=0;this.Kq=!1;this.Pq=!0;this.zr=null;this.Kn=this.so="None";this.Jq=1}t.ia("Shape",Y);t.Oa(Y,X); +Y.prototype.cloneProtected=function(a){X.prototype.cloneProtected.call(this,a);a.Ra=this.Ra;a.In=this.In;a.Rg=this.Rg;a.Fq=this.Fq;a.Bk=this.Bk;a.Jc=this.Jc;a.xb=this.xb;a.fe=this.fe;a.po=this.po;a.qo=this.qo;a.rm=this.rm;a.qm=null;this.qm&&(a.qm=this.qm.slice(0));a.ad=this.ad;a.xi=this.xi.Z();a.yi=this.yi.Z();a.wr=this.wr;a.xr=this.xr;a.Kq=this.Kq;a.Pq=this.Pq;a.zr=this.zr;a.so=this.so;a.Kn=this.Kn;a.Jq=this.Jq}; +Y.prototype.toString=function(){return"Shape("+("None"!==this.Ib?this.Ib:"None"!==this.gn?this.gn:this.jw)+")#"+t.oc(this)}; +function Gl(a,b,c,d){var e=0.001,g=d.Ea,h=g.width,g=g.height,k,l,m,n=c.length;if(!(2>n)){k=c[0][0];l=c[0][1];for(var p,q,r,s,v=0,x=t.Cb(),E=1;Ev){t.Da(x);return}e>r?(F=e-r,e=r):F=0;var G=Math.sqrt(e* +e/(1+q*q));0>p&&(G=-G);k+=G;l+=q*G;a.translate(k,l);a.rotate(s);a.translate(-(h/2),-(g/2));0===F&&d.hl(a,b);a.translate(h/2,g/2);a.rotate(-s);a.translate(-k,-l);v-=e;r-=e;if(0!==F){m++;if(m===x.length){t.Da(x);return}r=x[m];p=r[0];s=r[1];q=r[2];r=r[3];e=F}}t.Da(x)}} +Y.prototype.hl=function(a,b){if(null!==this.xb||null!==this.Jc){null!==this.Jc&&dk(this,a,this.Jc,!0);null!==this.xb&&dk(this,a,this.xb,!1);var c=this.fe;if(0===c){var d=this.S;d instanceof We&&d.type===wg&&d.Nc instanceof Y&&(c=d.Nc.ib)}a.lineWidth=c;a.lineJoin=this.qo;a.lineCap=this.po;a.miterLimit=this.rm;var e=!1;this.S&&(e=this.S.Lh);var g=!0;null!==this.xb&&null===this.Jc&&(g=!1);var d=!1,h=this.Rw;if(null!==h){var k=d=!0;void 0!==a.setLineDash?(a.setLineDash(h),a.lineDashOffset=this.ad):void 0!== +a.webkitLineDash?(a.webkitLineDash=h,a.webkitLineDashOffset=this.ad):void 0!==a.mozDash?(a.mozDash=h,a.mozDashOffset=this.ad):k=!1}var l=this.Ra;if(null!==l){if(l.ba===Vc)a.beginPath(),d&&!k?Lj(a,l.ec,l.nc,l.md,l.xd,h,this.ad):(a.moveTo(l.ec,l.nc),a.lineTo(l.md,l.xd)),null!==this.Jc&&ek(a,this.Jc,!0),0!==c&&null!==this.xb&&ek(a,this.xb,!1);else if(l.ba===Wc){var m=l.ec,n=l.nc,p=l.md,l=l.xd,q=Math.min(m,p),r=Math.min(n,l),m=Math.abs(p-m),n=Math.abs(l-n);null!==this.Jc&&(this.Jc instanceof ke&&this.Jc.type=== +oe?(a.beginPath(),a.rect(q,r,m,n),ek(a,this.Jc,!0)):a.fillRect(q,r,m,n));if(null!==this.xb){if(g&&e){var s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}d&&!k?(k=[[q,r],[q+m,r],[q+m,r+n],[q,r+n],[q,r]],a.beginPath(),Hl(a,k,h,this.ad),ek(a,this.xb,!1)):0!==c&&(this.xb instanceof ke&&this.xb.type===oe?(a.beginPath(),a.rect(q,r,m,n),ek(a,this.xb,!1)):a.strokeRect(q,r,m,n));g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2])}}else if(l.ba=== +Xc)m=l.ec,n=l.nc,p=l.md,l=l.xd,q=Math.abs(p-m)/2,r=Math.abs(l-n)/2,m=Math.min(m,p)+q,n=Math.min(n,l)+r,a.beginPath(),a.moveTo(m,n-r),a.bezierCurveTo(m+J.va*q,n-r,m+q,n-J.va*r,m+q,n),a.bezierCurveTo(m+q,n+J.va*r,m+J.va*q,n+r,m,n+r),a.bezierCurveTo(m-J.va*q,n+r,m-q,n+J.va*r,m-q,n),a.bezierCurveTo(m-q,n-J.va*r,m-J.va*q,n-r,m,n-r),a.closePath(),null!==this.Jc&&ek(a,this.Jc,!0),d&&!k&&(k=t.Cb(),J.ze(m,n-r,m+J.va*q,n-r,m+q,n-J.va*r,m+q,n,0.5,k),J.ze(m+q,n,m+q,n+J.va*r,m+J.va*q,n+r,m,n+r,0.5,k),J.ze(m,n+ +r,m-J.va*q,n+r,m-q,n+J.va*r,m-q,n,0.5,k),J.ze(m-q,n,m-q,n-J.va*r,m-J.va*q,n-r,m,n-r,0.5,k),a.beginPath(),Hl(a,k,h,this.ad),t.Da(k)),0!==c&&null!==this.xb&&(g&&e&&(s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0),ek(a,this.xb,!1),g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2]));else if(l.ba===Oc){for(var q=l.Fk,r=q.length,v=0;vN.Th);else for(var G=sd(N,x),W=G.length,T=0;Tm))if(h=b[0][0],k=b[0][1],2===m)Lj(a,h,k,b[1][0],b[1][1],c,d);else{a.moveTo(h,k);for(var n,p,q,r=0,s=t.Cb(),v=1;vr&&(e=r);e>q?(x=e-q,e=q):x=0;var E=Math.sqrt(e*e/(1+p*p));0>n&&(E= +-E);h+=E;k+=p*E;m?a.lineTo(h,k):a.moveTo(h,k);r-=e;q-=e;if(0!==x){l++;if(l===s.length){t.Da(s);return}q=s[l];n=q[0];p=q[1];q=q[2];e=x}else m=!m}t.Da(s)}}Y.prototype.getDocumentPoint=Y.prototype.gb=function(a,b){void 0===b&&(b=new C);a.qd()&&t.m("Spot must be real");var c=this.Ga,d=this.ib;b.q(a.x*(c.width+d)-d/2+c.x+a.offsetX,a.y*(c.height+d)-d/2+c.y+a.offsetY);this.he.Va(b);return b}; +Y.prototype.Vj=function(a,b){var c=this.Ra;if(null===c||null===this.fill&&null===this.stroke)return!1;var d=c.Mb,e=this.ib/2;c.type!==Vc||b||(e+=2);var g=t.wf();g.assign(d);g.Vg(e+2,e+2);if(!g.Ia(a))return t.Pc(g),!1;d=e+1E-4;if(c.type===Vc){if(null===this.stroke)return!1;g=(c.D-c.na)*(a.x-c.na)+(c.F-c.oa)*(a.y-c.oa);return 0>(c.na-c.D)*(a.x-c.D)+(c.oa-c.F)*(a.y-c.F)||0>g?!1:J.Cd(c.na,c.oa,c.D,c.F,e,a.x,a.y)}if(c.type===Wc){var h=c.na,k=c.oa,l=c.D,m=c.F,c=Math.min(h,l),n=Math.min(k,m),h=Math.abs(l- +h),k=Math.abs(m-k);g.x=c;g.y=n;g.width=h;g.height=k;if(null===this.fill){g.Vg(-d,-d);if(g.Ia(a))return!1;g.Vg(d,d)}null!==this.stroke&&g.Vg(e,e);e=g.Ia(a);t.Pc(g);return e}if(c.type===Xc){h=c.na;k=c.oa;l=c.D;m=c.F;c=Math.min(h,l);n=Math.min(k,m);h=Math.abs(l-h);k=Math.abs(m-k);g=h/2;k/=2;c=a.x-(c+g);n=a.y-(n+k);if(null===this.fill){g-=d;k-=d;if(0>=g||0>=k||1>=c*c/(g*g)+n*n/(k*k))return!1;g+=d;k+=d}null!==this.stroke&&(g+=e,k+=e);return 0>=g||0>=k?!1:1>=c*c/(g*g)+n*n/(k*k)}if(c.type===Oc)return null=== +this.fill?vd(c,a.x,a.y,e):c.Ia(a,e,1=this.ib)n=J.$g(p.ec,p.nc,p.md,p.xd,g,h,k,l,e);else{var r,s;p.ec===p.md?(r=m,s=0):(b=(p.xd-p.nc)/(p.md-p.ec),s=m/Math.sqrt(1+b*b),r=s*b);d=t.Cb();b=new C;J.$g(p.ec+ +r,p.nc+s,p.md+r,p.xd+s,g,h,k,l,b)&&d.push(b);b=new C;J.$g(p.ec-r,p.nc-s,p.md-r,p.xd-s,g,h,k,l,b)&&d.push(b);b=new C;J.$g(p.ec+r,p.nc+s,p.ec-r,p.nc-s,g,h,k,l,b)&&d.push(b);b=new C;J.$g(p.md+r,p.xd+s,p.md-r,p.xd-s,g,h,k,l,b)&&d.push(b);b=d.length;if(0===b)return t.Da(d),!1;n=!0;s=Infinity;for(r=0;rMath.abs(c)){n=h-b-c*(g-d);if(0>a*a*c*c+x*x-n*n){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(a*a*c*c+x*x-n*n);k=(-(a*a*c*n)+a*x*m)/(x*x+a*a*c*c)+d;a=(-(a*a*c*n)-a*x*m)/(x*x+a*a*c*c)+d;l=c*(k-d)+n+b;b=c*(a-d)+n+b;d=Math.abs((g-k)*(g-k))+Math.abs((h-l)*(h-l));h=Math.abs((g-a)*(g-a))+Math.abs((h-b)* +(h-b));dk){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(k);l=b+m;b-=m;d=Math.abs(l-h);h=Math.abs(b-h);dc?a-c:c-a)<(b>d?b-d:d-b)?(e=be||J.Ka(l.y,e))&&(l.ye||J.Ka(l.x,e))&&(l.x=h&&d<=a}a=h&&c<=a} +Y.prototype.XD=function(a,b,c){function d(a,b){for(var c=a.length,d=0;de)return!0}return!1}if(c&&null!==this.fill&&this.Vj(a,!0))return!0;var e=a.$j(b);b=e;1.5=e||eb(b,g,0,-p)>=e||eb(b,g,0,p)>=e||eb(b,g,n,0)>=e?!1: +!0}else if(g.type===Oc){h=g.Mb;k=h.x;l=h.y;m=h.x+h.width;h=h.y+h.height;if(a.x>m&&a.xh&&a.ye&&cb(a.x,a.y,k,l,m,l)>e&&cb(a.x,a.y,m,h,k,h)>e&&cb(a.x,a.y,m,h,m,l)>e)return!1;b=Math.sqrt(e);if(c){if(null===this.fill?vd(g,a.x,a.y,b):g.Ia(a,b,!0))return!0}else{c=g.ub;for(b=0;be)return!1;l=k.Ha.p;m=l.length;for(h=0;he)return!1;break;case od:g=t.Cb(); +J.ze(n,p,q.vb,q.Lb,q.oe,q.pe,q.D,q.F,0.8,g);n=d(g,a);t.Da(g);if(n)return!1;n=q.D;p=q.F;if(a.Fs(n,p)>e)return!1;break;case pd:g=t.Cb();J.xp(n,p,q.vb,q.Lb,q.D,q.F,0.8,g);n=d(g,a);t.Da(g);if(n)return!1;n=q.D;p=q.F;if(a.Fs(n,p)>e)return!1;break;case qd:case rd:var q=q.type===qd?sd(q,k):td(q,k,n,p),r=q.length,s=null,g=t.Cb();for(b=0;b= 0",Y,"strokeWidth:val")});t.g(Y,"strokeCap",Y.prototype.HF); +t.defineProperty(Y,{HF:"strokeCap"},function(){return this.po},function(a){var b=this.po;b!==a&&("string"!==typeof a||"butt"!==a&&"round"!==a&&"square"!==a?t.ha(a,'"butt", "round", or "square"',Y,"strokeCap"):(this.po=a,this.pa(),this.i("strokeCap",b,a)))});t.g(Y,"strokeJoin",Y.prototype.eJ); +t.defineProperty(Y,{eJ:"strokeJoin"},function(){return this.qo},function(a){var b=this.qo;b!==a&&("string"!==typeof a||"miter"!==a&&"bevel"!==a&&"round"!==a?t.ha(a,'"miter", "bevel", or "round"',Y,"strokeJoin"):(this.qo=a,this.pa(),this.i("strokeJoin",b,a)))});t.g(Y,"strokeMiterLimit",Y.prototype.fJ); +t.defineProperty(Y,{fJ:"strokeMiterLimit"},function(){return this.rm},function(a){var b=this.rm;if(b!==a)if(f&&t.o(a,Y,"strokeMiterLimit"),0 0",Y,"strokeWidth:val")});t.g(Y,"strokeDashArray",Y.prototype.Rw); +t.defineProperty(Y,{Rw:"strokeDashArray"},function(){return this.qm},function(a){var b=this.qm;if(b!==a){null===a||Array.isArray(a)||t.Vb(a,"Array",Y,"strokeDashArray:val");if(null!==a)for(var c=a.length,d=0;de||!isFinite(e))&&t.m("strokeDashArray:val "+e+" is a negative number or not a real number.")}this.qm=a;this.pa();this.i("strokeDashArray",b,a)}});t.g(Y,"strokeDashOffset",Y.prototype.IF); +t.defineProperty(Y,{IF:"strokeDashOffset"},function(){return this.ad},function(a){var b=this.ad;b!==a&&(f&&t.o(a,Y,"strokeDashOffset"),0<=a&&(this.ad=a,this.pa(),this.i("strokeDashOffset",b,a)))});t.g(Y,"figure",Y.prototype.Ib); +t.defineProperty(Y,{Ib:"figure"},function(){return this.In},function(a){var b=this.In;if(b!==a){f&&t.j(a,"string",Y,"figure");var c=J.Qi[a];"function"===typeof c?c=a:(c=J.Qi[a.toLowerCase()])||t.m("Unknown Shape.figure: "+a);if(b!==c){if(a=this.S)a.yj=NaN;this.In=c;this.Rg=!1;this.Jf();this.i("figure",b,c)}}});t.g(Y,"toArrow",Y.prototype.gn); +t.defineProperty(Y,{gn:"toArrow"},function(){return this.so},function(a){var b=this.so;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"toArrow");var c=J.Oo(a);c instanceof M?c=a:(c=J.Oo(a.toLowerCase()))||t.m("Unknown Shape.toArrow: "+a);b!==c&&(this.so=c,this.Rg=!1,this.Jf(),Ll(this,c),this.i("toArrow",b,c))}});t.g(Y,"fromArrow",Y.prototype.jw); +t.defineProperty(Y,{jw:"fromArrow"},function(){return this.Kn},function(a){var b=this.Kn;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"fromArrow");var c=J.Oo(a);c instanceof M?c=a:(c=J.Oo(a.toLowerCase()))||t.m("Unknown Shape.fromArrow: "+a);b!==c&&(this.Kn=c,this.Rg=!1,this.Jf(),Ll(this,c),this.i("fromArrow",b,c))}}); +function Ll(a,b){var c=a.h;if(null===c||!c.Aa.qb){a.ut=Ml;c=cc;switch(b){case "halfarrowtop":c=$b;break;case "halftriangletop":c=$b;break;case "openrighttriangletop":c=$b;break;case "opentriangletop":c=$b}"None"!==a.so?(a.tf=-1,a.Qj=c):"None"!==a.Kn&&(a.tf=0,a.Qj=new K(1-c.x,c.y))}}t.defineProperty(Y,{G:"spot1"},function(){return this.xi},function(a){t.l(a,K,Y,"spot1");var b=this.xi;b.N(a)||(this.xi=a=a.Z(),this.aa(),this.i("spot1",b,a))}); +t.defineProperty(Y,{H:"spot2"},function(){return this.yi},function(a){t.l(a,K,Y,"spot2");var b=this.yi;b.N(a)||(this.yi=a=a.Z(),this.aa(),this.i("spot2",b,a))});t.defineProperty(Y,{yc:"parameter1"},function(){return this.wr},function(a){var b=this.wr;b!==a&&(this.wr=a,this.aa(),this.i("parameter1",b,a))});t.defineProperty(Y,{lt:"parameter2"},function(){return this.xr},function(a){var b=this.xr;b!==a&&(this.xr=a,this.aa(),this.i("parameter2",b,a))}); +t.A(Y,{Ga:"naturalBounds"},function(){if(null!==this.Ra)return this.Yc.assign(this.Ra.Mb),this.Yc;var a=this.Ca;return new D(0,0,a.width,a.height)});t.g(Y,"isRectangular",Y.prototype.pI);t.defineProperty(Y,{pI:"isRectangular"},function(){return this.Pq},function(a){var b=this.Pq;b!==a&&(f&&t.j(a,"boolean",Y,"isRectangular"),this.Pq=a,this.aa(),this.i("isRectangular",b,a))});t.g(Y,"pathObject",Y.prototype.EA); +t.defineProperty(Y,{EA:"pathObject"},function(){return this.zr},function(a){var b=this.zr;b!==a&&(f&&t.l(a,X,Y,"pathObject"),this.zr=a,this.pa(),this.i("pathObject",b,a))});t.g(Y,"geometryStretch",Y.prototype.kw);t.defineProperty(Y,{kw:"geometryStretch"},function(){return this.Fq},function(a){var b=this.Fq;b!==a&&(t.tb(a,X,Y,"geometryStretch"),this.Fq=a,this.i("geometryStretch",b,a))});t.g(Y,"interval",Y.prototype.interval); +t.defineProperty(Y,{interval:"interval"},function(){return this.Jq},function(a){var b=this.Jq;f&&t.o(a,Y,"interval");a=Math.floor(a);b!==a&&0<=a&&(this.Jq=a,this.h&&si(this.h),this.aa(),this.i("interval",b,a))});function wa(){X.call(this);this.ge="";this.xb="black";this.mh="13px sans-serif";this.Pd="start";this.Mq=!0;this.Ul=this.Vl=!1;this.fo=Nl;this.um=Ol;this.Hu=this.Yq=0;this.Jn=this.Ey=this.Fy=null;this.Zn={};this.yq=!1;this.ef=this.Lj=this.fs=null}t.ia("TextBlock",wa);t.Oa(wa,X); +wa.prototype.cloneProtected=function(a){X.prototype.cloneProtected.call(this,a);a.ge=this.ge;a.xb=this.xb;a.mh=this.mh;a.Pd=this.Pd;a.Mq=this.Mq;a.Vl=this.Vl;a.Ul=this.Ul;a.um=this.um;a.fo=this.fo;a.Yq=this.Yq;a.Hu=this.Hu;a.Fy=this.Fy;a.Ey=this.Ey;a.Jn=this.Jn;a.Zn=this.Zn;a.yq=this.yq;a.fs=this.fs;a.Lj=this.Lj;a.ef=this.ef};wa.prototype.toString=function(){return 22m*k*k&&(h=!0);m=e.Di.length;for(k=0;kc&&(n=c);var p=l,l=a,q=g,r=c,s=d,v=0;h?("start"===this.Pd||"left"===this.Pd?v=0:"end"===this.Pd||"right"===this.Pd? +v=r-n:"center"===this.Pd?v=(r-n)/2:t.m("textAlign must be start, end, left, right, or center"),l.fillRect(0+v,q+0.25*s,n,1)):("start"===this.Pd||"left"===this.Pd?v=0:"end"===this.Pd||"right"===this.Pd?v=r:"center"===this.Pd?v=r/2:t.m("textAlign must be start, end, left, right, or center"),l.fillText(p,0+v,q+s-0.25*s),p=s/20|0,this.Vl&&("end"===this.Pd||"right"===this.Pd?v-=n:"center"===this.Pd&&(v-=n/2),l.beginPath(),l.lineWidth=p,l.moveTo(0+v,q+s-0.2*s),l.lineTo(0+v+n,q+s-0.2*s),l.stroke()),this.Ul&& +(l.beginPath(),l.lineWidth=p,q=q+s-s/2.2|0,0!==p%2&&(q+=0.5),l.moveTo(0,q),l.lineTo(0+n,q),l.stroke()));g+=d}}}; +wa.prototype.$s=function(a,b,c,d){var e={},g=0,h=0;if(isNaN(this.Ca.width)){g=this.ge;if(0===g.length)g=0;else if(this.uw){for(var k=h=0,l=!1,m={Vh:0};!l;){var n=Ul(g,k,m);-1===n&&(n=g.length,l=!0);k=Vl(g.substr(k,n-k).replace(/^\s+|\s+$/g,""),this.mh);k>h&&(h=k);k=m.Vh}g=h}else h=Ul(g,0,{}),0<=h&&(g=g.substr(0,h)),g=k=Vl(g,this.mh);g=Math.min(g,a/this.scale);g=Math.max(8,g)}else g=this.Ca.width;this.ga&&(g=Math.min(g,this.ga.He.width),g=Math.max(g,this.ga.Ye.width));h=Tl(this,g,e);h=isNaN(this.Ca.height)? +Math.min(h,b/this.scale):this.Ca.height;if(this.qB===Ql||isNaN(this.Ca.width))g=e.Wi,isNaN(this.Ca.width)&&(g=Math.max(8,g));g=Math.max(c,g);h=Math.max(d,h);nb(this.Yc,g,h);Nj(this,0,0,g,h);this.Zn=e};wa.prototype.Uj=function(a,b,c,d){Uj(this,a,b,c,d)}; +function Sl(a,b,c,d){b=b.replace(/^\s+|\s+$/g,"");void 0===c.Wi&&(c.Wi=0);void 0===c.Di&&(c.Di=[]);void 0===c.ym&&(c.ym=[]);var e=0,g,h,k=a.mh;a.fo===Rl?(t.Hp!==k&&(t.Gp.font=k,t.Hp=k),g=0,void 0!==t.Yz[k]&&5E3>t.$D?g=t.Yz[k]:(g=t.Gp.measureText(t.VD).width,t.Yz[k]=g,t.$D++)):g=0;var l=g;if(a.um===Pl){c.Vh=1;g=Vl(b,k);if(0===l||g<=d)return c.Wi=g,c.Di.push(c.Wi),c.ym.push(b),new pa(g,Ch(a));var m=Wl(b);b=b.substr(m.length);h=Wl(b);for(g=Vl(m+h,k);0d&&1d;){var n=1;g=Vl(m.substr(0,n),k);for(h=0;g<=d;)n++,h=g,g=Vl(m.substr(0,n),k);1===n?(c.Di[l]=g,e=Math.max(e,g)):(c.Di[l]=h,e=Math.max(e,h));n--;1>n&&(n=1);c.ym[l]=m.substr(0,n);l++; +m=m.substr(n)}h=Wl(b);for(g=Vl(m+h,k);0=b?a:a.substr(0,c)} +function Vl(a,b){t.Hp!==b&&(t.Gp.font=b,t.Hp=b);return t.Gp.measureText(a).width}function Ch(a){if(null!==a.Jn)return a.Jn;var b=a.mh;t.Hp!==b&&(t.Gp.font=b,t.Hp=b);var c=0;void 0!==t.Zz[b]&&5E3>t.aE?c=t.Zz[b]:(c=1.3*t.Gp.measureText("M").width,t.Zz[b]=c,t.aE++);return a.Jn=c}function Ul(a,b,c){void 0===c.Vh&&(c.Vh=0);var d=a.indexOf("\r",b);-1===d&&(d=a.indexOf("\n",b));0<=d&&(c.Vh="\r"===a[d]&&d+1e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.2,0.22);b.H=new K(0.8,0.9);t.v(a);return b},DataTransmission:"Hexagon", +Hexagon:function(a,b,c){var d=J.el(6);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;6>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.07,0.25);b.H=new K(0.93,0.75);t.v(a);return b},Heptagon:function(a,b,c){var d=J.el(7);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;7>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.2,0.15);b.H=new K(0.8,0.85);t.v(a);return b},Octagon:function(a,b,c){var d=J.el(8);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;8>e;e++)a.lineTo(d[e].x* +b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.15,0.15);b.H=new K(0.85,0.85);t.v(a);return b},Nonagon:function(a,b,c){var d=J.el(9);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;9>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.17,0.13);b.H=new K(0.82,0.82);t.v(a);return b},Decagon:function(a,b,c){var d=J.el(10);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.16,0.16);b.H=new K(0.84,0.84);t.v(a);return b},Dodecagon:function(a, +b,c){var d=J.el(12);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.16,0.16);b.H=new K(0.84,0.84);t.v(a);return b},FivePointedStar:function(a,b,c){var d=J.Hm(5);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.312,0.383);b.H=new K(0.693,0.765);t.v(a);return b},SixPointedStar:function(a,b,c){var d=J.Hm(6);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x* +b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.17,0.251);b.H=new K(0.833,0.755);t.v(a);return b},SevenPointedStar:function(a,b,c){var d=J.Hm(7);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;14>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.363,0.361);b.H=new K(0.641,0.709);t.v(a);return b},EightPointedStar:function(a,b,c){var d=J.Hm(8);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;16>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.252,0.255);b.H=new K(0.75,0.75);t.v(a); +return b},NinePointedStar:function(a,b,c){var d=J.Hm(9);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;18>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.355,0.361);b.H=new K(0.645,0.651);t.v(a);return b},TenPointedStar:function(a,b,c){var d=J.Hm(10);a=t.u();O(a,d[0].x*b,d[0].y*c,!0);for(var e=1;20>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.Da(d);Q(a);b=a.s;b.G=new K(0.281,0.261);b.H=new K(0.723,0.748);t.v(a);return b},FivePointedBurst:function(a,b,c){var d=J.Ho(5);a=t.u();O(a,d[0].x*b,d[0].y* +c,!0);for(var e=1;e=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=d*J.va;var e=t.u();O(e,d,0,!0); +e.lineTo(b-d,0);P(e,b-a,0,b,a,b,d);e.lineTo(b,c-d);P(e,b,c-a,b-a,c,b-d,c);e.lineTo(d,c);P(e,a,c,0,c-a,0,c-d);e.lineTo(0,d);P(e,0,a,a,0,d,0);Q(e);b=e.s;1=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=t.u();O(a,d,0,!0);a.lineTo(b-d,0);P(a,b-0,0,b,0,b,d);a.lineTo(b,c-d);P(a,b,c-0,b-0,c,b-d,c);a.lineTo(d,c);P(a,0,c,0,c-0,0,c-d);a.lineTo(0,d);P(a,0,0,0,0,d,0);Q(a);b=a.s;b.G=Tb;b.H=$b; +t.v(a);return b},SquareIBeam:function(a,b,c){var d=a?a.yc:0;0===d&&(d=0.2);a=t.u();O(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,d*c);a.lineTo((0.5+d/2)*b,d*c);a.lineTo((0.5+d/2)*b,(1-d)*c);a.lineTo(1*b,(1-d)*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,(1-d)*c);a.lineTo((0.5-d/2)*b,(1-d)*c);a.lineTo((0.5-d/2)*b,d*c);a.lineTo(0,d*c);Q(a);b=a.s;t.v(a);return b},Trapezoid:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.2);var d=t.u();O(d,a*b,0,!0);d.lineTo((1-a)*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);b=d.s; +b.G=new K(a,0);b.H=new K(1-a,1);t.v(d);return b},ManualLoop:"ManualOperation",ManualOperation:function(a,b,c){var d=a?a.yc:0;a=t.u();O(a,d,0,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);Q(a);b=a.s;b.G=new K(0.1,0);b.H=new K(0.9,1);t.v(a);return b},GenderMale:function(a,b,c){a=t.u();var d=J.va,e=0.4*d,g=0.4,h=t.O(),k=t.O(),l=t.O(),m=t.O();O(a,(0.5-g)*b,0.5*c,!0);P(a,(0.5-g)*b,(0.5-e)*c,(0.5-e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5, +0.44,l,m,k,h,h);P(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);var n=t.ic(k.x,k.y);J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.56,h,h,k,l,m);var p=t.ic(k.x,k.y);a.lineTo((0.1*n.x+0.855)*b,0.1*n.y*c);a.lineTo(0.85*b,0.1*n.y*c);a.lineTo(0.85*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,(0.1*p.y+0.05*0.9)*c);a.lineTo(p.x*b,p.y*c);P(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);P(a,(0.5+g)*b,(0.5+e)*c,(0.5+e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5-e)* +b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);g=0.35;e=0.35*d;O(a,0.5*b,(0.5-g)*c,!0,!0);P(a,(0.5-e)*b,(0.5-g)*c,(0.5-g)*b,(0.5-e)*c,(0.5-g)*b,0.5*c);P(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);P(a,(0.5+g)*b,(0.5-e)*c,(0.5+e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);O(a,(0.5-g)*b,0.5*c,!0);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);t.B(p);b=a.s;b.G=new K(0.202,0.257);b.H=new K(0.692,0.839);b.kc=Zg;t.v(a);return b},GenderFemale:function(a, +b,c){a=t.u();var d=0.375,e=0,g=-0.125,h=4*(Math.SQRT2-1)/3*d;O(a,(0.525+e)*b,(0.5+d+g)*c,!0);P(a,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+d+e)*b,(0.5+g)*c);P(a,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);P(a,(0.5-h+e)*b,(0.5-d+g)*c,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-d+e)*b,(0.5+g)*c);P(a,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-h+e)*b,(0.5+d+g)*c,(0.475+e)*b,(0.5+d+g)*c);a.lineTo(0.475*b,0.85*c);a.lineTo(0.425*b,0.85*c);a.lineTo(0.425*b,0.9*c);a.lineTo(0.475*b,0.9*c);a.lineTo(0.475* +b,1*c);a.lineTo(0.525*b,1*c);a.lineTo(0.525*b,0.9*c);a.lineTo(0.575*b,0.9*c);a.lineTo(0.575*b,0.85*c);a.lineTo(0.525*b,0.85*c);Q(a);d=0.325;e=0;g=-0.125;h=4*(Math.SQRT2-1)/3*d;O(a,(0.5+d+e)*b,(0.5+g)*c,!0,!0);P(a,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+e)*b,(0.5+d+g)*c);P(a,(0.5-h+e)*b,(0.5+d+g)*c,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-d+e)*b,(0.5+g)*c);P(a,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);P(a,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+d+e)*b,(0.5+ +g)*c);O(a,(0.525+e)*b,(0.5+d+g)*c,!0);b=a.s;b.G=new K(0.232,0.136);b.H=new K(0.782,0.611);b.kc=Zg;t.v(a);return b},PlusLine:function(a,b,c){a=t.u();O(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},XLine:function(a,b,c){a=t.u();O(a,0,1*c,!1);a.lineTo(1*b,0);a.moveTo(0,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},AsteriskLine:function(a,b,c){a=t.u();var d=0.2/Math.SQRT2;O(a,d*b,(1-d)*c,!1);a.lineTo((1-d)*b,d*c);a.moveTo(d*b,d*c);a.lineTo((1-d)*b,(1-d)* +c);a.moveTo(0*b,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0*c);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},CircleLine:function(a,b,c){var d=0.5*J.va;a=t.u();O(a,1*b,0.5*c,!1);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new K(0.146,0.146);b.H=new K(0.853,0.853);b.kc=Zg;t.v(a);return b},Pie:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;O(a,(0.5*Math.SQRT2/2+0.5)*b,(0.5- +0.5*Math.SQRT2/2)*c,!0);P(a,0.7*b,0*c,0.5*b,0*c,0.5*b,0*c);P(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);P(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.5*b,1*c);P(a,(0.5+d+0)*b,1*c,1*b,(0.5+d+0)*c,1*b,0.5*c);a.lineTo(0.5*b,0.5*c);Q(a);b=a.s;t.v(a);return b},PiePiece:function(a,b,c){var d=J.va/Math.SQRT2*0.5,e=Math.SQRT2/2,g=1-Math.SQRT2/2;a=t.u();O(a,b,c,!0);P(a,b,(1-d)*c,(e+d)*b,(g+d)*c,e*b,g*c);a.lineTo(0,c);Q(a);b=a.s;t.v(a);return b},StopSign:function(a,b,c){a=1/(Math.SQRT2+2);var d=t.u();O(d,a*b,0,!0); +d.lineTo((1-a)*b,0);d.lineTo(1*b,a*c);d.lineTo(1*b,(1-a)*c);d.lineTo((1-a)*b,1*c);d.lineTo(a*b,1*c);d.lineTo(0,(1-a)*c);d.lineTo(0,a*c);Q(d);b=d.s;b.G=new K(a/2,a/2);b.H=new K(1-a/2,1-a/2);t.v(d);return b},LogicImplies:function(a,b,c){var d=a?a.yc:0;0===d&&(d=0.2);a=t.u();O(a,(1-d)*b,0*c,!1);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);b=a.s;b.G=Tb;b.H=new K(0.8,0.5);t.v(a);return b},LogicIff:function(a,b,c){var d=a?a.yc:0;0===d&&(d=0.2);a=t.u();O(a,(1-d)*b,0*c,!1); +a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(d*b,0);a.lineTo(0,0.5*c);a.lineTo(d*b,c);b=a.s;b.G=new K(0.2,0);b.H=new K(0.8,0.5);t.v(a);return b},LogicNot:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},LogicAnd:function(a,b,c){a=t.u();O(a,0,1*c,!1);a.lineTo(0.5*b,0);a.lineTo(1*b,1*c);b=a.s;b.G=new K(0.25,0.5);b.H=new K(0.75,1);t.v(a);return b},LogicOr:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1* +b,0);b=a.s;b.G=new K(0.219,0);b.H=new K(0.78,0.409);t.v(a);return b},LogicXor:function(a,b,c){a=t.u();O(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);var d=0.5*J.va;P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.kc=Zg;t.v(a);return b},LogicTruth:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b}, +LogicFalsity:function(a,b,c){a=t.u();O(a,0,1*c,!1);a.lineTo(1*b,1*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);b=a.s;t.v(a);return b},LogicThereExists:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);b=a.s;t.v(a);return b},LogicForAll:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1*b,0);a.moveTo(0.25*b,0.5*c);a.lineTo(0.75*b,0.5*c);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,0.5);t.v(a);return b}, +LogicIsDefinedAs:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(b,0);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(0,c);a.lineTo(b,c);b=a.s;b.G=new K(0.01,0.01);b.H=new K(0.99,0.49);t.v(a);return b},LogicIntersect:function(a,b,c){var d=0.5*J.va;a=t.u();O(a,0,1*c,!1);a.lineTo(0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new K(0,0.5);b.H=$b;t.v(a);return b},LogicUnion:function(a,b,c){var d=0.5*J.va;a=t.u();O(a,1*b,0,!1);a.lineTo(1*b, +0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);a.lineTo(0,0);b=a.s;b.G=Tb;b.H=new K(1,0.5);t.v(a);return b},Arrow:function(a,b,c){var d=a?a.yc:0,e=a?a.lt:0;0===d&&(d=0.3);0===e&&(e=0.3);a=t.u();O(a,0,(0.5-e/2)*c,!0);a.lineTo((1-d)*b,(0.5-e/2)*c);a.lineTo((1-d)*b,0);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,1*c);a.lineTo((1-d)*b,(0.5+e/2)*c);a.lineTo(0,(0.5+e/2)*c);Q(a);b=a.s;b.G=new K(0,0.5-e/2);d=J.kl(0,0.5+e/2,1,0.5+e/2,1-d,1,1,0.5,t.O());b.H=new K(d.x,d.y); +t.B(d);t.v(a);return b},ISOProcess:"Chevron",Chevron:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.5*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);Q(a);b=a.s;t.v(a);return b},DoubleArrow:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.3*b,0.214*c);a.lineTo(0.3*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.3*b,1*c);a.lineTo(0.3*b,0.786*c);a.lineTo(0,1*c);Q(a);O(a,0.3*b,0.214*c,!1);a.lineTo(0.3*b,0.786*c);a.ab(!1);b=a.s;t.v(a);return b},DoubleEndArrow:function(a,b,c){a=t.u(); +O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.3*b,0.7*c);a.lineTo(0.3*b,1*c);a.lineTo(0,0.5*c);a.lineTo(0.3*b,0);a.lineTo(0.3*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);Q(a);b=a.s;c=J.kl(0,0.5,0.3,0,0,0.3,0.3,0.3,t.O());b.G=new K(c.x,c.y);c=J.kl(0.7,1,1,0.5,0.7,0.7,1,0.7,c);b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},IBeamArrow:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.2*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0,1*c); +a.lineTo(0,0);a.lineTo(0.2*b,0);a.lineTo(0.2*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);Q(a);b=a.s;b.G=new K(0,0.3);c=J.kl(0.7,1,1,0.5,0.7,0.7,1,0.7,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},Pointer:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0);Q(a);b=a.s;b.G=new K(0.2,0.35);c=J.kl(0.2,0.65,1,0.65,0,1,1,0.5,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},RoundedPointer:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0,1*c);P(a,0.5* +b,0.75*c,0.5*b,0.25*c,0,0);Q(a);b=a.s;b.G=new K(0.4,0.35);c=J.kl(0.2,0.65,1,0.65,0,1,1,0.5,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},SplitEndArrow:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0,0.7*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);Q(a);b=a.s;b.G=new K(0.2,0.3);c=J.kl(0.7,1,1,0.5,0.7,0.7,1,0.7,t.O());b.H=new K(c.x,c.y);t.B(c);t.v(a);return b},MessageToUser:"SquareArrow",SquareArrow:function(a, +b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.7*b,0);Q(a);b=a.s;b.G=Tb;b.H=new K(0.7,1);t.v(a);return b},Cone1:function(a,b,c){var d=J.va;a=0.5*d;var e=0.1*d,d=t.u();O(d,0,0.9*c,!0);d.lineTo(0.5*b,0);d.lineTo(1*b,0.9*c);P(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);P(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);Q(d);b=d.s;b.G=new K(0.25,0.5);b.H=new K(0.75,0.97);t.v(d);return b},Cone2:function(a,b,c){a=t.u();O(a,0,0.9*c,!0);P(a,(1-0.85/0.9)*b,1*c,0.85/0.9*b,1*c, +1*b,0.9*c);a.lineTo(0.5*b,0);a.lineTo(0,0.9*c);Q(a);O(a,0,0.9*c,!1);P(a,(1-0.85/0.9)*b,0.8*c,0.85/0.9*b,0.8*c,1*b,0.9*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.5);b.H=new K(0.75,0.82);t.v(a);return b},Cube1:function(a,b,c){a=t.u();O(a,0.5*b,1*c,!0);a.lineTo(1*b,0.85*c);a.lineTo(1*b,0.15*c);a.lineTo(0.5*b,0*c);a.lineTo(0*b,0.15*c);a.lineTo(0*b,0.85*c);Q(a);O(a,0.5*b,1*c,!1);a.lineTo(0.5*b,0.3*c);a.lineTo(0,0.15*c);a.moveTo(0.5*b,0.3*c);a.lineTo(1*b,0.15*c);a.ab(!1);b=a.s;b.G=new K(0,0.3);b.H=new K(0.5,0.85); +t.v(a);return b},Cube2:function(a,b,c){a=t.u();O(a,0,0.3*c,!0);a.lineTo(0*b,1*c);a.lineTo(0.7*b,c);a.lineTo(1*b,0.7*c);a.lineTo(1*b,0*c);a.lineTo(0.3*b,0*c);Q(a);O(a,0,0.3*c,!1);a.lineTo(0.7*b,0.3*c);a.lineTo(1*b,0*c);a.moveTo(0.7*b,0.3*c);a.lineTo(0.7*b,1*c);a.ab(!1);b=a.s;b.G=new K(0,0.3);b.H=new K(0.7,1);t.v(a);return b},MagneticData:"Cylinder1",Cylinder1:function(a,b,c){var d=J.va;a=0.5*d;var e=0.1*d,d=t.u();O(d,0,0.1*c,!0);P(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);P(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1* +b,0.1*c);d.lineTo(b,0.9*c);P(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);P(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);d.lineTo(0,0.1*c);O(d,0,0.1*c,!1);P(d,0,(0.1+e)*c,(0.5-a)*b,0.2*c,0.5*b,0.2*c);P(d,(0.5+a)*b,0.2*c,1*b,(0.1+e)*c,1*b,0.1*c);d.ab(!1);b=d.s;b.G=new K(0,0.2);b.H=new K(1,0.9);t.v(d);return b},Cylinder2:function(a,b,c){var d=J.va;a=0.5*d;var e=0.1*d,d=t.u();O(d,0,0.9*c,!0);d.lineTo(0,0.1*c);P(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);P(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1*b,0.1*c);d.lineTo(1*b,0.9*c);P(d,1* +b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);P(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);O(d,0,0.9*c,!1);P(d,0,(0.9-e)*c,(0.5-a)*b,0.8*c,0.5*b,0.8*c);P(d,(0.5+a)*b,0.8*c,1*b,(0.9-e)*c,1*b,0.9*c);d.ab(!1);b=d.s;b.G=new K(0,0.1);b.H=new K(1,0.8);t.v(d);return b},Cylinder3:function(a,b,c){var d=J.va;a=0.1*d;var e=0.5*d,d=t.u();O(d,0.1*b,0,!0);d.lineTo(0.9*b,0);P(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);P(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);P(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);P(d,0,(0.5- +e)*c,(0.1-a)*b,0,0.1*b,0);O(d,0.1*b,0,!1);P(d,(0.1+a)*b,0,0.2*b,(0.5-e)*c,0.2*b,0.5*c);P(d,0.2*b,(0.5+e)*c,(0.1+a)*b,1*c,0.1*b,1*c);d.ab(!1);b=d.s;b.G=new K(0.2,0);b.H=new K(0.9,1);t.v(d);return b},DirectData:"Cylinder4",Cylinder4:function(a,b,c){var d=J.va;a=0.1*d;var e=0.5*d,d=t.u();O(d,0.9*b,0,!0);P(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);P(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);P(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);P(d,0,(0.5-e)*c,(0.1-a)*b,0,0.1*b,0);d.lineTo(0.9*b,0);O(d, +0.9*b,0,!1);P(d,(0.9-a)*b,0,0.8*b,(0.5-e)*c,0.8*b,0.5*c);P(d,0.8*b,(0.5+e)*c,(0.9-a)*b,1*c,0.9*b,1*c);d.ab(!1);b=d.s;b.G=new K(0.1,0);b.H=new K(0.8,1);t.v(d);return b},Prism1:function(a,b,c){a=t.u();O(a,0.25*b,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(b,0.5*c);a.lineTo(0.5*b,c);a.lineTo(0,c);Q(a);O(a,0.25*b,0.25*c,!1);a.lineTo(0.5*b,c);a.ab(!1);b=a.s;b.G=new K(0.408,0.172);b.H=new K(0.833,0.662);t.v(a);return b},Prism2:function(a,b,c){a=t.u();O(a,0,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c); +a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);Q(a);O(a,0,c,!1);a.lineTo(0.25*b,0.5*c);a.lineTo(b,0.25*c);a.moveTo(0,0.25*c);a.lineTo(0.25*b,0.5*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.5);b.H=new K(0.75,0.75);t.v(a);return b},Pyramid1:function(a,b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(b,0.75*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.75*c);Q(a);O(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.367);b.H=new K(0.75,0.875);t.v(a);return b},Pyramid2:function(a,b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(b,0.85* +c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.85*c);Q(a);O(a,0.5*b,0,!1);a.lineTo(0.5*b,0.7*c);a.lineTo(0,0.85*c);a.moveTo(0.5*b,0.7*c);a.lineTo(1*b,0.85*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.367);b.H=new K(0.75,0.875);t.v(a);return b},Actor:function(a,b,c){var d=J.va,e=0.2*d,g=0.1*d,h=0.5,k=0.1;a=t.u();O(a,h*b,(k+0.1)*c,!0);P(a,(h-e)*b,(k+0.1)*c,(h-0.2)*b,(k+g)*c,(h-0.2)*b,k*c);P(a,(h-0.2)*b,(k-g)*c,(h-e)*b,(k-0.1)*c,h*b,(k-0.1)*c);P(a,(h+e)*b,(k-0.1)*c,(h+0.2)*b,(k-g)*c,(h+0.2)*b,k*c);P(a,(h+0.2)*b,(k+g)*c, +(h+e)*b,(k+0.1)*c,h*b,(k+0.1)*c);e=0.05;g=d*e;O(a,0.5*b,0.2*c,!0);a.lineTo(0.95*b,0.2*c);h=0.95;k=0.25;P(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);a.lineTo(1*b,0.6*c);a.lineTo(0.85*b,0.6*c);a.lineTo(0.85*b,0.35*c);e=0.025;g=d*e;h=0.825;k=0.35;P(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.8*b,1*c);a.lineTo(0.55*b,1*c);a.lineTo(0.55*b,0.7*c);e=0.05;g=d*e;h=0.5;k=0.7;P(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h-g)*b,(k-e)* +c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.45*b,1*c);a.lineTo(0.2*b,1*c);a.lineTo(0.2*b,0.35*c);e=0.025;g=d*e;h=0.175;k=0.35;P(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.15*b,0.6*c);a.lineTo(0*b,0.6*c);a.lineTo(0*b,0.25*c);e=0.05;g=d*e;h=0.05;k=0.25;P(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);a.lineTo(0.5*b,0.2*c);b=a.s;b.G=new K(0.2,0.2);b.H=new K(0.8,0.65);t.v(a);return b},Card:function(a,b,c){a=t.u();O(a,1*b,0*c,!0);a.lineTo(1* +b,1*c);a.lineTo(0*b,1*c);a.lineTo(0*b,0.2*c);a.lineTo(0.2*b,0*c);Q(a);b=a.s;b.G=new K(0,0.2);b.H=$b;t.v(a);return b},Collate:function(a,b,c){a=t.u();O(a,0.5*b,0.5*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);O(a,0.5*b,0.5*c,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,0.25);t.v(a);return b},CreateRequest:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,0,a* +c,!1);d.lineTo(1*b,a*c);d.moveTo(0,(1-a)*c);d.lineTo(1*b,(1-a)*c);d.ab(!1);b=d.s;b.G=new K(0,a);b.H=new K(1,1-a);t.v(d);return b},Database:function(a,b,c){a=t.u();var d=J.va,e=0.5*d,d=0.1*d;O(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);P(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);P(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);P(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);P(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);O(a,1*b,0.1*c,!1);P(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);P(a,(0.5-e)*b,0.2*c,0,(0.1+d)* +c,0,0.1*c);a.moveTo(1*b,0.2*c);P(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);P(a,(0.5-e)*b,0.3*c,0,(0.2+d)*c,0,0.2*c);a.moveTo(1*b,0.3*c);P(a,1*b,(0.3+d)*c,(0.5+e)*b,0.4*c,0.5*b,0.4*c);P(a,(0.5-e)*b,0.4*c,0,(0.3+d)*c,0,0.3*c);a.ab(!1);b=a.s;b.G=new K(0,0.4);b.H=new K(1,0.9);t.v(a);return b},StoredData:"DataStorage",DataStorage:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0);P(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0,1*c);P(a,0.25*b,0.9*c,0.25*b,0.1*c,0,0);Q(a);b=a.s;b.G=new K(0.226,0);b.H=new K(0.81, +1);t.v(a);return b},DiskStorage:function(a,b,c){a=t.u();var d=J.va,e=0.5*d,d=0.1*d;O(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);P(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);P(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);P(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);P(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);O(a,1*b,0.1*c,!1);P(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);P(a,(0.5-e)*b,0.2*c,0,(0.1+d)*c,0,0.1*c);a.moveTo(1*b,0.2*c);P(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);P(a,(0.5-e)*b,0.3*c,0,(0.2+d)* +c,0,0.2*c);a.ab(!1);b=a.s;b.G=new K(0,0.3);b.H=new K(1,0.9);t.v(a);return b},Display:function(a,b,c){a=t.u();O(a,0.25*b,0,!0);a.lineTo(0.75*b,0);P(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0.25*b,1*c);a.lineTo(0,0.5*c);Q(a);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,1);t.v(a);return b},DividedEvent:function(a,b,c){a=a?a.yc:0;0===a?a=0.2:0.15>a&&(a=0.15);var d=t.u(),e=0.2*J.va;O(d,0,0.2*c,!0);P(d,0,(0.2-e)*c,(0.2-e)*b,0,0.2*b,0);d.lineTo(0.8*b,0);P(d,(0.8+e)*b,0,1*b,(0.2-e)*c,1*b,0.2*c);d.lineTo(1*b,0.8*c); +P(d,1*b,(0.8+e)*c,(0.8+e)*b,1*c,0.8*b,1*c);d.lineTo(0.2*b,1*c);P(d,(0.2-e)*b,1*c,0,(0.8+e)*c,0,0.8*c);d.lineTo(0,0.2*c);O(d,0,a*c,!1);d.lineTo(1*b,a*c);d.ab(!1);b=d.s;b.G=new K(0,a);b.H=new K(1,1-a);t.v(d);return b},DividedProcess:function(a,b,c){a=a?a.yc:0;0.1>a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,0,a*c,!1);d.lineTo(1*b,a*c);d.ab(!1);b=d.s;b.G=new K(0,a);b.H=$b;t.v(d);return b},Document:function(a,b,c){c/=0.8;a=t.u();O(a,0,0.7*c,!0);a.lineTo(0, +0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);P(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);Q(a);b=a.s;b.G=Tb;b.H=new K(1,0.6);t.v(a);return b},ExternalOrganization:function(a,b,c){a=a?a.yc:0;0.2>a&&(a=0.2);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,a*b,0,!1);d.lineTo(0,a*c);d.moveTo(1*b,a*c);d.lineTo((1-a)*b,0);d.moveTo(0,(1-a)*c);d.lineTo(a*b,1*c);d.moveTo((1-a)*b,1*c);d.lineTo(1*b,(1-a)*c);d.ab(!1);b=d.s;b.G=new K(a/2,a/2);b.H=new K(1-a/2,1-a/2);t.v(d);return b},ExternalProcess:function(a, +b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);Q(a);O(a,0.1*b,0.4*c,!1);a.lineTo(0.1*b,0.6*c);a.moveTo(0.9*b,0.6*c);a.lineTo(0.9*b,0.4*c);a.moveTo(0.6*b,0.1*c);a.lineTo(0.4*b,0.1*c);a.moveTo(0.4*b,0.9*c);a.lineTo(0.6*b,0.9*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.25);b.H=new K(0.75,0.75);t.v(a);return b},File:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);Q(a);O(a,0.75*b,0,!1);a.lineTo(0.75*b,0.25*c); +a.lineTo(1*b,0.25*c);a.ab(!1);b=a.s;b.G=new K(0,0.25);b.H=$b;t.v(a);return b},Interrupt:function(a,b,c){a=t.u();O(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);O(a,1*b,0.5*c,!1);a.lineTo(1*b,1*c);O(a,1*b,0.5*c,!1);a.lineTo(1*b,0);b=a.s;b.G=new K(0,0.25);b.H=new K(0.5,0.75);t.v(a);return b},InternalStorage:function(a,b,c){var d=a?a.yc:0;a=a?a.lt:0;0===d&&(d=0.1);0===a&&(a=0.1);var e=t.u();O(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(1*b,1*c);e.lineTo(0,1*c);Q(e);O(e,d*b,0,!1);e.lineTo(d* +b,1*c);e.moveTo(0,a*c);e.lineTo(1*b,a*c);e.ab(!1);b=e.s;b.G=new K(d,a);b.H=$b;t.v(e);return b},Junction:function(a,b,c){a=t.u();var d=1/Math.SQRT2,e=(1-1/Math.SQRT2)/2,g=0.5*J.va;O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+g)*c,(0.5+g)*b,1*c,0.5*b,1*c);P(a,(0.5-g)*b,1*c,0,(0.5+g)*c,0,0.5*c);P(a,0,(0.5-g)*c,(0.5-g)*b,0,0.5*b,0);P(a,(0.5+g)*b,0,1*b,(0.5-g)*c,1*b,0.5*c);O(a,(e+d)*b,(e+d)*c,!1);a.lineTo(e*b,e*c);a.moveTo(e*b,(e+d)*c);a.lineTo((e+d)*b,e*c);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b},LinedDocument:function(a, +b,c){c/=0.8;a=t.u();O(a,0,0.7*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);P(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);Q(a);O(a,0.1*b,0,!1);a.lineTo(0.1*b,0.75*c);a.ab(!1);b=a.s;b.G=new K(0.1,0);b.H=new K(1,0.6);t.v(a);return b},LoopLimit:function(a,b,c){a=t.u();O(a,0,1*c,!0);a.lineTo(0,0.25*c);a.lineTo(0.25*b,0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=$b;t.v(a);return b},SequentialData:"MagneticTape",MagneticTape:function(a,b,c){a=t.u();var d= +0.5*J.va;O(a,0.5*b,1*c,!0);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,0.9*c,0.6*b,0.9*c);a.lineTo(1*b,0.9*c);a.lineTo(1*b,1*c);a.lineTo(0.5*b,1*c);b=a.s;b.G=new K(0.15,0.15);b.H=new K(0.85,0.8);t.v(a);return b},ManualInput:function(a,b,c){a=t.u();O(a,1*b,0,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.25*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=$b;t.v(a);return b},MessageFromUser:function(a,b,c){a= +a?a.yc:0;0===a&&(a=0.7);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(a*b,0.5*c);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);b=d.s;b.G=Tb;b.H=new K(a,1);t.v(d);return b},MicroformProcessing:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.25);var d=t.u();O(d,0,0,!0);d.lineTo(0.5*b,a*c);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.5*b,(1-a)*c);d.lineTo(0,1*c);Q(d);b=d.s;b.G=new K(0,a);b.H=new K(1,1-a);t.v(d);return b},MicroformRecording:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0.25*c);a.lineTo(1*b, +0.15*c);a.lineTo(1*b,0.85*c);a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=new K(1,0.75);t.v(a);return b},MultiDocument:function(a,b,c){c/=0.8;a=t.u();O(a,b,0,!0);a.lineTo(b,0.5*c);P(a,0.96*b,0.47*c,0.93*b,0.45*c,0.9*b,0.44*c);a.lineTo(0.9*b,0.6*c);P(a,0.86*b,0.57*c,0.83*b,0.55*c,0.8*b,0.54*c);a.lineTo(0.8*b,0.7*c);P(a,0.4*b,0.4*c,0.4*b,1*c,0,0.7*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);a.lineTo(0.1*b,0.1*c);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);Q(a);O(a,0.1*b,0.2*c, +!1);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.54*c);a.moveTo(0.2*b,0.1*c);a.lineTo(0.9*b,0.1*c);a.lineTo(0.9*b,0.44*c);a.ab(!1);b=a.s;b.G=new K(0,0.25);b.H=new K(0.8,0.77);t.v(a);return b},MultiProcess:function(a,b,c){a=t.u();O(a,0.1*b,0.1*c,!0);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.8*c);a.lineTo(0.9*b,0.8*c);a.lineTo(0.9*b,0.9*c);a.lineTo(0.8*b,0.9*c);a.lineTo(0.8*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);Q(a);O(a,0.2*b,0.1*c,!1);a.lineTo(0.9*b, +0.1*c);a.lineTo(0.9*b,0.8*c);a.moveTo(0.1*b,0.2*c);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.9*c);a.ab(!1);b=a.s;b.G=new K(0,0.2);b.H=new K(0.8,1);t.v(a);return b},OfflineStorage:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=1-a,e=t.u();O(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(0.5*b,1*c);Q(e);O(e,0.5*a*b,a*c,!1);e.lineTo((1-0.5*a)*b,a*c);e.ab(!1);b=e.s;b.G=new K(d/4+0.5*a,a);b.H=new K(3*d/4+0.5*a,a+0.5*d);t.v(e);return b},OffPageConnector:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1* +b,0.5*c);a.lineTo(0.75*b,1*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=Tb;b.H=new K(0.75,1);t.v(a);return b},Or:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);O(a,1*b,0.5*c,!1);a.lineTo(0,0.5*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b},PaperTape:function(a,b,c){c/=0.8;a=t.u();O(a,0,0.7*c,!0);a.lineTo(0, +0.3*c);P(a,0.5*b,0.6*c,0.5*b,0,1*b,0.3);a.lineTo(1*b,0.7*c);P(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);Q(a);b=a.s;b.G=new K(0,0.49);b.H=new K(1,0.75);t.v(a);return b},PrimitiveFromCall:function(a,b,c){var d=a?a.yc:0;a=a?a.lt:0;0===d&&(d=0.1);0===a&&(a=0.3);var e=t.u();O(e,0,0,!0);e.lineTo(1*b,0);e.lineTo((1-a)*b,0.5*c);e.lineTo(1*b,1*c);e.lineTo(0,1*c);Q(e);b=e.s;b.G=new K(d,0);b.H=new K(1-a,1);t.v(e);return b},PrimitiveToCall:function(a,b,c){var d=a?a.yc:0;a=a?a.lt:0;0===d&&(d=0.1);0===a&&(a=0.3);var e= +t.u();O(e,0,0,!0);e.lineTo((1-a)*b,0);e.lineTo(1*b,0.5*c);e.lineTo((1-a)*b,1*c);e.lineTo(0,1*c);Q(e);b=e.s;b.G=new K(d,0);b.H=new K(1-a,1);t.v(e);return b},Subroutine:"Procedure",Procedure:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,(1-a)*b,0,!1);d.lineTo((1-a)*b,1*c);d.moveTo(a*b,0);d.lineTo(a*b,1*c);d.ab(!1);b=d.s;b.G=new K(a,0);b.H=new K(1-a,1);t.v(d);return b},Process:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d= +t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);Q(d);O(d,a*b,0,!1);d.lineTo(a*b,1*c);d.ab(!1);b=d.s;b.G=new K(a,0);b.H=$b;t.v(d);return b},Sort:function(a,b,c){a=t.u();O(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);Q(a);O(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.ab(!1);b=a.s;b.G=new K(0.25,0.25);b.H=new K(0.75,0.5);t.v(a);return b},Start:function(a,b,c){a=t.u();O(a,0.25*b,0,!0);O(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25* +b,0.5*c,0.25*b,0.5*c);O(a,0.25*b,0,!1);a.lineTo(0.25*b,1*c);a.moveTo(0.75*b,0);a.lineTo(0.75*b,1*c);a.ab(!1);b=a.s;b.G=new K(0.25,0);b.H=new K(0.75,1);t.v(a);return b},Terminator:function(a,b,c){a=t.u();O(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25*b,0.5*c,0.25*b,0.5*c);b=a.s;b.G=new K(0.23,0);b.H=new K(0.77,1);t.v(a);return b},TransmittalTape:function(a,b,c){a=a?a.yc:0;0===a&&(a=0.1);var d=t.u();O(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.75*b,(1-a)* +c);d.lineTo(0,(1-a)*c);Q(d);b=d.s;b.G=Tb;b.H=new K(1,1-a);t.v(d);return b},AndGate:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0,0,!0);a.lineTo(0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=Tb;b.H=new K(0.55,1);t.v(a);return b},Buffer:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);Q(a);b=a.s;b.G=new K(0,0.25);b.H=new K(0.5,0.75);t.v(a);return b},Clock:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,1* +b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);O(a,1*b,0.5*c,!1);a.lineTo(1*b,0.5*c);O(a,0.8*b,0.75*c,!1);a.lineTo(0.8*b,0.25*c);a.lineTo(0.6*b,0.25*c);a.lineTo(0.6*b,0.75*c);a.lineTo(0.4*b,0.75*c);a.lineTo(0.4*b,0.25*c);a.lineTo(0.2*b,0.25*c);a.lineTo(0.2*b,0.75*c);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b},Ground:function(a,b,c){a=t.u();O(a,0.5*b,0,!1);a.lineTo(0.5*b,0.4*c); +a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.3*b,0.8*c);a.lineTo(0.7*b,0.8*c);a.moveTo(0.4*b,1*c);a.lineTo(0.6*b,1*c);b=a.s;t.v(a);return b},Inverter:function(a,b,c){a=t.u();var d=0.1*J.va;O(a,0.8*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.8*b,0.5*c);O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);P(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);P(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);P(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new K(0,0.25); +b.H=new K(0.4,0.75);t.v(a);return b},NandGate:function(a,b,c){a=t.u();var d=J.va,e=0.5*d,g=0.4*d,d=0.1*d;O(a,0.8*b,0.5*c,!0);P(a,0.8*b,(0.5+g)*c,(0.4+e)*b,1*c,0.4*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.4*b,0);P(a,(0.4+e)*b,0,0.8*b,(0.5-g)*c,0.8*b,0.5*c);O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);P(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);P(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);P(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new K(0,0.05);b.H=new K(0.55, +0.95);t.v(a);return b},NorGate:function(a,b,c){a=t.u();var d=J.va,e=0.5,g=d*e,h=0,k=0.5;O(a,0.8*b,0.5*c,!0);P(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0,1*c);P(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);P(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;O(a,(h-e)*b,k*c,!0);P(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);P(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);P(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new K(0.2,0.25); +b.H=new K(0.6,0.75);t.v(a);return b},OrGate:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0,0,!0);P(a,(0+d+d)*b,0*c,0.8*b,(0.5-d)*c,1*b,0.5*c);P(a,0.8*b,(0.5+d)*c,(0+d+d)*b,1*c,0,1*c);P(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);Q(a);b=a.s;b.G=new K(0.2,0.25);b.H=new K(0.75,0.75);t.v(a);return b},XnorGate:function(a,b,c){a=t.u();var d=J.va,e=0.5,g=d*e,h=0.2,k=0.5;O(a,0.1*b,0,!1);P(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);O(a,0.8*b,0.5*c,!0);P(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0.2*b,1*c);P(a,0.45*b,0.75*c,0.45* +b,0.25*c,0.2*b,0);P(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;O(a,(h-e)*b,k*c,!0);P(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);P(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);P(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);P(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new K(0.4,0.25);b.H=new K(0.65,0.75);t.v(a);return b},XorGate:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0.1*b,0,!1);P(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);O(a,0.2*b,0,!0);P(a,(0.2+ +d)*b,0*c,0.9*b,(0.5-d)*c,1*b,0.5*c);P(a,0.9*b,(0.5+d)*c,(0.2+d)*b,1*c,0.2*b,1*c);P(a,0.45*b,0.75*c,0.45*b,0.25*c,0.2*b,0);Q(a);b=a.s;b.G=new K(0.4,0.25);b.H=new K(0.8,0.75);t.v(a);return b},Capacitor:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Resistor:function(a,b,c){a=t.u();O(a,0,0.5*c,!1);a.lineTo(0.1*b,0);a.lineTo(0.2*b,1*c);a.lineTo(0.3*b,0);a.lineTo(0.4*b,1*c);a.lineTo(0.5*b,0);a.lineTo(0.6*b,1*c);a.lineTo(0.7*b,0.5*c);b=a.s;t.v(a); +return b},Inductor:function(a,b,c){a=t.u();var d=0.1*J.va,e=0.1,g=0.5;O(a,(e-0.5*d)*b,(g+0.1)*c,!1);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.3;g=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);g=e=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.7;g=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);P(a,(e-d)*b,(g+0.1)*c,(e-0.1)* +b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.9;g=0.5;P(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,(e+0.5*d)*b,(g+0.1)*c);b=a.s;t.v(a);return b},ACvoltageSource:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0*b,0.5*c,!1);P(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);P(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);a.moveTo(0.1*b,0.5*c);P(a,0.5*b,0*c,0.5*b,1*c,0.9*b,0.5*c);b=a.s;b.kc=Zg;t.v(a);return b},DCvoltageSource:function(a,b,c){a=t.u(); +O(a,0,0.75*c,!1);a.lineTo(0,0.25*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Diode:function(a,b,c){a=t.u();O(a,1*b,0,!1);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new K(0,0.25);b.H=new K(0.5,0.75);t.v(a);return b},Wifi:function(a,b,c){var d=b,e=c;b*=0.38;c*=0.6;a=t.u();var g=J.va,h=0.8*g,k=0.8,l=0,m=0.5,d=(d-b)/2,e=(e-c)/2;O(a,l*b+d,(m+k)*c+e,!0);P(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);P(a,(l-k)*b+d,(m-h)* +c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);P(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);P(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);Q(a);h=0.4*g;k=0.4;l=0.2;m=0.5;O(a,l*b+d,(m+k)*c+e,!0);P(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);P(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);P(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);P(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);Q(a);h=0.2*g;k=0.2; +m=l=0.5;O(a,(l-k)*b+d,m*c+e,!0);P(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);P(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);P(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);P(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);h=0.4*g;k=0.4;l=0.8;m=0.5;O(a,l*b+d,(m-k)*c+e,!0);P(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);P(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);P(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5* +h)*b+d,m*c+e);P(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);Q(a);h=0.8*g;k=0.8;l=1;m=0.5;O(a,l*b+d,(m-k)*c+e,!0);P(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);P(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);P(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5*h)*b+d,m*c+e);P(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);Q(a);b=a.s;t.v(a);return b},Email:function(a,b,c){a=t.u();O(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,1*c);a.lineTo(0,1* +c);a.lineTo(0,0);Q(a);O(a,0,0,!1);a.lineTo(0.5*b,0.6*c);a.lineTo(1*b,0);a.moveTo(0,1*c);a.lineTo(0.45*b,0.54*c);a.moveTo(1*b,1*c);a.lineTo(0.55*b,0.54*c);a.ab(!1);b=a.s;t.v(a);return b},Ethernet:function(a,b,c){a=t.u();O(a,0.35*b,0,!0);a.lineTo(0.65*b,0);a.lineTo(0.65*b,0.4*c);a.lineTo(0.35*b,0.4*c);a.lineTo(0.35*b,0);Q(a);O(a,0.1*b,1*c,!0,!0);a.lineTo(0.4*b,1*c);a.lineTo(0.4*b,0.6*c);a.lineTo(0.1*b,0.6*c);a.lineTo(0.1*b,1*c);Q(a);O(a,0.6*b,1*c,!0,!0);a.lineTo(0.9*b,1*c);a.lineTo(0.9*b,0.6*c);a.lineTo(0.6* +b,0.6*c);a.lineTo(0.6*b,1*c);Q(a);O(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.5*b,0.4*c);a.moveTo(0.75*b,0.5*c);a.lineTo(0.75*b,0.6*c);a.moveTo(0.25*b,0.5*c);a.lineTo(0.25*b,0.6*c);a.ab(!1);b=a.s;t.v(a);return b},Power:function(a,b,c){a=t.u();var d=J.va,e=0.4*d,g=0.4,h=t.O(),k=t.O(),l=t.O(),m=t.O();J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.5,h,h,k,l,m);var n=t.ic(k.x,k.y);O(a,k.x*b,k.y*c,!0);P(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);P(a,(0.5+g)*b,(0.5+e)*c,(0.5+ +e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5-e)*b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);J.Hi(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);P(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);e=0.3*d;g=0.3;J.Hi(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);a.lineTo(k.x*b,k.y*c);P(a,m.x*b,m.y*c,l.x*b,l.y*c,(0.5-g)*b,0.5*c);P(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);P(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);J.Hi(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5- +e,0.5+g,0.5,0.5,h,h,k,l,m);P(a,m.x*b,m.y*c,l.x*b,l.y*c,k.x*b,k.y*c);Q(a);O(a,0.45*b,0,!0);a.lineTo(0.45*b,0.5*c);a.lineTo(0.55*b,0.5*c);a.lineTo(0.55*b,0);Q(a);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);b=a.s;b.G=new K(0.25,0.55);b.H=new K(0.75,0.8);t.v(a);return b},Fallout:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,0*b,0.5*c,!0);P(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);P(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);var e= +d=0;O(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.4;e=0;Q(a);O(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.2;e=-0.3;Q(a);O(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);Q(a);b=a.s;b.kc=Zg;t.v(a);return b},IrritationHazard:function(a,b,c){a=t.u();O(a,0.2*b,0*c,!0);a.lineTo(0.5* +b,0.3*c);a.lineTo(0.8*b,0*c);a.lineTo(1*b,0.2*c);a.lineTo(0.7*b,0.5*c);a.lineTo(1*b,0.8*c);a.lineTo(0.8*b,1*c);a.lineTo(0.5*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0*b,0.8*c);a.lineTo(0.3*b,0.5*c);a.lineTo(0*b,0.2*c);Q(a);b=a.s;b.G=new K(0.3,0.3);b.H=new K(0.7,0.7);t.v(a);return b},ElectricalHazard:function(a,b,c){a=t.u();O(a,0.37,0*c,!0);a.lineTo(0.5*b,0.11*c);a.lineTo(0.77*b,0.04*c);a.lineTo(0.33*b,0.49*c);a.lineTo(1*b,0.37*c);a.lineTo(0.63*b,0.86*c);a.lineTo(0.77*b,0.91*c);a.lineTo(0.34*b,1*c);a.lineTo(0.34* +b,0.78*c);a.lineTo(0.44*b,0.8*c);a.lineTo(0.65*b,0.56*c);a.lineTo(0*b,0.68*c);Q(a);b=a.s;t.v(a);return b},FireHazard:function(a,b,c){a=t.u();O(a,0.1*b,1*c,!0);P(a,-0.25*b,0.63*c,0.45*b,0.44*c,0.29*b,0*c);P(a,0.48*b,0.17*c,0.54*b,0.35*c,0.51*b,0.42*c);P(a,0.59*b,0.29*c,0.58*b,0.28*c,0.59*b,0.18*c);P(a,0.8*b,0.34*c,0.88*b,0.43*c,0.75*b,0.6*c);P(a,0.87*b,0.48*c,0.88*b,0.43*c,0.88*b,0.31*c);P(a,1.17*b,0.76*c,0.82*b,0.8*c,0.9*b,1*c);Q(a);b=a.s;b.G=new K(0.05,0.645);b.H=new K(0.884,0.908);t.v(a);return b}, +BpmnActivityLoop:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;O(a,(0.5*Math.SQRT2/2+0.5)*b,(1-(0.5-0.5*Math.SQRT2/2))*c,!1);P(a,1*b,0.7*c,1*b,0.5*c,1*b,0.5*c);P(a,1*b,(0.5-d+0)*c,(0.5+d+0)*b,0*c,0.5*b,0*c);P(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);P(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.35*b,0.98*c);a.moveTo(0.35*b,0.8*c);a.lineTo(0.35*b,1*c);a.lineTo(0.15*b,1*c);b=a.s;t.v(a);return b},BpmnActivityParallel:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(0.5*b,0);a.lineTo(0.5* +b,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivitySequential:function(a,b,c){a=t.u();O(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0,1*c);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivityAdHoc:function(a,b,c){a=t.u();O(a,0,0,!1);O(a,1*b,1*c,!1);O(a,0,0.5*c,!1);P(a,0.2*b,0.35*c,0.3*b,0.35*c,0.5*b,0.5*c);P(a,0.7*b,0.65*c,0.8*b,0.65*c,1*b,0.5*c);b=a.s;t.v(a);return b},BpmnActivityCompensation:function(a,b,c){a=t.u();O(a,0,0.5*c,!0);a.lineTo(0.5* +b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(0.5*b,1*c);Q(a);b=a.s;t.v(a);return b},BpmnTaskMessage:function(a,b,c){a=t.u();O(a,0,0.2*c,!0);a.lineTo(1*b,0.2*c);a.lineTo(1*b,0.8*c);a.lineTo(0,0.8*c);a.lineTo(0,0.8*c);Q(a);O(a,0,0.2*c,!1);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,0.2*c);a.ab(!1);b=a.s;t.v(a);return b},BpmnTaskScript:function(a,b,c){a=t.u();O(a,0.7*b,1*c,!0);a.lineTo(0.3*b,1*c);P(a,0.6*b,0.5*c,0,0.5*c,0.3*b,0);a.lineTo(0.7*b,0);P(a,0.4*b,0.5*c, +1*b,0.5*c,0.7*b,1*c);Q(a);O(a,0.45*b,0.73*c,!1);a.lineTo(0.7*b,0.73*c);a.moveTo(0.38*b,0.5*c);a.lineTo(0.63*b,0.5*c);a.moveTo(0.31*b,0.27*c);a.lineTo(0.56*b,0.27*c);a.ab(!1);b=a.s;t.v(a);return b},BpmnTaskUser:function(a,b,c){a=t.u();O(a,0,0,!1);O(a,0.335*b,(1-0.555)*c,!0);a.lineTo(0.335*b,0.595*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.665*b,(1-0.555)*c);P(a,0.88*b,0.46*c,0.98*b,0.54*c,1*b,0.68*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.68*c);P(a,0.02*b,0.54*c,0.12*b,0.46*c,0.335*b,(1-0.555)* +c);a.lineTo(0.365*b,0.405*c);var d=0.5-0.285,e=Math.PI/4,g=4*(1-Math.cos(e))/(3*Math.sin(e)),e=g*d,g=g*d;P(a,(0.5-(e+d)/2)*b,(d+(d+g)/2)*c,(0.5-d)*b,(d+g)*c,(0.5-d)*b,d*c);P(a,(0.5-d)*b,(d-g)*c,(0.5-e)*b,(d-d)*c,0.5*b,(d-d)*c);P(a,(0.5+e)*b,(d-d)*c,(0.5+d)*b,(d-g)*c,(0.5+d)*b,d*c);P(a,(0.5+d)*b,(d+g)*c,(0.5+(e+d)/2)*b,(d+(d+g)/2)*c,0.635*b,0.405*c);a.lineTo(0.635*b,0.405*c);a.lineTo(0.665*b,(1-0.555)*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.335*b,0.595*c);O(a,0.2*b,1*c,!1);a.lineTo(0.2*b,0.8*c);O(a, +0.8*b,1*c,!1);a.lineTo(0.8*b,0.8*c);b=a.s;t.v(a);return b},BpmnEventConditional:function(a,b,c){a=t.u();O(a,0.1*b,0,!0);a.lineTo(0.9*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);Q(a);O(a,0.2*b,0.2*c,!1);a.lineTo(0.8*b,0.2*c);a.moveTo(0.2*b,0.4*c);a.lineTo(0.8*b,0.4*c);a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.2*b,0.8*c);a.lineTo(0.8*b,0.8*c);a.ab(!1);b=a.s;t.v(a);return b},BpmnEventError:function(a,b,c){a=t.u();O(a,0,1*c,!0);a.lineTo(0.33*b,0);a.lineTo(0.66*b,0.5*c);a.lineTo(1*b,0);a.lineTo(0.66* +b,1*c);a.lineTo(0.33*b,0.5*c);Q(a);b=a.s;t.v(a);return b},BpmnEventEscalation:function(a,b,c){a=t.u();O(a,0,0,!1);O(a,1*b,1*c,!1);O(a,0.1*b,1*c,!0);a.lineTo(0.5*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.5*b,0.5*c);Q(a);b=a.s;t.v(a);return b},BpmnEventTimer:function(a,b,c){a=t.u();var d=0.5*J.va;O(a,1*b,0.5*c,!0);P(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);P(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);P(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);P(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);O(a,0.5*b,0,!1);a.lineTo(0.5*b,0.15* +c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0.85*c);a.moveTo(0,0.5*c);a.lineTo(0.15*b,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(0.85*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.58*b,0.1*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.78*b,0.54*c);a.ab(!1);b=a.s;b.kc=Zg;t.v(a);return b}};for(var Xl in J.Qi)J.Qi[Xl.toLowerCase()]=Xl; +J.Kv={"":"",Standard:"F1 m 0,0 l 8,4 -8,4 2,-4 z",Backward:"F1 m 8,0 l -2,4 2,4 -8,-4 z",Triangle:"F1 m 0,0 l 8,4.62 -8,4.62 z",BackwardTriangle:"F1 m 8,4 l 0,4 -8,-4 8,-4 0,4 z",Boomerang:"F1 m 0,0 l 8,4 -8,4 4,-4 -4,-4 z",BackwardBoomerang:"F1 m 8,0 l -8,4 8,4 -4,-4 4,-4 z",SidewaysV:"m 0,0 l 8,4 -8,4 0,-1 6,-3 -6,-3 0,-1 z",BackwardV:"m 8,0 l -8,4 8,4 0,-1 -6,-3 6,-3 0,-1 z",OpenTriangle:"m 0,0 l 8,4 -8,4",BackwardOpenTriangle:"m 8,0 l -8,4 8,4",OpenTriangleLine:"m 0,0 l 8,4 -8,4 m 8.5,0 l 0,-8", +BackwardOpenTriangleLine:"m 8,0 l -8,4 8,4 m -8.5,0 l 0,-8",OpenTriangleTop:"m 0,0 l 8,4 m 0,4",BackwardOpenTriangleTop:"m 8,0 l -8,4 m 0,4",OpenTriangleBottom:"m 0,8 l 8,-4",BackwardOpenTriangleBottom:"m 0,4 l 8,4",HalfTriangleTop:"F1 m 0,0 l 0,4 8,0 z m 0,8",BackwardHalfTriangleTop:"F1 m 8,0 l 0,4 -8,0 z m 0,8",HalfTriangleBottom:"F1 m 0,4 l 0,4 8,-4 z",BackwardHalfTriangleBottom:"F1 m 8,4 l 0,4 -8,-4 z",ForwardSemiCircle:"m 4,0 b 270 180 0 4 4",BackwardSemiCircle:"m 4,8 b 90 180 0 -4 4",Feather:"m 0,0 l 3,4 -3,4", +BackwardFeather:"m 3,0 l -3,4 3,4",DoubleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardDoubleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4",TripleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardTripleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4 m 3,-8 l -3,4 3,4",ForwardSlash:"m 0,8 l 5,-8",BackSlash:"m 0,0 l 5,8",DoubleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8",DoubleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8",TripleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8 m -2,8 l 4,-8", +TripleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8 m -2,-8 l 4,8",Fork:"m 0,4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4",LineFork:"m 0,0 l 0,8 m 0,-4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardLineFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4 m 8,-8 l 0,8",CircleFork:"F1 m 6,4 b 0 360 -3 0 3 z m 0,0 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4",BackwardCircleFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 6,0 b 0 360 -3 0 3",CircleLineFork:"F1 m 6,4 b 0 360 -3 0 3 z m 1,-4 l 0,8 m 0,-4 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4", +BackwardCircleLineFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 0,-4 l 0,8 m 7,-4 b 0 360 -3 0 3",Circle:"F1 m 8,4 b 0 360 -4 0 4 z",Block:"F1 m 0,0 l 0,8 8,0 0,-8 z",StretchedDiamond:"F1 m 0,3 l 5,-3 5,3 -5,3 -5,-3 z",Diamond:"F1 m 0,4 l 4,-4 4,4 -4,4 -4,-4 z",Chevron:"F1 m 0,0 l 5,0 3,4 -3,4 -5,0 3,-4 -3,-4 z",StretchedChevron:"F1 m 0,0 l 8,0 3,4 -3,4 -8,0 3,-4 -3,-4 z",NormalArrow:"F1 m 0,2 l 4,0 0,-2 4,4 -4,4 0,-2 -4,0 z",X:"m 0,0 l 8,8 m 0,-8 l -8,8",TailedNormalArrow:"F1 m 0,0 l 2,0 1,2 3,0 0,-2 2,4 -2,4 0,-2 -3,0 -1,2 -2,0 1,-4 -1,-4 z", +DoubleTriangle:"F1 m 0,0 l 4,4 -4,4 0,-8 z m 4,0 l 4,4 -4,4 0,-8 z",BigEndArrow:"F1 m 0,0 l 5,2 0,-2 3,4 -3,4 0,-2 -5,2 0,-8 z",ConcaveTailArrow:"F1 m 0,2 h 4 v -2 l 4,4 -4,4 v -2 h -4 l 2,-2 -2,-2 z",RoundedTriangle:"F1 m 0,1 a 1,1 0 0 1 1,-1 l 7,3 a 0.5,1 0 0 1 0,2 l -7,3 a 1,1 0 0 1 -1,-1 l 0,-6 z",SimpleArrow:"F1 m 1,2 l -1,-2 2,0 1,2 -1,2 -2,0 1,-2 5,0 0,-2 2,2 -2,2 0,-2 z",AccelerationArrow:"F1 m 0,0 l 0,8 0.2,0 0,-8 -0.2,0 z m 2,0 l 0,8 1,0 0,-8 -1,0 z m 3,0 l 2,0 2,4 -2,4 -2,0 0,-8 z",BoxArrow:"F1 m 0,0 l 4,0 0,2 2,0 0,-2 2,4 -2,4 0,-2 -2,0 0,2 -4,0 0,-8 z", +TriangleLine:"F1 m 8,4 l -8,-4 0,8 8,-4 z m 0.5,4 l 0,-8",CircleEndedArrow:"F1 m 10,4 l -2,-3 0,2 -2,0 0,2 2,0 0,2 2,-3 z m -4,0 b 0 360 -3 0 3 z",DynamicWidthArrow:"F1 m 0,3 l 2,0 2,-1 2,-2 2,4 -2,4 -2,-2 -2,-1 -2,0 0,-2 z",EquilibriumArrow:"m 0,3 l 8,0 -3,-3 m 3,5 l -8,0 3,3",FastForward:"F1 m 0,0 l 3.5,4 0,-4 3.5,4 0,-4 1,0 0,8 -1,0 0,-4 -3.5,4 0,-4 -3.5,4 0,-8 z",Kite:"F1 m 0,4 l 2,-4 6,4 -6,4 -2,-4 z",HalfArrowTop:"F1 m 0,0 l 4,4 4,0 -8,-4 z m 0,8",HalfArrowBottom:"F1 m 0,8 l 4,-4 4,0 -8,4 z", +OpposingDirectionDoubleArrow:"F1 m 0,4 l 2,-4 0,2 4,0 0,-2 2,4 -2,4 0,-2 -4,0 0,2 -2,-4 z",PartialDoubleTriangle:"F1 m 0,0 4,3 0,-3 4,4 -4,4 0,-3 -4,3 0,-8 z",LineCircle:"F1 m 0,0 l 0,8 m 7 -4 b 0 360 -3 0 3 z",DoubleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",TripleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",CircleLine:"F1 m 6 4 b 0 360 -3 0 3 z m 1,-4 l 0,8",DiamondCircle:"F1 m 8,4 l -4,4 -4,-4 4,-4 4,4 m 8,0 b 0 360 -4 0 4 z",PlusCircle:"F1 m 8,4 b 0 360 -4 0 4 l -8 0 z m -4 -4 l 0 8", +OpenRightTriangleTop:"m 8,0 l 0,4 -8,0 m 0,4",OpenRightTriangleBottom:"m 8,8 l 0,-4 -8,0",Line:"m 0,0 l 0,8",DoubleLine:"m 0,0 l 0,8 m 2,0 l 0,-8",TripleLine:"m 0,0 l 0,8 m 2,0 l 0,-8 m 2,0 l 0,8",PentagonArrow:"F1 m 8,4 l -4,-4 -4,0 0,8 4,0 4,-4 z",None:""};J.GA={};J.Lv={};J.Oo=function(a){if(J.Kv){for(var b in J.Kv){var c=bd(J.Kv[b],!1);J.Lv[b]=c;b.toLowerCase()!==b&&(J.Lv[b.toLowerCase()]=b)}J.Kv=void 0}return J.Lv[a]};Y.FigureGenerators=J.Qi;Y.ArrowheadGeometries=J.Lv; +function w(a){0===arguments.length?B.call(this):B.call(this,a);this.ca=49663;this.Wn=this.gh="";this.Jr=this.Gr=this.Tr=this.Wq=null;this.Vr="";this.Cg=this.Ur=this.mm=null;this.Ir="";this.lo=null;this.Hr=(new pa(NaN,NaN)).freeze();this.Kr="";this.mo=null;this.ge="";this.Vn=this.lq=this.Ck=null;this.li=(new C(NaN,NaN)).freeze();this.dr="";this.Pk=null;this.er=Tb;this.nr=J.nG;this.gr=J.mG;this.vq=null;this.Xq=Yl;this.pm=(new C(6,6)).freeze();this.om="gray";this.nm=4;this.AG=-1;this.xG=new D;this.Aj= +null;this.yj=NaN}t.ia("Part",w);t.Oa(w,B);w.prototype.cloneProtected=function(a){B.prototype.cloneProtected.call(this,a);a.ca=this.ca&-4097|49152;a.gh=this.gh;a.Wn=this.Wn;a.Wq=this.Wq;a.Tr=this.Tr;a.Gr=this.Gr;a.Jr=this.Jr;a.Vr=this.Vr;a.Ur=this.Ur;a.Cg=null;a.Ir=this.Ir;a.Hr.assign(this.Hr);a.Kr=this.Kr;a.ge=this.ge;a.lq=this.lq;a.li.assign(this.li);a.dr=this.dr;a.er=this.er.Z();a.nr=this.nr.Z();a.gr=this.gr.Z();a.vq=this.vq;a.Xq=this.Xq;a.pm.assign(this.pm);a.om=this.om;a.nm=this.nm}; +w.prototype.Gh=function(a){B.prototype.Gh.call(this,a);Wj(a);a.mm=null;a.lo=null;a.mo=null;a.Pk=null;a.Aj=null};w.prototype.toString=function(){var a=t.Ug(Object.getPrototypeOf(this))+"#"+t.oc(this);this.data&&(a+="("+ma(this.data)+")");return a};w.LayoutNone=0;var Hi;w.LayoutAdded=Hi=1;var Mi;w.LayoutRemoved=Mi=2;var Kh;w.LayoutShown=Kh=4;var Lh;w.LayoutHidden=Lh=8;w.LayoutNodeSized=16;var dj;w.LayoutGroupLayout=dj=32;w.LayoutNodeReplaced=64;var Yl;w.LayoutStandard=Yl=Hi|Mi|Kh|Lh|16|dj|64; +w.prototype.$m=function(a,b,c,d,e,g,h){var k=this.h;null!==k&&(a===Jd&&"elements"===b?e instanceof B&&Ii(e,function(a){Ji(k,a)}):a===Td&&"elements"===b&&e instanceof B&&Ii(e,function(a){Li(k,a)}),k.Uc(a,b,c,d,e,g,h))};w.prototype.updateTargetBindings=w.prototype.Jb=function(a){B.prototype.Jb.call(this,a);if(null!==this.data)for(a=this.elements;a.next();){var b=a.value;b instanceof B&&Ii(b,function(a){null!==a.data&&a.Jb()})}};t.A(w,{Fv:"adornments"},function(){return null===this.Cg?t.dh:this.Cg.k}); +w.prototype.findAdornment=w.prototype.No=function(a){f&&t.j(a,"string",w,"findAdornment:category");var b=this.Cg;return null===b?null:b.Ba(a)};w.prototype.addAdornment=w.prototype.Xk=function(a,b){if(null!==b){f&&(t.j(a,"string",w,"addAdornment:category"),t.l(b,We,w,"addAdornment:ad"));var c=null,d=this.Cg;null!==d&&(c=d.Ba(a));if(c!==b){if(null!==c){var e=c.h;null!==e&&e.remove(c)}null===d&&(this.Cg=d=new sa("string",We));b.gh!==a&&(b.Oc=a);d.add(a,b);c=this.h;null!==c&&(c.add(b),b.data=this.data)}}}; +w.prototype.removeAdornment=w.prototype.ul=function(a){f&&t.j(a,"string",w,"removeAdornment:category");var b=this.Cg;if(null!==b){var c=b.Ba(a);if(null!==c){var d=c.h;null!==d&&d.remove(c)}b.remove(a);0===b.count&&(this.Cg=null)}};w.prototype.clearAdornments=w.prototype.Ae=function(){var a=this.Cg;if(null!==a){for(var b=t.Cb(),a=a.k;a.next();)b.push(a.key);for(var a=b.length,c=0;c=c.OE)){this.ca^=4096;var d=!1;if(null!==c){d=c.Bb;c.Bb=!0;var e=c.selection;e.Ua();a?e.add(this):e.remove(this);e.freeze()}this.i("isSelected",b,a);$l(this);a=this.vF;null!==a&&a(this);null!==c&&(c.Nf(),c.Bb=d)}}});t.g(w,"isShadowed",w.prototype.Lh); +t.defineProperty(w,{Lh:"isShadowed"},function(){return 0!==(this.ca&8192)},function(a){var b=0!==(this.ca&8192);b!==a&&(f&&t.j(a,"boolean",w,"isShadowed"),this.ca^=8192,this.i("isShadowed",b,a),this.pa())});function zi(a){return 0!==(a.ca&32768)}function am(a,b){a.ca=b?a.ca|32768:a.ca&-32769}function Yj(a,b){a.ca=b?a.ca|65536:a.ca&-65537}function Fh(a){return 0!==(a.ca&131072)}w.prototype.Of=function(a){this.ca=a?this.ca|131072:this.ca&-131073};t.g(w,"selectionObjectName",w.prototype.vt); +t.defineProperty(w,{vt:"selectionObjectName"},function(){return this.Vr},function(a){var b=this.Vr;b!==a&&(f&&t.j(a,"string",w,"selectionObjectName"),this.Vr=a,this.mm=null,this.i("selectionObjectName",b,a))});t.g(w,"selectionAdornmentTemplate",w.prototype.uF);t.defineProperty(w,{uF:"selectionAdornmentTemplate"},function(){return this.Tr},function(a){var b=this.Tr;b!==a&&(f&&t.l(a,We,w,"selectionAdornmentTemplate"),this instanceof A&&(a.type=wg),this.Tr=a,this.i("selectionAdornmentTemplate",b,a))}); +t.A(w,{bn:"selectionObject"},function(){if(null===this.mm){var a=this.vt;null!==a&&""!==a?(a=this.le(a),this.mm=null!==a?a:this):this instanceof A?(a=this.path,this.mm=null!==a?a:this):this.mm=this}return this.mm});t.g(w,"selectionChanged",w.prototype.vF);t.defineProperty(w,{vF:"selectionChanged"},function(){return this.Ur},function(a){var b=this.Ur;b!==a&&(null!==a&&t.j(a,"function",w,"selectionChanged"),this.Ur=a,this.i("selectionChanged",b,a))});t.g(w,"resizeAdornmentTemplate",w.prototype.hF); +t.defineProperty(w,{hF:"resizeAdornmentTemplate"},function(){return this.Gr},function(a){var b=this.Gr;b!==a&&(f&&t.l(a,We,w,"resizeAdornmentTemplate"),this.Gr=a,this.i("resizeAdornmentTemplate",b,a))});t.g(w,"resizeObjectName",w.prototype.kF);t.defineProperty(w,{kF:"resizeObjectName"},function(){return this.Ir},function(a){var b=this.Ir;b!==a&&(f&&t.j(a,"string",w,"resizeObjectName"),this.Ir=a,this.lo=null,this.i("resizeObjectName",b,a))}); +t.A(w,{jF:"resizeObject"},function(){if(null===this.lo){var a=this.kF;null!==a&&""!==a?(a=this.le(a),this.lo=null!==a?a:this):this.lo=this}return this.lo});t.g(w,"resizeCellSize",w.prototype.iF);t.defineProperty(w,{iF:"resizeCellSize"},function(){return this.Hr},function(a){var b=this.Hr;b.N(a)||(f&&t.l(a,pa,w,"resizeCellSize"),this.Hr=a=a.Z(),this.i("resizeCellSize",b,a))});t.g(w,"rotateAdornmentTemplate",w.prototype.mF); +t.defineProperty(w,{mF:"rotateAdornmentTemplate"},function(){return this.Jr},function(a){var b=this.Jr;b!==a&&(f&&t.l(a,We,w,"rotateAdornmentTemplate"),this.Jr=a,this.i("rotateAdornmentTemplate",b,a))});t.g(w,"rotateObjectName",w.prototype.oF);t.defineProperty(w,{oF:"rotateObjectName"},function(){return this.Kr},function(a){var b=this.Kr;b!==a&&(f&&t.j(a,"string",w,"rotateObjectName"),this.Kr=a,this.mo=null,this.i("rotateObjectName",b,a))}); +t.A(w,{nF:"rotateObject"},function(){if(null===this.mo){var a=this.oF;null!==a&&""!==a?(a=this.le(a),this.mo=null!==a?a:this):this.mo=this}return this.mo});t.g(w,"text",w.prototype.text);t.defineProperty(w,{text:"text"},function(){return this.ge},function(a){var b=this.ge;b!==a&&(f&&t.j(a,"string",w,"text"),this.ge=a,this.i("text",b,a))});t.g(w,"containingGroup",w.prototype.fb); +t.defineProperty(w,{fb:"containingGroup"},function(){return this.Ck},function(a){if(this.Ud()){var b=this.Ck;if(b!==a){f&&null!==a&&t.l(a,z,w,"containingGroup");null===a||this!==a&&!a.Us(this)||(this===a&&t.m("Cannot make a Group a member of itself: "+this.toString()),t.m("Cannot make a Group indirectly contain itself: "+this.toString()+" already contains "+a.toString()));this.K(Mi);var c=this.h;null!==b?gm(b,this):this instanceof z&&null!==c&&c.Vk.remove(this);this.Ck=a;null!==a?hm(a,this):this instanceof +z&&null!==c&&c.Vk.add(this);this.K(Hi);if(null!==c){var d=this.data,e=c.fa;null!==d&&e instanceof V&&e.$A(d,e.Nb(null!==a?a.data:null))}d=this.Lz;null!==d&&(e=!0,null!==c&&(e=c.Wa,c.Wa=!0),d(this,b,a),null!==c&&(c.Wa=e));if(this instanceof z)for(c=new ua(w),Ve(c,this,!0,0),c=c.k;c.next();)if(d=c.value,d instanceof y)for(d=d.Dd;d.next();)e=d.value,$i(e);if(this instanceof y)for(d=this.Dd;d.next();)e=d.value,$i(e);this.i("containingGroup",b,a);null!==a&&a.Pw()}}else t.m("cannot set the Part.containingGroup of a Link or Adornment")}); +function Wj(a){a=a.fb;null!==a&&(a.aa(),null!==a.wb&&a.wb.aa(),a.Wg())}w.prototype.Ps=function(){var a=this.Ck;null!==a&&hm(a,this)};w.prototype.Qs=function(){var a=this.Ck;null!==a&&gm(a,this)};w.prototype.Jm=function(){var a=this.data;if(null!==a){var b=this.h;null!==b&&(b=b.fa,null!==b&&b.Iw(a))}};t.g(w,"containingGroupChanged",w.prototype.Lz); +t.defineProperty(w,{Lz:"containingGroupChanged"},function(){return this.lq},function(a){var b=this.lq;b!==a&&(null!==a&&t.j(a,"function",w,"containingGroupChanged"),this.lq=a,this.i("containingGroupChanged",b,a))});w.prototype.findTopLevelPart=function(){return im(this,this)};function im(a,b){var c=b.fb;return null!==c?im(a,c):b instanceof y&&(c=b.Sc,null!==c)?im(a,c):b}t.A(w,{ep:"isTopLevel"},function(){return null!==this.fb||this instanceof y&&this.Ih?!1:!0}); +w.prototype.isMemberOf=w.prototype.Us=function(a){return a instanceof z?jm(this,this,a):!1};function jm(a,b,c){if(b===c||null===c)return!1;var d=b.fb;return null===d||d!==c&&!jm(a,d,c)?b instanceof y&&(b=b.Sc,null!==b)?jm(a,b,c):!1:!0}w.prototype.findCommonContainingGroup=w.prototype.UH=function(a){return km(this,this,a)}; +function km(a,b,c){if(null===b||null===c)return null;var d=b.fb;if(null===d)return null;if(b===c)return d;var e=c.fb;return null===e?null:d===e?e:jm(a,c,d)?d:jm(a,b,e)?e:km(a,d,e)}t.g(w,"layoutConditions",w.prototype.GE);t.defineProperty(w,{GE:"layoutConditions"},function(){return this.Xq},function(a){var b=this.Xq;b!==a&&(f&&t.j(a,"number",w,"layoutConditions"),this.Xq=a,this.i("layoutConditions",b,a))}); +w.prototype.canLayout=function(){if(!this.tw||!this.zb())return!1;var a=this.layer;return null!==a&&a.pc||this instanceof y&&this.Ih?!1:!0};w.prototype.invalidateLayout=w.prototype.K=function(a){void 0===a&&(a=16777215);var b;this.tw&&0!==(a&this.GE)?(b=this.layer,null!==b&&b.pc||this instanceof y&&this.Ih?b=!1:(b=this.h,b=null!==b&&b.Aa.qb?!1:!0)):b=!1;if(b)if(b=this.Ck,null!==b){var c=b.Tb;null!==c?c.K():b.K(a)}else a=this.h,null!==a&&(c=a.Tb,null!==c&&c.K())};t.g(w,"dragComputation",w.prototype.Sz); +t.defineProperty(w,{Sz:"dragComputation"},function(){return this.vq},function(a){var b=this.vq;b!==a&&(null!==a&&t.j(a,"function",w,"dragComputation"),this.vq=a,this.i("dragComputation",b,a))});t.g(w,"shadowOffset",w.prototype.zF);t.defineProperty(w,{zF:"shadowOffset"},function(){return this.pm},function(a){var b=this.pm;b.N(a)||(f&&t.l(a,C,w,"shadowOffset"),this.pm=a=a.Z(),this.pa(),this.i("shadowOffset",b,a))});t.g(w,"shadowColor",w.prototype.shadowColor); +t.defineProperty(w,{shadowColor:"shadowColor"},function(){return this.om},function(a){var b=this.om;b!==a&&(f&&t.j(a,"string",w,"shadowColor"),this.om=a,this.pa(),this.i("shadowColor",b,a))});t.g(w,"shadowBlur",w.prototype.shadowBlur);t.defineProperty(w,{shadowBlur:"shadowBlur"},function(){return this.nm},function(a){var b=this.nm;b!==a&&(f&&t.j(a,"number",w,"shadowBlur"),this.nm=a,this.pa(),this.i("shadowBlur",b,a))}); +function We(a){0===arguments.length?w.call(this,bh):w.call(this,a);this.Xd="Adornment";this.La=null;this.ca&=-257;this.li=new C(NaN,NaN);this.Zh=new H(D);this.wb=null;this.yy=!1}t.ia("Adornment",We);t.Oa(We,w);aa=We.prototype;aa.toString=function(){var a=this.Dh;return"Adornment("+this.Oc+")"+(null!==a?a.toString():"")};aa.oj=function(){return this.La&&this.La.S instanceof A?this.La.S.oj():null};aa.Gq=function(){return null}; +aa.zw=function(){var a=this.Nc.S,b=this.Nc;if(a instanceof A&&b instanceof Y){var c=a.path,b=c.Ra;a.zw();for(var b=c.Ra,a=this.za,c=a.length,d=0;da&&(a=1);var b=this.h;if(null!==b&&!b.Sd){b.Sd=!0;var c=b.fd,d=new ua(y);d.add(this);sm(this,d,c,a,this.Gc);b.Sd=!1;b.pa()}}; +function sm(a,b,c,d,e){if(1a&&(a=2);var b=this.h;if(null!==b&&!b.Sd){b.Sd=!0;var c=b.fd,d=new ua(y);d.add(this);um(this,d,c,a,this.Gc);b.Sd=!1}};function um(a,b,c,d,e){a.Gc=!0;for(var g=c?a.fw():a.mg();g.next();){var h=g.value;h.xc&&(e||(h.Sg||h.$b(),h.updateAdornments()),h=h.bA(a),null!==h&&h!==a&&!b.contains(h)&&(b.add(h),e||(h.pa(),h.updateAdornments(),Wj(h),h.K(Kh)),2a&&(a=2),null===c||c.Sd||(c.Sd=!0,b=c.fd,d=new ua(y),d.add(this),um(this,d,b,a,!1),c.Sd=!1)):(a=1,1>a&&(a=1),null===c||c.Sd||(c.Sd=!0,b=c.fd,d=new ua(y),d.add(this),sm(this,d,b,a,!0),c.Sd=!1)))}}); +t.g(y,"wasTreeExpanded",y.prototype.jn);t.defineProperty(y,{jn:"wasTreeExpanded"},function(){return this.os},function(a){var b=this.os;b!==a&&(f&&t.j(a,"boolean",y,"wasTreeExpanded"),this.os=a,this.i("wasTreeExpanded",b,a))});t.g(y,"treeExpandedChanged",y.prototype.VF);t.defineProperty(y,{VF:"treeExpandedChanged"},function(){return this.js},function(a){var b=this.js;b!==a&&(null!==a&&t.j(a,"function",y,"treeExpandedChanged"),this.js=a,this.i("treeExpandedChanged",b,a))});t.g(y,"isTreeLeaf",y.prototype.Mh); +t.defineProperty(y,{Mh:"isTreeLeaf"},function(){return this.Sq},function(a){var b=this.Sq;b!==a&&(f&&t.j(a,"boolean",y,"isTreeLeaf"),this.Sq=a,this.i("isTreeLeaf",b,a))}); +function A(){w.call(this,wg);this.Wf=null;this.nh="";this.fg=this.Eq=null;this.Ah="";this.is=null;this.Fr=this.Er=this.Dr=!1;this.Tq=!0;this.$p=Jg;this.mq=0;this.pq=Jg;this.qq=NaN;this.im=Gk;this.$r=0.5;this.ui=this.ff=null;this.mc=(new H(C)).freeze();this.ue=null;this.Sg=!1;this.Uy=null;this.fz=!1;this.rn=this.gi=this.Ra=null;this.cf=0;this.Bn=this.xn=null;this.Zh=new H(D);this.kz=new C;this.RC=this.PC=null;this.Ix=!1;this.V=null}t.ia("Link",A);t.Oa(A,w); +A.prototype.cloneProtected=function(a){w.prototype.cloneProtected.call(this,a);a.nh=this.nh;a.Eq=this.Eq;a.Ah=this.Ah;a.is=this.is;a.Dr=this.Dr;a.Er=this.Er;a.Fr=this.Fr;a.Tq=this.Tq;a.$p=this.$p;a.mq=this.mq;a.pq=this.pq;a.qq=this.qq;a.im=this.im;a.$r=this.$r};A.prototype.Gh=function(a){w.prototype.Gh.call(this,a);this.nh=a.nh;this.Ah=a.Ah;a.ui=null;a.ue=null;a.$b();a.rn=this.rn;a.cf=this.cf};var Gk;A.Normal=Gk=t.w(A,"Normal",1);A.Orthogonal=t.w(A,"Orthogonal",2); +A.AvoidsNodes=t.w(A,"AvoidsNodes",6);var vm;A.AvoidsNodesStraight=vm=t.w(A,"AvoidsNodesStraight",7);var Jg;A.None=Jg=t.w(A,"None",0);var Rg;A.Bezier=Rg=t.w(A,"Bezier",9);var Ig;A.JumpGap=Ig=t.w(A,"JumpGap",10);var Gg;A.JumpOver=Gg=t.w(A,"JumpOver",11);var Dk;A.End=Dk=t.w(A,"End",17);var Ek;A.Scale=Ek=t.w(A,"Scale",18);var Fk;A.Stretch=Fk=t.w(A,"Stretch",19);var Ml;A.OrientAlong=Ml=t.w(A,"OrientAlong",21);var wm;A.OrientPlus90=wm=t.w(A,"OrientPlus90",22);var xm; +A.OrientMinus90=xm=t.w(A,"OrientMinus90",23);var ym;A.OrientOpposite=ym=t.w(A,"OrientOpposite",24);var zm;A.OrientUpright=zm=t.w(A,"OrientUpright",25);var Am;A.OrientPlus90Upright=Am=t.w(A,"OrientPlus90Upright",26);var Bm;A.OrientMinus90Upright=Bm=t.w(A,"OrientMinus90Upright",27);var Cm;A.OrientUpright45=Cm=t.w(A,"OrientUpright45",28);A.prototype.Ge=function(){this.V={nj:Pb,Pj:Pb,lj:NaN,Nj:NaN,kj:lm,Mj:lm,mj:NaN,Oj:NaN}}; +A.prototype.nl=function(){var a=this.da;if(null!==a&&(yi(a)||zi(a)))return!1;a=this.ja;return null!==a&&(yi(a)||zi(a))?!1:!0};A.prototype.Ud=function(){return!1}; +A.prototype.computeAngle=function(a,b,c){switch(b){default:case Jg:a=0;break;case Ml:a=c;break;case wm:a=c+90;break;case xm:a=c-90;break;case ym:a=c+180;break;case zm:a=J.jt(c);90a&&(a-=180);break;case Am:a=J.jt(c+90);90a&&(a-=180);break;case Bm:a=J.jt(c-90);90a&&(a-=180);break;case Cm:a=J.jt(c);if(45a||225a)return 0;90a&&(a-=180)}return J.jt(a)};t.g(A,"fromNode",A.prototype.da); +t.defineProperty(A,{da:"fromNode"},function(){return this.Wf},function(a){var b=this.Wf;if(b!==a){f&&null!==a&&t.l(a,y,A,"fromNode");var c=this.Qc;null!==b&&(this.fg!==b&&qm(b,this,c),null!==c&&(c.ee=null),Dm(this),b.K(Mi));this.Wf=a;this.gi=null;this.$b();var d=this.h;if(null!==d){var e=this.data,g=d.fa;if(null!==e)if(g instanceof V){var h=null!==a?a.data:null;g.YA(e,g.Nb(h))}else g instanceof Zd&&(h=null!==a?a.data:null,d.fd?g.Qh(e,g.Nb(h)):(null!==b&&g.Qh(b.data,void 0),g.Qh(h,g.Nb(null!==this.fg? +this.fg.data:null))))}e=this.Qc;g=this.aA;null!==g&&(h=!0,null!==d&&(h=d.Wa,d.Wa=!0),g(this,c,e),null!==d&&(d.Wa=h));null!==a&&(this.fg!==a&&pm(a,this,e),null!==e&&(e.ee=null),Em(this),a.K(Hi));this.i("fromNode",b,a);$i(this)}});t.g(A,"fromPortId",A.prototype.nf); +t.defineProperty(A,{nf:"fromPortId"},function(){return this.nh},function(a){var b=this.nh;if(b!==a){f&&t.j(a,"string",A,"fromPortId");var c=this.Qc;null!==c&&(c.ee=null);Dm(this);this.nh=a;var d=this.Qc;null!==d&&(d.ee=null);var e=this.h;if(null!==e){var g=this.data,h=e.fa;null!==g&&h instanceof V&&h.ZA(g,a)}c!==d&&(this.gi=null,this.$b(),g=this.aA,null!==g&&(h=!0,null!==e&&(h=e.Wa,e.Wa=!0),g(this,c,d),null!==e&&(e.Wa=h)));Em(this);this.i("fromPortId",b,a)}}); +t.A(A,{Qc:"fromPort"},function(){var a=this.Wf;return null===a?null:a.Js(this.nh)});t.g(A,"fromPortChanged",A.prototype.aA);t.defineProperty(A,{aA:"fromPortChanged"},function(){return this.Eq},function(a){var b=this.Eq;b!==a&&(null!==a&&t.j(a,"function",A,"fromPortChanged"),this.Eq=a,this.i("fromPortChanged",b,a))});t.g(A,"toNode",A.prototype.ja); +t.defineProperty(A,{ja:"toNode"},function(){return this.fg},function(a){var b=this.fg;if(b!==a){f&&null!==a&&t.l(a,y,A,"toNode");var c=this.Ed;null!==b&&(this.Wf!==b&&qm(b,this,c),null!==c&&(c.ee=null),Dm(this),b.K(Mi));this.fg=a;this.gi=null;this.$b();var d=this.h;if(null!==d){var e=this.data,g=d.fa;if(null!==e)if(g instanceof V){var h=null!==a?a.data:null;g.cB(e,g.Nb(h))}else g instanceof Zd&&(h=null!==a?a.data:null,d.fd?(null!==b&&g.Qh(b.data,void 0),g.Qh(h,g.Nb(null!==this.Wf?this.Wf.data:null))): +g.Qh(e,g.Nb(h)))}e=this.Ed;g=this.lB;null!==g&&(h=!0,null!==d&&(h=d.Wa,d.Wa=!0),g(this,c,e),null!==d&&(d.Wa=h));null!==a&&(this.Wf!==a&&pm(a,this,e),null!==e&&(e.ee=null),Em(this),a.K(Hi));this.i("toNode",b,a);$i(this)}});t.g(A,"toPortId",A.prototype.Qf); +t.defineProperty(A,{Qf:"toPortId"},function(){return this.Ah},function(a){var b=this.Ah;if(b!==a){f&&t.j(a,"string",A,"toPortId");var c=this.Ed;null!==c&&(c.ee=null);Dm(this);this.Ah=a;var d=this.Ed;null!==d&&(d.ee=null);var e=this.h;if(null!==e){var g=this.data,h=e.fa;null!==g&&h instanceof V&&h.dB(g,a)}c!==d&&(this.gi=null,this.$b(),g=this.lB,null!==g&&(h=!0,null!==e&&(h=e.Wa,e.Wa=!0),g(this,c,d),null!==e&&(e.Wa=h)));Em(this);this.i("toPortId",b,a)}}); +t.A(A,{Ed:"toPort"},function(){var a=this.fg;return null===a?null:a.Js(this.Ah)});t.g(A,"toPortChanged",A.prototype.lB);t.defineProperty(A,{lB:"toPortChanged"},function(){return this.is},function(a){var b=this.is;b!==a&&(null!==a&&t.j(a,"function",A,"toPortChanged"),this.is=a,this.i("toPortChanged",b,a))}); +t.defineProperty(A,{lb:"fromSpot"},function(){return null!==this.V?this.V.nj:Pb},function(a){null===this.V&&this.Ge();var b=this.V.nj;b.N(a)||(f&&t.l(a,K,A,"fromSpot"),a=a.Z(),this.V.nj=a,this.i("fromSpot",b,a),this.$b())}); +t.defineProperty(A,{ek:"fromEndSegmentLength"},function(){return null!==this.V?this.V.lj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.lj;b!==a&&(f&&t.j(a,"number",A,"fromEndSegmentLength"),0>a&&t.ha(a,">= 0",A,"fromEndSegmentLength"),this.V.lj=a,this.i("fromEndSegmentLength",b,a),this.$b())}); +t.defineProperty(A,{So:"fromEndSegmentDirection"},function(){return null!==this.V?this.V.kj:lm},function(a){null===this.V&&this.Ge();var b=this.V.kj;b!==a&&(f&&t.tb(a,y,A,"fromEndSegmentDirection"),this.V.kj=a,this.i("fromEndSegmentDirection",b,a),this.$b())});t.defineProperty(A,{To:"fromShortLength"},function(){return null!==this.V?this.V.mj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.mj;b!==a&&(f&&t.j(a,"number",A,"fromShortLength"),this.V.mj=a,this.i("fromShortLength",b,a),this.$b())}); +t.defineProperty(A,{mb:"toSpot"},function(){return null!==this.V?this.V.Pj:Pb},function(a){null===this.V&&this.Ge();var b=this.V.Pj;b.N(a)||(f&&t.l(a,K,A,"toSpot"),a=a.Z(),this.V.Pj=a,this.i("toSpot",b,a),this.$b())}); +t.defineProperty(A,{mk:"toEndSegmentLength"},function(){return null!==this.V?this.V.Nj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.Nj;b!==a&&(f&&t.j(a,"number",A,"toEndSegmentLength"),0>a&&t.ha(a,">= 0",A,"toEndSegmentLength"),this.V.Nj=a,this.i("toEndSegmentLength",b,a),this.$b())}); +t.defineProperty(A,{Lp:"toEndSegmentDirection"},function(){return null!==this.V?this.V.Mj:lm},function(a){null===this.V&&this.Ge();var b=this.V.Mj;b!==a&&(f&&t.tb(a,y,A,"toEndSegmentDirection"),this.V.Mj=a,this.i("toEndSegmentDirection",b,a),this.$b())});t.defineProperty(A,{Mp:"toShortLength"},function(){return null!==this.V?this.V.Oj:NaN},function(a){null===this.V&&this.Ge();var b=this.V.Oj;b!==a&&(f&&t.j(a,"number",A,"toShortLength"),this.V.Oj=a,this.i("toShortLength",b,a),this.$b())}); +function $i(a){var b=a.da,c=a.ja;null!==b&&null!==c?Fm(a,b.UH(c)):Fm(a,null)}function Fm(a,b){var c=a.Ck;if(c!==b){null!==c&&gm(c,a);a.Ck=b;null!==b&&hm(b,a);var d=a.Lz;if(null!==d){var e=!0,g=a.h;null!==g&&(e=g.Wa,g.Wa=!0);d(a,c,b);null!==g&&(g.Wa=e)}!a.Sg||a.PC!==c&&a.RC!==c||a.$b()}}A.prototype.getOtherNode=A.prototype.bA=function(a){f&&t.l(a,y,A,"getOtherNode:node");var b=this.da;return a===b?this.ja:b}; +A.prototype.getOtherPort=function(a){f&&t.l(a,X,A,"getOtherPort:port");var b=this.Qc;return a===b?this.Ed:b};t.A(A,{uJ:"isLabeledLink"},function(){return null===this.ff?!1:0=d&&(l=d-1),k=this.n(l-1),g=this.n(l),J.Eo(e.x,e.y,h.x,h.y,k.x,k.y,g.x,g.y,0.5,a),b=Math.min(g.x,b),c=Math.min(g.y,c),e=g;else for(e=this.n(0),g=this.n(1),b=Math.min(e.x,g.x),c=Math.min(e.y,g.y),a.q(e.x,e.y,0,0),a.$i(g),l=2;lc&&(c=-c)):J.Ka(c.y,d.y)?(c=d.x-c.x,0>c&&(c=-c)):c=Math.sqrt(c.$j(d)),g.push(c),e+=c;for(d=h=c=0;ce/2)break;c+=d;h++}t.Da(g);b=this.n(h);g=this.n(h+1);b.x===g.x?b.y>g.y?a.q(b.x,b.y-(e/2-c)):a.q(b.x,b.y+(e/2-c)):b.y===g.y?b.x>g.x?a.q(b.x-(e/2-c),b.y):a.q(b.x+(e/2-c),b.y):(e=(e/2-c)/d,a.q(b.x+e*(g.x-b.x),b.y+e*(g.y-b.y)));return a};t.A(A,{RE:"midAngle"},function(){this.updateRoute();return this.computeMidAngle()}); +A.prototype.computeMidAngle=function(){var a=this.ma;if(2>a)return NaN;if(this.computeCurve()===Rg&&4<=a&&!this.ac){var b=(a-1)/3|0,c=3*(b/2|0);if(1===b%2){var c=Math.floor(c),a=this.n(c),b=this.n(c+1),d=this.n(c+2),c=this.n(c+3);return J.jH(a.x,a.y,b.x,b.y,d.x,d.y,c.x,c.y)}if(0e?a.Li(b):b.Li(d)};t.g(A,"points",A.prototype.points); +t.defineProperty(A,{points:"points"},function(){return this.mc},function(a){f&&(Array.isArray(a)||a instanceof H||t.m("Link.points value is not an instance of List or Array"));var b=this.mc;if(b!==a){if(Array.isArray(a)){for(var c=0===a.length%2,d=0;dp&&(v-=180));0>v?v+=360:360<=v&&(v-=360);k&&(x+=Math.abs(p));0===v?r=x:90===v?s=x:180===v?r=-x:270===v?s=-x:(r=x*Math.cos(v*Math.PI/180),s=x*Math.sin(v*Math.PI/180));if(g.qd()&&k){var E=c.gb(Wb,t.O()),F=t.ic(E.x+1E3*r,E.y+1E3*s);this.getLinkPointFromPoint(b,c,E,F,!0,q);t.B(E);t.B(F)}}var x=this.getLinkPoint(d,e,h,!1,l,b,c),G=0,L=0,N=0;if(l||h!==Ob||k)E=this.computeEndSegmentLength(d,e,h, +!1),N=this.getLinkDirection(d,e,x,h,!1,l,b,c),k&&(N+=l?0:30,0>p&&(N+=180)),0>N?N+=360:360<=N&&(N-=360),k&&(E+=Math.abs(p)),0===N?G=E:90===N?L=E:180===N?G=-E:270===N?L=-E:(G=E*Math.cos(N*Math.PI/180),L=E*Math.sin(N*Math.PI/180)),h.qd()&&k&&(E=e.gb(Wb,t.O()),F=t.ic(E.x+1E3*G,E.y+1E3*L),this.getLinkPointFromPoint(d,e,E,F,!1,x),t.B(E),t.B(F));e=q;if(l||g!==Ob||k)e=new C(q.x+r,q.y+s);c=x;if(l||h!==Ob||k)c=new C(x.x+G,x.y+L);!n&&!l&&g.qd()&&3k&&(m=-m),r=(0>h?-1:1)*m+q,s=l*(r-q)+v),q=a.x+2*g/3,v=a.y+2*h/3,x=q,G=v,J.I(h,0)?G=0h?-1:1)*m+q,G=l*(x-q)+v),this.Fo(),this.Ch(a),this.Yk(r,s),this.Yk(x,G),this.Ch(n),this.uf(0,this.getLinkPoint(b,c,Ob,!0,!1,d,e)),this.uf(3,this.getLinkPoint(d,e,Ob,!1,!1,b,c))):(a=d,d=this.getLinkPoint(b,c,Ob,!0,!1,a,e),e=this.getLinkPoint(a, +e,Ob,!1,!1,b,c),this.hasCurviness()?(h=e.x-d.x,b=e.y-d.y,c=this.computeCurviness(),a=d.x+h/2,n=d.y+b/2,g=a,k=n,J.I(b,0)?k=0c&&(g=-g),g=(0>b?-1:1)*g+a,k=h*(g-a)+n),this.Ch(d),this.Yk(g,k)):this.Ch(d),this.Ch(e)));return!0};function Lm(a,b){Math.abs(b.x-a.x)>Math.abs(b.y-a.y)?(b.x=b.x>=a.x?a.x+9E9:a.x-9E9,b.y=a.y):(b.y=b.y>=a.y?a.y+9E9:a.y-9E9,b.x=a.x);return b} +A.prototype.getLinkPointFromPoint=function(a,b,c,d,e,g){void 0===g&&(g=new C);if(null===a||null===b)return g.assign(c),g;a.zb()||(e=dm(a),null!==e&&e!==a&&(b=e.port));var h;a=null;if(null===b.ga)e=d.x,d=d.y,h=c.x,c=c.y;else{a=b.ga.he;e=1/(a.m11*a.m22-a.m12*a.m21);h=a.m22*e;var k=-a.m12*e,l=-a.m21*e,m=a.m11*e,n=e*(a.m21*a.dy-a.m22*a.dx),p=e*(a.m12*a.dx-a.m11*a.dy);e=d.x*h+d.y*l+n;d=d.x*k+d.y*m+p;h=c.x*h+c.y*l+n;c=c.x*k+c.y*m+p}b.Wo(e,d,h,c,g);a&&g.transform(a);return g}; +function Mm(a,b){var c=b.ee;null===c&&(c=new Nm,c.port=b,c.Ic=b.S,b.ee=c);return Om(c,a)} +A.prototype.getLinkPoint=function(a,b,c,d,e,g,h,k){void 0===k&&(k=new C);if(c.rd())return b.gb(c,k),k;if(c.dp()&&(c=Mm(this,b),null!==c)){k.assign(c.kp);if(e&&this.st===vm){var l=Mm(this,h);if(c.Gm=m.x&&a.x<=m.x+m.width?k.x=a.x:a.y>=m.y&&a.y<=m.y+m.height&&(k.y=a.y);t.B(c);t.B(l)}}return k}g=b.gb(Wb,t.O());c=null;this.ma>(e?6:2)?(h=d?this.n(1):this.n(this.ma-2),e&&(h=Lm(g,h.copy()))): +(c=t.O(),h=h.gb(Wb,c),e&&(h=Lm(g,h)));this.getLinkPointFromPoint(a,b,g,h,d,k);t.B(g);null!==c&&t.B(c);return k}; +A.prototype.getLinkDirection=function(a,b,c,d,e,g,h,k){a:if(d.rd())c=d.x>d.y?d.x>1-d.y?0:d.x<1-d.y?270:315:d.x1-d.y?90:d.x<1-d.y?180:135:0.5>d.x?225:0.5(g?6:2)?(k=e?this.n(1):this.n(this.ma-2),k=g?Lm(a,k.copy()):c):(d=t.O(),k=k.gb(Wb,d));c=Math.abs(k.x-a.x)>Math.abs(k.y-a.y)?k.x>=a.x?0:180:k.y>= +a.y?90:270;t.B(a);null!==d&&t.B(d)}g=lm;g=e?this.So:this.Lp;g===lm&&(g=e?b.So:b.Lp);switch(g){case mm:b=b.jl();c+=b;360<=c&&(c-=360);break;case lm:case Kj:b=b.jl();if(0===b)break;45<=b&&135>b?c+=90:135<=b&&225>b?c+=180:225<=b&&315>b&&(c+=270);360<=c&&(c-=360)}return c};A.prototype.computeEndSegmentLength=function(a,b,c,d){if(c.dp()&&(a=Mm(this,b),null!==a))return a.cw;a=NaN;a=d?this.ek:this.mk;isNaN(a)&&(a=d?b.ek:b.mk);isNaN(a)&&(a=10);return a}; +A.prototype.computeSpot=function(a){return a?Jm(this,this.Qc):Km(this,this.Ed)};function Jm(a,b){var c=a.lb;c.Fc()&&(void 0===b&&(b=a.Qc),null!==b&&(c=b.lb));return c===Pb?Ob:c}function Km(a,b){var c=a.mb;c.Fc()&&(void 0===b&&(b=a.Ed),null!==b&&(c=b.mb));return c===Pb?Ob:c}A.prototype.computeOtherPoint=function(a,b){var c=b.gb(Wb),d;d=b.ee;d=null!==d?Om(d,this):null;null!==d&&(c=d.kp);return c};A.prototype.computeShortLength=function(a){return a?Pm(this):Qm(this)}; +function Pm(a){var b=a.To;isNaN(b)&&(a=a.Qc,null!==a&&(b=a.To));return isNaN(b)?0:b}function Qm(a){var b=a.Mp;isNaN(b)&&(a=a.Ed,null!==a&&(b=a.Mp));return isNaN(b)?0:b} +A.prototype.ck=function(a,b,c,d,e,g){if(!1===this.Ze)return!1;void 0===b&&(b=null);void 0===c&&(c=null);var h=g;void 0===g&&(h=t.bh(),h.reset());h.multiply(this.transform);if(this.Fm(a,h))return Dl(this,b,c,e),void 0===g&&t.Se(h),!0;if(this.If(a,h)){var k=!1;if(!this.Jg)for(var l=this.za.length;l--;){var m=this.za.p[l];if(m.visible||m===this.Ub){var n=m.wa,p=this.Ga;if(!(n.x>p.width||n.y>p.height||0>n.x+n.width||0>n.y+n.height)){n=t.bh();n.set(h);if(m instanceof B)k=m.ck(a,b,c,d,e,n);else if(this.path=== +m){var k=m,q=a,r=d,p=n;if(!1===k.Ze)k=!1;else if(p.multiply(k.transform),r)b:{var s=q,v=p;if(k.Fm(s,v))k=!0;else{if(void 0===v&&(v=k.transform,s.Wj(k.wa))){k=!0;break b}var p=s.left,q=s.right,r=s.top,s=s.bottom,x=t.O(),E=t.O(),F=t.O(),G=t.bh();G.set(v);G.yA(k.transform);G.jA();E.x=q;E.y=r;E.transform(G);x.x=p;x.y=r;x.transform(G);v=!1;Kl(k,x,E,F)?v=!0:(x.x=q,x.y=s,x.transform(G),Kl(k,x,E,F)?v=!0:(E.x=p,E.y=s,E.transform(G),Kl(k,x,E,F)?v=!0:(x.x=p,x.y=r,x.transform(G),Kl(k,x,E,F)&&(v=!0))));t.Se(G); +t.B(x);t.B(E);t.B(F);k=v}}else k=k.Fm(q,p)}else k=Pj(m,a,d,n);k&&(null!==b&&(m=b(m)),m&&(null===c||c(m))&&e.add(m));t.Se(n)}}}void 0===g&&t.Se(h);return k||null!==this.background||null!==this.Tj}void 0===g&&t.Se(h);return!1};t.A(A,{ac:"isOrthogonal"},function(){return 2===(this.im.value&2)});t.A(A,{Si:"isAvoiding"},function(){return 4===(this.im.value&4)});A.prototype.computeCurve=function(){if(null===this.gi){var a=this.ac;this.gi=this.Qc===this.Ed&&!a}return this.gi?Rg:this.Ee}; +A.prototype.computeCorner=function(){if(this.Ee===Rg)return 0;var a=this.Wv;if(isNaN(a)||0>a)a=10;return a};A.prototype.computeCurviness=function(){var a=this.Ds;if(isNaN(a)){var b=this.cf;if(0!==b){var a=10,c=this.h;null!==c&&(a=c.lp);c=Math.abs(b);a=a/2+((c-1)/2|0)*a;0===c%2&&(a=-a);0>b&&(a=-a)}else a=10}return a};A.prototype.hasCurviness=function(){return!isNaN(this.Ds)||0!==this.cf&&!this.ac}; +A.prototype.adjustPoints=function(a,b,c,d){var e=this.xo;if(this.ac){if(e===Ek)return!1;e===Fk&&(e=Dk)}switch(e){case Ek:var g=this.n(a),h=this.n(c);if(!g.N(b)||!h.N(d)){var e=g.x,g=g.y,k=h.x-e,l=h.y-g,m=Math.sqrt(k*k+l*l);if(!J.I(m,0)){var n;J.I(k,0)?n=0>l?-Math.PI/2:Math.PI/2:(n=Math.atan(l/Math.abs(k)),0>k&&(n=Math.PI-n));var h=b.x,p=b.y,k=d.x-h,q=d.y-p,l=Math.sqrt(k*k+q*q);J.I(k,0)?q=0>q?-Math.PI/2:Math.PI/2:(q=Math.atan(q/Math.abs(k)),0>k&&(q=Math.PI-q));m=l/m;n=q-n;this.uf(a,b);for(a+=1;al?-Math.PI/2:Math.PI/2:(l=Math.atan(l/Math.abs(k)),0>k&&(l=Math.PI-l)),k=l+n,b*=m,this.Y(a,h+b*Math.cos(k),p+b*Math.sin(k)));this.uf(c,d)}}return!0;case Fk:g=this.n(a);p=this.n(c);if(!g.N(b)||!p.N(d)){e=g.x;g=g.y;h=p.x;p=p.y;m=(h-e)*(h-e)+(p-g)*(p-g);k=b.x;n=b.y;var l=d.x,q=d.y,r=0,s=1,r=0!==l-k?(q-n)/(l-k):9E9;0!==r&&(s=Math.sqrt(1+1/(r*r)));this.uf(a,b);for(a+=1;ab?0:45<=b&&135>b?90:135<=b&&225>b?180:270;d=-45<=d&&45>d?0:45<=d&&135>d?90:135<=d&&225>d?180:270;var h=e.wa.copy(),k=g.wa.copy();if(h.Q()&&k.Q()){h.Vg(8,8);k.Vg(8,8);h.$i(a);k.$i(c);var l,m;if(0===b)if(c.x>a.x||270===d&&c.ya.x||90===d&&c.y>a.y&&k.right>a.x)l=new C(c.x,a.y),m=new C(c.x,(a.y+c.y)/2),180===d?(l.x=this.computeMidOrthoPosition(a.x,c.x,!1),m.x=l.x,m.y=c.y):270===d&&c.ya.y?(l.x=a.xk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.right,m.x=l.x,m.y=c.y):0===d&&a.xk.top&&a.yh.bottom)180===d&&(k.Ia(a)||h.Ia(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(180===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=h.left&&c.x<=a.x||a.x<=k.right&&a.x>=c.x){if(90===d||270===d)l=new C(Math.max((a.x+c.x)/2,a.x),a.y),m=new C(l.x,c.y)}else l.y=270===d||(0===d||180===d)&&c.ya.y&&k.lefta.y?(l.x=a.x>k.right?this.computeMidOrthoPosition(a.x,k.right,!1):a.x>k.left&&(270===d&&a.yk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.left,m.x=l.x,m.y=c.y):180===d&&a.x>k.right&&a.y>k.top&&a.yh.bottom)0===d&&(k.Ia(a)||h.Ia(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(0===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=a.x||a.x>=k.left&&a.x<=c.x){if(90===d||270===d)l=new C(Math.min((a.x+c.x)/2,a.x),a.y),m=new C(l.x,c.y)}else l.y=270=== +d||(0===d||180===d)&&c.ya.y||180===d&&c.xa.y||0===d&&c.x>a.x&&k.bottom>a.y)l=new C(a.x,c.y),m=new C((a.x+c.x)/2,c.y),270===d?(l.y=this.computeMidOrthoPosition(a.y,c.y,!0),m.x=c.x,m.y=l.y):180===d&&c.xa.x?(l.y=a.yk.right)? +this.computeMidOrthoPosition(a.y,c.y,!0):k.bottom,m.x=c.x,m.y=l.y):90===d&&a.yk.left&&a.xh.right)270===d&&(k.Ia(a)||h.Ia(c))?l.x=this.computeMidOrthoPosition(a.x,c.x,!1):c.xa.x&&(270===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right, +Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=h.top&&c.y<=a.y||a.y<=k.bottom&&a.y>=c.y){if(0===d||180===d)l=new C(a.x,Math.max((a.y+c.y)/2,a.y)),m=new C(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xa.x&&k.top=a.x?(l.y=a.y>k.bottom?this.computeMidOrthoPosition(a.y,k.bottom,!0):a.y>k.top&&(180===d&&a.xk.right)?this.computeMidOrthoPosition(a.y,c.y,!0):k.top,m.x=c.x,m.y=l.y):270===d&&a.y>k.bottom&&a.x>k.left&&a.xh.right)90===d&&(k.Ia(a)||h.Ia(c))?l.x=this.computeMidOrthoPosition(a.x, +c.x,!1):c.xa.x&&(90===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right,Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=a.y||a.y>=k.top&&a.y<=c.y){if(0===d||180===d)l=new C(a.x,Math.min((a.y+c.y)/2,a.y)),m=new C(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xthis.ma)0===b||180===b?(d.x=a.x,d.y=c.y):(d.x=c.x,d.y=a.y),this.Y(2,d.x,d.y),this.C(3,d.x,d.y);else if(c=this.n(3),0===b||180===b)J.I(d.x,c.x)?(b=0===b?Math.max(d.x,a.x):Math.min(d.x,a.x),this.Y(2,b,a.y),this.Y(3,b,c.y)):J.I(d.y,c.y)? +(Math.abs(a.y-d.y)<=e.Bm/2&&(this.Y(2,d.x,a.y),this.Y(3,c.x,a.y)),this.C(2,d.x,a.y)):this.Y(2,a.x,d.y);else if(90===b||270===b)J.I(d.y,c.y)?(b=90===b?Math.max(d.y,a.y):Math.min(d.y,a.y),this.Y(2,a.x,b),this.Y(3,c.x,b)):J.I(d.x,c.x)?(Math.abs(a.x-d.x)<=e.Cm/2&&(this.Y(2,a.x,d.y),this.Y(3,a.x,c.y)),this.C(2,a.x,d.y)):this.Y(2,d.x,a.y);a=!0}else a=!1}else a=!1;a||(this.Ch(l),this.Ch(m))}}; +A.prototype.computeMidOrthoPosition=function(a,b){if(this.hasCurviness()){var c=this.computeCurviness();return(a+b)/2+c}return(a+b)/2};function Ef(a){if(!a.Si)return!1;var b=a.points.p,c=b.length;if(4>c)return!1;a=ia(a.h,!0,a);for(var d=1;dVm&&Tm(b,m,n)===l-Wm;)c=m,d=n,0===e?m+=h:90===e?n+=k:180===e?m-=h:n-=k,l-=Wm;if(g){if(l>Vm)if(180===e||0===e)c=Math.floor(c/h)*h+h/2;else if(90===e||270===e)d=Math.floor(d/k)*k+k/2}else c=Math.floor(c/h)*h+h/2,d=Math.floor(d/k)*k+k/2;l>Vm&&(g=e,m=c,n=d,0===e?(g=90,n+=k):90===e?(g=180,m-=h):180===e?(g=270,n-=k):270===e&&(g=0,m+=h),Tm(b,m,n)===l-Wm?Um(a,b,m,n,g,!1):(m=c,n=d,0===e?(g=270,n-= +k):90===e?(g=0,m+=h):180===e?(g=90,n+=k):270===e&&(g=180,m-=h),Tm(b,m,n)===l-Wm&&Um(a,b,m,n,g,!1)));a.Yk(c,d)}A.prototype.findClosestSegment=function(a){f&&t.l(a,C,A,"findClosestSegment:p");var b=a.x;a=a.y;for(var c=this.n(0),d=this.n(1),e=cb(b,a,c.x,c.y,d.x,d.y),g=0,h=1;ha){var b=new M(Oc),c=new Pc(0,0);b.ub.add(c);return b}var d=this.n(0).copy(),e=d.copy(),g=this.computeCurve();if(g===Rg&&3<=a&&!J.Ka(this.en,0))if(3===a)var h=this.n(1),b=Math.min(d.x,h.x),c=Math.min(d.y,h.y),h=this.n(2),b=Math.min(b,h.x),c=Math.min(c,h.y);else{if(this.ac)for(h=0;h=a&&(h=a-1),k=this.n(h),e.x=Math.min(k.x,e.x),e.y=Math.min(k.y,e.y); +b=e.x;c=e.y}else{for(h=0;hE?r>q?(v.x=F-L,v.y=q-L,x.x=F+s,x.y=q+s):(v.x=F-L,v.y=q+L,x.x=F+s,x.y=q-s):r>q?(v.x=F+L,v.y=q-L,x.x= +F-s,x.y=q+s):(v.x=F+L,v.y=q+L,x.x=F-s,x.y=q-s));J.Ka(E,F)&&J.Ka(q,r)&&(q>p?(G>F?(v.x=F-L,v.y=q-L,x.x=F+s):(v.x=F+L,v.y=q-L,x.x=F-s),x.y=q+s):(G>F?(v.x=F-L,v.y=q+L,x.x=F+s):(v.x=F+L,v.y=q+L,x.x=F-s),x.y=q-s));if(J.Ka(E,F)&&J.Ka(F,G)||J.Ka(p,q)&&J.Ka(q,r))E=0.5*(E+G),p=0.5*(p+r),v.x=E,v.y=p,x.x=E,x.y=p;1===h?(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y)):2===h&&J.Ka(e.x,this.n(0).x)&&J.Ka(e.y,this.n(0).y)&&(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y));P(l,g.x-b,g.y-c,k.x-b,k.y-c,m.x-b,m.y-c);d.set(k);g.set(a);e=m}}h= +e.x;e=e.y;d=this.n(this.ma-1);h=0.5*(h+d.x);e=0.5*(e+d.y);P(l,a.x-b,a.y-c,h-b,e-c,d.x-b,d.y-c)}else for(h=3;h=a&&(h=a-1),d=this.n(h-1),k=this.n(h),h===a-1&&0!==Qm(this)&&(k=k.copy(),Xm(this,k,!1,J.ok)),P(l,e.x-b,e.y-c,d.x-b,d.y-c,k.x-b,k.y-c);else{e=t.O();e.assign(this.n(0));for(h=1;h=a-1){e!==n&&(0!==Qm(this)&&(n=n.copy(),Xm(this,n,!1,J.ok)),$m(this,l,-b,-c,e,n));break}h=Ym(this,n,h+1,hm.x?n.x-E:n.x+E,G=v.y>n.y?n.y+p:n.y-p,$m(this,d,g,k,m,new C(s,F)),cd(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):J.I(m.x,n.x)&&J.I(n.y,v.y)?(E=this.computeCorner(),p=Math.min(E,Math.abs(n.y-m.y)/2),p=E=Math.min(p,Math.abs(v.x-n.x)/2),J.I(E,0)?($m(this,d,g,k,m,n),x.assign(n)):(s=n.x,G=F=n.y,F=n.y>m.y?n.y-p:n.y+p,q=v.x>n.x?n.x+E: +n.x-E,$m(this,d,g,k,m,new C(s,F)),cd(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):($m(this,d,g,k,m,n),x.assign(n))}t.B(e)}b=l.s;t.v(l)}return b};function Zm(a,b,c,d){a=c-a;if(isNaN(a)||Infinity===a||-Infinity===a)return NaN;0>a&&(a=-a);b=d-b;if(isNaN(b)||Infinity===b||-Infinity===b)return NaN;0>b&&(b=-b);return J.Ka(a,0)?b:J.Ka(b,0)?a:Math.sqrt(a*a+b*b)} +function Xm(a,b,c,d){var e=a.ma;if(!(2>e))if(c){var g=a.n(1);c=g.x-d.x;d=g.y-d.y;g=Zm(b.x,b.y,c,d);0!==g&&(e=2===e?0.5*g:g,a=Pm(a),a>e&&(a=e),c=a*(c-b.x)/g,a=a*(d-b.y)/g,b.x+=c,b.y+=a)}else g=a.n(e-2),c=g.x-d.x,d=g.y-d.y,g=Zm(b.x,b.y,c,d),0!==g&&(e=2===e?0.5*g:g,a=Qm(a),a>e&&(a=e),c=a*(b.x-c)/g,a=a*(b.y-d)/g,b.x-=c,b.y-=a)} +function Ym(a,b,c,d){for(var e=a.ma,g=b;J.Ka(b.x,g.x)&&J.Ka(b.y,g.y);){if(c>=e)return e-1;g=a.n(c++)}if(!J.Ka(b.x,g.x)&&!J.Ka(b.y,g.y))return c-1;for(var h=g;J.Ka(b.x,g.x)&&J.Ka(g.x,h.x)&&(!d||(b.y>=g.y?g.y>=h.y:g.y<=h.y))||J.Ka(b.y,g.y)&&J.Ka(g.y,h.y)&&(!d||(b.x>=g.x?g.x>=h.x:g.x<=h.x));){if(c>=e)return e-1;h=a.n(c++)}return c-2} +function $m(a,b,c,d,e,g){if(Gm(a)){var h=new H("number"),k=an(a,e,g,h),l=e.x,l=e.y;if(0p-10)m--,p=Math.max(q-5,g.x);else break;q=g.y-10+d;n=p+c;p=g.y+d;a.Ee===Ig?O(b,n,p,!1,!1):P(b,l,q,n,q,n,p)}else if(J.I(e.x,g.x))if(e.yp-10)m--,p=Math.max(q-5,g.y);else break;q=g.x-10+c;n=g.x+c;p+=d;a.Ee===Ig?O(b,n,p,!1,!1):P(b,q,l,q,p,n,p)}}b.lineTo(g.x+c,g.y+d)} +function an(a,b,c,d){var e=a.h;if(null===e)return 0;Math.min(b.x,c.x);Math.min(b.y,c.y);Math.max(b.x,c.x);Math.max(b.y,c.y);for(e=e.Um;e.next();){var g=e.value;if(null!==g&&g.visible)for(var g=g.cb.p,h=g.length,k=0;k=h.x&&Math.min(h.y,k.y)<=m.y&&Math.max(h.y,k.y)>=m.y&&!J.I(h.y,k.y)){p.x=h.x;p.y=m.y;m=!0;break a}}else if(J.I(h.y,k.y)&&Math.min(m.y,n.y)<=h.y&&Math.max(m.y,n.y)>=h.y&&Math.min(h.x,k.x)<=m.x&&Math.max(h.x,k.x)>=m.x&&!J.I(h.x,k.x)){p.x=m.x;p.y=h.y;m=!0;break a}p.x=0;p.y=0;m=!1}m&&(J.I(a.y,b.y)?c.add(l.x):c.add(l.y));t.B(l)}} +t.A(A,{Ls:"firstPickIndex"},function(){return 2>=this.ma?0:this.ac||Jm(this)!==Ob?1:0});t.A(A,{ww:"lastPickIndex"},function(){var a=this.ma;return 0===a?0:2>=a?a-1:this.ac||Km(this)!==Ob?a-2:a-1});function Gm(a){a=a.Ee;return a===Gg||a===Ig}function Im(a,b){if(b||Gm(a)){var c=a.h;null===c||c.En.contains(a)||null===a.Uy||c.En.add(a,a.Uy)}} +function Kg(a,b){var c=a.layer;if(null!==c&&c.visible&&!c.pc){var d=c.h;if(null!==d)for(var e=!1,d=d.Um;d.next();){var g=d.value;if(g.visible)if(g===c)for(var e=!0,h=!1,g=g.cb.p,k=g.length,l=0;lb.links.count)1===b.links.count&&(c=b.links.p[0],c.rn=null,c.cf=0,c.$b()),c=b.tp,null!==b&&null!==c.fh&&c.fh.remove(b),c=b.gt,null!==b&&null!==c.fh&&c.fh.remove(b);else for(c=Math.abs(c),a=0===c%2,b=b.links.k;b.next();){var d=b.value,e=Math.abs(d.cf),g=0===e%2;e>c&&a===g&&(d.cf=0=a.width||0>=a.height)){var b=a.y,c=a.x+a.width,d=a.y+a.height;this.Bf=Math.floor((a.x-this.vd)/this.vd)*this.vd;this.Cf=Math.floor((b-this.kd)/this.kd)*this.kd;this.hr=Math.ceil((c+2*this.vd)/this.vd)*this.vd;this.ir=Math.ceil((d+2*this.kd)/this.kd)*this.kd;a=1+(Math.ceil((this.hr-this.Bf)/this.vd)|0);b=1+(Math.ceil((this.ir-this.Cf)/this.kd)|0);if(null===this.bc||this.sm=Vm&&(a.bc[b][c]|=la)} +function Rm(a,b,c,d,e){if(b>a.hr||b+da.ir||c+eb&&(d+=b,b=0);0>c&&(g+=c,c=0);if(0>d||0>g)return!0;e=Math.min(b+d-1,a.sm)|0;for(d=Math.min(c+g-1,a.tm)|0;b<=e;b++)for(g=c;g<=d;g++)if(a.bc[b][g]===ja)return!1;return!0} +function fn(a,b,c,d,e,g,h,k,l){if(!(bh||cl)){var m,n;m=b|0;n=c|0;var p=a.bc[m][n];if(p>=Vm&&p=a.bc[m][n]);)a.bc[m][n]=p,p+=Wm,e?n+=d:m+=d;m=e?n:m;if(e)if(0m;c+=d)fn(a,b,c,1,!e,g,h,k,l),fn(a,b,c,-1,!e,g,h,k,l);else if(0m;b+=d)fn(a,b,c,1,!e,g,h,k,l),fn(a,b,c,-1,!e,g,h, +k,l)}}function gn(a,b,c,d,e,g,h,k,l,m,n){for(var p=b|0,q=c|0,r=a.bc[p][q];0===r&&p>k&&pm&&q=Math.abs(p-d)&&1>=Math.abs(q-e))return a.abort=!0,0;p=b|0;q=c|0;r=a.bc[p][q];b=Vm;for(a.bc[p][q]=b;0===r&&p>k&&pm&&q=Math.abs(h-l)&&1>=Math.abs(k-m))a.abort=!0;else{var n=g.x;b=g.y;d=g.x+g.width;var p=g.y+g.height,n=n-a.Bf,n=n/a.vd;b-=a.Cf;b/=a.kd;d-=a.Bf;d/=a.vd;p-=a.Cf;p/=a.kd;g=Math.max(0,Math.min(a.sm,n|0));d=Math.min(a.sm,Math.max(0,d|0));b=Math.max(0,Math.min(a.tm,b|0));var p=Math.min(a.tm,Math.max(0,p|0)),h=h|0,k=k|0,l=l|0, +m=m|0,n=h,q=k,r=0===c||90===c?1:-1;(c=90===c||270===c)?q=gn(a,h,k,l,m,r,c,g,d,b,p):n=gn(a,h,k,l,m,r,c,g,d,b,p);if(!a.abort){a:{c=0===e||90===e?1:-1;e=90===e||270===e;for(var r=l|0,s=m|0,v=a.bc[r][s];0===v&&r>g&&rb&&s=Math.abs(r-h)&&1>=Math.abs(s-k)){a.abort=!0;break a}r=l|0;s=m|0;v=a.bc[r][s];for(a.bc[r][s]=dn;0===v&&r>g&&rb&&s=c?180:0}a=180*Math.atan2(a.height,a.width)/Math.PI;switch(b){case t.hd|t.Fd:return c>a&&c<=180+a?180:270;case t.Fd|t.ud:return c>180-a&&c<=360-a?270:0;case t.ud|t.td:return c>a&&c<=180+a?90:0;case t.td|t.hd:return c>180-a&&c<=360-a?180:90;case t.hd|t.Fd|t.ud:return 90180+a&&c<=360- +a?270:0;case t.Fd|t.ud|t.td:return 180a&&180>=c?90:0;case t.ud|t.td|t.hd:return c>a&&c<=180-a?90:c>180-a&&270>=c?180:0;case t.td|t.hd|t.Fd:return c>180-a&&c<=180+a?180:c>180+a?270:90}d&&b!==(t.hd|t.Fd|t.ud|t.td)&&(c-=15,0>c&&(c+=360));return c>a&&c<180-a?90:c>=180-a&&c<=180+a?180:c>180+a&&c<360-a?270:0} +function Om(a,b){var c=a.rg;if(0===c.length){if(!a.ft){c=a.ft;a.ft=!0;var d=a.Ic.Dd,e=a.rg.length=0,g=a.port.gb(Tb,t.O()),h=a.port.gb($b,t.O()),k=t.lk(g.x,g.y,0,0);k.$i(h);t.B(g);t.B(h);g=t.ic(k.x+k.width/2,k.y+k.height/2);for(d=d.k;d.next();)if(h=d.value,h.zb()){var l=Ob,l=h.Qc===a.port?Jm(h,a.port):Km(h,a.port);if(l.dp()){var m;m=h.Qc===a.port?h.Ed:h.Qc;if(null!==m){var n=m.S;if(null!==n){m=h.computeOtherPoint(n,m);var n=g.Li(m),l=hn(k,l,n,h.ac),p;0===l?(p=t.ud,180b.Ie?1:a.angleb.angle?1:0}; +Nm.prototype.computeEndSegmentLength=function(a){var b=a.link,c=b.computeEndSegmentLength(this.Ic,this.port,Ob,b.Qc===this.port),d=a.Zo;if(0>d)return c;var e=a.Gm;if(1>=e||!b.ac)return c;var b=a.Cw,g=a.kp;if(a.Ie===t.hd||a.Ie===t.td)d=e-1-d;return((a=a.Ie===t.hd||a.Ie===t.ud)?b.ye&&(e=k.right);k.bottom>g&&(g=k.bottom)}}isFinite(c)&&isFinite(d)?a.q(c,d,e-c,g-d):(b=b.location,c=this.padding,a.q(b.x+c.left,b.y+c.top,0,0));return a}; +t.g(Wg,"padding",Wg.prototype.padding);t.defineProperty(Wg,{padding:"padding"},function(){return this.Le},function(a){"number"===typeof a?(0>a&&t.ha(a,">= 0",Wg,"padding"),a=new pb(a)):(t.l(a,pb,Wg,"padding"),0>a.left&&t.ha(a.left,">= 0",Wg,"padding:val.left"),0>a.right&&t.ha(a.right,">= 0",Wg,"padding:val.right"),0>a.top&&t.ha(a.top,">= 0",Wg,"padding:val.top"),0>a.bottom&&t.ha(a.bottom,">= 0",Wg,"padding:val.bottom"));var b=this.Le;b.N(a)||(this.Le=a=a.Z(),this.i("padding",b,a))}); +function xe(){0=c-1?(h=0,e=d,g+=k+20,k=0):h++}null!==a&&a.De("Layout")}this.of=!0};xe.prototype.zA=function(a){return!a.location.Q()||a instanceof z&&a.zC?!0:!1};function nn(a,b,c,d,e,g,h,k){for(c=c.k;c.next();){var l=c.value;d&&!l.ep||e&&!e(l)||l.canLayout()&&(g&&l instanceof y?l.Ih||(l instanceof z&&null===l.Tb?nn(a,b,l.Hc,!1,e,g,h,k):b.add(l)):h&&l instanceof A?b.add(l):!k||!l.Ud()||l instanceof y||b.add(l))}} +t.g(xe,"arrangementOrigin",xe.prototype.zd);t.defineProperty(xe,{zd:"arrangementOrigin"},function(){return this.bq},function(a){this.bq.N(a)||(t.l(a,C,xe,"arrangementOrigin"),this.bq.assign(a),this.K())});xe.prototype.initialOrigin=xe.prototype.iA=function(a){var b=this.group;if(null!==b){var c=b.location;if(isNaN(c.x)||isNaN(c.y))return a;a=b.placeholder;null!==a?(c=a.gb(Tb),c.x+=a.padding.left,c.y+=a.padding.top):c=b.position.copy();return c}return a}; +function Ca(){t.zc(this);this.Ld=null;this.clear()}t.ia("LayoutNetwork",Ca);Ca.prototype.clear=function(){if(this.vertexes)for(var a=this.vertexes.k;a.next();){var b=a.value;b.clear();b.network=null}if(this.edges)for(a=this.edges.k;a.next();)b=a.value,b.clear(),b.network=null;this.vertexes=new ua(Da);this.edges=new ua(Ea);this.CA=new sa(y,Da);this.pA=new sa(A,Ea)};Ca.prototype.toString=function(){return"LayoutNetwork"+(null!==this.Tb?"("+this.Tb.toString()+")":"")};t.A(Ca,{Tb:"layout"},function(){return this.Ld}); +function mn(a,b){f&&null!==b&&t.l(b,xe,Ca,"setLayout");a.Ld=b}Ca.prototype.createVertex=function(){return new Da};Ca.prototype.createEdge=function(){return new Ea}; +Ca.prototype.addParts=Ca.prototype.ss=function(a,b){if(null!==a){void 0===b&&(b=!1);t.j(b,"boolean",Ca,"addParts:toplevelonly");for(var c=a.k;c.next();){var d=c.value;if(d instanceof y&&(!b||d.ep)&&d.canLayout()&&!d.Ih)if(d instanceof z&&null===d.Tb)this.ss(d.Hc,!1);else if(null===this.Nm(d)){var e=this.createVertex();e.Ic=d;this.Zk(e)}}for(c.reset();c.next();)if(d=c.value,d instanceof A&&(!b||d.ep)&&d.canLayout()&&null===this.dw(d)){var g=d.da,e=d.ja;g!==e&&(g=this.ew(g),e=this.ew(e),null!==g&&null!== +e&&this.Vm(g,e,d))}}};Ca.prototype.findGroupVertex=Ca.prototype.ew=function(a){if(null===a)return null;a=dm(a);if(null===a)return null;var b=this.Nm(a);if(null!==b)return b;a=a.fb;return null!==a&&(b=this.Nm(a),null!==b)?b:null};Ca.prototype.addVertex=Ca.prototype.Zk=function(a){if(null!==a){f&&t.l(a,Da,Ca,"addVertex:vertex");this.vertexes.add(a);var b=a.Ic;null!==b&&this.CA.add(b,a);a.network=this}}; +Ca.prototype.addNode=Ca.prototype.wo=function(a){if(null===a)return null;f&&t.l(a,y,Ca,"addNode:node");var b=this.Nm(a);null===b&&(b=this.createVertex(),b.Ic=a,this.Zk(b));return b};Ca.prototype.deleteVertex=Ca.prototype.LD=function(a){if(null!==a&&(f&&t.l(a,Da,Ca,"deleteVertex:vertex"),on(this,a))){for(var b=a.$e,c=b.count-1;0<=c;c--){var d=b.qa(c);this.Ko(d)}b=a.Qe;for(c=b.count-1;0<=c;c--)d=b.qa(c),this.Ko(d)}}; +function on(a,b){if(null===b)return!1;var c=a.vertexes.remove(b);c&&(a.CA.remove(b.Ic),b.network=null);return c}Ca.prototype.deleteNode=function(a){null!==a&&(f&&t.l(a,y,Ca,"deleteNode:node"),a=this.Nm(a),null!==a&&this.LD(a))};Ca.prototype.findVertex=Ca.prototype.Nm=function(a){if(null===a)return null;f&&t.l(a,y,Ca,"findVertex:node");return this.CA.Ba(a)}; +Ca.prototype.addEdge=Ca.prototype.vo=function(a){if(null!==a){f&&t.l(a,Ea,Ca,"addEdge:edge");this.edges.add(a);var b=a.link;null!==b&&null===this.dw(b)&&this.pA.add(b,a);b=a.toVertex;null!==b&&b.dD(a);b=a.fromVertex;null!==b&&b.bD(a);a.network=this}}; +Ca.prototype.addLink=function(a){if(null===a)return null;f&&t.l(a,A,Ca,"addLink:link");var b=a.da,c=a.ja,d=this.dw(a);null===d?(d=this.createEdge(),d.link=a,null!==b&&(d.fromVertex=this.wo(b)),null!==c&&(d.toVertex=this.wo(c)),this.vo(d)):(d.fromVertex=null!==b?this.wo(b):null,d.toVertex=null!==c?this.wo(c):null);return d};Ca.prototype.deleteEdge=Ca.prototype.Ko=function(a){if(null!==a){f&&t.l(a,Ea,Ca,"deleteEdge:edge");var b=a.toVertex;null!==b&&b.KD(a);b=a.fromVertex;null!==b&&b.JD(a);pn(this,a)}}; +function pn(a,b){null!==b&&a.edges.remove(b)&&(a.pA.remove(b.link),b.network=null)}Ca.prototype.deleteLink=function(a){null!==a&&(f&&t.l(a,A,Ca,"deleteLink:link"),a=this.dw(a),null!==a&&this.Ko(a))};Ca.prototype.findEdge=Ca.prototype.dw=function(a){if(null===a)return null;f&&t.l(a,A,Ca,"findEdge:link");return this.pA.Ba(a)}; +Ca.prototype.linkVertexes=Ca.prototype.Vm=function(a,b,c){if(null===a||null===b)return null;f&&(t.l(a,Da,Ca,"linkVertexes:fromVertex"),t.l(b,Da,Ca,"linkVertexes:toVertex"),null!==c&&t.l(c,A,Ca,"linkVertexes:link"));if(a.network===this&&b.network===this){var d=this.createEdge();d.link=c;d.fromVertex=a;d.toVertex=b;this.vo(d);return d}return null}; +Ca.prototype.reverseEdge=Ca.prototype.Jw=function(a){if(null!==a){f&&t.l(a,Ea,Ca,"reverseEdge:edge");var b=a.fromVertex,c=a.toVertex;null!==b&&null!==c&&(b.JD(a),c.KD(a),a.Jw(),b.dD(a),c.bD(a))}};Ca.prototype.deleteSelfEdges=Ca.prototype.$v=function(){for(var a=t.Cb(),b=this.edges.k;b.next();){var c=b.value;c.fromVertex===c.toVertex&&a.push(c)}b=a.length;for(c=0;cd?1:0):1:null!==d?-1:0}; +Da.smartComparer=function(a,b){f&&t.l(a,Da,Da,"smartComparer:m");f&&t.l(b,Da,Da,"smartComparer:n");if(null!==a){if(null!==b){var c=a.nd,d=b.nd;if(null!==c){if(null!==d){var c=c.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=d.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=d&&0>=a&&(d=1);var e=this.spacing.width;isFinite(e)||(e=0);var g=this.spacing.height;isFinite(g)||(g=0);b.rc("Layout");switch(this.alignment){case Pk:var h= +Math.max(this.bl.width,1);if(!isFinite(h))for(var k=h=0;kd-1||0a)v=0,r=q,s+=x,x=0;x=Math.max(x,F);switch(p){case Nk:m=-m.width;break;default:m=0}l.moveTo(r+m,s);switch(p){case Nk:r-=E;break;default:r+=E}v++}break;case Ok:h=Math.max(this.bl.width,1);k=x=v=0;l=t.O();for(n=0;nd-1||0a){for(L=0;Ld?1:0}; +Dj.smartComparer=function(a,b){f&&t.l(a,w,Dj,"standardComparer:a");f&&t.l(b,w,Dj,"standardComparer:b");if(null!==a){if(null!==b){var c=a.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=b.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=a.count)1===a.count&&(a=a.eb(),a.Fa=0,a.Sa=0);else{var b=new H(wn);b.Me(a.k);a=new H(wn);var c=new H(wn),b=this.sort(b);a=new H(wn);var c=new H(wn),d=this.$x,e=this.ZB,g=this.wd,h=this.Gn,k=this.ay,l=this.xq,m=this.Ek,n=this.UC,p=this.jg,q=this.bu,d=this.Oe,e=this.ht,g= +this.bF;if(!isFinite(g)||0>=g)g=NaN;h=this.iD;if(!isFinite(h)||0>=h)h=1;k=this.yg;isFinite(k)||(k=0);l=this.Th;if(!isFinite(l)||360l)l=360;m=this.spacing;isFinite(m)||(m=NaN);d===cl&&e===dl?d=bl:d===cl&&e!==dl&&(e=dl,d=this.Oe);if((this.direction===Wk||this.direction===Xk)&&this.sorting!==Vk){for(var r=0;!(r>=b.length);r+=2){a.add(b.qa(r));if(r+1>=b.length)break;c.add(b.qa(r+1))}this.direction===Wk?(this.Oe===cl&&a.reverse(),b=new H(wn),b.Me(a),b.Me(c)):(this.Oe===cl&&c.reverse(),b=new H(wn), +b.Me(c),b.Me(a))}for(var s=b.length,v=n=0,r=0;rl&&(0===r||r===b.length-1)&&(x/=2);n+=x;v++}if(isNaN(g)||d===cl){isNaN(m)&&(m=6);if(d!==bl&&d!==cl){x=-Infinity;for(r=0;rg?(g=r,p=g*h):q=v/(360<=l?s:s-1)}this.$x=d;this.ZB=e;this.wd=g;this.Gn=h;this.ay=k;this.xq=l;this.Ek=m;this.UC=n;this.jg=p;this.bu=q;c=[b,a,c];b=c[0];a=c[1];c=c[2];d=this.$x;e=this.wd;h=this.ay;k=this.xq;l=this.Ek;m=this.jg;n=this.bu;if(this.direction!==Wk&&this.direction!==Xk||d!==cl)if(this.direction===Wk||this.direction===Xk){g=0;switch(d){case al:g=180*An(this,e,m,h,n)/Math.PI;break;case bl:n=b=0;g=a.eb();null!==g&&(b=xn(g,Math.PI/2));g=c.eb();null!== +g&&(n=xn(g,Math.PI/2));g=180*An(this,e,m,h,l+(b+n)/2)/Math.PI;break;case $k:g=k/b.length}if(this.direction===Wk){switch(d){case al:Bn(this,a,h,Zk);break;case bl:Cn(this,a,h,Zk);break;case $k:Dn(this,a,k/2,h,Zk)}switch(d){case al:Bn(this,c,h+g,Yk);break;case bl:Cn(this,c,h+g,Yk);break;case $k:Dn(this,c,k/2,h+g,Yk)}}else{switch(d){case al:Bn(this,c,h,Zk);break;case bl:Cn(this,c,h,Zk);break;case $k:Dn(this,c,k/2,h,Zk)}switch(d){case al:Bn(this,a,h+g,Yk);break;case bl:Cn(this,a,h+g,Yk);break;case $k:Dn(this, +a,k/2,h+g,Yk)}}}else switch(d){case al:Bn(this,b,h,this.direction);break;case bl:Cn(this,b,h,this.direction);break;case $k:Dn(this,b,k,h,this.direction);break;case cl:En(this,b,k,h,this.direction)}else En(this,b,k,h-k/2,Yk)}this.updateParts();this.network=null;this.of=!0}; +function Dn(a,b,c,d,e){var g=a.xq,h=a.wd;a=a.jg;d=d*Math.PI/180;c=c*Math.PI/180;for(var k=b.length,l=0;lc){for(g=d+(e===Yk?g:-g);0>g;)g+=360;g%=360;180=n.length-1)break;var p=Hn(a,l,m,n,g,e);p[0]||(p=In(a,l,m,n,g,e));l=p[1];m=p[2]}a.fm++;if(!(23Math.abs(r)?Math.abs(l-g)<(n[0].width+n[n.length-1].width)/2&&(h=0):h=0Math.abs(q)?0:q;q=!1;q=Math.abs(g)>Math.abs(p)?0p:0l.Uo||Math.abs(h)h&&0a.fm?a.wd-h/(2*Math.PI):5>n.length&&10=n.length-1)break;var q=Hn(a,l,m,n,p,e);q[0]||(q=In(a,l,m,n,p,e));l=q[1];m=q[2]}a.fm++;if(!(23a.fm?a.wd-g/(2*Math.PI):a.wd-(0h){l=b-a;if(l<-h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(l=b-a,l<-h){l=b+a;if(l>h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}m=Math.sqrt(1-Math.min(1,l*l/(h*h)))*k;0>c!==n&&(m=-m);b=Math.abs(c-m)>(d[e].height+d[e+1].height)/2?[!1]:[!0];b[1]=l;b[2]=m;return b} +function In(a,b,c,d,e,g){var h=a.wd,k=a.jg,l=0,m=0;a=(d[e].height+d[e+1].height)/2+a.Ek;var n=!1;if(0<=b!==(g===Yk)){if(m=c-a,m<-k){m=c+a;if(m>k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(m=c+a,m>k){m=c-a;if(m<-k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}l=Math.sqrt(1-Math.min(1,m*m/(k*k)))*h;0>b!==n&&(l=-l);b=Math.abs(b-l)>(d[e].width+d[e+1].width)/2?[!1]:[!0];b[1]=l;b[2]=m;return b}function un(){this.Uo=-Infinity;this.Op=this.kn=null} +un.prototype.commit=function(a){if(null!==this.kn&&null!==this.Op)for(var b=0;bMath.abs(a.Gn-1))return void 0!==d&&void 0!==e?e*b:2*Math.PI*b;a=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c;var h=0,k;k=void 0!==d&&void 0!==e?e/(g+1):Math.PI/(2*(g+1));for(var l=0;l<=g;l++)var m=Math.sin(void 0!==d&&void 0!==e?d+l*e/g:l*Math.PI/(2*g)),h=h+Math.sqrt(1-a*a*m*m)*k;return void 0!==d&&void 0!==e?(b>c?b:c)*h:4*(b>c?b:c)*h}function yn(a,b,c,d,e){a=void 0!==d&&void 0!==e?zn(a,1,c,d,e):zn(a,1,c);return b/a} +function An(a,b,c,d,e){if(0.001>Math.abs(a.Gn-1))return e/b;var g=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c,h=0;a=2*Math.PI/(700*a.network.vertexes.count);b>c&&(d+=Math.PI/2);for(var k=0;;k++){var l=Math.sin(d+k*a),h=h+(b>c?b:c)*Math.sqrt(1-g*g*l*l)*a;if(h>=e)return k*a}return 0} +Qk.prototype.sort=function(a){switch(this.sorting){case Tk:break;case Uk:a.reverse();break;case Rk:a.sort(this.comparer);break;case Sk:a.sort(this.comparer);a.reverse();break;case Vk:for(var b=[],c=0;ce&&(e=k,g=h)}else for(h=0;he&&(e=k,g=h);d.add(a.qa(g));b[g]=-1;g=a.qa(g);e=g.hc;for(g=g.Zb;e.next();)h=e.value,h=h.fromVertex,h=a.indexOf(h),0> +h||0<=b[h]&&b[h]++;for(;g.next();)h=g.value,h=h.toVertex,h=a.indexOf(h),0>h||0<=b[h]&&b[h]++}a=[];for(b=0;ba[b].indexOf(m)&&a[b].push(m);for(;e.next();)l=e.value,m=d.indexOf(l.fromVertex),m!==b&&0>a[b].indexOf(m)&&a[b].push(m)}k=[];for(b=0;ba[c[q]].indexOf(c[q===c.length-1?0:q+1])&&x.push(q===c.length-1?0:q+1);if(0===x.length)for(q=0;qN.indexOf(da)||RN.indexOf(da)||R=E?m+1:m)),G+=m=E&&m++,L>=E&&L++,m>L&&(N=L,L=m,m=N),L-m<(c.length+2)/2===(mr||r===m||(v=r>m?r-m:m-r,s+=rp-v?1:-1);c.splice(0>s?m:m+1,0,b);e.splice(k,1);k--}else n=!1;if(n)break;else c.push(e[0]),e.splice(0,1)}for(b=0;b=a?a:360,this.K())});t.g(Qk,"arrangement",Qk.prototype.Oe);t.defineProperty(Qk,{Oe:"arrangement"},function(){return this.jd},function(a){this.jd!==a&&(f&&t.l(a,oa,Qk,"arrangement"),a===cl||a===bl||a===al||a===$k)&&(this.jd=a,this.K())});t.g(Qk,"direction",Qk.prototype.direction); +t.defineProperty(Qk,{direction:"direction"},function(){return this.sa},function(a){this.sa!==a&&(f&&t.l(a,oa,Qk,"direction"),a===Yk||a===Zk||a===Wk||a===Xk)&&(this.sa=a,this.K())});t.g(Qk,"sorting",Qk.prototype.sorting);t.defineProperty(Qk,{sorting:"sorting"},function(){return this.xh},function(a){this.xh!==a&&(f&&t.l(a,oa,Qk,"sorting"),a===Tk||a===Uk||a===Rk||Sk||a===Vk)&&(this.xh=a,this.K())});t.g(Qk,"comparer",Qk.prototype.comparer); +t.defineProperty(Qk,{comparer:"comparer"},function(){return this.ih},function(a){this.ih!==a&&(f&&t.j(a,"function",Qk,"comparer"),this.ih=a,this.K())});t.g(Qk,"spacing",Qk.prototype.spacing);t.defineProperty(Qk,{spacing:"spacing"},function(){return this.yh},function(a){this.yh!==a&&(this.yh=a,this.K())});t.g(Qk,"nodeDiameterFormula",Qk.prototype.ht); +t.defineProperty(Qk,{ht:"nodeDiameterFormula"},function(){return this.vr},function(a){this.vr!==a&&(f&&t.l(a,oa,Qk,"nodeDiameterFormula"),a===el||a===dl)&&(this.vr=a,this.K())});t.A(Qk,{MG:"actualXRadius"},function(){return this.wd});t.A(Qk,{NG:"actualYRadius"},function(){return this.jg});t.A(Qk,{nJ:"actualSpacing"},function(){return this.Ek});t.A(Qk,{LG:"actualCenter"},function(){return isNaN(this.zd.x)||isNaN(this.zd.y)?new C(0,0):new C(this.zd.x+this.MG,this.zd.y+this.NG)});var bl; +Qk.ConstantSpacing=bl=t.w(Qk,"ConstantSpacing",0);var al;Qk.ConstantDistance=al=t.w(Qk,"ConstantDistance",1);var $k;Qk.ConstantAngle=$k=t.w(Qk,"ConstantAngle",2);var cl;Qk.Packed=cl=t.w(Qk,"Packed",3);var Yk;Qk.Clockwise=Yk=t.w(Qk,"Clockwise",4);var Zk;Qk.Counterclockwise=Zk=t.w(Qk,"Counterclockwise",5);var Wk;Qk.BidirectionalLeft=Wk=t.w(Qk,"BidirectionalLeft",6);var Xk;Qk.BidirectionalRight=Xk=t.w(Qk,"BidirectionalRight",7);var Tk;Qk.Forwards=Tk=t.w(Qk,"Forwards",8);var Uk; +Qk.Reverse=Uk=t.w(Qk,"Reverse",9);var Rk;Qk.Ascending=Rk=t.w(Qk,"Ascending",10);var Sk;Qk.Descending=Sk=t.w(Qk,"Descending",11);var Vk;Qk.Optimized=Vk=t.w(Qk,"Optimized",12);var el;Qk.Pythagorean=el=t.w(Qk,"Pythagorean",13);var dl;Qk.Circular=dl=t.w(Qk,"Circular",14);function vn(){Ca.call(this)}t.ia("CircularNetwork",vn);t.Oa(vn,Ca);vn.prototype.createVertex=function(){return new wn};vn.prototype.createEdge=function(){return new Jn};function wn(){Da.call(this);this.actualAngle=this.diameter=NaN} +t.ia("CircularVertex",wn);t.Oa(wn,Da);function xn(a,b){var c=a.network;if(null===c)return NaN;c=c.Tb;if(null===c)return NaN;if(c.Oe===cl)if(c.ht===dl)a.diameter=Math.max(a.width,a.height);else{var c=Math.abs(Math.sin(b)),d=Math.abs(Math.cos(b));if(0===c)return a.width;if(0===d)return a.height;a.diameter=Math.min(a.height/c,a.width/d)}else a.diameter=c.ht===dl?Math.max(a.width,a.height):Math.sqrt(a.width*a.width+a.height*a.height);return a.diameter}function Jn(){Ea.call(this)}t.ia("CircularEdge",Jn); +t.Oa(Jn,Ea);function Kn(){0k?(e=l.x+l.width/2,g=l.y+l.height/2,h[0]=new C(l.x+l.width+c.width,l.y),h[1]=new C(l.x,l.y+ +l.height+c.height),k=2):(p=Nn(h,k,e,g,l.width,l.height,c),q=h[p],r=new C(q.x+l.width+c.width,q.y),s=new C(q.x,q.y+l.height+c.height),p+1this.network.vertexes.count)return!1;var a=0,b=0,c=this.network.vertexes.k;c.next();for(var d=c.value.T;c.next();){if(c.value.T.If(d)&&(a++,1a.network.vertexes.count)return!1;null===a.ig?a.ig=new H(Tn):a.ig.clear();a.ig.Me(a.network.vertexes);var c=a.ig;c.sort(function(a,b){return null===a||null===b||a===b?0:b.Lf-a.Lf});for(var d=c.count-1;0<=d&&1>=c.p[d].Lf;)d--;return 1=h))){for(var n=0,p=0,q=m.count-h;qs&&(s=1);n=J.sqrt((n+s+p*p*4/(h*h))/s);h=(n-1)*l/2;n=(n-1)*q/2;g.Mb=new D(m-r.x-h,k-r.y-n,l+2*h,q+2*n);g.focus=new C(r.x+h,r.y+n)}a.network=d;return c} +function Sn(a,b,c){f&&(t.l(b,Ln,Kn,"popNetwork:oldnet"),t.o(c,Kn,"popNetwork:level"));for(c=a.network.vertexes.k;c.next();){var d=c.value;d.network=b;if(null!==d.ah){var e=d.ah.p[d.UA];d.Lf=e.wB;var g=e.kG,h=e.lG;d.Mb=new D(d.Fa-g,d.Sa-h,e.yB,e.vB);d.focus=new C(g,h);d.UA--}}for(c=a.network.edges.k;c.next();)c.value.network=b;a.network=b} +function Un(a,b,c){f&&(t.l(b,Tn,Kn,"surroundNode:oldnet"),t.o(c,Kn,"surroundNode:level"));var d=b.Em;if(null!==d&&0!==d.count){c=b.Fa;var e=b.Sa,g=b.width,h=b.height;null!==b.ah&&0=p.Lf?l++:(k=!0,m++,h+=Math.atan2(b.Sa-p.Sa,b.Fa-p.Fa))}if(0!==l)for(0>1)+m)*(0==k%2?1:-1);p.Fa=c+d*Math.cos(l);p.Sa=e+d*Math.sin(l);k++}}} +function Nn(a,b,c,d,e,g,h){var k=9E19,l=-1,m=0;a:for(;mn.y&&a[q].x-n.xn.x&&a[q].y-n.yl+h?(d=d+g-k,e=e-l-h,J.sqrt(d*d+e*e)):e+ck+m?e>l+h?(d=d-k-m,e=e-l-h,J.sqrt(d*d+e*e)):e+cl+h?e-(l+h):e+c=b.length)return!1;var c=b[0];c.forceX=0;c.forceY=0;for(var d=c.Fa,e=d,g=c.Sa,h=g,c=1;ch-g)?b.sort(function(a,b){return null===a||null===b||a===b?0:a.Fa-b.Fa}):b.sort(function(a,b){return null===a||null===b||a===b?0:a.Sa-b.Sa});for(var h=a.oh,m=0,n=0,p=0,c=0;ch||p-d>h){if(g)break}else if(l-r>h||r-l>h){if(!g)break}else{var s=Vn(k,e);1>s?(d>p?(n=Math.abs(e.T.right-k.T.x),n=(1+n)*Math.random()):dr?(p=Math.abs(e.T.bottom-k.T.y),p=(1+p)*Math.random()):ds?(n=(d>p?1:-1)*(1+(e.width>k.width)?e.width: +k.width)*Math.random(),p=(l>r?1:-1)*(1+(e.height>k.height)?e.height:k.height)*Math.random()):(m=g.stiffness*(s-g.length),n=(p-d)/s*m,p=(r-l)/s*m),k.forceX+=n,k.forceY+=p,e.forceX-=n,e.forceY-=p;c=0;d=Math.max(a.oh/20,50);for(e=0;ed&&(g=d),h<-d?h=-d:h>d&&(h=d),k.Fa+=g,k.Sa+=h,c=Math.max(c,g*g+h*h));return c>a.Vz*a.Vz}Kn.prototype.moveFixedVertex=function(){}; +Kn.prototype.commitLayout=function(){this.bB();this.commitNodes();this.Vs&&this.commitLinks()};Kn.prototype.bB=function(){if(this.wl)for(var a=this.network.edges.k;a.next();){var b=a.value.link;null!==b&&(b.lb=Pb,b.mb=Pb)}};Kn.prototype.commitNodes=function(){var a=0,b=0;if(this.gD){var c=t.wf();this.kf(this.network,c);b=this.zd;a=b.x-c.x;b=b.y-c.y;t.Pc(c)}for(var c=t.wf(),d=this.network.vertexes.k;d.next();){var e=d.value;if(0!==a||0!==b)c.assign(e.T),c.x+=a,c.y+=b,e.Mb=c;e.commit()}t.Pc(c)}; +Kn.prototype.commitLinks=function(){for(var a=this.network.edges.k;a.next();)a.value.commit()};Kn.prototype.springStiffness=function(a){a=a.stiffness;return isNaN(a)?this.An:a};Kn.prototype.springLength=function(a){a=a.length;return isNaN(a)?this.zn:a};Kn.prototype.electricalCharge=function(a){a=a.charge;return isNaN(a)?this.wn:a};Kn.prototype.electricalFieldX=function(){return 0};Kn.prototype.electricalFieldY=function(){return 0}; +Kn.prototype.gravitationalMass=function(a){a=a.mass;return isNaN(a)?this.yn:a};Kn.prototype.gravitationalFieldX=function(){return 0};Kn.prototype.gravitationalFieldY=function(){return 0};Kn.prototype.isFixed=function(a){return a.isFixed};t.A(Kn,{oJ:"currentIteration"},function(){return this.Vq});t.g(Kn,"arrangementSpacing",Kn.prototype.Jv);t.defineProperty(Kn,{Jv:"arrangementSpacing"},function(){return this.Rf},function(a){this.Rf.N(a)||(this.Rf.assign(a),this.K())});t.g(Kn,"arrangesToOrigin",Kn.prototype.gD); +t.defineProperty(Kn,{gD:"arrangesToOrigin"},function(){return this.cq},function(a){this.cq!==a&&(this.cq=a,this.K())});t.g(Kn,"setsPortSpots",Kn.prototype.wl);t.defineProperty(Kn,{wl:"setsPortSpots"},function(){return this.wh},function(a){this.wh!==a&&(this.wh=a,this.K())});t.g(Kn,"comments",Kn.prototype.comments);t.defineProperty(Kn,{comments:"comments"},function(){return this.hh},function(a){this.hh!==a&&(this.hh=a,this.K())});t.g(Kn,"maxIterations",Kn.prototype.Aw); +t.defineProperty(Kn,{Aw:"maxIterations"},function(){return this.ao},function(a){this.ao!==a&&0<=a&&(this.ao=a,this.K())});t.g(Kn,"epsilonDistance",Kn.prototype.Vz);t.defineProperty(Kn,{Vz:"epsilonDistance"},function(){return this.zq},function(a){this.zq!==a&&0b.toVertex.index&&(this.network.Jw(b),b.rev=!0);break;case Yn:for(b=this.network.vertexes.k;b.next();)b.value.Lo=-1,b.value.finish=-1;for(a=this.network.edges.k;a.next();)a.value.forest=!1;this.sr=0;for(b.reset();b.next();)0===b.value.hc.count&&jo(this,b.value);for(b.reset();b.next();)-1===b.value.Lo&&jo(this,b.value);for(a.reset();a.next();)b=a.value,b.forest|| +(c=b.fromVertex,d=c.finish,e=b.toVertex,g=e.finish,e.Los&&0s&&0b[this.Af]&&(this.Gu=b[c]-1,this.Af=c),b[c]k)for(p=k+1;pl;p--)n=d[p],n.near===m&&n.zm===m.zm||h++;var q,r,s,v,x,E;if(0<=c)for(l=d[k].$e,m=0;mv||n===v&&q>s)&&h++,xn||v===n&&s>q)&&h++);if(0>=c)for(l=d[k].Qe,m=0;mv||n===v&&p>x)&&h++,sn||v===n&&x>p)&&h++);g[k*e+k]=h;for(l= +k+1;l=c)for(h=d[k].Qe,E=d[l].Qe,m=0;m=c&&(l=k.$e);var m=null;0<=c&&(m=k.Qe);var n=0,p=0,q=k.near;null!==q&&q.layer===k.layer&&(n+=q.column-1,p++);if(null!==l)for(q=0;q=c&&(l=k.$e);var m=null;0<=c&&(m=k.Qe);var n=0,p=[],q=k.near;null!==q&&q.layer===k.layer&&(p[n]=q.column-1,n++);if(null!==l)for(q=0;q>1,g[h]=n&1?p[m]:p[m-1]+p[m]>>1)}Bo(a,b,d);return g}function Ko(a,b,c,d,e,g){if(b.component===d){b.component=c;var h,k;if(e)for(var l=b.Zb;l.next();){var m=l.value.toVertex;h=b.layer-m.layer;k=Co(l.value);h===k&&Ko(a,m,c,d,e,g)}if(g)for(l=b.hc;l.next();)m=l.value.fromVertex,h=m.layer-b.layer,k=Co(l.value),h===k&&Ko(a,m,c,d,e,g)}} +function Lo(a,b,c,d,e,g){if(b.component===d){b.component=c;if(e)for(var h=b.Zb,k;h.next();)k=h.value.toVertex,Lo(a,k,c,d,e,g);if(g)for(b=b.hc;b.next();)h=b.value.fromVertex,Lo(a,h,c,d,e,g)}}function fo(a){for(a=a.vertexes.k;a.next();){var b=a.value;if(b.valid)return b}return null}function ho(a){for(a=a.vertexes.k;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.Zb;d.next();)if(d.value.toVertex.valid){c=!1;break}if(c)return b}}return null} +function io(a){for(a=a.vertexes.k;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.hc;d.next();)if(d.value.fromVertex.valid){c=!1;break}if(c)return b}}return null}function jo(a,b){b.Lo=a.sr;a.sr++;for(var c=b.Zb;c.next();){var d=c.value,e=d.toVertex;-1===e.Lo&&(d.forest=!0,jo(a,e))}b.finish=a.sr;a.sr++} +Hk.prototype.assignLayers=function(){switch(this.Yn){case Mo:No(this);break;case Oo:for(var a,b=this.network.vertexes.k;b.next();)a=Po(this,b.value),this.ob=Math.max(a,this.ob);for(b.reset();b.next();)a=b.value,a.layer=this.ob-a.layer;break;default:case Zn:No(this);for(b=this.network.vertexes.k;b.next();)b.value.valid=!1;for(b.reset();b.next();)0===b.value.hc.count&&Qo(this,b.value);a=Infinity;for(b.reset();b.next();)a=Math.min(a,b.value.layer);this.ob=-1;for(b.reset();b.next();)b.value.layer-=a, +this.ob=Math.max(this.ob,b.value.layer)}};function No(a){for(var b=a.network.vertexes.k;b.next();){var c=Ro(a,b.value);a.ob=Math.max(c,a.ob)}}function Ro(a,b){var c=0;if(-1===b.layer){for(var d=b.Zb;d.next();)var e=d.value,g=Co(e),c=Math.max(c,Ro(a,e.toVertex)+g);b.layer=c}else c=b.layer;return c}function Po(a,b){var c=0;if(-1===b.layer){for(var d,e,g=b.hc;g.next();)e=g.value,d=Co(e),c=Math.max(c,Po(a,e.fromVertex)+d);b.layer=c}else c=b.layer;return c} +function Qo(a,b){if(!b.valid){b.valid=!0;for(var c=b.Zb;c.next();)Qo(a,c.value.toVertex);for(c=a.network.vertexes.k;c.next();)c.value.component=-1;for(var d=b.$e.p,e=d.length,g=0;gk&&Ko(a,h.fromVertex,0,-1,!0,!1)}for(Ko(a,b,1,-1,!0,!0);0!==b.component;){for(var k=0,d=Infinity,l=0,m=null,n=a.network.vertexes.k;n.next();){var p=n.value;if(1===p.component){for(var q=0,r=!1,s=p.$e.p,e=s.length,g=0;gd)&&!p&&(k=m,d=n)}if(0>g){for(c.reset();c.next();)g=c.value,1===g.component&&(g.layer-=e);b.component=0}else k.component=0}}}function zo(a,b,c){return 90===a.sa?c&&!b.rev||!c&&b.rev?270:90:180===a.sa?c&&!b.rev||!c&&b.rev?0:180:270===a.sa?c&&!b.rev||!c&&b.rev?90:270:c&&!b.rev||!c&&b.rev?180:0} +Hk.prototype.initializeIndices=function(){switch(this.On){default:case So:for(var a,b=this.network.vertexes.k;b.next();){var c=b.value;a=c.layer;c.index=this.Hd[a];this.Hd[a]++}break;case $n:b=this.network.vertexes.k;for(a=this.ob;0<=a;a--){for(;b.next();)b.value.layer===a&&-1===b.value.index&&To(this,b.value);b.reset()}break;case Uo:for(b=this.network.vertexes.k,a=0;a<=this.ob;a++){for(;b.next();)b.value.layer===a&&-1===b.value.index&&Vo(this,b.value);b.reset()}}}; +function To(a,b){var c=b.layer;b.index=a.Hd[c];a.Hd[c]++;for(var c=b.Qe.af(),d=!0,e;d;)for(d=!1,e=0;eh.portFromColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;eh.portToColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;e=h;d--)g=Xo(this,d,-1)||g;e=this.countCrossings();e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,1)||g;e=this.countCrossings();e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g= +Xo(this,d,-1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this))}break;default:case ao:for(c=this.ob,h=0,k=a+1;(d=this.countCrossings())=h;d--)g=Xo(this,d,-1)||g;e=this.countCrossings();e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,1)||g;e=this.countCrossings();e>=a?Fo(this,b): +(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,-1)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Xo(this,d,0)||g;e>=a?Fo(this,b):(a=e,b=Eo(this))}}Fo(this,b)}; +function Wo(a,b,c){f&&(t.o(b,Hk,"medianBarycenterCrossingReduction:unfixedLayer"),t.o(c,Hk,"medianBarycenterCrossingReduction:direction"));var d=Ao(a,b),e=a.Hd[b],g=Jo(a,b,c),h=Io(a,b,c);for(c=0;cg+1&&(q+=4*(F-g),r+=4*(F-(g+1)))}L=d[g].Zb.k;for(L.reset();L.next();)if(G=L.value,G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g+1&&(r+=1)}L=d[g+1].hc.k;for(L.reset();L.next();)if(G=L.value,G.valid&&G.fromVertex.layer===b){G=G.fromVertex;for(F=0;d[F]!==G;)F++;Fg+1&&(q+=4*(F-(g+1)),r+=4*(F-g))}L=d[g+1].Zb.k;for(L.reset();L.next();)if(G=L.value, +G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g&&(q+=1)}var F=G=0,L=h[d[g].index],N=k[d[g].index],W=h[d[g+1].index],T=k[d[g+1].index];-1!==L&&(G+=Math.abs(L-s),F+=Math.abs(L-E));-1!==N&&(G+=Math.abs(N-s),F+=Math.abs(N-E));-1!==W&&(G+=Math.abs(W-v),F+=Math.abs(W-x));-1!==T&&(G+=Math.abs(T-v),F+=Math.abs(T-x));if(r>1)+8*g;this.Hb*=8}if(0!==(this.si&ap))for(b=!0;b;){b=!1;for(a=this.Af+1;a<=this.ob;a++)b=bp(this,a,1)||b;for(a=this.Af- +1;0<=a;a--)b=bp(this,a,-1)||b;b=bp(this,this.Af,0)||b}if(0!==(this.si&cp)){for(a=this.Af+1;a<=this.ob;a++)dp(this,a,1);for(a=this.Af-1;0<=a;a--)dp(this,a,-1);dp(this,this.Af,0)}c&&(ep(this,-1),ep(this,1));if(0!==(this.si&ap))for(b=!0;b;){b=!1;b=bp(this,this.Af,0)||b;for(a=this.Af+1;a<=this.ob;a++)b=bp(this,a,0)||b;for(a=this.Af-1;0<=a;a--)b=bp(this,a,0)||b}};function bp(a,b,c){f&&(t.o(b,Hk,"bendStraighten:unfixedLayer"),t.o(c,Hk,"bendStraighten:direction"));for(var d=!1;fp(a,b,c);)d=!0;return d} +function fp(a,b,c){f&&(t.o(b,Hk,"shiftbendStraighten:unfixedLayer"),t.o(c,Hk,"shiftbendStraighten:direction"));var d,e=Ao(a,b),g=a.Hd[b],h=Io(a,b,-1);if(0c)for(d=0;dd-1||n-e[d-1].column-1>p+a.nodeMinColumnSpace(e[d-1],!1)?n-1:n,q=d+1>=g||e[d+1].column-n-1>q+a.nodeMinColumnSpace(e[d+1],!0)?n+1:n,r=0,s=0,v=0,x, +E,F,G;if(0>=c)for(var L=e[d].hc.k;L.next();)x=L.value,x.valid&&x.fromVertex.layer!==b&&(E=Do(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.fromVertex.column,r+=(Math.abs(n+G-(x+F))+1)*E,s+=(Math.abs(p+G-(x+F))+1)*E,v+=(Math.abs(q+G-(x+F))+1)*E);if(0<=c)for(L=e[d].Zb.k;L.next();)x=L.value,x.valid&&x.toVertex.layer!==b&&(E=Do(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.toVertex.column,r+=(Math.abs(n+F-(x+G))+1)*E,s+=(Math.abs(p+F-(x+G))+1)*E,v+=(Math.abs(q+F-(x+G))+1)*E);G=F=E=0;x=h[e[d].index]; +L=k[e[d].index];-1!==x&&(E+=Math.abs(x-n),F+=Math.abs(x-p),G+=Math.abs(x-q));-1!==L&&(E+=Math.abs(L-n),F+=Math.abs(L-p),G+=Math.abs(L-q));if(s=h[c]?n=l:m<=h[c]&&(n=m));n!==k&&(g=!0,d[c].column=n)}Bo(a,b,d);a.normalize()} +function gp(a,b){f&&(t.o(b,Hk,"packAux:column"),t.o(1,Hk,"packAux:direction"));for(var c=!0,d=a.network.vertexes.k,e;d.next();){e=d.value;var g=a.nodeMinColumnSpace(e,!0),h=a.nodeMinColumnSpace(e,!1);if(e.column-g<=b&&e.column+h>=b){c=!1;break}}g=!1;if(c)for(d.reset();d.next();)e=d.value,e.column>b&&(e.column-=1,g=!0);return g} +function hp(a,b){f&&(t.o(b,Hk,"tightPackAux:column"),t.o(1,Hk,"tightPackAux:direction"));var c=b,c=b+1,d,e=[],g=[];for(d=0;d<=a.ob;d++)e[d]=!1,g[d]=!1;for(var h=a.network.vertexes.k;h.next();){d=h.value;var k=d.column-a.nodeMinColumnSpace(d,!0),l=d.column+a.nodeMinColumnSpace(d,!1);k<=b&&l>=b&&(e[d.layer]=!0);k<=c&&l>=c&&(g[d.layer]=!0)}k=!0;c=!1;for(d=0;d<=a.ob;d++)k=k&&!(e[d]&&g[d]);if(k)for(h.reset();h.next();)d=h.value,d.column>b&&(d.column-=1,c=!0);return c} +function ep(a,b){f&&t.o(b,Hk,"componentPack:direction");for(var c=0;c<=a.Hb;c++)for(;gp(a,c););a.normalize();for(c=0;ce?Fo(a,d):hb)for(c=a.Hb;0<=c;c--)for(d=Eo(a),e=Ho(a),g=e+1;ee?Fo(a,d):hc)for(d.reset();d.next();)e=d.value,e.column+a.nodeMinColumnSpace(e,!1)>=b&&(e.component=a.ag);a.ag++;for(d.reset();d.next();)e=d.value,-1===e.component&&(Lo(a,e,a.ag,-1,!0,!0),a.ag++);b=[];for(e=0;ec)for(k=a.Hb;0c)for(d.reset();d.next();)e=d.value,g[e.component]&&(e.column+=1)}Hk.prototype.commitLayout=function(){if(this.wl)for(var a=to(this,!0),b=to(this,!1),c=this.network.edges.k,d;c.next();)d=c.value.link,null!==d&&(d.lb=a,d.mb=b);this.commitNodes();this.Vs&&this.commitLinks()}; +function to(a,b){return 270===a.sa?b?ac:dc:90===a.sa?b?dc:ac:180===a.sa?b?bc:cc:b?cc:bc} +Hk.prototype.commitNodes=function(){this.th=[];this.Lg=[];this.yf=[];this.Kd=[];for(var a=0;a<=this.ob;a++)this.th[a]=0,this.Lg[a]=0,this.yf[a]=0,this.Kd[a]=0;for(var a=this.network.vertexes.k,b,c;a.next();)b=a.value,c=b.layer,this.th[c]=Math.max(this.th[c],this.nodeMinLayerSpace(b,!0)),this.Lg[c]=Math.max(this.Lg[c],this.nodeMinLayerSpace(b,!1));b=0;for(var d=this.Xn,e=0;e<=this.ob;e++)c=d,0>=this.th[e]+this.Lg[e]&&(c=0),0=Ja.T.y&&Zb<=Ja.T.bottom&&(za=Ja.Fa+jf,Zb=Zb=Ja.T.x&&Zb<=Ja.T.right&&(za=Ja.Sa+jf,Zb=Zbqb.y&&(jd=Rc.y>qb.y?0:Ya.xsb.x&&(Cc=se.x>sb.x?0:Sc.yb.layer?1:a.Ceb.Ce?1:a.Qdb.Qd?1:0:0}; +Hk.prototype.rF=function(a,b){return a instanceof jp&&b instanceof jp&&a!==b?a.ebb.eb||a.Uhb.Uh||a.Ceb.Ce?1:a.Qdb.Qd?1:0:0};Hk.prototype.Lw=function(a,b){return a instanceof jp&&b instanceof jp&&a!==b?a.Wdb.Wd||a.Uhb.Uh||a.Ceb.Ce?1:a.Qdb.Qd?1:0:0};Hk.prototype.I=function(a,b){f&&(t.o(a,Hk,"isApprox:a"),t.o(b,Hk,"isApprox:b"));var c=a-b;return-1c}; +function kp(a,b,c,d){f&&(t.o(a,Hk,"isUnoccupied2:px"),t.o(b,Hk,"isUnoccupied2:py"),t.o(c,Hk,"isUnoccupied2:qx"),t.o(d,Hk,"isUnoccupied2:qy"));return!0}function Ao(a,b){var c,d=a.Hd[b];if(d>=a.Ng.length){c=[];var e;for(e=0;ea&&(this.si=a,this.K())});t.g(Hk,"setsPortSpots",Hk.prototype.wl);t.defineProperty(Hk,{wl:"setsPortSpots"},function(){return this.wh},function(a){this.wh!==a&&"boolean"===typeof a&&(this.wh=a,this.K())});t.g(Hk,"linkSpacing",Hk.prototype.lp);t.defineProperty(Hk,{lp:"linkSpacing"},function(){return this.uj},function(a){this.uj!==a&&(this.uj=a,this.K())});t.A(Hk,{zJ:"maxLayer"},function(){return this.ob}); +t.A(Hk,{xJ:"maxIndex"},function(){return this.Gu});t.A(Hk,{wJ:"maxColumn"},function(){return this.Hb});t.A(Hk,{AJ:"minIndexLayer"},function(){return this.mr});t.A(Hk,{yJ:"maxIndexLayer"},function(){return this.Af});var Yn;Hk.CycleDepthFirst=Yn=t.w(Hk,"CycleDepthFirst",0);var eo;Hk.CycleGreedy=eo=t.w(Hk,"CycleGreedy",1);var Zn;Hk.LayerOptimalLinkLength=Zn=t.w(Hk,"LayerOptimalLinkLength",0);var Mo;Hk.LayerLongestPathSink=Mo=t.w(Hk,"LayerLongestPathSink",1);var Oo; +Hk.LayerLongestPathSource=Oo=t.w(Hk,"LayerLongestPathSource",2);var $n;Hk.InitDepthFirstOut=$n=t.w(Hk,"InitDepthFirstOut",0);var Uo;Hk.InitDepthFirstIn=Uo=t.w(Hk,"InitDepthFirstIn",1);var So;Hk.InitNaive=So=t.w(Hk,"InitNaive",2);var Yo;Hk.AggressiveNone=Yo=t.w(Hk,"AggressiveNone",0);var ao;Hk.AggressiveLess=ao=t.w(Hk,"AggressiveLess",1);var Zo;Hk.AggressiveMore=Zo=t.w(Hk,"AggressiveMore",2);Hk.PackNone=0;var $o;Hk.PackExpand=$o=1;var ap;Hk.PackStraighten=ap=2;var cp;Hk.PackMedian=cp=4;var bo; +Hk.PackAll=bo=7;function co(){Ca.call(this)}t.ia("LayeredDigraphNetwork",co);t.Oa(co,Ca);co.prototype.createVertex=function(){return new lp};co.prototype.createEdge=function(){return new mp};function lp(){Da.call(this);this.index=this.column=this.layer=-1;this.component=NaN;this.near=null;this.valid=!1;this.finish=this.Lo=NaN;this.zm=0;this.AA=this.BA=void 0}t.ia("LayeredDigraphVertex",lp);t.Oa(lp,Da); +function mp(){Ea.call(this);this.forest=this.rev=this.valid=!1;this.portToPos=this.portFromPos=NaN;this.portToColOffset=this.portFromColOffset=0}t.ia("LayeredDigraphEdge",mp);t.Oa(mp,Ea);function Z(){0b.level)return!1;a.removeChild(c.parent,c)}return!0} +Z.prototype.removeChild=function(a,b){f&&t.l(a,rp,Z,"removeChild:p");f&&t.l(b,rp,Z,"removeChild:c");if(null!==a&&null!==b){for(var c=a.children,d=0,e=0;eh?$p(b,l,ab,L,N):aq(b,l,ab,L,N);ab=R[0];L=R[1];N=R[2];break;case Op:for(n=0;nv&&(yaKb&&(fq(b,-Kb,0,va,n-1),gq(T,-Kb,0),gq(U,-Kb,0),Kb=0);p.la.q(Kb,Na);L=Math.max(L,da);N=Math.max(N,W+(0===Ja?0:F)+za.height);ya=da}else{0v&&(NaKb&&(fq(b,0,-Kb,va,n-1),gq(T,0,-Kb),gq(U,0,-Kb),Kb=0);p.la.q(ya,Kb);N=Math.max(N,R);L=Math.max(L,W+(0===Ja?0:F)+za.width);Na=R}Ka++}0k&&(k=0),135r&&(r=0), +q===Pp&&(m+=x/2+b.P.y),l+=e+d):c?(null===b.comments?e>L&&(q=kq(q,e-L,0),l=q[0],m=q[1],L=e,k=0):L=iq(b,L,k),0>k&&(l-=k,k=0),135N&&(q=kq(q,0,g-N),l=q[0],m=q[1],N=g,r=0):N=jq(b,N,r),0>r&&(m-=r,r=0),l+=e+d);if(0h[0].x?h[2].assign(h[1]):h[1].assign(h[2])),h[3].yh[0].x?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(k+e,0),q[1].q(q[0].x,g),q[2].yh[0].y?h[2].assign(h[1]):h[1].assign(h[2])),h[3].xh[0].y?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(0,r+g),q[1].q(e,q[0].y),q[2].xc?$p(b,e,Ja,N,W):aq(b,e,Ja,N,W);Ja=W[0];N=W[1];W=W[2];break;case Op:for(k=0;kr&&(Ur&&(dap&&(p=0),135G&&(G=0));b.Ma.q(p,G);b.Ya.q(N,W)}} +function $p(a,b,c,d,e){f&&t.l(a,rp,Z,"layoutBusChildrenPosDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ya.width;e=h.Ya.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=90===Vp(a),n=0,p=0,q=0,r=0;rm&&(d-=m),e=Math.max(e,Math.max(F,q)+b+s.height),0>h.la.x&&(c=tq(a,h.la.x,!1,c,k))):(h.la.q(d+b,c+k/2-h.P.y-h.Ma.y),d=Math.max(d,Math.max(E,p)+b+s.width),m=c+k/2-h.P.y-h.Ma.y,e=Math.max(e,m+s.height),0>m&&(e-=m),0>h.la.y&&(c=tq(a,h.la.y,!0,c,k))));a=[];a[0]=c;a[1]=d;a[2]=e;return a} +function aq(a,b,c,d,e){f&&t.l(a,rp,Z,"layoutBusChildrenNegDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ya.width;e=h.Ya.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=270===Vp(a),n=0,p=0,q=0,r=0;rp&&(d-=p),e=Math.max(e,Math.abs(Math.min(F,q))+l+s.height),0>h.la.x&&(c=tq(a,h.la.x,!1,c,k))):(h.la.q(-d-s.width-l,c+k/2-h.P.y-h.Ma.y),d=Math.max(d,Math.abs(Math.min(E,p))+l+s.width),p=c+k/2-h.P.y-h.Ma.y,e=Math.max(e,p+s.height),0>p&&(e-=p),0>h.la.y&&(c=tq(a,h.la.y,!0,c,k))));for(r=0;rd&&(d=c+a.width);0>c&&(d-=c);return d;case Wp:return a.width>b?a.width:b;case Xp:return 2*a.P.x>b?a.width:b+a.width-2*a.P.x;case Np:case Cp:return d=Math.min(0,c),c=Math.max(b,c+a.width),Math.max(a.width,c-d);case Op:return a.width-a.P.x+a.nodeSpacing/2+b;case Pp:return Math.max(a.width,a.P.x+a.nodeSpacing/2+b);default:return b}} +function jq(a,b,c){f&&t.l(a,rp,Z,"calculateSubheight:v");switch(a.alignment){case Lp:case hq:var d=b;c+a.height>d&&(d=c+a.height);0>c&&(d-=c);return d;case Wp:return a.height>b?a.height:b;case Xp:return 2*a.P.y>b?a.height:b+a.height-2*a.P.y;case Np:case Cp:return d=Math.min(0,c),c=Math.max(b,c+a.height),Math.max(a.height,c-d);case Op:return a.height-a.P.y+a.nodeSpacing/2+b;case Pp:return Math.max(a.height,a.P.y+a.nodeSpacing/2+b);default:return b}} +function kq(a,b,c){f&&t.l(a,oa,Z,"alignOffset:align");switch(a){case hq:b/=2;c/=2;break;case Lp:b/=2;c/=2;break;case Wp:c=b=0;break;case Xp:break;default:t.m("Unhandled alignment value "+a.toString())}a=[];a[0]=b;a[1]=c;return a}function cq(a,b,c,d,e,g){f&&t.l(a,rp,Z,"shiftRelPosAlign:v");f&&t.l(b,oa,Z,"shiftRelPosAlign:align");b=kq(b,c,d);fq(a,b[0],b[1],e,g)}function fq(a,b,c,d,e){f&&t.l(a,rp,Z,"shiftRelPos:v");if(0!==b||0!==c)for(a=a.children;d<=e;d++){var g=a[d].la;g.x+=b;g.y+=c}} +function dq(a,b,c,d){f&&(t.l(b,rp,Z,"recordMidPoints:v"),t.j(c,"number",Z,"recordMidPoints:x"),t.j(d,"number",Z,"recordMidPoints:y"));var e=b.parent;switch(a.xf){case op:for(a=b.hc;a.next();)b=a.value,b.fromVertex===e&&b.Cr.q(c,d);break;case vp:for(a=b.Zb;a.next();)b=a.value,b.toVertex===e&&b.Cr.q(c,d);break;default:t.m("Unhandled path value "+a.xf.toString())}}function gq(a,b,c){for(var d=0;dn.length||null===p||2>p.length))for(g= +e=0;ev&&k.yk.y&&vb.length||null===e||2>e.length)d=null;else{m=bq(a,b.length+e.length);for(d=l=k=0;lk;)v=e[l++],m[d++].q(v.x+g,v.y);e=bq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=bq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x, +k.y);k=bq(a,g);for(e=0;en.length||null===p||2>p.length))for(g=e=0;el&&k.xk.x&&lb.length||null===e||2>e.length)d=null;else{m=bq(a,b.length+e.length);for(d=l=k=0;lk;)v=e[l++],m[d++].q(v.x,v.y+g);e=bq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=bq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x,k.y);k=bq(a,g);for(e=0;e=a?0:135>=a?90:225>=a?180:315>=a?270:0} +function Yp(a){f&&t.l(a,rp,Z,"computeLayerSpacing:v");var b=Vp(a),b=90===b||270===b,c=a.layerSpacing;if(0=a&&(this.ua.nodeIndentPastParent=a,this.K())});t.g(Z,"nodeSpacing",Z.prototype.nodeSpacing); +t.defineProperty(Z,{nodeSpacing:"nodeSpacing"},function(){return this.ua.nodeSpacing},function(a){this.ua.nodeSpacing!==a&&(this.ua.nodeSpacing=a,this.K())});t.g(Z,"layerSpacing",Z.prototype.layerSpacing);t.defineProperty(Z,{layerSpacing:"layerSpacing"},function(){return this.ua.layerSpacing},function(a){this.ua.layerSpacing!==a&&(this.ua.layerSpacing=a,this.K())});t.g(Z,"layerSpacingParentOverlap",Z.prototype.layerSpacingParentOverlap); +t.defineProperty(Z,{layerSpacingParentOverlap:"layerSpacingParentOverlap"},function(){return this.ua.layerSpacingParentOverlap},function(a){this.ua.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.ua.layerSpacingParentOverlap=a,this.K())});t.g(Z,"compaction",Z.prototype.compaction);t.defineProperty(Z,{compaction:"compaction"},function(){return this.ua.compaction},function(a){this.ua.compaction!==a&&(f&&t.l(a,oa,Z,"compaction"),a===Sp||a===Up)&&(this.ua.compaction=a,this.K())}); +t.g(Z,"breadthLimit",Z.prototype.breadthLimit);t.defineProperty(Z,{breadthLimit:"breadthLimit"},function(){return this.ua.breadthLimit},function(a){this.ua.breadthLimit!==a&&0<=a&&(this.ua.breadthLimit=a,this.K())});t.g(Z,"rowSpacing",Z.prototype.rowSpacing);t.defineProperty(Z,{rowSpacing:"rowSpacing"},function(){return this.ua.rowSpacing},function(a){this.ua.rowSpacing!==a&&(this.ua.rowSpacing=a,this.K())});t.g(Z,"rowIndent",Z.prototype.rowIndent); +t.defineProperty(Z,{rowIndent:"rowIndent"},function(){return this.ua.rowIndent},function(a){this.ua.rowIndent!==a&&0<=a&&(this.ua.rowIndent=a,this.K())});t.g(Z,"commentSpacing",Z.prototype.commentSpacing);t.defineProperty(Z,{commentSpacing:"commentSpacing"},function(){return this.ua.commentSpacing},function(a){this.ua.commentSpacing!==a&&(this.ua.commentSpacing=a,this.K())});t.g(Z,"commentMargin",Z.prototype.commentMargin); +t.defineProperty(Z,{commentMargin:"commentMargin"},function(){return this.ua.commentMargin},function(a){this.ua.commentMargin!==a&&(this.ua.commentMargin=a,this.K())});t.g(Z,"setsPortSpot",Z.prototype.setsPortSpot);t.defineProperty(Z,{setsPortSpot:"setsPortSpot"},function(){return this.ua.setsPortSpot},function(a){this.ua.setsPortSpot!==a&&(this.ua.setsPortSpot=a,this.K())});t.g(Z,"portSpot",Z.prototype.portSpot); +t.defineProperty(Z,{portSpot:"portSpot"},function(){return this.ua.portSpot},function(a){this.ua.portSpot.N(a)||(this.ua.portSpot=a,this.K())});t.g(Z,"setsChildPortSpot",Z.prototype.setsChildPortSpot);t.defineProperty(Z,{setsChildPortSpot:"setsChildPortSpot"},function(){return this.ua.setsChildPortSpot},function(a){this.ua.setsChildPortSpot!==a&&(this.ua.setsChildPortSpot=a,this.K())});t.g(Z,"childPortSpot",Z.prototype.childPortSpot); +t.defineProperty(Z,{childPortSpot:"childPortSpot"},function(){return this.ua.childPortSpot},function(a){this.ua.childPortSpot.N(a)||(this.ua.childPortSpot=a,this.K())});t.g(Z,"alternateSorting",Z.prototype.iH);t.defineProperty(Z,{iH:"alternateSorting"},function(){return this.ta.sorting},function(a){this.ta.sorting!==a&&(f&&t.l(a,oa,Z,"alternateSorting"),a===Hp||a===Ip||a===Jp||Kp)&&(this.ta.sorting=a,this.K())});t.g(Z,"alternateComparer",Z.prototype.XG); +t.defineProperty(Z,{XG:"alternateComparer"},function(){return this.ta.comparer},function(a){this.ta.comparer!==a&&(f&&t.j(a,"function",Z,"alternateComparer"),this.ta.comparer=a,this.K())});t.g(Z,"alternateAngle",Z.prototype.RG);t.defineProperty(Z,{RG:"alternateAngle"},function(){return this.ta.angle},function(a){this.ta.angle===a||0!==a&&90!==a&&180!==a&&270!==a||(this.ta.angle=a,this.K())});t.g(Z,"alternateAlignment",Z.prototype.QG); +t.defineProperty(Z,{QG:"alternateAlignment"},function(){return this.ta.alignment},function(a){this.ta.alignment!==a&&(f&&t.tb(a,Z,Z,"alternateAlignment"),this.ta.alignment=a,this.K())});t.g(Z,"alternateNodeIndent",Z.prototype.aH);t.defineProperty(Z,{aH:"alternateNodeIndent"},function(){return this.ta.nodeIndent},function(a){this.ta.nodeIndent!==a&&0<=a&&(this.ta.nodeIndent=a,this.K())});t.g(Z,"alternateNodeIndentPastParent",Z.prototype.bH); +t.defineProperty(Z,{bH:"alternateNodeIndentPastParent"},function(){return this.ta.nodeIndentPastParent},function(a){this.ta.nodeIndentPastParent!==a&&0<=a&&1>=a&&(this.ta.nodeIndentPastParent=a,this.K())});t.g(Z,"alternateNodeSpacing",Z.prototype.cH);t.defineProperty(Z,{cH:"alternateNodeSpacing"},function(){return this.ta.nodeSpacing},function(a){this.ta.nodeSpacing!==a&&(this.ta.nodeSpacing=a,this.K())});t.g(Z,"alternateLayerSpacing",Z.prototype.ZG); +t.defineProperty(Z,{ZG:"alternateLayerSpacing"},function(){return this.ta.layerSpacing},function(a){this.ta.layerSpacing!==a&&(this.ta.layerSpacing=a,this.K())});t.g(Z,"alternateLayerSpacingParentOverlap",Z.prototype.$G);t.defineProperty(Z,{$G:"alternateLayerSpacingParentOverlap"},function(){return this.ta.layerSpacingParentOverlap},function(a){this.ta.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.ta.layerSpacingParentOverlap=a,this.K())});t.g(Z,"alternateCompaction",Z.prototype.WG); +t.defineProperty(Z,{WG:"alternateCompaction"},function(){return this.ta.compaction},function(a){this.ta.compaction!==a&&(f&&t.l(a,oa,Z,"alternateCompaction"),a===Sp||a===Up)&&(this.ta.compaction=a,this.K())});t.g(Z,"alternateBreadthLimit",Z.prototype.SG);t.defineProperty(Z,{SG:"alternateBreadthLimit"},function(){return this.ta.breadthLimit},function(a){this.ta.breadthLimit!==a&&0<=a&&(this.ta.breadthLimit=a,this.K())});t.g(Z,"alternateRowSpacing",Z.prototype.fH); +t.defineProperty(Z,{fH:"alternateRowSpacing"},function(){return this.ta.rowSpacing},function(a){this.ta.rowSpacing!==a&&(this.ta.rowSpacing=a,this.K())});t.g(Z,"alternateRowIndent",Z.prototype.eH);t.defineProperty(Z,{eH:"alternateRowIndent"},function(){return this.ta.rowIndent},function(a){this.ta.rowIndent!==a&&0<=a&&(this.ta.rowIndent=a,this.K())});t.g(Z,"alternateCommentSpacing",Z.prototype.VG); +t.defineProperty(Z,{VG:"alternateCommentSpacing"},function(){return this.ta.commentSpacing},function(a){this.ta.commentSpacing!==a&&(this.ta.commentSpacing=a,this.K())});t.g(Z,"alternateCommentMargin",Z.prototype.UG);t.defineProperty(Z,{UG:"alternateCommentMargin"},function(){return this.ta.commentMargin},function(a){this.ta.commentMargin!==a&&(this.ta.commentMargin=a,this.K())});t.g(Z,"alternateSetsPortSpot",Z.prototype.hH); +t.defineProperty(Z,{hH:"alternateSetsPortSpot"},function(){return this.ta.setsPortSpot},function(a){this.ta.setsPortSpot!==a&&(this.ta.setsPortSpot=a,this.K())});t.g(Z,"alternatePortSpot",Z.prototype.dH);t.defineProperty(Z,{dH:"alternatePortSpot"},function(){return this.ta.portSpot},function(a){this.ta.portSpot.N(a)||(this.ta.portSpot=a,this.K())});t.g(Z,"alternateSetsChildPortSpot",Z.prototype.gH); +t.defineProperty(Z,{gH:"alternateSetsChildPortSpot"},function(){return this.ta.setsChildPortSpot},function(a){this.ta.setsChildPortSpot!==a&&(this.ta.setsChildPortSpot=a,this.K())});t.g(Z,"alternateChildPortSpot",Z.prototype.TG);t.defineProperty(Z,{TG:"alternateChildPortSpot"},function(){return this.ta.childPortSpot},function(a){this.ta.childPortSpot.N(a)||(this.ta.childPortSpot=a,this.K())});var np;Z.PathDefault=np=t.w(Z,"PathDefault",-1);var op;Z.PathDestination=op=t.w(Z,"PathDestination",0);var vp; +Z.PathSource=vp=t.w(Z,"PathSource",1);var Hp;Z.SortingForwards=Hp=t.w(Z,"SortingForwards",10);var Ip;Z.SortingReverse=Ip=t.w(Z,"SortingReverse",11);var Jp;Z.SortingAscending=Jp=t.w(Z,"SortingAscending",12);var Kp;Z.SortingDescending=Kp=t.w(Z,"SortingDescending",13);var hq;Z.AlignmentCenterSubtrees=hq=t.w(Z,"AlignmentCenterSubtrees",20);var Lp;Z.AlignmentCenterChildren=Lp=t.w(Z,"AlignmentCenterChildren",21);var Wp;Z.AlignmentStart=Wp=t.w(Z,"AlignmentStart",22);var Xp; +Z.AlignmentEnd=Xp=t.w(Z,"AlignmentEnd",23);var Np;Z.AlignmentBus=Np=t.w(Z,"AlignmentBus",24);var Cp;Z.AlignmentBusBranching=Cp=t.w(Z,"AlignmentBusBranching",25);var Op;Z.AlignmentTopLeftBus=Op=t.w(Z,"AlignmentTopLeftBus",26);var Pp;Z.AlignmentBottomRightBus=Pp=t.w(Z,"AlignmentBottomRightBus",27);var Sp;Z.CompactionNone=Sp=t.w(Z,"CompactionNone",30);var Up;Z.CompactionBlock=Up=t.w(Z,"CompactionBlock",31);var pp;Z.StyleLayered=pp=t.w(Z,"StyleLayered",40);var Gp; +Z.StyleLastParents=Gp=t.w(Z,"StyleLastParents",41);var Fp;Z.StyleAlternating=Fp=t.w(Z,"StyleAlternating",42);var Ep;Z.StyleRootOnly=Ep=t.w(Z,"StyleRootOnly",43);var qp;Z.ArrangementVertical=qp=t.w(Z,"ArrangementVertical",50);var vq;Z.ArrangementHorizontal=vq=t.w(Z,"ArrangementHorizontal",51);var up;Z.ArrangementFixedRoots=up=t.w(Z,"ArrangementFixedRoots",52);function sp(){Ca.call(this)}t.ia("TreeNetwork",sp);t.Oa(sp,Ca);sp.prototype.createVertex=function(){return new rp};sp.prototype.createEdge=function(){return new xq}; +function rp(){Da.call(this);this.initialized=!1;this.parent=null;this.children=[];this.maxGenerationCount=this.maxChildrenCount=this.descendantCount=this.level=0;this.comments=null;this.la=new C(0,0);this.Ya=new pa(0,0);this.Ma=new C(0,0);this.Cp=this.Bp=this.aJ=!1;this.qt=this.Ys=null;this.sorting=Hp;this.comparer=sn;this.angle=0;this.alignment=Lp;this.nodeIndentPastParent=this.nodeIndent=0;this.nodeSpacing=20;this.layerSpacing=50;this.layerSpacingParentOverlap=0;this.compaction=Up;this.breadthLimit= +0;this.rowSpacing=25;this.commentSpacing=this.rowIndent=10;this.commentMargin=20;this.setsPortSpot=!0;this.portSpot=Pb;this.setsChildPortSpot=!0;this.childPortSpot=Pb}t.ia("TreeVertex",rp);t.Oa(rp,Da); +rp.prototype.copyInheritedPropertiesFrom=function(a){null!==a&&(this.sorting=a.sorting,this.comparer=a.comparer,this.angle=a.angle,this.alignment=a.alignment,this.nodeIndent=a.nodeIndent,this.nodeIndentPastParent=a.nodeIndentPastParent,this.nodeSpacing=a.nodeSpacing,this.layerSpacing=a.layerSpacing,this.layerSpacingParentOverlap=a.layerSpacingParentOverlap,this.compaction=a.compaction,this.breadthLimit=a.breadthLimit,this.rowSpacing=a.rowSpacing,this.rowIndent=a.rowIndent,this.commentSpacing=a.commentSpacing, +this.commentMargin=a.commentMargin,this.setsPortSpot=a.setsPortSpot,this.portSpot=a.portSpot,this.setsChildPortSpot=a.setsChildPortSpot,this.childPortSpot=a.childPortSpot)};t.A(rp,{Dm:"childrenCount"},function(){return this.children.length});t.g(rp,"relativePosition",rp.prototype.VI);t.defineProperty(rp,{VI:"relativePosition"},function(){return this.la},function(a){t.l(a,C,rp,"relativePosition");this.la.set(a)});t.g(rp,"subtreeSize",rp.prototype.iJ); +t.defineProperty(rp,{iJ:"subtreeSize"},function(){return this.Ya},function(a){t.l(a,pa,rp,"subtreeSize");this.Ya.set(a)});t.g(rp,"subtreeOffset",rp.prototype.hJ);t.defineProperty(rp,{hJ:"subtreeOffset"},function(){return this.Ma},function(a){t.l(a,C,rp,"subtreeOffset");this.Ma.set(a)});function xq(){Ea.call(this);this.Cr=new C(0,0)}t.ia("TreeEdge",xq);t.Oa(xq,Ea); +xq.prototype.commit=function(){var a=this.link;if(null!==a&&!a.Si){var b=this.network.Tb,c=null,d=null;switch(b.xf){case op:c=this.fromVertex;d=this.toVertex;break;case vp:c=this.toVertex;d=this.fromVertex;break;default:t.m("Unhandled path value "+b.xf.toString())}if(null!==c&&null!==d)if(b=this.Cr,0!==b.x||0!==b.y||c.aJ){var d=c.Mb,e=Vp(c),g=Yp(c),h=c.rowSpacing;a.updateRoute();var k=a.Ee===Rg,l=a.ac,m,n,p,q;a.xl();if(l||k){for(m=2;4q.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Zp(c))))):c.alignment===Wp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Zp(c))))):c.alignment===Wp?(e=d.left+b.x,0===b.x&&n.xq.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Zp(c))))):c.alignment===Wp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Zp(c))))):c.alignment===Wp?(e=d.left+b.x,0===b.x&&n.xl?h=null:(m=parseFloat(n.getAttribute("cx")),isNaN(m)&&(m=0),n=parseFloat(n.getAttribute("cy")),isNaN(n)&&(n=0),p=new M(Xc),p.na=0,p.oa=0,p.D=2*l,p.F=2*l,h.position=new C(m-l,n-l),h.ed=p);break;case "ellipse":p=g;h=new Y;l=parseFloat(p.getAttribute("rx"));isNaN(l)||0>l?h=null:(m=parseFloat(p.getAttribute("ry")),isNaN(m)||0>m?h=null:(n=parseFloat(p.getAttribute("cx")),isNaN(n)&&(n=0),p=parseFloat(p.getAttribute("cy")), +isNaN(p)&&(p=0),q=new M(Xc),q.na=0,q.oa=0,q.D=2*l,q.F=2*m,h.position=new C(n-l,p-m),h.ed=q));break;case "rect":q=g;h=new Y;l=parseFloat(q.getAttribute("width"));if(isNaN(l)||0>l)h=null;else if(m=parseFloat(q.getAttribute("height")),isNaN(m)||0>m)h=null;else{n=parseFloat(q.getAttribute("x"));isNaN(n)&&(n=0);p=parseFloat(q.getAttribute("y"));isNaN(p)&&(p=0);var r=q.getAttribute("rx"),s=q.getAttribute("ry"),q=parseFloat(r);if(isNaN(q)||0>q)q=0;var v=parseFloat(s);if(isNaN(v)||0>v)v=0;!r&&s?q=v:r&&!s&& +(v=q);q=Math.min(q,l/2);v=Math.min(v,m/2);s=void 0;0===q&&0===v?(s=new M(Wc),s.na=0,s.oa=0,s.D=l,s.F=m):(s=J.va/2,r=t.u(),O(r,q,0,!0),r.lineTo(l-q,0),P(r,l-q*s,0,l,v*s,l,v),r.lineTo(l,m-v),P(r,l,m-v*s,l-q*s,m,l-q,m),r.lineTo(q,m),P(r,q*s,m,0,m-v*s,0,m-v),r.lineTo(0,v),P(r,0,v*s,q*s,0,q,0),Q(r),s=r.s,t.v(r));h.position=new C(n,p);h.ed=s}break;case "polygon":h=Cq(g);break;case "polyline":h=Cq(g)}if(null!==h){if(h instanceof Y){l=zq(a,g,"fill");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+ +1,l.length-1),l=a["_brush"+l],h.fill=l instanceof ke?l:"black"):h.fill=null===l?"black":"none"===l?null:l;l=zq(a,g,"stroke");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+1,l.length-1),l=a["_brush"+l],h.stroke=l instanceof ke?l:"black"):h.stroke="none"===l?null:l;l=parseFloat(zq(a,g,"stroke-width"));isNaN(l)||(h.ib=l);l=zq(a,g,"stroke-linecap");null!==l&&(h.HF=l);if(l=zq(a,g,"stroke-dasharray")){m=l.split(",");n=[];for(l=0;lg.length)return null;for(var h,d=new H(S),k,l,m=1;m=a.length?a.push(c):a.splice(b,0,c):t.l("Cannot insert an object into an HTMLCollection or NodeList: "+c+" at "+b)},ri:function(a,b){t.lc&&t.lc(a)&&(a=a());Array.isArray(a)?b>=a.length?a.pop():a.splice(b,1):t.l("Cannot remove an object from an HTMLCollection or NodeList at "+b)},gx:[],M:function(){var a=t.gx.pop();return void 0===a?new v:a},cc:function(a,b){var c=t.gx.pop();if(void 0===c)return new v(a,b);c.x=a;c.y=b;return c},B:function(a){t.gx.push(a)}, -bB:[],kl:function(){var a=t.bB.pop();return void 0===a?new ea:a},Qj:function(a){t.bB.push(a)},hx:[],qf:function(){var a=t.hx.pop();return void 0===a?new w:a},Yj:function(a,b,c,d){var e=t.hx.pop();if(void 0===e)return new w(a,b,c,d);e.x=a;e.y=b;e.width=c;e.height=d;return e},Ic:function(a){t.hx.push(a)},cB:[],Og:function(){var a=t.cB.pop();return void 0===a?new fa:a},Ne:function(a){t.cB.push(a)},ix:null,u:function(){var a=t.ix;return null!==a?(t.ix=null,a):new ha},v:function(a){a.reset();t.ix=a},aB:[], -yb:function(){var a=t.aB.pop();return void 0===a?[]:a},xa:function(a){a.length=0;t.aB.push(a)},dB:1,uc:function(a){a.__gohashid=t.dB++},zs:function(a){var b=a.__gohashid;void 0===b&&(b=t.dB++,a.__gohashid=b);return b},jc:function(a){return a.__gohashid},g:function(a,b,c){"name"!==b&&"length"!==b&&(a[b]=c)},ea:function(a,b){b.px=a;ba[a]=b},Ja:function(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a},th:function(a){a.jG=!0},defineProperty:function(a,b,c,d,e){t.j(a, -"function","Util.defineProperty:classfunc");t.j(b,"object","Util.defineProperty:propobj");t.j(c,"function","Util.defineProperty:getter");t.j(d,"function","Util.defineProperty:setter");for(var g in b){var h=b[g];b={get:c,set:d};if(void 0!==e)for(var k in e)b[k]=e[k];Object.defineProperty(a.prototype,g,b);e=Object.getOwnPropertyDescriptor(a.prototype,g);h&&e&&Object.defineProperty(a.prototype,h,e);if(f&&h){var l=h.charAt(0).toUpperCase()+h.slice(1);h==l&&t.l('Defining capitalized property "'+l+'"!?'); -Object.defineProperty(a.prototype,l,{get:function(){t.l('Getting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')},set:function(){t.l('Setting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')}})}break}},A:function(a,b,c,d){t.j(a,"function","Util.defineReadOnlyProperty:classfunc");t.j(b,"object","Util.defineReadOnlyProperty:propobj");t.j(c,"function","Util.defineReadOnlyProperty:getter");for(var e in b){var g= -b[e];b={get:c,set:function(a){t.l('The property "'+g+'" is read-only and cannot be set to '+a)}};if(void 0!==d)for(var h in d)b[h]=d[h];Object.defineProperty(a.prototype,e,b);d=Object.getOwnPropertyDescriptor(a.prototype,e);g&&d&&Object.defineProperty(a.prototype,g,d);if(f&&g){var k=g.charAt(0).toUpperCase()+g.slice(1);Object.defineProperty(a.prototype,k,{get:function(){t.l('Getting the property "'+k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'"')},set:function(){t.l('Setting the read-only property "'+ -k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'", and cannot be set anyway')}})}break}},be:function(a,b){for(var c in b)b[c]=!0;a.prototype.eC=b},vh:function(a){return void 0===a?"":"string"===typeof a?a:"function"===typeof a?t.Gg(a):null===a?"*":""},Gg:function(a){if("function"===typeof a){if(a.px)return a.px;if(a.name)return a.name;var b=a.toString(),c=b.indexOf("(");if(b=b.substring(9,c).trim())return a.px=b}else if("object"===typeof a&&a.constructor)return t.Gg(a.constructor); -return typeof a},w:function(a,b,c){t.j(a,"function","Util.defineEnumValue:classfunc");t.j(b,"string","Util.defineEnumValue:name");t.j(c,"number","Util.defineEnumValue:num");c=new ca(a,b,c);Object.freeze(c);a[b]=c;var d=a.rt;d||(d=new ia("string",ca),a.rt=d);d.add(b,c);return c},um:function(a,b){if(!b)return null;t.j(a,"function","Util.findEnumValueForName:classfunc");t.j(b,"string","Util.findEnumValueForName:name");var c=a.rt;return c?c.wa(b):null},XG:function(a,b,c,d){var e={},g;for(g in a){for(var h= -!1,k=1;k=d.length)){var e=t.ab(b,d);null===e||"function"===typeof e||t.Vv(b,d)||(""===c&&(c=b+"\n"),c+=' unknown property "'+d+'" has value: '+e+" at "+a+"\n")}return c},wv:function(a,b){if(b&&"number"!==typeof b&&"string"!==typeof b&&"boolean"!==typeof b&&"function"!==typeof b)if(void 0!==t.jc(b)){if(!t.Su.contains(b))if(t.Su.add(b), -t.su.add(t.NC(a,b)),b instanceof A||b instanceof la||b instanceof ia)for(var c=b.m;c.next();)t.wv(a+"["+c.key+"]",c.value);else for(c in b){var d=t.ab(b,c);if(void 0!==d&&null!==d&&t.jb(d)&&d!==b.eC){if(b instanceof ma){if(d===b.Gn)continue}else if(b instanceof y){if("data"===c||d===b.xl)continue;if("itemArray"===c||d===b.fj)continue;if(b instanceof B&&d===b.nj)continue}else if(!(b instanceof z))if(b instanceof oa){if("archetypeGroupData"===c||d===b.lx)continue}else if(b instanceof pa){if("archetypeLinkData"=== -c||d===b.Dt)continue;if("archetypeLabelNodeData"===c||d===b.Ct)continue}else if(b instanceof qa){if("archetypeNodeData"===c||d===b.Oi)continue}else if(b instanceof C){if("nodeDataArray"===c||d===b.Fe)continue;if("linkDataArray"===c||d===b.xg||d===b.Ll)continue;if(d===b.pc)continue;if(d===b.Yg)continue}else if(b instanceof ra||b instanceof sa||b instanceof ta)continue;t.wv(a+"."+c,d)}}}else if(Array.isArray(b))for(c=0;cc;c++)b[c]=c;for(var d=0,e,c=0;256>c;c++)d=(d+b[c]+119)%256,e=b[c],b[c]=b[d],b[d]=e;for(var d=c=0,g="",h=0;hc;c++)b["0123456789abcdef".charAt(c>>4)+"0123456789abcdef".charAt(c&15)]=String.fromCharCode(c); -a.length%2&&(a="0"+a);for(var d=[],e=0,c=0;cd;d++)b[t.Ka("7ca11abfd7330390")](t.Ka(c[d-1]),10,15*d+0);b[t.Ka("7ca11abfd022028846")]=t.Ka("39f046ebb36e4b");for(d=1;5>d;d++)b[t.Ka("7ca11abfd7330390")](t.Ka(c[d- -1]),10,15*d+0);if(4!==c.length||"5"!==c[0][0]||"7"!==c[3][0])t.w=function(a,b){var c=new ca(a,b,2);Object.freeze(c);a[b]=c;var d=a.rt;d||(d=new ia("string",ca),a.rt=d);d.add(b,c);return c};return a}();function ca(a,b,c){t.uc(this);this.hB=a;this.Mb=b;this.oG=c}ca.prototype.toString=function(){return t.Gg(this.hB)+"."+this.Mb};t.A(ca,{Ke:"classType"},function(){return this.hB});t.A(ca,{name:"name"},function(){return this.Mb});t.A(ca,{value:"value"},function(){return this.oG}); -function va(){this.gB=[]}va.prototype.toString=function(){return this.gB.join("")};va.prototype.add=function(a){a&&this.gB.push(a)};function wa(){}t.A(wa,{m:"iterator"},function(){return this});wa.prototype.reset=wa.prototype.reset=function(){};wa.prototype.next=wa.prototype.hasNext=wa.prototype.next=function(){return!1};wa.prototype.first=wa.prototype.Ya=function(){return null};t.A(wa,{count:"count"},function(){return 0});wa.prototype.sg=function(){};wa.prototype.toString=function(){return"EmptyIterator"}; -t.Pg=new wa;function za(a){this.key=-1;this.value=a}t.be(za,{key:!0,value:!0});t.A(za,{m:"iterator"},function(){return this});za.prototype.reset=za.prototype.reset=function(){this.key=-1};za.prototype.next=za.prototype.hasNext=za.prototype.next=function(){return-1===this.key?(this.key=0,!0):!1};za.prototype.first=za.prototype.Ya=function(){this.key=0;return this.value};t.A(za,{count:"count"},function(){return 1});za.prototype.sg=function(){this.value=null}; -za.prototype.toString=function(){return"SingletonIterator("+this.value+")"};function Aa(a){this.tf=a;this.Pn=null;this.reset()}t.be(Aa,{key:!0,value:!0});t.A(Aa,{m:"iterator"},function(){return this});t.g(Aa,"predicate",Aa.prototype.el);t.defineProperty(Aa,{el:"predicate"},function(){return this.Pn},function(a){this.Pn=a});Aa.prototype.reset=Aa.prototype.reset=function(){var a=this.tf;a.eh=null;this.eb=a.Pb;this.oe=-1}; -Aa.prototype.next=Aa.prototype.hasNext=Aa.prototype.next=function(){var a=this.tf;a.Pb!==this.eb&&t.l("the List has been modified during iteration");var a=a.p,b=a.length,c=++this.oe,d=this.Pn;if(null!==d)for(;ca||a>=b.length)&&t.ia(a,"0 <= i < length",A,"elt:i");return b[a]}; -A.prototype.setElt=A.prototype.set=A.prototype.jg=function(a,b){f&&(this.pg(b),t.o(a,A,"setElt:i"));var c=this.p;(0>a||a>=c.length)&&t.ia(a,"0 <= i < length",A,"setElt:i");t.L(this,a);c[a]=b};A.prototype.first=A.prototype.Ya=function(){var a=this.p;return 0===a.length?null:a[0]};A.prototype.insertAt=A.prototype.td=function(a,b){f&&(this.pg(b),t.o(a,A,"insertAt:i"));0>a&&t.ia(a,">= 0",A,"insertAt:i");t.L(this,a);var c=this.p;a>=c.length?c.push(b):c.splice(a,0,b);this.Dd();return!0}; -A.prototype.remove=A.prototype["delete"]=A.prototype.remove=function(a){if(null===a)return!1;f&&this.pg(a);t.L(this,a);var b=this.p;a=b.indexOf(a);if(-1===a)return!1;a===b.length-1?b.pop():b.splice(a,1);this.Dd();return!0};A.prototype.removeAt=A.prototype.Zc=function(a){f&&t.o(a,A,"removeAt:i");var b=this.p;(0>a||a>=b.length)&&t.ia(a,"0 <= i < length",A,"removeAt:i");t.L(this,a);a===b.length-1?b.pop():b.splice(a,1);this.Dd()}; -A.prototype.removeRange=A.prototype.removeRange=function(a,b){f&&(t.o(a,A,"removeRange:from"),t.o(b,A,"removeRange:to"));var c=this.p;(0>a||a>=c.length)&&t.ia(a,"0 <= from < length",A,"elt:from");(0>b||b>=c.length)&&t.ia(b,"0 <= to < length",A,"elt:to");t.L(this,a);var d=c.slice((b||a)+1||c.length);c.length=0>a?c.length+a:a;c.push.apply(c,d);this.Dd()};A.prototype.copy=function(){for(var a=new A(this.Z),b=this.p,c=this.count,d=0;d=g)return this;(0>b||b>=e-1)&&t.ia(b,"0 <= from < length",A,"sortRange:from");if(2===g)return c=d[b],e=d[b+1],0=e)d.sort(a);else for(g=d.slice(0,c),g.sort(a),a=0;a=e)for(g=d.slice(b),g.sort(a), -a=b;a=this.p.length)return t.Pg;var a=this.eh;return null!==a?(a.reset(),a):new Aa(this)}); -t.A(A,{Bm:"iteratorBackwards"},function(){if(0>=this.p.length)return t.Pg;var a=this.ly;return null!==a?(a.reset(),a):new Ba(this)});function Ca(a){this.q=a;this.reset()}t.be(Ca,{key:!0,value:!0});t.A(Ca,{m:"iterator"},function(){return this});Ca.prototype.reset=Ca.prototype.reset=function(){var a=this.q;a.eh=null;this.eb=a.Pb;this.Vd=null}; -Ca.prototype.next=Ca.prototype.hasNext=Ca.prototype.next=function(){var a=this.q;a.Pb!==this.eb&&t.l("the Set has been modified during iteration");var b=this.Vd,b=null===b?a.ne:b.oj;if(null!==b)return this.Vd=b,this.value=b.value,this.key=b.key,!0;this.sg();return!1};Ca.prototype.first=Ca.prototype.Ya=function(){var a=this.q;this.eb=a.Pb;a=a.ne;if(null!==a){this.Vd=a;var b=a.value;this.key=a.key;return this.value=b}return null};t.A(Ca,{count:"count"},function(){return this.q.cd}); -Ca.prototype.sg=function(){this.value=null;this.eb=-1;this.q.eh=this};Ca.prototype.toString=function(){return null!==this.Vd?"SetIterator@"+this.Vd.value:"SetIterator"}; -function la(a){t.uc(this);this.cb=!1;void 0===a||null===a?this.Z=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.Z=a:t.ia(a,"the string 'object', 'number' or 'string'","Set constructor: type"):"function"===typeof a?this.Z=a===Object?"object":a===String?"string":a===Number?"number":a:t.ia(a,"null, a primitive type name, or a class type","Set constructor: type");this.Oc={};this.cd=0;this.eh=null;this.Pb=0;this.gh=this.ne=null}t.ea("Set",la); -la.prototype.pg=function(a){null!==this.Z&&("string"===typeof this.Z?typeof a===this.Z&&null!==a||t.Nb(a,this.Z):a instanceof this.Z||t.Nb(a,this.Z))};la.prototype.Dd=function(){var a=this.Pb;a++;999999999=this.cd)return t.Pg;var a=this.eh;return null!==a?(a.reset(),a):new Ca(this)});function Ea(a){this.wc=a;this.reset()}t.be(Ea,{key:!0,value:!0});t.A(Ea,{m:"iterator"},function(){return this});Ea.prototype.reset=Ea.prototype.reset=function(){this.eb=this.wc.Pb;this.Vd=null}; -Ea.prototype.next=Ea.prototype.hasNext=Ea.prototype.next=function(){var a=this.wc;a.Pb!==this.eb&&t.l("the Map has been modified during iteration");var b=this.Vd,b=null===b?a.ne:b.oj;if(null!==b)return this.Vd=b,this.value=this.key=a=b.key,!0;this.sg();return!1};Ea.prototype.first=Ea.prototype.Ya=function(){var a=this.wc;this.eb=a.Pb;a=a.ne;return null!==a?(this.Vd=a,this.value=this.key=a=a.key):null};t.A(Ea,{count:"count"},function(){return this.wc.cd}); -Ea.prototype.sg=function(){this.value=null;this.eb=-1};Ea.prototype.toString=function(){return null!==this.Vd?"MapKeySetIterator@"+this.Vd.value:"MapKeySetIterator"};function Fa(a){t.uc(this);this.cb=!0;this.wc=a}t.Ja(Fa,la);Fa.prototype.freeze=function(){return this};Fa.prototype.Pa=function(){return this};Fa.prototype.toString=function(){return"MapKeySet("+this.wc.toString()+")"};Fa.prototype.add=Fa.prototype.set=Fa.prototype.add=function(){t.l("This Set is read-only: "+this.toString());return!1}; -Fa.prototype.contains=Fa.prototype.has=Fa.prototype.contains=function(a){return this.wc.contains(a)};Fa.prototype.remove=Fa.prototype["delete"]=Fa.prototype.remove=function(){t.l("This Set is read-only: "+this.toString());return!1};Fa.prototype.clear=Fa.prototype.clear=function(){t.l("This Set is read-only: "+this.toString())};Fa.prototype.first=Fa.prototype.Ya=function(){var a=this.wc.ne;return null!==a?a.key:null};Fa.prototype.copy=function(){return new Fa(this.wc)}; -Fa.prototype.toSet=function(){var a=new la(this.wc.fh),b=this.wc.Oc,c;for(c in b)a.add(b[c].key);return a};Fa.prototype.toArray=Fa.prototype.Ve=function(){var a=this.wc.Oc,b=Array(this.wc.cd),c=0,d;for(d in a)b[c]=a[d].key,c++;return b};Fa.prototype.toList=function(){var a=new A(this.Z),b=this.wc.Oc,c;for(c in b)a.add(b[c].key);return a};t.A(Fa,{count:"count"},function(){return this.wc.cd});t.A(Fa,{size:"size"},function(){return this.wc.cd}); -t.A(Fa,{m:"iterator"},function(){return 0>=this.wc.cd?t.Pg:new Ea(this.wc)});function Da(a,b){this.key=a;this.value=b;this.Qn=this.oj=null}t.be(Da,{key:!0,value:!0});Da.prototype.toString=function(){return"{"+this.key+":"+this.value+"}"};function Ia(a){this.wc=a;this.reset()}t.be(Ia,{key:!0,value:!0});t.A(Ia,{m:"iterator"},function(){return this});Ia.prototype.reset=Ia.prototype.reset=function(){var a=this.wc;a.eh=null;this.eb=a.Pb;this.Vd=null}; -Ia.prototype.next=Ia.prototype.hasNext=Ia.prototype.next=function(){var a=this.wc;a.Pb!==this.eb&&t.l("the Map has been modified during iteration");var b=this.Vd,b=null===b?a.ne:b.oj;if(null!==b)return this.Vd=b,this.key=b.key,this.value=b.value,!0;this.sg();return!1};Ia.prototype.first=Ia.prototype.Ya=function(){var a=this.wc;this.eb=a.Pb;a=a.ne;if(null!==a){this.Vd=a;var b=a.key;this.key=b;this.value=a.value;return b}return null};t.A(Ia,{count:"count"},function(){return this.wc.cd}); -Ia.prototype.sg=function(){this.value=this.key=null;this.eb=-1;this.wc.eh=this};Ia.prototype.toString=function(){return null!==this.Vd?"MapIterator@"+this.Vd:"MapIterator"}; -function ia(a,b){t.uc(this);this.cb=!1;void 0===a||null===a?this.fh=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.fh=a:t.ia(a,"the string 'object', 'number' or 'string'","Map constructor: keytype"):"function"===typeof a?this.fh=a===Object?"object":a===String?"string":a===Number?"number":a:t.ia(a,"null, a primitive type name, or a class type","Map constructor: keytype");void 0===b||null===b?this.oi=null:"string"===typeof b?"object"===b||"string"===b||"boolean"===b||"number"=== -b||"function"===b?this.oi=b:t.ia(b,"the string 'object', 'number', 'string', 'boolean', or 'function'","Map constructor: valtype"):"function"===typeof b?this.oi=b===Object?"object":b===String?"string":b===Number?"number":b===Boolean?"boolean":b===Function?"function":b:t.ia(b,"null, a primitive type name, or a class type","Map constructor: valtype");this.Oc={};this.cd=0;this.eh=null;this.Pb=0;this.gh=this.ne=null}t.ea("Map",ia); -function La(a,b){null!==a.fh&&("string"===typeof a.fh?typeof b===a.fh&&null!==b||t.Nb(b,a.fh):b instanceof a.fh||t.Nb(b,a.fh))}ia.prototype.Dd=function(){var a=this.Pb;a++;999999999=this.count)return t.Pg;var a=this.eh;return null!==a?(a.reset(),a):new Ia(this)});function v(a,b){void 0===a||void 0===b?this.y=this.x=0:!f||"number"===typeof a&&"number"===typeof b?(this.x=a,this.y=b):t.l("Invalid arguments to Point constructor")}t.ea("Point",v);t.th(v);t.be(v,{x:!0,y:!0});v.prototype.assign=function(a){this.x=a.x;this.y=a.y};v.prototype.q=function(a,b){this.x=a;this.y=b}; -v.prototype.setTo=v.prototype.pp=function(a,b){f&&(t.j(a,"number",v,"setTo:x"),t.j(b,"number",v,"setTo:y"));t.L(this);this.x=a;this.y=b;return this};v.prototype.set=v.prototype.set=function(a){f&&t.k(a,v,v,"set:p");t.L(this);this.x=a.x;this.y=a.y;return this};v.prototype.copy=function(){var a=new v;a.x=this.x;a.y=this.y;return a};v.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};v.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; -v.prototype.freeze=function(){this.cb=!0;return this};v.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};v.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new v(c,e)}return new v};v.stringify=function(a){return a instanceof v?a.x.toString()+" "+a.y.toString():a.toString()}; -v.prototype.toString=function(){return"Point("+this.x+","+this.y+")"};v.prototype.equals=v.prototype.K=function(a){return a instanceof v?this.x===a.x&&this.y===a.y:!1};v.prototype.equalTo=function(a,b){return this.x===a&&this.y===b};v.prototype.Oj=function(a){return D.Fa(this.x,a.x)&&D.Fa(this.y,a.y)};v.prototype.zi=function(a){return D.I(this.x,a.x)&&D.I(this.y,a.y)};v.prototype.add=v.prototype.add=function(a){f&&t.k(a,v,v,"add:p");t.L(this);this.x+=a.x;this.y+=a.y;return this}; -v.prototype.subtract=v.prototype.it=function(a){f&&t.k(a,v,v,"subtract:p");t.L(this);this.x-=a.x;this.y-=a.y;return this};v.prototype.offset=v.prototype.offset=function(a,b){f&&(t.o(a,v,"offset:dx"),t.o(b,v,"offset:dy"));t.L(this);this.x+=a;this.y+=b;return this}; -v.prototype.rotate=v.prototype.rotate=function(a){f&&t.o(a,v,"rotate:angle");t.L(this);if(0===a)return this;var b=this.x,c=this.y;if(0===b&&0===c)return this;var d;90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));this.x=a*b-d*c;this.y=d*b+a*c;return this};v.prototype.scale=v.prototype.scale=function(a,b){f&&(t.o(a,v,"scale:sx"),t.o(b,v,"scale:sy"));this.x*=a;this.y*=b;return this}; -v.prototype.distanceSquaredPoint=v.prototype.Mj=function(a){f&&t.k(a,v,v,"distanceSquaredPoint:p");var b=a.x-this.x;a=a.y-this.y;return b*b+a*a};v.prototype.distanceSquared=v.prototype.ps=function(a,b){f&&(t.o(a,v,"distanceSquared:px"),t.o(b,v,"distanceSquared:py"));var c=a-this.x,d=b-this.y;return c*c+d*d};v.prototype.normalize=v.prototype.normalize=function(){t.L(this);var a=this.x,b=this.y,c=Math.sqrt(a*a+b*b);0b?270:0;if(0===b)return 0a?c=0>b?c+180:180-c:0>b&&(c=360-c);return c} -v.prototype.projectOntoLineSegment=function(a,b,c,d){f&&(t.o(a,v,"projectOntoLineSegment:px"),t.o(b,v,"projectOntoLineSegment:py"),t.o(c,v,"projectOntoLineSegment:qx"),t.o(d,v,"projectOntoLineSegment:qy"));D.Hm(a,b,c,d,this.x,this.y,this);return this};v.prototype.projectOntoLineSegmentPoint=function(a,b){f&&(t.k(a,v,v,"projectOntoLineSegmentPoint:p"),t.k(b,v,v,"projectOntoLineSegmentPoint:q"));D.Hm(a.x,a.y,b.x,b.y,this.x,this.y,this);return this}; -v.prototype.snapToGrid=function(a,b,c,d){f&&(t.o(a,v,"snapToGrid:originx"),t.o(b,v,"snapToGrid:originy"),t.o(c,v,"snapToGrid:cellwidth"),t.o(d,v,"snapToGrid:cellheight"));D.ss(this.x,this.y,a,b,c,d,this);return this};v.prototype.snapToGridPoint=function(a,b){f&&(t.k(a,v,v,"snapToGridPoint:p"),t.k(b,ea,v,"snapToGridPoint:q"));D.ss(this.x,this.y,a.x,a.y,b.width,b.height,this);return this}; -v.prototype.setRectSpot=v.prototype.et=function(a,b){f&&(t.k(a,w,v,"setRectSpot:r"),t.k(b,H,v,"setRectSpot:spot"));t.L(this);this.x=a.x+b.x*a.width+b.offsetX;this.y=a.y+b.y*a.height+b.offsetY;return this}; -v.prototype.setSpot=v.prototype.ft=function(a,b,c,d,e){f&&(t.o(a,v,"setSpot:x"),t.o(b,v,"setSpot:y"),t.o(c,v,"setSpot:w"),t.o(d,v,"setSpot:h"),(0>c||0>d)&&t.l("Point.setSpot:Width and height cannot be negative"),t.k(e,H,v,"setSpot:spot"));t.L(this);this.x=a+e.x*c+e.offsetX;this.y=b+e.y*d+e.offsetY;return this};v.prototype.transform=function(a){f&&t.k(a,fa,v,"transform:t");a.Qa(this);return this};function Oa(a,b){f&&t.k(b,fa,v,"transformInverted:t");b.Ci(a);return a}var Pa; -v.distanceLineSegmentSquared=Pa=function(a,b,c,d,e,g){f&&(t.o(a,v,"distanceLineSegmentSquared:px"),t.o(b,v,"distanceLineSegmentSquared:py"),t.o(c,v,"distanceLineSegmentSquared:ax"),t.o(d,v,"distanceLineSegmentSquared:ay"),t.o(e,v,"distanceLineSegmentSquared:bx"),t.o(g,v,"distanceLineSegmentSquared:by"));var h=e-c,k=g-d,l=h*h+k*k;c-=a;d-=b;var m=-c*h-d*k;if(0>=m||m>=l)return h=e-a,k=g-b,Math.min(c*c+d*d,h*h+k*k);a=h*d-k*c;return a*a/l};var Qa; -v.distanceSquared=Qa=function(a,b,c,d){f&&(t.o(a,v,"distanceSquared:px"),t.o(b,v,"distanceSquared:py"),t.o(c,v,"distanceSquared:qx"),t.o(d,v,"distanceSquared:qy"));a=c-a;b=d-b;return a*a+b*b};var Ra; -v.direction=Ra=function(a,b,c,d){f&&(t.o(a,v,"direction:px"),t.o(b,v,"direction:py"),t.o(c,v,"direction:qx"),t.o(d,v,"direction:qy"));a=c-a;b=d-b;if(0===a)return 0b?270:0;if(0===b)return 0a?d=0>b?d+180:180-d:0>b&&(d=360-d);return d};v.prototype.isReal=v.prototype.P=function(){return isFinite(this.x)&&isFinite(this.y)}; -function ea(a,b){void 0===a||void 0===b?this.height=this.width=0:!f||"number"===typeof a&&(0<=a||isNaN(a))&&"number"===typeof b&&(0<=b||isNaN(b))?(this.width=a,this.height=b):t.l("Invalid arguments to Size constructor")}t.ea("Size",ea);t.th(ea);t.be(ea,{width:!0,height:!0});ea.prototype.assign=function(a){this.width=a.width;this.height=a.height};ea.prototype.q=function(a,b){this.width=a;this.height=b}; -ea.prototype.setTo=ea.prototype.pp=function(a,b){f&&(t.j(a,"number",ea,"setTo:w"),t.j(b,"number",ea,"setTo:h"));0>a&&t.ia(a,">= 0",ea,"setTo:w");0>b&&t.ia(b,">= 0",ea,"setTo:h");t.L(this);this.width=a;this.height=b;return this};ea.prototype.set=ea.prototype.set=function(a){f&&t.k(a,ea,ea,"set:s");t.L(this);this.width=a.width;this.height=a.height;return this};ea.prototype.copy=function(){var a=new ea;a.width=this.width;a.height=this.height;return a}; -ea.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};ea.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()};ea.prototype.freeze=function(){this.cb=!0;return this};ea.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this}; -ea.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new ea(c,e)}return new ea};ea.stringify=function(a){return a instanceof ea?a.width.toString()+" "+a.height.toString():a.toString()};ea.prototype.toString=function(){return"Size("+this.width+","+this.height+")"}; -ea.prototype.equals=ea.prototype.K=function(a){return a instanceof ea?this.width===a.width&&this.height===a.height:!1};ea.prototype.equalTo=function(a,b){return this.width===a&&this.height===b};ea.prototype.Oj=function(a){return D.Fa(this.width,a.width)&&D.Fa(this.height,a.height)};ea.prototype.zi=function(a){return D.I(this.width,a.width)&&D.I(this.height,a.height)};ea.prototype.isReal=ea.prototype.P=function(){return isFinite(this.width)&&isFinite(this.height)}; -function w(a,b,c,d){void 0===a?this.height=this.width=this.y=this.x=0:a instanceof v?b instanceof v?(this.x=Math.min(a.x,b.x),this.y=Math.min(a.y,b.y),this.width=Math.abs(a.x-b.x),this.height=Math.abs(a.y-b.y)):b instanceof ea?(this.x=a.x,this.y=a.y,this.width=b.width,this.height=b.height):t.l("Incorrect arguments supplied"):!f||"number"===typeof a&&"number"===typeof b&&"number"===typeof c&&(0<=c||isNaN(c))&&"number"===typeof d&&(0<=d||isNaN(d))?(this.x=a,this.y=b,this.width=c,this.height=d):t.l("Invalid arguments to Rect constructor")} -t.ea("Rect",w);t.th(w);t.be(w,{x:!0,y:!0,width:!0,height:!0});w.prototype.assign=function(a){this.x=a.x;this.y=a.y;this.width=a.width;this.height=a.height};w.prototype.q=function(a,b,c,d){this.x=a;this.y=b;this.width=c;this.height=d};function Sa(a,b,c){a.width=b;a.height=c} -w.prototype.setTo=w.prototype.pp=function(a,b,c,d){f&&(t.j(a,"number",w,"setTo:x"),t.j(b,"number",w,"setTo:y"),t.j(c,"number",w,"setTo:w"),t.j(d,"number",w,"setTo:h"));0>c&&t.ia(c,">= 0",w,"setTo:w");0>d&&t.ia(d,">= 0",w,"setTo:h");t.L(this);this.x=a;this.y=b;this.width=c;this.height=d;return this};w.prototype.set=w.prototype.set=function(a){f&&t.k(a,w,w,"set:r");t.L(this);this.x=a.x;this.y=a.y;this.width=a.width;this.height=a.height;return this}; -w.prototype.setPoint=w.prototype.of=function(a){f&&t.k(a,v,w,"setPoint:p");t.L(this);this.x=a.x;this.y=a.y;return this};w.prototype.setSize=function(a){f&&t.k(a,ea,w,"setSize:s");t.L(this);this.width=a.width;this.height=a.height;return this};w.prototype.copy=function(){var a=new w;a.x=this.x;a.y=this.y;a.width=this.width;a.height=this.height;return a};w.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};w.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; -w.prototype.freeze=function(){this.cb=!0;return this};w.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};w.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new w(c,e,g,h)}return new w}; -w.stringify=function(a){return a instanceof w?a.x.toString()+" "+a.y.toString()+" "+a.width.toString()+" "+a.height.toString():a.toString()};w.prototype.toString=function(){return"Rect("+this.x+","+this.y+","+this.width+","+this.height+")"};w.prototype.equals=w.prototype.K=function(a){return a instanceof w?this.x===a.x&&this.y===a.y&&this.width===a.width&&this.height===a.height:!1};w.prototype.equalTo=function(a,b,c,d){return this.x===a&&this.y===b&&this.width===c&&this.height===d}; -w.prototype.Oj=function(a){return D.Fa(this.x,a.x)&&D.Fa(this.y,a.y)&&D.Fa(this.width,a.width)&&D.Fa(this.height,a.height)};w.prototype.zi=function(a){return D.I(this.x,a.x)&&D.I(this.y,a.y)&&D.I(this.width,a.width)&&D.I(this.height,a.height)};w.prototype.containsPoint=w.prototype.Da=function(a){f&&t.k(a,v,w,"containsPoint:p");return this.x<=a.x&&this.x+this.width>=a.x&&this.y<=a.y&&this.y+this.height>=a.y}; -w.prototype.containsRect=w.prototype.Ij=function(a){f&&t.k(a,w,w,"containsRect:r");return this.x<=a.x&&a.x+a.width<=this.x+this.width&&this.y<=a.y&&a.y+a.height<=this.y+this.height}; -w.prototype.contains=w.prototype.contains=function(a,b,c,d){f?(t.o(a,w,"contains:x"),t.o(b,w,"contains:y"),void 0===c?c=0:t.o(c,w,"contains:w"),void 0===d?d=0:t.o(d,w,"contains:h"),(0>c||0>d)&&t.l("Rect.contains:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return this.x<=a&&a+c<=this.x+this.width&&this.y<=b&&b+d<=this.y+this.height};w.prototype.reset=function(){t.L(this);this.height=this.width=this.y=this.x=0}; -w.prototype.offset=w.prototype.offset=function(a,b){f&&(t.o(a,w,"offset:dx"),t.o(b,w,"offset:dy"));t.L(this);this.x+=a;this.y+=b;return this};w.prototype.inflate=w.prototype.Hg=function(a,b){f&&(t.o(a,w,"inflate:w"),t.o(b,w,"inflate:h"));return Ua(this,b,a,b,a)};w.prototype.addMargin=w.prototype.mv=function(a){f&&t.k(a,Va,w,"addMargin:m");return Ua(this,a.top,a.right,a.bottom,a.left)}; -w.prototype.subtractMargin=w.prototype.EI=function(a){f&&t.k(a,Va,w,"subtractMargin:m");return Ua(this,-a.top,-a.right,-a.bottom,-a.left)};w.prototype.grow=function(a,b,c,d){f&&(t.o(a,w,"grow:t"),t.o(b,w,"grow:r"),t.o(c,w,"grow:b"),t.o(d,w,"grow:l"));return Ua(this,a,b,c,d)};function Ua(a,b,c,d,e){t.L(a);var g=a.width;c+e<=-g?(a.x+=g/2,a.width=0):(a.x-=e,a.width+=c+e);c=a.height;b+d<=-c?(a.y+=c/2,a.height=0):(a.y-=b,a.height+=b+d);return a} -w.prototype.intersectRect=function(a){f&&t.k(a,w,w,"intersectRect:r");return Xa(this,a.x,a.y,a.width,a.height)};w.prototype.intersect=function(a,b,c,d){f&&(t.o(a,w,"intersect:x"),t.o(b,w,"intersect:y"),t.o(c,w,"intersect:w"),t.o(d,w,"intersect:h"),(0>c||0>d)&&t.l("Rect.intersect:Width and height cannot be negative"));return Xa(this,a,b,c,d)}; -function Xa(a,b,c,d,e){t.L(a);var g=Math.max(a.x,b),h=Math.max(a.y,c);b=Math.min(a.x+a.width,b+d);c=Math.min(a.y+a.height,c+e);a.x=g;a.y=h;a.width=Math.max(0,b-g);a.height=Math.max(0,c-h);return a}w.prototype.intersectsRect=w.prototype.Bf=function(a){f&&t.k(a,w,w,"intersectsRect:r");return this.VD(a.x,a.y,a.width,a.height)}; -w.prototype.intersects=w.prototype.VD=function(a,b,c,d){f&&(t.o(a,w,"intersects:x"),t.o(b,w,"intersects:y"),t.o(a,w,"intersects:w"),t.o(b,w,"intersects:h"),(0>c||0>d)&&t.l("Rect.intersects:Width and height cannot be negative"));var e=this.width,g=this.x;if(Infinity!==e&&Infinity!==c&&(e+=g,c+=a,isNaN(c)||isNaN(e)||g>c||a>e))return!1;a=this.height;c=this.y;return Infinity!==a&&Infinity!==d&&(a+=c,d+=b,isNaN(d)||isNaN(a)||c>d||b>a)?!1:!0}; -function $a(a,b){var c=a.width,d=b.width+10+10,e=a.x,g=b.x-10;if(e>d+g||g>c+e)return!1;c=a.height;d=b.height+10+10;e=a.y;g=b.y-10;return e>d+g||g>c+e?!1:!0}w.prototype.unionPoint=w.prototype.Mi=function(a){f&&t.k(a,v,w,"unionPoint:p");return cb(this,a.x,a.y,0,0)};w.prototype.unionRect=w.prototype.$j=function(a){f&&t.k(a,w,w,"unionRect:r");return cb(this,a.x,a.y,a.width,a.height)}; -w.prototype.union=w.prototype.DF=function(a,b,c,d){t.L(this);f?(t.o(a,w,"union:x"),t.o(b,w,"union:y"),void 0===c?c=0:t.o(c,w,"union:w"),void 0===d?d=0:t.o(d,w,"union:h"),(0>c||0>d)&&t.l("Rect.union:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return cb(this,a,b,c,d)};function cb(a,b,c,d,e){var g=Math.min(a.x,b),h=Math.min(a.y,c);b=Math.max(a.x+a.width,b+d);c=Math.max(a.y+a.height,c+e);a.x=g;a.y=h;a.width=b-g;a.height=c-h;return a} -w.prototype.setSpot=w.prototype.ft=function(a,b,c){f&&(t.o(a,w,"setSpot:x"),t.o(b,w,"setSpot:y"),t.k(c,H,w,"setSpot:spot"));t.L(this);this.x=a-c.offsetX-c.x*this.width;this.y=b-c.offsetY-c.y*this.height;return this};var eb; -w.contains=eb=function(a,b,c,d,e,g,h,k){f?(t.o(a,w,"contains:rx"),t.o(b,w,"contains:ry"),t.o(c,w,"contains:rw"),t.o(d,w,"contains:rh"),t.o(e,w,"contains:x"),t.o(g,w,"contains:y"),void 0===h?h=0:t.o(h,w,"contains:w"),void 0===k?k=0:t.o(k,w,"contains:h"),(0>c||0>d||0>h||0>k)&&t.l("Rect.contains:Width and height cannot be negative")):(void 0===h&&(h=0),void 0===k&&(k=0));return a<=e&&e+h<=a+c&&b<=g&&g+k<=b+d}; -w.intersects=function(a,b,c,d,e,g,h,k){f&&(t.o(a,w,"intersects:rx"),t.o(b,w,"intersects:ry"),t.o(c,w,"intersects:rw"),t.o(d,w,"intersects:rh"),t.o(e,w,"intersects:x"),t.o(g,w,"intersects:y"),t.o(h,w,"intersects:w"),t.o(k,w,"intersects:h"),(0>c||0>d||0>h||0>k)&&t.l("Rect.intersects:Width and height cannot be negative"));c+=a;h+=e;if(a>h||e>c)return!1;a=d+b;k+=g;return b>k||g>a?!1:!0};t.g(w,"left",w.prototype.left); -t.defineProperty(w,{left:"left"},function(){return this.x},function(a){t.L(this,a);f&&t.j(a,"number",w,"left");this.x=a});t.g(w,"top",w.prototype.top);t.defineProperty(w,{top:"top"},function(){return this.y},function(a){t.L(this,a);f&&t.j(a,"number",w,"top");this.y=a});t.g(w,"right",w.prototype.right);t.defineProperty(w,{right:"right"},function(){return this.x+this.width},function(a){t.L(this,a);f&&t.o(a,w,"right");this.x+=a-(this.x+this.width)});t.g(w,"bottom",w.prototype.bottom); -t.defineProperty(w,{bottom:"bottom"},function(){return this.y+this.height},function(a){t.L(this,a);f&&t.o(a,w,"top");this.y+=a-(this.y+this.height)});t.g(w,"position",w.prototype.position);t.defineProperty(w,{position:"position"},function(){return new v(this.x,this.y)},function(a){t.L(this,a);f&&t.k(a,v,w,"position");this.x=a.x;this.y=a.y});t.g(w,"size",w.prototype.size); -t.defineProperty(w,{size:"size"},function(){return new ea(this.width,this.height)},function(a){t.L(this,a);f&&t.k(a,ea,w,"size");this.width=a.width;this.height=a.height});t.g(w,"center",w.prototype.tz);t.defineProperty(w,{tz:"center"},function(){return new v(this.x+this.width/2,this.y+this.height/2)},function(a){t.L(this,a);f&&t.k(a,v,w,"center");this.x=a.x-this.width/2;this.y=a.y-this.height/2});t.g(w,"centerX",w.prototype.Aa); -t.defineProperty(w,{Aa:"centerX"},function(){return this.x+this.width/2},function(a){t.L(this,a);f&&t.o(a,w,"centerX");this.x=a-this.width/2});t.g(w,"centerY",w.prototype.Ma);t.defineProperty(w,{Ma:"centerY"},function(){return this.y+this.height/2},function(a){t.L(this,a);f&&t.o(a,w,"centerY");this.y=a-this.height/2});w.prototype.isReal=w.prototype.P=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)}; -w.prototype.isEmpty=function(){return 0===this.width&&0===this.height};function Va(a,b,c,d){void 0===a?this.left=this.bottom=this.right=this.top=0:void 0===b?this.left=this.bottom=this.right=this.top=a:void 0===c?(d=b,this.top=a,this.right=b,this.bottom=a,this.left=d):void 0!==d?(this.top=a,this.right=b,this.bottom=c,this.left=d):t.l("Invalid arguments to Margin constructor")}t.ea("Margin",Va);t.th(Va);t.be(Va,{top:!0,right:!0,bottom:!0,left:!0}); -Va.prototype.assign=function(a){this.top=a.top;this.right=a.right;this.bottom=a.bottom;this.left=a.left};Va.prototype.setTo=Va.prototype.pp=function(a,b,c,d){f&&(t.j(a,"number",Va,"setTo:t"),t.j(b,"number",Va,"setTo:r"),t.j(c,"number",Va,"setTo:b"),t.j(d,"number",Va,"setTo:l"));t.L(this);this.top=a;this.right=b;this.bottom=c;this.left=d;return this}; -Va.prototype.set=Va.prototype.set=function(a){f&&t.k(a,Va,Va,"assign:m");t.L(this);this.top=a.top;this.right=a.right;this.bottom=a.bottom;this.left=a.left;return this};Va.prototype.copy=function(){var a=new Va;a.top=this.top;a.right=this.right;a.bottom=this.bottom;a.left=this.left;return a};Va.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};Va.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()};Va.prototype.freeze=function(){this.cb=!0;return this}; -Va.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};Va.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=void 0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=void 0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=void 0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new Va(c,e,g,h)}return new Va}; -Va.stringify=function(a){return a instanceof Va?a.top.toString()+" "+a.right.toString()+" "+a.bottom.toString()+" "+a.left.toString():a.toString()};Va.prototype.toString=function(){return"Margin("+this.top+","+this.right+","+this.bottom+","+this.left+")"};Va.prototype.equals=Va.prototype.K=function(a){return a instanceof Va?this.top===a.top&&this.right===a.right&&this.bottom===a.bottom&&this.left===a.left:!1}; -Va.prototype.equalTo=function(a,b,c,d){return this.top===a&&this.right===b&&this.bottom===c&&this.left===d};Va.prototype.Oj=function(a){return D.Fa(this.top,a.top)&&D.Fa(this.right,a.right)&&D.Fa(this.bottom,a.bottom)&&D.Fa(this.left,a.left)};Va.prototype.zi=function(a){return D.I(this.top,a.top)&&D.I(this.right,a.right)&&D.I(this.bottom,a.bottom)&&D.I(this.left,a.left)};Va.prototype.isReal=Va.prototype.P=function(){return isFinite(this.top)&&isFinite(this.right)&&isFinite(this.bottom)&&isFinite(this.left)}; -function fa(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}t.th(fa);t.be(fa,{m11:!0,m12:!0,m21:!0,m22:!0,dx:!0,dy:!0});fa.prototype.set=fa.prototype.set=function(a){f&&t.k(a,fa,fa,"set:t");this.m11=a.m11;this.m12=a.m12;this.m21=a.m21;this.m22=a.m22;this.dx=a.dx;this.dy=a.dy;return this};fa.prototype.copy=function(){var a=new fa;a.m11=this.m11;a.m12=this.m12;a.m21=this.m21;a.m22=this.m22;a.dx=this.dx;a.dy=this.dy;return a}; -fa.prototype.toString=function(){return"Transform("+this.m11+","+this.m12+","+this.m21+","+this.m22+","+this.dx+","+this.dy+")"};fa.prototype.equals=fa.prototype.K=function(a){return a instanceof fa?this.m11===a.m11&&this.m12===a.m12&&this.m21===a.m21&&this.m22===a.m22&&this.dx===a.dx&&this.dy===a.dy:!1};fa.prototype.reset=fa.prototype.reset=function(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}; -fa.prototype.multiply=fa.prototype.multiply=function(a){f&&t.k(a,fa,fa,"multiply:matrix");var b=this.m12*a.m11+this.m22*a.m12,c=this.m11*a.m21+this.m21*a.m22,d=this.m12*a.m21+this.m22*a.m22,e=this.m11*a.dx+this.m21*a.dy+this.dx,g=this.m12*a.dx+this.m22*a.dy+this.dy;this.m11=this.m11*a.m11+this.m21*a.m12;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g;return this}; -fa.prototype.multiplyInverted=fa.prototype.vE=function(a){f&&t.k(a,fa,fa,"multiplyInverted:matrix");var b=1/(a.m11*a.m22-a.m12*a.m21),c=a.m22*b,d=-a.m12*b,e=-a.m21*b,g=a.m11*b,h=b*(a.m21*a.dy-a.m22*a.dx),k=b*(a.m12*a.dx-a.m11*a.dy);a=this.m12*c+this.m22*d;b=this.m11*e+this.m21*g;e=this.m12*e+this.m22*g;g=this.m11*h+this.m21*k+this.dx;h=this.m12*h+this.m22*k+this.dy;this.m11=this.m11*c+this.m21*d;this.m12=a;this.m21=b;this.m22=e;this.dx=g;this.dy=h;return this}; -fa.prototype.invert=fa.prototype.Qz=function(){var a=1/(this.m11*this.m22-this.m12*this.m21),b=-this.m12*a,c=-this.m21*a,d=this.m11*a,e=a*(this.m21*this.dy-this.m22*this.dx),g=a*(this.m12*this.dx-this.m11*this.dy);this.m11=this.m22*a;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g}; -fa.prototype.rotate=fa.prototype.rotate=function(a,b,c){f&&(t.o(a,fa,"rotate:angle"),t.o(b,fa,"rotate:rx"),t.o(c,fa,"rotate:ry"));this.translate(b,c);var d;0===a?(a=1,d=0):90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));var e=this.m12*a+this.m22*d,g=this.m11*-d+this.m21*a,h=this.m12*-d+this.m22*a;this.m11=this.m11*a+this.m21*d;this.m12=e;this.m21=g;this.m22=h;this.translate(-b,-c)}; -fa.prototype.translate=fa.prototype.translate=function(a,b){f&&(t.o(a,fa,"translate:x"),t.o(b,fa,"translate:y"));this.dx+=this.m11*a+this.m21*b;this.dy+=this.m12*a+this.m22*b};fa.prototype.scale=fa.prototype.scale=function(a,b){void 0===b&&(b=a);f&&(t.o(a,fa,"translate:sx"),t.o(b,fa,"translate:sy"));this.m11*=a;this.m12*=a;this.m21*=b;this.m22*=b}; -fa.prototype.transformPoint=fa.prototype.Qa=function(a){f&&t.k(a,v,fa,"transformPoint:p");var b=a.x,c=a.y;a.x=b*this.m11+c*this.m21+this.dx;a.y=b*this.m12+c*this.m22+this.dy;return a};fa.prototype.invertedTransformPoint=fa.prototype.Ci=function(a){f&&t.k(a,v,fa,"invertedTransformPoint:p");var b=1/(this.m11*this.m22-this.m12*this.m21),c=-this.m12*b,d=this.m11*b,e=b*(this.m12*this.dx-this.m11*this.dy),g=a.x,h=a.y;a.x=g*this.m22*b+h*-this.m21*b+b*(this.m21*this.dy-this.m22*this.dx);a.y=g*c+h*d+e;return a}; -fa.prototype.transformRect=fa.prototype.yF=function(a){f&&t.k(a,w,fa,"transformRect:rect");var b=a.x,c=a.y,d=b+a.width,e=c+a.height,g=this.m11,h=this.m12,k=this.m21,l=this.m22,m=this.dx,n=this.dy,p=b*g+c*k+m,q=b*h+c*l+n,r=d*g+c*k+m,c=d*h+c*l+n,s=b*g+e*k+m,b=b*h+e*l+n,g=d*g+e*k+m,d=d*h+e*l+n,e=p,h=q,p=Math.min(p,r),e=Math.max(e,r),h=Math.min(h,c),q=Math.max(q,c),p=Math.min(p,s),e=Math.max(e,s),h=Math.min(h,b),q=Math.max(q,b),p=Math.min(p,g),e=Math.max(e,g),h=Math.min(h,d),q=Math.max(q,d);a.x=p;a.y= -h;a.width=e-p;a.height=q-h};fa.prototype.isIdentity=fa.prototype.Es=function(){return 1===this.m11&&0===this.m12&&0===this.m21&&1===this.m22&&0===this.dx&&0===this.dy};function H(a,b,c,d){void 0===a?this.offsetY=this.offsetX=this.y=this.x=0:(void 0===b&&(b=0),void 0===c&&(c=0),void 0===d&&(d=0),this.x=a,this.y=b,this.offsetX=c,this.offsetY=d)}t.ea("Spot",H);t.th(H);t.be(H,{x:!0,y:!0,offsetX:!0,offsetY:!0});H.prototype.assign=function(a){this.x=a.x;this.y=a.y;this.offsetX=a.offsetX;this.offsetY=a.offsetY}; -H.prototype.setTo=H.prototype.pp=function(a,b,c,d){f&&(kb(a,"setTo:x"),kb(b,"setTo:y"),nb(c,"setTo:offx"),nb(d,"setTo:offy"));t.L(this);this.x=a;this.y=b;this.offsetX=c;this.offsetY=d;return this};H.prototype.set=H.prototype.set=function(a){f&&t.k(a,H,H,"set:s");t.L(this);this.x=a.x;this.y=a.y;this.offsetX=a.offsetX;this.offsetY=a.offsetY;return this};H.prototype.copy=function(){var a=new H;a.x=this.x;a.y=this.y;a.offsetX=this.offsetX;a.offsetY=this.offsetY;return a}; -H.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};H.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()};H.prototype.freeze=function(){this.cb=!0;return this};H.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};function ob(a,b){a.x=NaN;a.y=NaN;a.offsetX=b;return a}function kb(a,b){(isNaN(a)||1a)&&t.ia(a,"0 <= "+b+" <= 1",H,b)} -function nb(a,b){(isNaN(a)||Infinity===a||-Infinity===a)&&t.ia(a,"real number, not NaN or Infinity",H,b)}var pb; -H.parse=pb=function(a){if("string"===typeof a){a=a.trim();if("None"===a)return t.NONE;if("TopLeft"===a)return t.Zw;if("Top"===a||"TopCenter"===a||"MiddleTop"===a)return t.Ep;if("TopRight"===a)return t.ax;if("Left"===a||"LeftCenter"===a||"MiddleLeft"===a)return t.Bp;if("Center"===a)return t.Nw;if("Right"===a||"RightCenter"===a||"MiddleRight"===a)return t.Cp;if("BottomLeft"===a)return t.Iw;if("Bottom"===a||"BottomCenter"===a||"MiddleBottom"===a)return t.Ap;if("BottomRight"===a)return t.Kw;if("TopSide"=== -a)return t.ex;if("LeftSide"===a)return t.Rw;if("RightSide"===a)return t.Xw;if("BottomSide"===a)return t.Mw;if("TopBottomSides"===a)return t.Yw;if("LeftRightSides"===a)return t.Qw;if("TopLeftSides"===a)return t.$w;if("TopRightSides"===a)return t.bx;if("BottomLeftSides"===a)return t.Jw;if("BottomRightSides"===a)return t.Lw;if("NotTopSide"===a)return t.Vw;if("NotLeftSide"===a)return t.Tw;if("NotRightSide"===a)return t.Uw;if("NotBottomSide"===a)return t.Sw;if("AllSides"===a)return t.Hw;if("Default"=== -a)return t.Ow;a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new H(c,e,g,h)}return new H};H.stringify=function(a){return a instanceof H?a.kd()?a.x.toString()+" "+a.y.toString()+" "+a.offsetX.toString()+" "+a.offsetY.toString():a.toString():a.toString()}; -H.prototype.toString=function(){return this.kd()?0===this.offsetX&&0===this.offsetY?"Spot("+this.x+","+this.y+")":"Spot("+this.x+","+this.y+","+this.offsetX+","+this.offsetY+")":this.K(t.NONE)?"None":this.K(t.Zw)?"TopLeft":this.K(t.Ep)?"Top":this.K(t.ax)?"TopRight":this.K(t.Bp)?"Left":this.K(t.Nw)?"Center":this.K(t.Cp)?"Right":this.K(t.Iw)?"BottomLeft":this.K(t.Ap)?"Bottom":this.K(t.Kw)?"BottomRight":this.K(t.ex)?"TopSide":this.K(t.Rw)?"LeftSide":this.K(t.Xw)?"RightSide":this.K(t.Mw)?"BottomSide": -this.K(t.Yw)?"TopBottomSides":this.K(t.Qw)?"LeftRightSides":this.K(t.$w)?"TopLeftSides":this.K(t.bx)?"TopRightSides":this.K(t.Jw)?"BottomLeftSides":this.K(t.Lw)?"BottomRightSides":this.K(t.Vw)?"NotTopSide":this.K(t.Tw)?"NotLeftSide":this.K(t.Uw)?"NotRightSide":this.K(t.Sw)?"NotBottomSide":this.K(t.Hw)?"AllSides":this.K(t.Ow)?"Default":"None"}; -H.prototype.equals=H.prototype.K=function(a){return a instanceof H?(this.x===a.x||isNaN(this.x)&&isNaN(a.x))&&(this.y===a.y||isNaN(this.y)&&isNaN(a.y))&&this.offsetX===a.offsetX&&this.offsetY===a.offsetY:!1};H.prototype.opposite=function(){return new H(0.5-(this.x-0.5),0.5-(this.y-0.5),-this.offsetX,-this.offsetY)};H.prototype.includesSide=function(a){if(!this.No()||!a.No())return!1;a=a.offsetY;return(this.offsetY&a)===a};H.prototype.isSpot=H.prototype.kd=function(){return!isNaN(this.x)&&!isNaN(this.y)}; -H.prototype.isNoSpot=H.prototype.jd=function(){return isNaN(this.x)||isNaN(this.y)};H.prototype.isSide=H.prototype.No=function(){return this.jd()&&1===this.offsetX&&0!==this.offsetY};H.prototype.isDefault=H.prototype.zc=function(){return isNaN(this.x)&&isNaN(this.y)&&-1===this.offsetX&&0===this.offsetY};t.wd=1;t.ad=2;t.od=4;t.nd=8;t.NONE=ob(new H(0,0,0,0),0).Ia();t.Ow=ob(new H(0,0,-1,0),-1).Ia();t.Zw=(new H(0,0,0,0)).Ia();t.Ep=(new H(0.5,0,0,0)).Ia();t.ax=(new H(1,0,0,0)).Ia(); -t.Bp=(new H(0,0.5,0,0)).Ia();t.Nw=(new H(0.5,0.5,0,0)).Ia();t.Cp=(new H(1,0.5,0,0)).Ia();t.Iw=(new H(0,1,0,0)).Ia();t.Ap=(new H(0.5,1,0,0)).Ia();t.Kw=(new H(1,1,0,0)).Ia();t.ex=ob(new H(0,0,1,t.wd),1).Ia();t.Rw=ob(new H(0,0,1,t.ad),1).Ia();t.Xw=ob(new H(0,0,1,t.od),1).Ia();t.Mw=ob(new H(0,0,1,t.nd),1).Ia();t.Yw=ob(new H(0,0,1,t.wd|t.nd),1).Ia();t.Qw=ob(new H(0,0,1,t.ad|t.od),1).Ia();t.$w=ob(new H(0,0,1,t.wd|t.ad),1).Ia();t.bx=ob(new H(0,0,1,t.wd|t.od),1).Ia();t.Jw=ob(new H(0,0,1,t.nd|t.ad),1).Ia(); -t.Lw=ob(new H(0,0,1,t.nd|t.od),1).Ia();t.Vw=ob(new H(0,0,1,t.ad|t.od|t.nd),1).Ia();t.Tw=ob(new H(0,0,1,t.wd|t.od|t.nd),1).Ia();t.Uw=ob(new H(0,0,1,t.wd|t.ad|t.nd),1).Ia();t.Sw=ob(new H(0,0,1,t.wd|t.ad|t.od),1).Ia();t.Hw=ob(new H(0,0,1,t.wd|t.ad|t.od|t.nd),1).Ia();var ub;H.None=ub=t.NONE;var vb;H.Default=vb=t.Ow;var wb;H.TopLeft=wb=t.Zw;var Db;H.TopCenter=Db=t.Ep;var Eb;H.TopRight=Eb=t.ax;H.LeftCenter=t.Bp;var Fb;H.Center=Fb=t.Nw;H.RightCenter=t.Cp;var Jb;H.BottomLeft=Jb=t.Iw;var Nb; -H.BottomCenter=Nb=t.Ap;var Ob;H.BottomRight=Ob=t.Kw;var Pb;H.MiddleTop=Pb=t.Ep;var Tb;H.MiddleLeft=Tb=t.Bp;var Ub;H.MiddleRight=Ub=t.Cp;var Vb;H.MiddleBottom=Vb=t.Ap;H.Top=t.Ep;var Wb;H.Left=Wb=t.Bp;var Xb;H.Right=Xb=t.Cp;H.Bottom=t.Ap;var Yb;H.TopSide=Yb=t.ex;var $b;H.LeftSide=$b=t.Rw;var ac;H.RightSide=ac=t.Xw;var bc;H.BottomSide=bc=t.Mw;H.TopBottomSides=t.Yw;H.LeftRightSides=t.Qw;H.TopLeftSides=t.$w;H.TopRightSides=t.bx;H.BottomLeftSides=t.Jw;H.BottomRightSides=t.Lw;H.NotTopSide=t.Vw; -H.NotLeftSide=t.Tw;H.NotRightSide=t.Uw;H.NotBottomSide=t.Sw;var cc;H.AllSides=cc=t.Hw;function dc(){this.Se=[1,0,0,1,0,0]}dc.prototype.copy=function(){var a=new dc;a.Se[0]=this.Se[0];a.Se[1]=this.Se[1];a.Se[2]=this.Se[2];a.Se[3]=this.Se[3];a.Se[4]=this.Se[4];a.Se[5]=this.Se[5];return a};function ic(a){this.type=a;this.r2=this.y2=this.x2=this.r1=this.y1=this.x1=0;this.RC=[]}ic.prototype.addColorStop=function(a,b){this.RC.push({offset:a,color:b})}; -function nc(a){this.fillStyle="#000000";this.font="10px sans-serif";this.globalAlpha=1;this.lineCap="butt";this.fw=0;this.lineJoin="miter";this.lineWidth=1;this.miterLimit=10;this.shadowBlur=0;this.shadowColor="rgba(0, 0, 0, 0)";this.shadowOffsetY=this.shadowOffsetX=0;this.strokeStyle="#000000";this.textAlign="start";this.path=[];this.vi=new dc;this.stack=[];this.ag=[];this.eF=this.ED=this.zv=0;this.Kv=a;this.gI="http://www.w3.org/2000/svg";this.jt=oc(this,"svg",{width:this.Kv.width+"px",height:this.Kv.height+ -"px",vJ:"0 0 "+this.Kv.width+" "+this.Kv.height})}aa=nc.prototype;aa.arc=function(a,b,c,d,e,g){pc(this,a,b,c,d,e,g)};aa.beginPath=function(){this.path=[]};aa.bezierCurveTo=function(a,b,c,d,e,g){this.path.push(["C",a,b,c,d,e,g])};aa.clearRect=function(){};aa.clip=function(){tc(this,"clipPath",this.path,new dc)};aa.closePath=function(){this.path.push(["z"])};aa.createLinearGradient=function(a,b,c,d){var e=new ic("linear");e.x1=a;e.y1=b;e.x2=c;e.y2=d;return e};aa.createPattern=function(){}; -aa.createRadialGradient=function(a,b,c,d,e,g){var h=new ic("radial");h.x1=a;h.y1=b;h.r1=c;h.x2=d;h.y2=e;h.r2=g;return h}; -aa.drawImage=function(a,b,c,d,e,g,h,k,l){a=[b,c,d,e,g,h,k,l,a];b=this.vi;e=a[8];c={x:0,y:0,width:e.naturalWidth,height:e.naturalHeight,href:e.src};d="";g=a[6]/a[2];h=a[7]/a[3];if(0!==a[4]||0!==a[5])d+=" translate("+a[4]+", "+a[5]+")";if(1!==g||1!==h)d+=" scale("+g+", "+h+")";if(0!==a[0]||0!==a[1])d+=" translate("+-a[0]+", "+-a[1]+")";if(0!==a[0]||0!==a[1]||a[2]!==e.naturalWidth||a[3]!==e.naturalHeight)e="CLIP"+this.zv,this.zv++,g=oc(this,"clipPath",{id:e}),g.appendChild(oc(this,"rect",{x:a[0],y:a[1], -width:a[2],height:a[3]})),this.jt.appendChild(g),c["clip-path"]="url(#"+e+")";uc(this,"image",c,b,d);this.addElement("image",c)};aa.fill=function(){tc(this,"fill",this.path,this.vi)};aa.fillRect=function(a,b,c,d){vc(this,"fill",[a,b,c,d],this.vi)};aa.fillText=function(a,b,c){a=[a,b,c];b=this.textAlign;"left"===b?b="start":"right"===b?b="end":"center"===b&&(b="middle");b={x:a[1],y:a[2],style:"font: "+this.font,"text-anchor":b};uc(this,"fill",b,this.vi);this.addElement("text",b,a[0])}; -aa.lineTo=function(a,b){this.path.push(["L",a,b])};aa.moveTo=function(a,b){this.path.push(["M",a,b])};aa.quadraticCurveTo=function(a,b,c,d){this.path.push(["Q",a,b,c,d])};aa.rect=function(a,b,c,d){this.path.push(["M",a,b],["L",a+c,b],["L",a+c,b+d],["L",a,b+d],["z"])}; -aa.restore=function(){this.vi=this.stack.pop();this.path=this.stack.pop();var a=this.stack.pop();this.fillStyle=a.fillStyle;this.font=a.font;this.globalAlpha=a.globalAlpha;this.lineCap=a.lineCap;this.fw=a.fw;this.lineJoin=a.lineJoin;this.lineWidth=a.lineWidth;this.miterLimit=a.miterLimit;this.shadowBlur=a.shadowBlur;this.shadowColor=a.shadowColor;this.shadowOffsetX=a.shadowOffsetX;this.shadowOffsetY=a.shadowOffsetY;this.strokeStyle=a.strokeStyle;this.textAlign=a.textAlign}; -aa.save=function(){this.stack.push({fillStyle:this.fillStyle,font:this.font,globalAlpha:this.globalAlpha,lineCap:this.lineCap,fw:this.fw,lineJoin:this.lineJoin,lineWidth:this.lineWidth,miterLimit:this.miterLimit,shadowBlur:this.shadowBlur,shadowColor:this.shadowColor,shadowOffsetX:this.shadowOffsetX,shadowOffsetY:this.shadowOffsetY,strokeStyle:this.strokeStyle,textAlign:this.textAlign});for(var a=[],b=0;bb.offset?1:-1});for(k=0;k=2*Math.PI?(pc(a,b,c,d,e,e+Math.PI,h),pc(a,b,c,d,e+Math.PI,e+2*Math.PI,h),a.path.push(["M",l,g])):(b+=d*Math.cos(e),c+=d*Math.sin(e),k=180*k/Math.PI,e=h?0:1,h=180<=k==!!h?0:1,0!=a.path.length?a.path.push(["L",b,c]):a.path.push(["M",b,c]),a.path.push(["A",d,d,k,h,e,l,g]))}} -function xc(a,b,c,d,e,g,h){var k=new dc;k.Se=[b,c,d,e,g,h];b={};uc(a,"g",b,k);k=a.addElement("g",b);a.ag.push(k)} -aa.Xa=function(){var a="SHADOW"+this.eF;this.eF++;var b=this.addElement("filter",{id:a,width:"250%",height:"250%"},null),c,d,e,g,h;if(0!=this.shadowOffsetX||0!=this.shadowOffsetY)c=oc(this,"feGaussianBlur",{"in":"SourceAlpha",result:"blur",tJ:this.shadowBlur/2}),d=oc(this,"feFlood",{"in":"blur",result:"flood","flood-color":this.shadowColor}),e=oc(this,"feComposite",{"in":"flood",in2:"blur",operator:"in",result:"comp"}),g=oc(this,"feOffset",{"in":"comp",result:"offsetBlur",dx:this.shadowOffsetX,dy:this.shadowOffsetY}), -h=oc(this,"feMerge",{}),h.appendChild(oc(this,"feMergeNode",{"in":"offsetBlur"})),h.appendChild(oc(this,"feMergeNode",{"in":"SourceGraphic"})),b.appendChild(c),b.appendChild(d),b.appendChild(e),b.appendChild(g),b.appendChild(h);0=a)return 0;var b=D.ZA;if(null===b){for(var b=[],c=0;2E3>=c;c++)b[c]=Math.sqrt(c);D.ZA=b}return 1>a?(c=1/a,2E3>=c?1/b[c| -0]:Math.sqrt(a)):2E3>=a?b[a|0]:Math.sqrt(a)},I:function(a,b){var c=a-b;return 0.5>c&&-0.5c&&-5E-8=e&&(e=1E-6);var k,l,m,n;am-n)if(a-c>e||c-a>e){if(g=(d-b)/(c-a)*(g-a)+b,g-e<=h&&h<=g+e)return!0}else return!0;else if(b-d>e||d-b>e){if(h=(c- -a)/(d-b)*(h-b)+a,h-e<=g&&g<=h+e)return!0}else return!0;return!1},uv:function(a,b,c,d,e,g,h,k,l,m,n,p){if(D.vd(a,b,h,k,p,c,d)&&D.vd(a,b,h,k,p,e,g))return D.vd(a,b,h,k,p,m,n);var q=(a+c)/2,r=(b+d)/2,s=(c+e)/2,u=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(q+s)/2;c=(r+u)/2;var s=(s+e)/2,u=(u+g)/2,x=(d+s)/2,E=(c+u)/2;return D.uv(a,b,q,r,d,c,x,E,l,m,n,p)||D.uv(x,E,s,u,e,g,h,k,l,m,n,p)},RG:function(a,b,c,d,e,g,h,k,l){var m=(c+e)/2,n=(d+g)/2;l.x=(((a+c)/2+m)/2+(m+(e+h)/2)/2)/2;l.y=(((b+d)/2+n)/2+(n+(g+k)/2)/2)/2;return l}, -QG:function(a,b,c,d,e,g,h,k){var l=(c+e)/2,m=(d+g)/2;return Ra(((a+c)/2+l)/2,((b+d)/2+m)/2,(l+(e+h)/2)/2,(m+(g+k)/2)/2)},oo:function(a,b,c,d,e,g,h,k,l,m){if(D.vd(a,b,h,k,l,c,d)&&D.vd(a,b,h,k,l,e,g))cb(m,a,b,0,0),cb(m,h,k,0,0);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,u=(c+r)/2;D.oo(a,b,n,p,d,c,s,u,l,m);D.oo(s,u,q,r,e,g,h,k,l,m)}return m},ue:function(a,b,c,d,e,g,h,k,l,m){if(D.vd(a,b,h,k,l,c,d)&&D.vd(a,b,h,k,l,e,g))0=== -m.length&&m.push([a,b]),m.push([h,k]);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,u=(c+r)/2;D.ue(a,b,n,p,d,c,s,u,l,m);D.ue(s,u,q,r,e,g,h,k,l,m)}return m},pA:function(a,b,c,d,e,g,h,k,l,m){if(D.vd(a,b,e,g,m,c,d))return D.vd(a,b,e,g,m,k,l);var n=(a+c)/2,p=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var q=(n+c)/2,r=(p+d)/2;return D.pA(a,b,n,p,q,r,h,k,l,m)||D.pA(q,r,c,d,e,g,h,k,l,m)},sJ:function(a,b,c,d,e,g,h){h.x=((a+c)/2+(c+e)/2)/2;h.y=((b+ -d)/2+(d+g)/2)/2;return h},oA:function(a,b,c,d,e,g,h,k){if(D.vd(a,b,e,g,h,c,d))cb(k,a,b,0,0),cb(k,e,g,0,0);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;D.oA(a,b,l,m,n,p,h,k);D.oA(n,p,c,d,e,g,h,k)}return k},hp:function(a,b,c,d,e,g,h,k){if(D.vd(a,b,e,g,h,c,d))0===k.length&&k.push([a,b]),k.push([e,g]);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;D.hp(a,b,l,m,n,p,h,k);D.hp(n,p,c,d,e,g,h,k)}return k},hs:function(a,b,c,d,e,g,h,k,l,m,n,p,q,r){0>=q&& -(q=1E-6);if(D.vd(a,b,h,k,q,c,d)&&D.vd(a,b,h,k,q,e,g)){var s=(a-h)*(m-p)-(b-k)*(l-n);if(!s)return!1;q=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/s;s=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/s;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(bh)return!1}else if(ah)return!1;r.x=q;r.y=s;return!0}var s=(a+c)/2,u=(b+d)/2;c=(c+e)/2;d=(d+g)/2;e=(e+h)/2;g=(g+k)/2;var x=(s+c)/2,E=(u+d)/2;c=(c+e)/2;d=(d+g)/2;var F=(x+c)/2,G=(E+d)/2,L=(n-l)*(n-l)+(p-m)*(p-m),M=!1;D.hs(a,b,s,u,x,E,F,G, -l,m,n,p,q,r)&&(a=(r.x-l)*(r.x-l)+(r.y-m)*(r.y-m),a=q&&(q=1E-6);if(D.vd(a,b,h,k,q,c,d)&&D.vd(a,b,h,k,q,e,g)){q=(a-h)*(m-p)-(b-k)*(l-n);if(!q)return r;var s=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/q,u=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/q;if(s>=n)return r;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(ba)return r}else if(a< -h?(l=a,a=h):l=h,sa)return r;0q&&r--}else{var s=(a+c)/2,u=(b+d)/2,x=(c+e)/2,E=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(s+x)/2;c=(u+E)/2;var x=(x+e)/2,E=(E+g)/2,F=(d+x)/2,G=(c+E)/2,r=r+D.is(a,b,s,u,d,c,F,G,l,m,n,p,q),r=r+D.is(F,G,x,E,e,g,h,k,l,m,n,p,q)}return r},Hm:function(a,b,c,d,e,g,h){if(D.Fa(a,c)){var k;bc)return h.x=a,h.y=c,!1;h.x=a;h.y=d;return!0}if(D.Fa(b,d)){ac)return h.x= -c,h.y=b,!1;h.x=d;h.y=b;return!0}k=((a-e)*(a-c)+(b-g)*(b-d))/((c-a)*(c-a)+(d-b)*(d-b));if(-5E-6>k)return h.x=a,h.y=b,!1;if(1.000005c)return l.x=a,l.y=c,!1;l.x=a; -l.y=g;return!0}h=(d-b)/(c-a);if(D.Fa(k,h))return D.Hm(a,b,c,d,e,g,l),!1;e=(h*a-k*e+g-b)/(h-k);if(D.Fa(h,0)){ac)return l.x=c,l.y=b,!1;l.x=e;l.y=b;return!0}g=h*(e-a)+b;return D.Hm(a,b,c,d,e,g,l)},gJ:function(a,b,c,d,e){return D.Mg(c.x,c.y,d.x,d.y,a.x,a.y,b.x,b.y,e)},eJ:function(a,b,c,d,e,g,h,k,l,m){function n(c,d){var e=(c-a)*(c-a)+(d-b)*(d-b);e(c>a?c-a:a-c)){q=1-(c-e)*(c-e)/(q*q);if(0>q)return l;q=Math.sqrt(q);d=-m*q+g;n(c,m*q+g);n(c,d)}else{c=(d-b)/(c-a);d=1/(q*q)+c*c/(m*m);k=2*c*(b-c*a)/(m*m)-2*c*g/(m*m)-2*e/(q*q);q=k*k-4*d*(2*c*a*g/(m*m)-2*b*g/(m*m)+g*g/(m*m)+e*e/(q*q)-1+(b-c*a)*(b-c*a)/(m*m));if(0>q)return l;q=Math.sqrt(q);m=(-k+q)/(2*d);n(m,c*m-c*a+b);q=(-k-q)/(2*d);n(q,c*q-c*a+b)}return l},Zk:function(a,b,c,d,e,g,h,k,l){var m=1E21,n=a,p=b;if(D.Mg(a,b,a, -d,e,g,h,k,l)){var q=(l.x-e)*(l.x-e)+(l.y-g)*(l.y-g);qm},Xv:function(a,b,c){var d=b.x,e=b.y,g=c.x,h=c.y,k=a.left,l=a.right,m=a.top,n=a.bottom;return d===g?(e=m): -e===h?(d=k):a.Da(b)||a.Da(c)||D.Wv(k,m,l,m,d,e,g,h)||D.Wv(l,m,l,n,d,e,g,h)||D.Wv(l,n,k,n,d,e,g,h)||D.Wv(k,n,k,m,d,e,g,h)?!0:!1},Wv:function(a,b,c,d,e,g,h,k){return 0>=D.Bv(a,b,c,d,e,g)*D.Bv(a,b,c,d,h,k)&&0>=D.Bv(e,g,h,k,a,b)*D.Bv(e,g,h,k,c,d)},Bv:function(a,b,c,d,e,g){c-=a;d-=b;a=e-a;b=g-b;g=a*d-b*c;0===g&&(g=a*c+b*d,0g&&(g=0)));return 0>g?-1:0a&&(a+=360);360<=a&&(a-=360);return a},aD:function(a,b,c,d,e,g){var h= -Math.PI;g||(d*=h/180,e*=h/180);g=dc,g=0>d,h,k;am;++m){b=0.5*(k+l);if(b===k||b===l)break;var n=a/(b+g),p=h/(b+e),n=n*n+p*p-1;if(0n)l=b;else break}c=g*c/(b+g)-c;d=e*d/(b+e)-d;c=Math.sqrt(c*c+d*d)}else c=Math.abs(d-b);else d=a*a-b*b,e=a*c,e=x-1?!0:null!==m[n+1].match(/[A-Za-z]/)}function d(){n++;return m[n]}function e(){var a=new v(parseFloat(d()),parseFloat(d()));p===p.toLowerCase()&&(a.x=u.x+a.x,a.y=u.y+a.y);return a}function g(){return u=e()}function h(){return s=e()}function k(){var a=[parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d())];c()||(a.push(parseFloat(d())),c()||a.push(parseFloat(d())));p===p.toLowerCase()&&(a[2]+=u.x,a[3]+=u.y);return a}function l(){return"c"!== -q.toLowerCase()&&"s"!==q.toLowerCase()?u:new v(2*u.x-s.x,2*u.y-s.y)}void 0===b&&(b=!1);"string"!==typeof a&&t.Nb(a,"string",I,"parse:str");a=a.replace(/,/gm," ");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([^\s])/gm,"$1 $2");a=a.replace(/([^\s])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([0-9])([+\-])/gm,"$1 $2");a= -a.replace(/(\.[0-9]*)(\.)/gm,"$1 $2");a=a.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,"$1 $3 $4 ");a=a.replace(/[\s\r\t\n]+/gm," ");a=a.replace(/^\s+|\s+$/g,"");for(var m=a.split(" "),n=-1,p="",q="",r=new v(0,0),s=new v(0,0),u=new v(0,0),x=m.length,E=t.u(),F,G=!1,L=!1,M=!0;!(n>=x-1);)if(q=p,p=d(),""!==p)switch(p.toUpperCase()){case "X":M=!0;L=G=!1;break;case "M":F=g();null===E.Kb||!0===M?(J(E,F.x,F.y,G,!1,!L),M=!1):E.moveTo(F.x,F.y);for(r=u;!c();)F=g(),E.lineTo(F.x,F.y);break;case "L":for(;!c();)F= -g(),E.lineTo(F.x,F.y);break;case "H":for(;!c();)u=F=new v((p===p.toLowerCase()?u.x:0)+parseFloat(d()),u.y),E.lineTo(u.x,u.y);break;case "V":for(;!c();)u=F=new v(u.x,(p===p.toLowerCase()?u.y:0)+parseFloat(d())),E.lineTo(u.x,u.y);break;case "C":for(;!c();){var W=e(),T=h();F=g();K(E,W.x,W.y,T.x,T.y,F.x,F.y)}break;case "S":for(;!c();)W=l(),T=h(),F=g(),K(E,W.x,W.y,T.x,T.y,F.x,F.y);break;case "Q":for(;!c();)T=h(),F=g(),Vc(E,T.x,T.y,F.x,F.y);break;case "T":for(;!c();)s=T=l(),F=g(),Vc(E,T.x,T.y,F.x,F.y); -break;case "B":for(;!c();)F=k(),E.arcTo(F[0],F[1],F[2],F[3],F[4],F[5],F[6]);break;case "A":for(;!c();){var W=Math.abs(parseFloat(d())),T=Math.abs(parseFloat(d())),U=parseFloat(d()),da=!!parseFloat(d()),R=!!parseFloat(d());F=g();Wc(E,W,T,U,da,R,F.x,F.y)}break;case "Z":N(E);u=r;break;case "F":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Uu]/))W++;else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?G=!0:Xc(E);break;case "U":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Ff]/))W++; -else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?L=!0:E.Xa(!1)}r=E.s;t.v(E);if(b)for(E=r.ob.m;E.next();)E.value.Lo=!0;return r};function Yc(a,b){for(var c=a.length,d=t.M(),e=0;e=a&&t.ia(a,"scale must be greater than zero",I,"scale:x"),0>=b&&t.ia(b,"scale must be greater than zero",I,"scale:y"));this.transform(a,0,0,b,0,0)}; -I.prototype.rotate=I.prototype.rotate=function(a,b,c){t.L(this);void 0===b&&(b=0);void 0===c&&(c=0);f&&(t.o(a,I,"rotate:angle"),t.o(b,I,"rotate:x"),t.o(c,I,"rotate:y"));var d=t.Og();d.reset();d.rotate(a,b,c);this.transform(d.m11,d.m12,d.m21,d.m22,d.dx,d.dy);t.Ne(d)}; -I.prototype.transform=I.prototype.transform=function(a,b,c,d,e,g){var h,k;switch(this.type){case Jc:case Kc:case Lc:h=this.Yb;k=this.ic;this.Yb=h*a+k*c+e;this.ic=h*b+k*d+g;h=this.dd;k=this.qd;this.dd=h*a+k*c+e;this.qd=h*b+k*d+g;break;case zc:for(var l=this.ob,m=l.length,n=0;n=a)return 0;if((e>h?e-h:h-e)<(g>k?g-k:k-g)){if(ge)return 0}else if(ee)return 0;return 0a||1a)return n=(a-m)/l,t.xa(c),new v(b[0]+(d[0]-b[0])*n,b[1]+(d[1]-b[1])*n);m+=l}b=d}t.xa(c);return null};t.g(I,"type",I.prototype.type);t.defineProperty(I,{type:"type"},function(){return this.Z},function(a){this.Z!==a&&(f&&t.nb(a,I,I,"type"),t.L(this,a),this.Z=a,this.Ta=!0)});t.g(I,"startX",I.prototype.la);t.defineProperty(I,{la:"startX"},function(){return this.Yb},function(a){this.Yb!==a&&(f&&t.o(a,I,"startX"),t.L(this,a),this.Yb=a,this.Ta=!0)}); -t.g(I,"startY",I.prototype.ma);t.defineProperty(I,{ma:"startY"},function(){return this.ic},function(a){this.ic!==a&&(f&&t.o(a,I,"startY"),t.L(this,a),this.ic=a,this.Ta=!0)});t.g(I,"endX",I.prototype.D);t.defineProperty(I,{D:"endX"},function(){return this.dd},function(a){this.dd!==a&&(f&&t.o(a,I,"endX"),t.L(this,a),this.dd=a,this.Ta=!0)});t.g(I,"endY",I.prototype.F);t.defineProperty(I,{F:"endY"},function(){return this.qd},function(a){this.qd!==a&&(f&&t.o(a,I,"endY"),t.L(this,a),this.qd=a,this.Ta=!0)}); -t.g(I,"figures",I.prototype.ob);t.defineProperty(I,{ob:"figures"},function(){return this.rk},function(a){this.rk!==a&&(f&&t.k(a,A,I,"figures"),t.L(this,a),this.rk=a,this.Ta=!0)});t.defineProperty(I,{G:"spot1"},function(){return this.ji},function(a){f&&t.k(a,H,I,"spot1");t.L(this,a);this.ji=a.W()});t.defineProperty(I,{H:"spot2"},function(){return this.ki},function(a){f&&t.k(a,H,I,"spot2");t.L(this,a);this.ki=a.W()});t.A(I,{Gb:"bounds"},function(){this.Uz()&&(this.RA(),this.df());return this.Jt}); -t.g(I,"minSize",I.prototype.Te);t.defineProperty(I,{Te:"minSize"},function(){return this.Wd},function(a){this.Wd.K(a)||(f&&t.k(a,ea,I,"minSize"),a=a.W(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.Wd=a)});function Ac(a,b,c){t.uc(this);void 0===c&&(c=!0);this.Cl=c;this.yn=!0;void 0!==a?(f&&t.o(a,Ac,"sx"),this.Yb=a):this.Yb=0;void 0!==b?(f&&t.o(b,Ac,"sy"),this.ic=b):this.ic=0;this.Cr=new A(O);this.Tu=this.Cr.Pb;this.Ta=!0}t.ea("PathFigure",Ac);t.th(Ac); -Ac.prototype.copy=function(){var a=new Ac;a.Cl=this.Cl;a.yn=this.yn;a.Yb=this.Yb;a.ic=this.ic;for(var b=this.Cr,c=b.length,d=a.Cr,e=0;ea&&(a+=360),this.bo=a):(void 0!==b?(f&&t.o(b,O,"ex"),this.qe=b):this.qe=0,void 0!==c?(f&&t.o(c,O,"ey"),this.re=c):this.re=0,void 0!==d&&(f&&t.o(d,O,"x1"),this.Ag=d),void 0!==e&&(f&&t.o(e,O,"y1"),this.Bg=e),void 0!==g&&(f&&t.o(g,O,"x2"),this.Fk=g),void 0!==h&&"number"===typeof h&&(f&&t.o(h,O,"y2"),this.Gk=h));this.Ta=!0;this.dh= -!1;this.Pi=null}t.ea("PathSegment",O);t.th(O);O.prototype.copy=function(){var a=new O;a.Z=this.Z;this.Z===cd?(a.se=this.se,a.te=this.te,a.Zm=this.Zm,a.$m=this.$m,a.rj=this.rj,a.sj=this.sj):this.Z===dd?(a.se=this.se,a.te=this.te,a.qe=this.qe,a.re=this.re,a.rj=this.rj,a.sj=this.sj,a.bo=this.bo):(a.qe=this.qe,a.re=this.re,a.Ag=this.Ag,a.Bg=this.Bg,a.Fk=this.Fk,a.Gk=this.Gk);a.Ta=this.Ta;a.dh=this.dh;return a}; -O.prototype.equalsApprox=O.prototype.Oj=function(a){if(!(a instanceof O)||this.type!==a.type||this.Ds!==a.Ds)return!1;switch(this.type){case $c:case Nc:return D.I(this.D,a.D)&&D.I(this.F,a.F);case ad:return D.I(this.D,a.D)&&D.I(this.F,a.F)&&D.I(this.pb,a.pb)&&D.I(this.Fb,a.Fb)&&D.I(this.je,a.je)&&D.I(this.ke,a.ke);case bd:return D.I(this.D,a.D)&&D.I(this.F,a.F)&&D.I(this.pb,a.pb)&&D.I(this.Fb,a.Fb);case cd:return D.I(this.kg,a.kg)&&D.I(this.Fh,a.Fh)&&D.I(this.Aa,a.Aa)&&D.I(this.Ma,a.Ma)&&D.I(this.radiusX, -a.radiusX)&&D.I(this.radiusY,a.radiusY);case dd:return this.Zv===a.Zv&&this.aw===a.aw&&D.I(this.Gw,a.Gw)&&D.I(this.D,a.D)&&D.I(this.F,a.F)&&D.I(this.radiusX,a.radiusX)&&D.I(this.radiusY,a.radiusY);default:return!1}}; -O.prototype.toString=function(a){switch(this.type){case $c:a=void 0===a?"M"+this.D.toString()+" "+this.F.toString():"M"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case Nc:a=void 0===a?"L"+this.D.toString()+" "+this.F.toString():"L"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case ad:a=void 0===a?"C"+this.pb.toString()+" "+this.Fb.toString()+" "+this.je.toString()+" "+this.ke.toString()+" "+this.D.toString()+" "+this.F.toString():"C"+this.pb.toFixed(a)+" "+this.Fb.toFixed(a)+" "+this.je.toFixed(a)+ -" "+this.ke.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case bd:a=void 0===a?"Q"+this.pb.toString()+" "+this.Fb.toString()+" "+this.D.toString()+" "+this.F.toString():"Q"+this.pb.toFixed(a)+" "+this.Fb.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case cd:a=void 0===a?"B"+this.kg.toString()+" "+this.Fh.toString()+" "+this.Aa.toString()+" "+this.Ma.toString()+" "+this.radiusX:"B"+this.kg.toFixed(a)+" "+this.Fh.toFixed(a)+" "+this.Aa.toFixed(a)+" "+this.Ma.toFixed(a)+ -" "+this.radiusX;break;case dd:a=void 0===a?"A"+this.radiusX.toString()+" "+this.radiusY.toString()+" "+this.Gw.toString()+" "+(this.aw?1:0)+" "+(this.Zv?1:0)+" "+this.D.toString()+" "+this.F.toString():"A"+this.radiusX.toFixed(a)+" "+this.radiusY.toFixed(a)+" "+this.Gw.toFixed(a)+" "+(this.aw?1:0)+" "+(this.Zv?1:0)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;default:a=this.type.toString()}return a+(this.dh?"z":"")};var $c;O.Move=$c=t.w(O,"Move",0);var Nc;O.Line=Nc=t.w(O,"Line",1);var ad; -O.Bezier=ad=t.w(O,"Bezier",2);var bd;O.QuadraticBezier=bd=t.w(O,"QuadraticBezier",3);var cd;O.Arc=cd=t.w(O,"Arc",4);var dd;O.SvgArc=dd=t.w(O,"SvgArc",4);O.prototype.freeze=function(){this.cb=!0;return this};O.prototype.Pa=function(){this.cb=!1;return this};O.prototype.close=O.prototype.close=function(){this.dh=!0;return this}; -function ed(a,b){if(null!==a.Pi&&!1===b.Ta)return a.Pi;var c=a.radiusX,d=a.radiusY;void 0===d&&(d=c);var e=a.Zm,g=a.$m,h=D.aD(0,0,c=g(p,r)&&(q=Math.PI);1<=g(p,r)&&(q=0);0===m&&0q&&(q+=2*Math.PI);m=b>h?1:b/h; -r=b>h?h/b:1;b=D.aD(0,0,b>h?b:h,k,k+q,!0);h=t.Og();h.reset();h.translate(c,d);h.rotate(a.bo,0,0);h.scale(m,r);Yc(b,h);t.Ne(h);a.Pi=b;return a.Pi}t.g(O,"isClosed",O.prototype.Ds);t.defineProperty(O,{Ds:"isClosed"},function(){return this.dh},function(a){this.dh!==a&&(this.dh=a,this.Ta=!0)});t.g(O,"type",O.prototype.type);t.defineProperty(O,{type:"type"},function(){return this.Z},function(a){f&&t.nb(a,O,O,"type");t.L(this,a);this.Z=a;this.Ta=!0});t.g(O,"endX",O.prototype.D); -t.defineProperty(O,{D:"endX"},function(){return this.qe},function(a){f&&t.o(a,O,"endX");t.L(this,a);this.qe=a;this.Ta=!0});t.g(O,"endY",O.prototype.F);t.defineProperty(O,{F:"endY"},function(){return this.re},function(a){f&&t.o(a,O,"endY");t.L(this,a);this.re=a;this.Ta=!0});t.defineProperty(O,{pb:"point1X"},function(){return this.Ag},function(a){f&&t.o(a,O,"point1X");t.L(this,a);this.Ag=a;this.Ta=!0}); -t.defineProperty(O,{Fb:"point1Y"},function(){return this.Bg},function(a){f&&t.o(a,O,"point1Y");t.L(this,a);this.Bg=a;this.Ta=!0});t.defineProperty(O,{je:"point2X"},function(){return this.Fk},function(a){f&&t.o(a,O,"point2X");t.L(this,a);this.Fk=a;this.Ta=!0});t.defineProperty(O,{ke:"point2Y"},function(){return this.Gk},function(a){f&&t.o(a,O,"point2Y");t.L(this,a);this.Gk=a;this.Ta=!0}); -t.defineProperty(O,{Aa:"centerX"},function(){return this.Zm},function(a){f&&t.o(a,O,"centerX");t.L(this,a);this.Zm=a;this.Ta=!0});t.defineProperty(O,{Ma:"centerY"},function(){return this.$m},function(a){f&&t.o(a,O,"centerY");t.L(this,a);this.$m=a;this.Ta=!0});t.defineProperty(O,{radiusX:"radiusX"},function(){return this.rj},function(a){f&&t.o(a,O,"radiusX");0>a&&t.ia(a,">= zero",O,"radiusX");t.L(this,a);this.rj=a;this.Ta=!0}); -t.defineProperty(O,{radiusY:"radiusY"},function(){return this.sj},function(a){f&&t.o(a,O,"radiusY");0>a&&t.ia(a,">= zero",O,"radiusY");t.L(this,a);this.sj=a;this.Ta=!0});t.defineProperty(O,{kg:"startAngle"},function(){return this.se},function(a){this.se!==a&&(t.L(this,a),f&&t.o(a,O,"startAngle"),a%=360,0>a&&(a+=360),this.se=a,this.Ta=!0)}); -t.defineProperty(O,{Fh:"sweepAngle"},function(){return this.te},function(a){f&&t.o(a,O,"sweepAngle");t.L(this,a);360a&&(a=-360);this.te=a;this.Ta=!0});t.defineProperty(O,{Zv:"isClockwiseArc"},function(){return!!this.te},function(a){t.L(this,a);this.te=a?1:0;this.Ta=!0});t.defineProperty(O,{aw:"isLargeArc"},function(){return!!this.se},function(a){t.L(this,a);this.se=a?1:0;this.Ta=!0}); -t.defineProperty(O,{Gw:"xAxisRotation"},function(){return this.bo},function(a){f&&t.o(a,O,"xAxisRotation");a%=360;0>a&&(a+=360);t.L(this,a);this.bo=a;this.Ta=!0});function od(){this.ba=null;this.cz=(new v(0,0)).freeze();this.Ix=(new v(0,0)).freeze();this.Gt=this.vu=0;this.ju="";this.gv=this.Ut=!1;this.Rt=this.It=0;this.Qi=this.au=!1;this.lq=null;this.ev=0;this.Sf=this.cv=null}t.ea("InputEvent",od); -od.prototype.copy=function(){var a=new od;a.ba=this.ba;a.cz=this.$c.copy().freeze();a.Ix=this.V.copy().freeze();a.vu=this.vu;a.Gt=this.Gt;a.ju=this.ju;a.Ut=this.Ut;a.gv=this.gv;a.It=this.It;a.Rt=this.Rt;a.au=this.au;a.Qi=this.Qi;a.lq=this.lq;a.ev=this.ev;a.cv=this.cv;a.Sf=this.Sf;return a}; -od.prototype.toString=function(){var a="^";this.Lc&&(a+="M:"+this.Lc);this.button&&(a+="B:"+this.button);this.key&&(a+="K:"+this.key);this.we&&(a+="C:"+this.we);this.Lj&&(a+="D:"+this.Lj);this.Ae&&(a+="h");this.bubbles&&(a+="b");null!==this.V&&(a+="@"+this.V.toString());return a};t.g(od,"diagram",od.prototype.h);t.defineProperty(od,{h:"diagram"},function(){return this.ba},function(a){this.ba=a});t.g(od,"viewPoint",od.prototype.$c); -t.defineProperty(od,{$c:"viewPoint"},function(){return this.cz},function(a){t.k(a,v,od,"viewPoint");this.cz.assign(a)});t.g(od,"documentPoint",od.prototype.V);t.defineProperty(od,{V:"documentPoint"},function(){return this.Ix},function(a){t.k(a,v,od,"documentPoint");this.Ix.assign(a)});t.g(od,"modifiers",od.prototype.Lc);t.defineProperty(od,{Lc:"modifiers"},function(){return this.vu},function(a){this.vu=a});t.g(od,"button",od.prototype.button); -t.defineProperty(od,{button:"button"},function(){return this.Gt},function(a){this.Gt=a});t.g(od,"key",od.prototype.key);t.defineProperty(od,{key:"key"},function(){return this.ju},function(a){this.ju=a});t.g(od,"down",od.prototype.Nj);t.defineProperty(od,{Nj:"down"},function(){return this.Ut},function(a){this.Ut=a});t.g(od,"up",od.prototype.Ni);t.defineProperty(od,{Ni:"up"},function(){return this.gv},function(a){this.gv=a});t.g(od,"clickCount",od.prototype.we); -t.defineProperty(od,{we:"clickCount"},function(){return this.It},function(a){this.It=a});t.g(od,"delta",od.prototype.Lj);t.defineProperty(od,{Lj:"delta"},function(){return this.Rt},function(a){this.Rt=a});t.g(od,"handled",od.prototype.Ae);t.defineProperty(od,{Ae:"handled"},function(){return this.au},function(a){this.au=a});t.g(od,"bubbles",od.prototype.bubbles);t.defineProperty(od,{bubbles:"bubbles"},function(){return this.Qi},function(a){this.Qi=a});t.g(od,"event",od.prototype.event); -t.defineProperty(od,{event:"event"},function(){return this.lq},function(a){this.lq=a});t.A(od,{cw:"isTouchEvent"},function(){var a=window.TouchEvent;return a&&this.event instanceof a});t.g(od,"timestamp",od.prototype.timestamp);t.defineProperty(od,{timestamp:"timestamp"},function(){return this.ev},function(a){this.ev=a});t.g(od,"targetDiagram",od.prototype.lg);t.defineProperty(od,{lg:"targetDiagram"},function(){return this.cv},function(a){this.cv=a});t.g(od,"targetObject",od.prototype.Nd); -t.defineProperty(od,{Nd:"targetObject"},function(){return this.Sf},function(a){this.Sf=a});t.g(od,"control",od.prototype.control);t.defineProperty(od,{control:"control"},function(){return 0!==(this.Lc&1)},function(a){this.Lc=a?this.Lc|1:this.Lc&-2});t.g(od,"shift",od.prototype.shift);t.defineProperty(od,{shift:"shift"},function(){return 0!==(this.Lc&4)},function(a){this.Lc=a?this.Lc|4:this.Lc&-5});t.g(od,"alt",od.prototype.alt); -t.defineProperty(od,{alt:"alt"},function(){return 0!==(this.Lc&2)},function(a){this.Lc=a?this.Lc|2:this.Lc&-3});t.g(od,"meta",od.prototype.Fm);t.defineProperty(od,{Fm:"meta"},function(){return 0!==(this.Lc&8)},function(a){this.Lc=a?this.Lc|8:this.Lc&-9});t.g(od,"left",od.prototype.left);t.defineProperty(od,{left:"left"},function(){return 0===this.button},function(a){this.button=a?0:2});t.g(od,"middle",od.prototype.cI); -t.defineProperty(od,{cI:"middle"},function(){return 1===this.button},function(a){this.button=a?1:0});t.g(od,"right",od.prototype.right);t.defineProperty(od,{right:"right"},function(){return 2===this.button},function(a){this.button=a?2:0});function pd(){this.ba=null;this.Mb="";this.Iu=this.Zu=null;this.Ht=!1}t.ea("DiagramEvent",pd);pd.prototype.copy=function(){var a=new pd;a.ba=this.ba;a.Mb=this.Mb;a.Zu=this.Zu;a.Iu=this.Iu;a.Ht=this.Ht;return a}; -pd.prototype.toString=function(){var a="*"+this.name;this.cancel&&(a+="x");null!==this.Cw&&(a+=":"+this.Cw.toString());null!==this.ow&&(a+="("+this.ow.toString()+")");return a};t.g(pd,"diagram",pd.prototype.h);t.defineProperty(pd,{h:"diagram"},function(){return this.ba},function(a){this.ba=a});t.g(pd,"name",pd.prototype.name);t.defineProperty(pd,{name:"name"},function(){return this.Mb},function(a){this.Mb=a});t.g(pd,"subject",pd.prototype.Cw); -t.defineProperty(pd,{Cw:"subject"},function(){return this.Zu},function(a){this.Zu=a});t.g(pd,"parameter",pd.prototype.ow);t.defineProperty(pd,{ow:"parameter"},function(){return this.Iu},function(a){this.Iu=a});t.g(pd,"cancel",pd.prototype.cancel);t.defineProperty(pd,{cancel:"cancel"},function(){return this.Ht},function(a){this.Ht=a});function qd(){this.clear()}t.ea("ChangedEvent",qd);var rd;qd.Transaction=rd=t.w(qd,"Transaction",-1);var sd;qd.Property=sd=t.w(qd,"Property",0);var td; -qd.Insert=td=t.w(qd,"Insert",1);var ud;qd.Remove=ud=t.w(qd,"Remove",2);qd.prototype.clear=qd.prototype.clear=function(){this.Sp=sd;this.Tl=this.uu="";this.yu=this.zu=this.Fu=this.Ln=this.Eu=this.ba=this.Cd=null}; -qd.prototype.copy=function(){var a=new qd;a.Cd=this.Cd;a.ba=this.ba;a.Sp=this.Sp;a.uu=this.uu;a.Tl=this.Tl;a.Eu=this.Eu;var b=this.Ln;a.Ln=t.jb(b)&&"function"===typeof b.W?b.W():b;b=this.Fu;a.Fu=t.jb(b)&&"function"===typeof b.W?b.W():b;b=this.zu;a.zu=t.jb(b)&&"function"===typeof b.W?b.W():b;b=this.yu;a.yu=t.jb(b)&&"function"===typeof b.W?b.W():b;return a}; -qd.prototype.toString=function(){var a="",a=this.fd===rd?a+"* ":this.fd===sd?a+(null!==this.da?"!m":"!d"):a+((null!==this.da?"!m":"!d")+this.fd);this.propertyName&&"string"===typeof this.propertyName&&(a+=" "+this.propertyName);this.kf&&this.kf!==this.propertyName&&(a+=" "+this.kf);a+=": ";this.fd===rd?null!==this.oldValue&&(a+=" "+this.oldValue):(null!==this.object&&(a+=vd(this.object)),null!==this.oldValue&&(a+=" old: "+vd(this.oldValue)),null!==this.Ff&&(a+=" "+this.Ff),null!==this.newValue&& -(a+=" new: "+vd(this.newValue)),null!==this.Df&&(a+=" "+this.Df));return a};qd.prototype.getValue=qd.prototype.wa=function(a){return a?this.oldValue:this.newValue};qd.prototype.getParam=function(a){return a?this.Ff:this.Df};qd.prototype.canUndo=qd.prototype.canUndo=function(){return null!==this.da||null!==this.h?!0:!1};qd.prototype.undo=qd.prototype.undo=function(){this.canUndo()&&(null!==this.da?this.da.changeState(this,!0):null!==this.h&&this.h.changeState(this,!0))}; -qd.prototype.canRedo=qd.prototype.canRedo=function(){return null!==this.da||null!==this.h?!0:!1};qd.prototype.redo=qd.prototype.redo=function(){this.canRedo()&&(null!==this.da?this.da.changeState(this,!1):null!==this.h&&this.h.changeState(this,!1))};t.g(qd,"model",qd.prototype.da);t.defineProperty(qd,{da:"model"},function(){return this.Cd},function(a){this.Cd=a});t.g(qd,"diagram",qd.prototype.h);t.defineProperty(qd,{h:"diagram"},function(){return this.ba},function(a){this.ba=a});t.g(qd,"change",qd.prototype.fd); -t.defineProperty(qd,{fd:"change"},function(){return this.Sp},function(a){f&&t.nb(a,qd,qd,"change");this.Sp=a});t.g(qd,"modelChange",qd.prototype.kf);t.defineProperty(qd,{kf:"modelChange"},function(){return this.uu},function(a){f&&t.j(a,"string",qd,"modelChange");this.uu=a});t.g(qd,"propertyName",qd.prototype.propertyName);t.defineProperty(qd,{propertyName:"propertyName"},function(){return this.Tl},function(a){f&&"string"!==typeof a&&t.k(a,Function,qd,"propertyName");this.Tl=a}); -t.g(qd,"isTransactionFinished",qd.prototype.QH);t.A(qd,{QH:"isTransactionFinished"},function(){return this.Sp===rd&&("CommittedTransaction"===this.Tl||"FinishedUndo"===this.Tl||"FinishedRedo"===this.Tl)});t.g(qd,"object",qd.prototype.object);t.defineProperty(qd,{object:"object"},function(){return this.Eu},function(a){this.Eu=a});t.g(qd,"oldValue",qd.prototype.oldValue);t.defineProperty(qd,{oldValue:"oldValue"},function(){return this.Ln},function(a){this.Ln=a});t.g(qd,"oldParam",qd.prototype.Ff); -t.defineProperty(qd,{Ff:"oldParam"},function(){return this.Fu},function(a){this.Fu=a});t.g(qd,"newValue",qd.prototype.newValue);t.defineProperty(qd,{newValue:"newValue"},function(){return this.zu},function(a){this.zu=a});t.g(qd,"newParam",qd.prototype.Df);t.defineProperty(qd,{Df:"newParam"},function(){return this.yu},function(a){this.yu=a}); -function C(a){1b||(t.ri(this.Fe,b),me(this,"nodeDataArray",ud,"nodeDataArray",this,a,null,b,null),this.nt(a)))}};C.prototype.removeNodeDataCollection=function(a){if(t.isArray(a))for(var b=t.wb(a),c=0;cb&&(b=t.wb(a));t.qi(a,b,c);me(this,"",td,"",a,null,c,null,b)}; -C.prototype.removeArrayItem=function(a,b){void 0===b&&(b=-1);f&&(t.js(a,C,"removeArrayItem:arr"),t.o(b,C,"removeArrayItem:idx"));a===this.Fe&&t.l("Model.removeArrayItem should not be called on the Model.nodeDataArray");-1===b&&(b=t.wb(a)-1);var c=t.mb(a,b);t.ri(a,b);me(this,"",ud,"",a,c,null,b,null)};t.g(C,"nodeCategoryProperty",C.prototype.dl); -t.defineProperty(C,{dl:"nodeCategoryProperty"},function(){return this.fr},function(a){var b=this.fr;b!==a&&(ne(a,C,"nodeCategoryProperty"),this.fr=a,this.i("nodeCategoryProperty",b,a))});C.prototype.getCategoryForNodeData=C.prototype.getCategoryForNodeData=function(a){if(null===a)return"";var b=this.fr;if(""===b)return"";b=t.ab(a,b);if(void 0===b)return"";if("string"===typeof b)return b;t.l("getCategoryForNodeData found a non-string category for "+a+": "+b);return""}; -C.prototype.setCategoryForNodeData=C.prototype.ww=function(a,b){t.j(b,"string",C,"setCategoryForNodeData:cat");if(null!==a){var c=this.fr;if(""!==c)if(this.ae(a)){var d=t.ab(a,c);void 0===d&&(d="");d!==b&&(t.Oa(a,c,b),me(this,"nodeCategory",sd,c,a,d,b))}else t.Oa(a,c,b)}}; -function P(a,b){2e||(t.ri(d,e),this.ui(a)&&(xe(this,b,a),me(this,"linkLabelKeys",ud,c,a,b,null)))}else void 0!==d&&t.l(c+" property is not an Array; cannot removeLabelKeyforLinkData: "+a)}}};t.g(P,"linkDataArray",P.prototype.Hi); -t.defineProperty(P,{Hi:"linkDataArray"},function(){return this.xg},function(a){var b=this.xg;if(b!==a){t.js(a,P,"linkDataArray");this.Ld&&t.lc&&(null!==b&&t.Cm(b,"linkDataArray",this,!0),a=t.Cm(a,"linkDataArray",this,!1));for(var c=t.wb(a),d=0;db)){t.ri(this.xg,b);me(this,"linkDataArray",ud,"linkDataArray",this,a,null,b,null);b=this.xm(a);xe(this,b,a);b=this.ym(a);xe(this,b,a);var c=this.Yk(a);if(t.isArray(c))for(var d=t.wb(c),e=0;ea.ol&&t.trace("Ending transaction without having started a transaction: "+c);var d=1===a.ol;d&&b&&a.isEnabled&&a.Ec("CommittingTransaction",c,a.Uk);var e=0;if(0a.Tj;e--)g=d.ta(e),null!==g&&g.clear(), -d.Zc(e);e=a.$z;0===e&&(e=1);0=e&&(g=d.ta(0),null!==g&&g.clear(),d.Zc(0),a.vk--);d.add(b);a.vk++;d.freeze();g=b}a.Ec("CommittedTransaction",c,g)}else{a.Wh=!0;try{a.isEnabled&&null!==g&&(g.Ko=!0,g.undo())}finally{a.Ec("RolledBackTransaction",c,g),a.Wh=!1}null!==g&&g.clear()}a.Qt=null;return!0}if(a.isEnabled&&!b&&null!==g){a=e;c=g.sh;for(b=c.count-1;b>=a;b--)d=c.ta(b),null!==d&&d.undo(),c.Pa(),c.Zc(b);c.freeze()}return!1} -wd.prototype.canUndo=wd.prototype.canUndo=function(){if(!this.isEnabled||0=this.ol&&!this.Px&&(a=a.h,null!==a&&!1===a.Mf||t.trace("Change not within a transaction: "+c.toString()))}}; -wd.prototype.skipsEvent=function(a){if(null===a||0>a.fd.value)return!0;a=a.object;if(a instanceof Q){if(a=a.layer,null!==a&&a.kc)return!0}else if(a instanceof Zd&&a.kc)return!0;return!1};t.A(wd,{dI:"models"},function(){return this.sy.m});t.g(wd,"isEnabled",wd.prototype.isEnabled);t.defineProperty(wd,{isEnabled:"isEnabled"},function(){return this.Vh},function(a){this.Vh=a});t.A(wd,{xF:"transactionToUndo"},function(){return 0<=this.Tj&&this.Tj<=this.history.count-1?this.history.ta(this.Tj):null}); -t.A(wd,{wF:"transactionToRedo"},function(){return this.Tjb.bg||(b.scale=a))};oa.prototype.canDecreaseZoom=function(a){void 0===a&&(a=1/this.qt);t.o(a,oa,"canDecreaseZoom:factor");var b=this.h;if(null===b||b.jm!==Je)return!1;a*=b.scale;return ab.bg?!1:b.fs}; -oa.prototype.increaseZoom=function(a){void 0===a&&(a=this.qt);t.o(a,oa,"increaseZoom:factor");var b=this.h;null!==b&&b.jm===Je&&(a*=b.scale,ab.bg||(b.scale=a))};oa.prototype.canIncreaseZoom=function(a){void 0===a&&(a=this.qt);t.o(a,oa,"canIncreaseZoom:factor");var b=this.h;if(null===b||b.jm!==Je)return!1;a*=b.scale;return ab.bg?!1:b.fs};oa.prototype.resetZoom=function(a){void 0===a&&(a=this.gD);t.o(a,oa,"resetZoom:newscale");var b=this.h;null===b||ab.bg||(b.scale=a)}; -oa.prototype.canResetZoom=function(a){void 0===a&&(a=1);t.o(a,oa,"canResetZoom:newscale");var b=this.h;return null===b||ab.bg?!1:b.fs};oa.prototype.zoomToFit=function(){var a=this.h;if(null!==a){var b=a.scale,c=a.position;b!==this.AC||isNaN(this.my)?(this.my=b,this.PB=c.copy(),a.zoomToFit(),a.zh(),this.AC=a.scale):(a.scale=this.my,a.position=this.PB)}};oa.prototype.canZoomToFit=function(){var a=this.h;return null===a?!1:a.fs}; -oa.prototype.collapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b)return!1;b.mc("Collapse Tree");var c=new A(S);if(a instanceof S&&a.Ac)a.collapseTree(),c.add(a);else for(a=b.selection.m;a.next();){var d=a.value;d instanceof S&&d.Ac&&(d.collapseTree(),c.add(d))}b.Ea("TreeCollapsed",c);b.ye("Collapse Tree")}; -oa.prototype.canCollapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b||b.Wa)return!1;if(a instanceof S){if(!a.Ac)return!1;if(0c||Math.abs(b.y-a.y)>d};t.A($d,{h:"diagram"},function(){return this.ba}); -t.g($d,"name",$d.prototype.name);t.defineProperty($d,{name:"name"},function(){return this.Mb},function(a){this.Mb=a});t.g($d,"isEnabled",$d.prototype.isEnabled);t.defineProperty($d,{isEnabled:"isEnabled"},function(){return this.Vh},function(a){this.Vh=a});t.g($d,"isActive",$d.prototype.oa);t.defineProperty($d,{oa:"isActive"},function(){return this.FB},function(a){this.FB=a});t.g($d,"transactionResult",$d.prototype.We); -t.defineProperty($d,{We:"transactionResult"},function(){return this.wC},function(a){this.wC=a}); -function $e(){0e&&(e=k),l>g&&(g=l))}}Infinity===c?b.q(0,0,0,0):b.q(c,d,e-c,g-d)} -function zf(a,b){if(null===a.gd){var c=a.h;if(null!==c&&!c.Wa&&!c.Pe&&null!==a.rc){wf(a);c.xb=!b;a.Kp=!b;a.Li=c.yc.V;for(var c=a.XC?c.copyParts(a.rc.nl(),c,!0):c.copyParts(c.selection,c,!0),d=c.m;d.next();)d.value.location=d.key.location;d=t.qf();yf(c,d);t.Ic(d);for(var d=new ia(B,Object),e=a.rc.m;e.next();){var g=e.key;g.Kd()&&g.canCopy()&&(g=c.wa(g),null!==g&&(a.Kp&&(g.he="Tool"),g.yf(),d.add(g,gf(g.location))))}for(c=c.m;c.next();)e=c.value,e instanceof X&&e.canCopy()&&d.add(e,gf());a.gd=d;af(a, -d.nl());null!==a.Vc&&(c=a.Vc,d=c.bj(),c.cl(a.Li.x-(d.x+d.width/2),a.Li.y-(d.y+d.height/2)))}}}function vf(a){var b=a.h;null!==b&&(null!==a.gd&&(b.wA(a.gd.nl(),!1),a.gd=null),b.xb=!1,a.Kp=!1,a.Li=b.yc.V)}function uf(a){if(null!==a.Vc){if(a.yi&&null!==a.hi){var b=a.hi;b.h.remove(b.Od);b.h.remove(b.Pd)}a.Vc=null;a.hi=null}}function Af(a,b,c){var d=a.h;if(null!==d){var e=a.Li,g=t.M();g.assign(d.S.V);a.moveParts(b,g.it(e),c);t.B(g)}} -$e.prototype.moveParts=function(a,b,c){if(null!==a&&(t.k(a,ia,$e,"moveParts:parts"),0!==a.count)){var d=t.M(),e=t.M();e.assign(b);isNaN(e.x)&&(e.x=0);isNaN(e.y)&&(e.y=0);var g=this.$u;g||bf(this,a);for(var h=new A,k=new A(Da),l=a.m;l.next();){var m=l.key;if(m.Kd()){var n=Bf(this,m,a);if(null!==n)h.add({Bc:m,info:l.value,BH:n});else if(!c||m.canMove()){n=l.value.point;d.assign(n);var p=this.computeMove(m,d.add(e),a);m.location=p;l.value.Jy=p.it(n)}}else l.key instanceof X&&k.add(l.Vd)}for(c=h.m;c.next();)h= -c.value,n=h.info.point,d.assign(n),h.Bc.location=d.add(h.BH.Jy);n=t.M();c=t.M();for(k=k.m;k.next();)if(p=k.value,h=p.key,h instanceof X)if(h.up)if(l=h.ca,m=h.ga,null!==this.Vc&&this.yi)p=p.value.point,a.add(h,gf(e)),l=b.x-p.x,m=b.y-p.y,h.cl(l,m);else{if(null!==l){n.assign(l.location);var q=a.wa(l);null!==q&&n.it(q.point)}null!==m&&(c.assign(m.location),q=a.wa(m),null!==q&&c.it(q.point));null!==l&&null!==m?n.zi(c)?(p=p.value.point,l=d,l.assign(n),l.it(p),a.add(h,gf(n)),h.cl(l.x,l.y)):(h.up=!1,h.Tb()): -(p=p.value.point,a.add(h,gf(null!==l?n:null!==m?c:b)),l=e.x-p.x,m=e.y-p.y,h.cl(l,m))}else if(null===h.ca||null===h.ga)p=p.value.point,a.add(h,gf(b)),l=e.x-p.x,m=e.y-p.y,h.cl(l,m);t.B(d);t.B(e);t.B(n);t.B(c);g||sf(this,a)}};function Bf(a,b,c){b=b.ib;if(null!==b){a=Bf(a,b,c);if(null!==a)return a;a=c.wa(b);if(null!==a)return a}return null} -function wf(a){if(null!==a.rc){for(var b=a.h,c=a.rc.m;c.next();){var d=c.key;d.Kd()&&(d.location=c.value.point)}for(c=a.rc.m;c.next();)if(d=c.key,d instanceof X&&d.up){var e=c.value.point;a.rc.add(d,gf());d.cl(-e.x,-e.y)}b.zh()}} -$e.prototype.computeMove=function(a,b,c,d){void 0===d&&(d=new v);d.assign(b);if(null===a)return d;void 0===c&&(c=null);var e=b;if(this.Mo&&(this.XD||null===c||this.h.S.Ni)&&(e=t.M(),c=e,c.assign(b),null!==a)){var g=this.h;if(null!==g){var h=g.Io,k=this.Lz,g=k.width,k=k.height,l=this.GD,m=l.x,l=l.y,n=this.FD;if(null!==h){var p=h.xs;isNaN(g)&&(g=p.width);isNaN(k)&&(k=p.height);h=h.Kz;isNaN(m)&&(m=h.x);isNaN(l)&&(l=h.y)}h=t.cc(0,0);h.ft(0,0,g,k,n);D.ss(b.x,b.y,m+h.x,l+h.y,g,k,c);t.B(h)}}c=null!==a.Bz? -a.Bz(a,b,e):e;k=a.rE;g=k.x;isNaN(g)&&(g=a.location.x);k=k.y;isNaN(k)&&(k=a.location.y);h=a.lE;m=h.x;isNaN(m)&&(m=a.location.x);h=h.y;isNaN(h)&&(h=a.location.y);d.q(Math.max(g,Math.min(c.x,m)),Math.max(k,Math.min(c.y,h)));e!==b&&t.B(e);return d};function Cf(a,b){if(null===b)return!0;var c=b.Q;return null===c||c instanceof Fe||c.layer.kc||a.rc&&a.rc.contains(c)||a.gd&&a.gd.contains(c)?!0:!1} -function Df(a,b,c,d){var e=a.h;if(null!==e){a.yi&&(null!==a.Vc&&(a.Vc.ca=null,a.Vc.ga=null),Ef(a,!1));var g=!1;!1===a.Vu&&(g=e.xb,e.xb=!0);var h=!1,k=Ff(e,b,null,function(b){return!Cf(a,b)}),l=e.S;l.Nd=k;var m=e.xb;e.xb=!0;if(k!==a.wl){var n=a.wl;a.Ku=n;for(a.wl=k;null!==n;){var p=n.cA;if(null!==p){if(k===n)break;if(null!==k&&k.Ei(n))break;p(l,n,k);h=!0;if(l.Ae)break}n=n.fa}for(n=a.Ku;null!==k;){p=k.sE;if(null!==p){if(n===k)break;if(null!==n&&n.Ei(k))break;p(l,k,n);h=!0;if(l.Ae)break}k=k.fa}k=a.wl}null=== -k&&(p=e.tE,null!==p&&(p(l),h=!0));a.doDragOver(b,k);e.xb=m;h&&e.zh();!1===a.Vu&&(e.xb=g);(e.bf||e.cf)&&(c||d)&&Gf(e,b)}}function Qf(a,b,c){var d=a.hi;if(null===d)return null;var e=a.h.vm(b,d.lA,function(a){return d.findValidLinkablePort(a,c)});a=t.M();for(var g=Infinity,h=null,e=e.m;e.next();){var k=e.value;if(null!==k.Q){var l=k.$a(Fb,a),l=b.Mj(l);lc.ka)){var d=a.h;if(null!==d&&!d.Wa&&(d=a.hi,null!==d)){var e=null,g=null;null===c.ca&&(e=Qf(a,c.n(0),!1),null!==e&&(g=e.Q));var h=null,k=null;null===c.ga&&(h=Qf(a,c.n(c.ka-1),!0),null!==h&&(k=h.Q));if((null===g||g instanceof S)&&(null===k||k instanceof S)){var l=d.isValidLink(g,e,k,h);b?(c.dn=c.n(0).copy(),c.hn=c.n(c.ka-1).copy(),c.up=!1,c.ca=g,null!==e&&(c.Af=e.md),c.ga=k,null!==h&&(c.ng=h.md)):l?Rf(d,g,e,k,h):Rf(d,null,null,null,null)}}}} -$e.prototype.doDragOver=function(){};function Sf(a,b){var c=a.h;if(null!==c&&null!==c.da){a.yi&&Ef(a,!0);rf(a);var d=Ff(c,b,null,function(b){return!Cf(a,b)}),e=c.S;e.Nd=d;if(null!==d)for(var g=d;null!==g;){var h=g.Ls;if(null!==h&&(h(e,g),e.Ae))break;g=g.fa}else h=c.Ls,null!==h&&h(e);a.doDropOnto(b,d);for(d=c.selection.m;d.next();)e=d.value,e instanceof S&&Tf(c,e.ua)}}$e.prototype.doDropOnto=function(){}; -$e.prototype.doMouseMove=function(){if(this.oa){var a=this.h;if(null!==a&&null!==this.to&&null!==this.rc){var b=!1,c=!1;this.mayCopy()?(b=!0,zf(this,!1),Af(this,this.gd,!0)):this.mayMove()?(c=!0,vf(this),Af(this,this.rc,!0)):vf(this);Df(this,a.S.V,c,b)}}}; -$e.prototype.doMouseUp=function(){if(this.oa){this.hq=!0;var a=this.h;if(null!==a){var b=!1,c=this.mayCopy();c&&null!==this.gd?(wf(this),vf(this),zf(this,!0),Af(this,this.gd,!0),null!==this.gd&&a.XE(this.gd.nl())):(b=!0,vf(this),this.mayMove()&&(Af(this,this.rc,!0),this.Vu=!1,Df(this,a.S.V,!0,!1),this.Vu=!0));Sf(this,a.S.V);if(this.oa){this.gd=null;if(b&&null!==this.rc)for(b=this.rc.m;b.next();){var d=b.key;d instanceof S&&(d=d.ib,null===d||null===d.placeholder||this.rc.contains(d)||d.vz&&d.Y())}a.Jc(); -sf(this,this.rc);this.We=c?"Copy":"Move";a.Ea(c?"SelectionCopied":"SelectionMoved",a.selection)}this.stopTool()}}};$e.prototype.mayCopy=function(){var a=this.h;if(null===a||a.Wa||a.Pe||!a.fm||!a.Ej||(a.El?!a.S.Fm:!a.S.control))return!1;for(a=a.selection.m;a.next();){var b=a.value;if(b.Kd()&&b.canCopy())return!0}return null!==this.Vc&&this.yi&&this.Vc.canCopy()?!0:!1}; -$e.prototype.mayMove=function(){var a=this.h;if(null===a||a.Wa||!a.Nk)return!1;for(a=a.selection.m;a.next();){var b=a.value;if(b.Kd()&&b.canMove())return!0}return null!==this.Vc&&this.yi&&this.Vc.canMove()?!0:!1};var tf=new A($e),cf=null,df=null;$e.prototype.mayCopyExternal=function(){var a=this.h;return null===a||!a.lz||a.Wa||a.Pe||!a.fm||null===a.da?!1:!0}; -$e.prototype.doSimulatedDragEnter=function(){if(this.mayCopyExternal()){var a=cf;if(null!==a){vf(a);wf(a);var b=a.h;null!==b&&a.Un.P()&&(b.position=a.Un);null!==b&&qf(b)}tf.contains(this)||tf.add(this)}};$e.prototype.doSimulatedDragLeave=function(){cf.$v=!1;this.doCancel()};$e.prototype.doSimulatedDragOver=function(){if(this.mayCopyExternal()){var a=this.h;if(null!==a){var b=cf;null!==b&&null!==b.rc&&(Uf(this,b.rc.nl(),!1),Af(this,this.gd,!1),Df(this,a.S.V,!1,!0))}}}; -$e.prototype.doSimulatedDrop=function(){var a=cf;if(null!==a&&(a.hq=!0,vf(this),this.mayCopyExternal())){var b=this.h;null!==b&&(this.mc("Drop"),Uf(this,a.rc.nl(),!0),Af(this,this.gd,!0),null!==this.gd&&b.XE(this.gd.nl()),this.We="ExternalCopy",Sf(this,b.S.V),this.gd=null,b.Ea("ExternalObjectsDropped",b.selection),this.Xj(),b.Jc())}}; -function Uf(a,b,c){if(null===a.gd){var d=a.h;if(null!==d&&!d.Wa&&!d.Pe&&null!==d.da){d.xb=!c;a.Kp=!c;a.Li=d.S.V;d=d.copyParts(b,d,!0);c=t.qf();yf(b,c);var e=c.x+c.width/2,g=c.y+c.height/2;t.Ic(c);var h=a.Xu;c=new ia(B,Object);var k=t.M();for(b=b.m;b.next();){var l=b.value;if(l.Kd()&&l.canCopy()){var m=l.location,l=d.wa(l);k.q(h.x-(e-m.x),h.y-(g-m.y));l.location=k;a.Kp&&(l.he="Tool");l.yf();c.add(l,gf(k))}}t.B(k);for(d=d.m;d.next();)e=d.value,e instanceof X&&e.canCopy()&&c.add(e,gf());a.gd=c;af(a, -c.nl());null!==a.Vc&&(c=a.Vc,d=c.bj(),c.cl(a.Li.x-(d.x+d.width/2),a.Li.y-(d.y+d.height/2)))}}} -function Vf(){0=d&&(d=0.1);for(var e=this,g=b.vm(c,d,function(b){return e.findValidLinkablePort(b,a)},null,!0),d=Infinity,b=null,g=g.m;g.next();){var h=g.value,k=h.Q;if(k instanceof S){var l=h.$a(Fb,t.M()),m=c.x-l.x,n=c.y-l.y;t.B(l);l=m*m+n*n;lc){if(null!==this.$b&&a===this.fg&&b===this.gg)return!0;var d=b.md;null===d&&(d="");if(a.Ov(d).count>=c)return!1}return!0}; -Vf.prototype.isValidTo=function(a,b){if(null===a||null===b)return this.Am;if(this.h.Va===this&&(null!==a.layer&&!a.layer.gm||!0!==b.NA))return!1;var c=b.sF;if(Infinity>c){if(null!==this.$b&&a===this.hg&&b===this.ig)return!0;var d=b.md;null===d&&(d="");if(a.Zf(d).count>=c)return!1}return!0};Vf.prototype.isInSameNode=function(a,b){if(null===a||null===b)return!1;if(a===b)return!0;var c=a.Q,d=b.Q;return null!==c&&c===d}; -Vf.prototype.isLinked=function(a,b){if(null===a||null===b)return!1;var c=a.Q;if(!(c instanceof S))return!1;var d=a.md;null===d&&(d="");var e=b.Q;if(!(e instanceof S))return!1;var g=b.md;null===g&&(g="");for(e=e.Zf(g);e.next();)if(g=e.value,g.ca===c&&g.Af===d)return!0;return!1}; -Vf.prototype.isValidLink=function(a,b,c,d){if(!this.isValidFrom(a,b)||!this.isValidTo(c,d)||!(null===b||null===d||(b.zD&&d.rF||!this.isInSameNode(b,d))&&(b.yD&&d.qF||!this.isLinked(b,d)))||null!==this.$b&&(null!==a&&Wf(this,a,this.$b)||null!==c&&Wf(this,c,this.$b))||null!==a&&null!==c&&(null===a.data&&null!==c.data||null!==a.data&&null===c.data)||!Xf(this,a,c,this.$b))return!1;if(null!==a){var e=a.Yo;if(null!==e&&!e(a,b,c,d,this.$b))return!1}if(null!==c&&(e=c.Yo,null!==e&&!e(a,b,c,d,this.$b)))return!1; -e=this.Yo;return null!==e?e(a,b,c,d,this.$b):!0};function Wf(a,b,c){if(null===b)return!1;var d=b.ld;if(null===d)return!1;if(d===c)return!0;var e=new la(S);e.add(b);return Yf(a,d,c,e)}function Yf(a,b,c,d){if(b===c)return!0;var e=b.ca;if(null!==e&&e.wh&&(d.add(e),Yf(a,e.ld,c,d)))return!0;b=b.ga;return null!==b&&b.wh&&(d.add(b),Yf(a,b.ld,c,d))?!0:!1} -function Xf(a,b,c,d){if(null===b||null===c)return a.Am;var e=a.h.GF;if(e!==Zf){if(e===$f){if(null!==d&&!d.sc)return!0;for(e=c.ie;e.next();){var g=e.value;if(g!==d&&g.sc&&g.ga===c)return!1}return!ag(a,b,c,d,!0)}if(e===gg){if(null!==d&&!d.sc)return!0;for(e=b.ie;e.next();)if(g=e.value,g!==d&&g.sc&&g.ca===b)return!1;return!ag(a,b,c,d,!0)}if(e===hg)return b===c?a=!0:(e=new la(S),e.add(c),a=ig(a,e,b,c,d)),!a;if(e===jg)return!ag(a,b,c,d,!1);if(e===kg)return b===c?a=!0:(e=new la(S),e.add(c),a=lg(a,e,b,c, -d)),!a}return!0}function ag(a,b,c,d,e){if(b===c)return!0;if(null===b||null===c)return!1;for(var g=b.ie;g.next();){var h=g.value;if(h!==d&&(!e||h.sc)&&h.ga===b&&(h=h.ca,h!==b&&ag(a,h,c,d,e)))return!0}return!1}function ig(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.ie;g.next();){var h=g.value;if(h!==e&&h.ga===c&&(h=h.ca,h!==c&&ig(a,b,h,d,e)))return!0}return!1} -function lg(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.ie;g.next();){var h=g.value;if(h!==e){var k=h.ca,h=h.ga,k=k===c?h:k;if(k!==c&&lg(a,b,k,d,e))return!0}}return!1}t.g(Vf,"linkValidation",Vf.prototype.Yo);t.defineProperty(Vf,{Yo:"linkValidation"},function(){return this.zk},function(a){null!==a&&t.j(a,"function",Vf,"linkValidation");this.zk=a});t.g(Vf,"portTargeted",Vf.prototype.Ws); -t.defineProperty(Vf,{Ws:"portTargeted"},function(){return this.fC},function(a){null!==a&&t.j(a,"function",Vf,"portTargeted");this.fC=a});function pa(){0b.ws+1&&ch.Mj(e)&&(k=b.points.copy(),k.Zc(c), -b.points=k,b.ve(),b.updateAdornments()),t.B(h)}a.Jc();this.We=this.name;a.Ea("LinkReshaped",this.es)}this.stopTool()};function Lg(a,b,c,d,e,g){return g?Math.abs(b.y-c.y)=a.x)c=0>=a.y?c+225:1<=a.y?c+135:c+180;else if(1<=a.x)0>=a.y?c+=315:1<=a.y&&(c+=45);else if(0>=a.y)c+=270;else if(1<=a.y)c+=90;else break a;0>c?c+=360:360<=c&&(c-=360);b.cursor=22.5>c?"e-resize":67.5>c?"se-resize":112.5>c?"s-resize":157.5>c?"sw-resize":202.5>c?"w-resize":247.5>c?"nw-resize":292.5>c?"n-resize":337.5>c?"ne-resize":"e-resize"}else if(b instanceof y)for(b=b.elements;b.next();)Ng(a, -b.value,c)}t.defineProperty(Mg,{ys:"handleArchetype"},function(){return this.tk},function(a){a&&t.k(a,Q,Mg,"handleArchetype");this.tk=a});t.A(Mg,{handle:"handle"},function(){return this.Qb});t.defineProperty(Mg,{Gc:"adornedObject"},function(){return this.Ga},function(a){a&&t.k(a,Q,Mg,"adornedObject");this.Ga=a});Mg.prototype.canStart=function(){if(!this.isEnabled)return!1;var a=this.h;return null!==a&&!a.Wa&&a.jo&&a.S.left?null!==this.findToolHandleAt(a.yc.V,this.name)?!0:!1:!1}; -Mg.prototype.doActivate=function(){var a=this.h;null!==a&&(this.Qb=this.findToolHandleAt(a.yc.V,this.name),null!==this.Qb&&(this.Ga=this.Qb.Q.Gc,this.Mn=this.Ga.angle,this.hG.set(this.Ga.Na),this.yy.set(this.Ga.Q.location),this.Gu.set(this.Ga.ya),this.Mx=this.computeCellSize(),this.Ox=this.computeMinSize(),this.Nx=this.computeMaxSize(),a.ud=!0,this.mc(this.name),this.oa=!0))};Mg.prototype.doDeactivate=function(){var a=this.h;null!==a&&(this.Xj(),this.Ga=this.Qb=null,this.oa=a.ud=!1)}; -Mg.prototype.doCancel=function(){this.Ga.ya=this.Gu;this.Ga.Q.location=this.yy;this.stopTool()};Mg.prototype.doMouseMove=function(){var a=this.h;if(this.oa&&null!==a){var b=this.Ox,c=this.Nx,d=this.Mx,e=this.Ga.DD(a.S.V,t.M()),g=Qg;this.Ga instanceof Y&&(g=this.Ga.Tv,g===Rg&&(g=this.Ga.La.fc));b=this.computeResize(e,this.Qb.alignment,b,c,d,!(g===Sg||g===Tg||a.S.shift));this.resize(b);a.zh();t.B(e)}}; -Mg.prototype.doMouseUp=function(){var a=this.h;if(this.oa&&null!==a){var b=this.Ox,c=this.Nx,d=this.Mx,e=this.Ga.DD(a.S.V,t.M()),g=Qg;this.Ga instanceof Y&&(g=this.Ga.Tv,g===Rg&&(g=this.Ga.La.fc));b=this.computeResize(e,this.Qb.alignment,b,c,d,!(g===Sg||g===Tg||a.S.shift));this.resize(b);t.B(e);a.Jc();this.We=this.name;a.Ea("PartResized",this.Ga,this.Gu)}this.stopTool()}; -Mg.prototype.resize=function(a){if(null!==this.h){var b=this.Ga.Q,c=b.position.copy(),d=this.Ga.Na.copy(),e=this.Ga.Wk(),g=this.Ga.Sj();360<=e?e-=360:0>e&&(e+=360);var h=Math.PI*e/180,k=Math.cos(h),h=Math.sin(h),l=a.width-d.width,d=a.height-d.height,m=90e?1:0;c.x+=g*((a.x+l*m)*k-(a.y+d*(0e?1:0))*h);c.y+=g*((a.x+l*(180e?1:0))*h+(a.y+d*m)*k);this.Ga.ya=a.size;b.yf();b.move(c)}}; -Mg.prototype.computeResize=function(a,b,c,d,e,g){b.jd()&&(b=Fb);var h=this.Ga.Na,k=h.x,l=h.y,m=h.x+h.width,n=h.y+h.height,p=1;if(!g){var p=h.width,q=h.height;0>=p&&(p=1);0>=q&&(q=1);p=q/p}q=t.M();D.ss(a.x,a.y,k,l,e.width,e.height,q);a=h.copy();0>=b.x?0>=b.y?(a.x=Math.max(q.x,m-d.width),a.x=Math.min(a.x,m-c.width),a.width=Math.max(m-a.x,c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.width=Math.max(Math.min(q.x-k,d.width),c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y, -n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=n-a.y,g||(a.width= -a.height/p,a.x=k+0.5*(m-k-a.width))):1<=b.y&&(a.height=Math.max(Math.min(q.y-l,d.height),c.height),g||(a.width=a.height/p,a.x=k+0.5*(m-k-a.width)));t.B(q);return a};Mg.prototype.computeMinSize=function(){var a=this.Ga.Te.copy(),b=this.Te;!isNaN(b.width)&&b.width>a.width&&(a.width=b.width);!isNaN(b.height)&&b.height>a.height&&(a.height=b.height);return a}; -Mg.prototype.computeMaxSize=function(){var a=this.Ga.Ce.copy(),b=this.Ce;!isNaN(b.width)&&b.widtha&&(a+=360));var b=Math.min(Math.abs(this.jF),180),c=Math.min(Math.abs(this.iF),b/2);!this.h.S.shift&&0b-c&&(a=(Math.floor(a/b)+1)*b));360<=a?a-=360:0>a&&(a+=360);return a};t.g(Ug,"snapAngleMultiple",Ug.prototype.jF); -t.defineProperty(Ug,{jF:"snapAngleMultiple"},function(){return this.My},function(a){this.My!==a&&(f&&t.j(a,"number",Ug,"snapAngleMultiple"),this.My=a)});t.g(Ug,"snapAngleEpsilon",Ug.prototype.iF);t.defineProperty(Ug,{iF:"snapAngleEpsilon"},function(){return this.Ly},function(a){this.Ly!==a&&(f&&t.j(a,"number",Ug,"snapAngleEpsilon"),this.Ly=a)});t.g(Ug,"originalAngle",Ug.prototype.iI);t.A(Ug,{iI:"originalAngle"},function(){return this.Mn}); -function Wg(){0e.right&&(c.x-=d.width+5);c.xe.bottom&&(c.y-=d.height+5);c.ye.right&&(c.x-=d.width+5);c.xe.bottom?c.y-(d.height+5):c.y+20;c.y=a)return b;for(var c=0,d=0,e=0,g=0,h=0,k=this.qb.m;k.next();){var l=k.value;l instanceof V?e++:l instanceof S?d++:l instanceof X?g++:l instanceof Fe?h++:c++}k="";0=d.count)a=d.count;else if(d.ta(a)===b)return-1;d.td(a,b);b.As();d=this.h;null!==d&&(c?d.na():d.zm(b));b instanceof V&&this.zw(b);return a};aa.Oe=function(a,b,c){var d=this.qb;if(0>a||a>=d.length){if(a=d.indexOf(b),0>a)return-1}else if(d.ta(a)!==b&&(a=d.indexOf(b),0>a))return-1;b.Bs();d.Zc(a);d=this.h;null!==d&&(c?d.na():d.Oe(b));b.Cn=null;return a}; -aa.zw=function(a){for(;null!==a;){if(a.layer===this){var b=a;if(b.Kc.next()){for(var c=-1,d=-1,e=this.qb.p,g=e.length,h=0;hd&&k.ib===b&&(d=h,0<=c))break}!(0>d)&&da||1=a)return b;for(var c=this.Lb.m;c.next();)b+="\n "+c.value.toString(a-1);return b};z.prototype.checkProperties=function(){return t.SG(this)};z.fromDiv=function(a){var b=a;"string"===typeof a&&(b=document.getElementById(a));return b instanceof HTMLDivElement&&b.ba instanceof z?b.ba:null};t.g(z,"div",z.prototype.xi); -t.defineProperty(z,{xi:"div"},function(){return this.vb},function(a){null!==a&&t.k(a,HTMLDivElement,z,"div");if(this.vb!==a){var b=this.vb;if(null!==b){delete b.ba;b.innerHTML="";null!==this.Sa&&(this.Sa.ba=null,this.Sa.removeEventListener("touchstart",this.vF,!1),this.Sa.removeEventListener("touchmove",this.uF,!1),this.Sa.removeEventListener("touchend",this.tF,!1));b=this.fv;if(null!==b){for(var c=b.WB.p,d=c.length,e=0;e=d&&t.Ka(t.ov)!==t.Ka("7da71ca0ad381e90")&&(d=a[t.Ka("73a612b6fb191d")](t.Ka("76a715b2ef3e149757")));if(this.Xi=!(0a.scale&&h.canIncreaseZoom()||gc)b.preventDefault();else{a.Ql=null;return}if(null!==a.Ql){var d=a.Sa,e=d.getBoundingClientRect();b=new v(b.pageX-window.scrollX-d.width/e.width*e.left,b.pageY-window.scrollY-d.height/e.height*e.top);d=a.Ih;c*=a.Ql;e=a.Yf;if(c>a.scale&&e.canIncreaseZoom()||cl&&(a.position= -new v(-(a.uj.scrollWidth-a.oc)+this.scrollLeft-a.oc/r+a.hd.right,a.position.y))),this.kC&&a.cf&&(bn&&(a.position=new v(a.position.x,-(a.vj.scrollHeight-a.nc)+this.scrollTop-a.nc/r+a.hd.bottom))),t.B(s),Wh(a),a.Pu=!1,a.ej=!1,b=a.hd,c=a.lb,k=b.right,l=c.right,m=b.bottom,n=c.bottom,p=b.x,q=c.x,b=b.y,c=c.y,e>=d&&p>=q&&k<=l&&(a.Hy.style.width="1px"),h>=g&&b>=c&&m<=n&&(a.Iy.style.height="1px")}}else Xh(this.ba)}; -z.prototype.bC=function(){this.ba.isEnabled?this.ba.Gy=!0:Xh(this.ba)};z.prototype.computeBounds=z.prototype.df=function(){0a.bg&&(l=a.bg),l):b===ei?(l=k>h?(g-a.af)/c:(e-a.af)/d,1a.bg&&(l=a.bg),l):a.scale}}z.prototype.zoomToFit=z.prototype.zoomToFit=function(){this.scale=ai(this,di)}; -z.prototype.zoomToRect=function(a,b){void 0===b&&(b=di);var c=a.width,d=a.height;if(!(0===c||0===d||isNaN(c)&&isNaN(d))){var e=1;if(b===di||b===ei)if(isNaN(c))e=this.lb.height*this.scale/d;else if(isNaN(d))e=this.lb.width*this.scale/c;else var e=this.oc,g=this.nc,e=b===ei?g/d>e/c?(g-(this.Al?this.af:0))/d:(e-(this.Bl?this.af:0))/c:Math.min(g/d,e/c);this.scale=e;this.position=new v(a.x,a.y)}}; -z.prototype.alignDocument=function(a,b){this.dj&&ci(this,this.df());var c=this.hd,d=this.lb,e=this.gc;this.gc=!0;this.position=new v(c.x+(a.x*c.width+a.offsetX)-(b.x*d.width-b.offsetX),c.y+(a.y*c.height+a.offsetY)-(b.y*d.height-b.offsetY));this.gc=e;this.na()}; -function bi(a,b,c,d,e,g){g.kd()&&(d>c.width&&(b.x=c.x+(g.x*c.width+g.offsetX)-(g.x*d-g.offsetX)),e>c.height&&(b.y=c.y+(g.y*c.height+g.offsetY)-(g.y*e-g.offsetY)));dc.left?b.x=c.left:b.xc.top?b.y=c.top:b.yc.touches.length)&&c.preventDefault();c.cancelBubble=!0;return!1} -z.prototype.VH=function(a){if(this.ba.isEnabled){var b=this.ba.hc;Ph(this.ba,this.ba,a,b,!1);b.key=String.fromCharCode(a.which);b.Nj=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del";break;case 48:b.key="0";break;case 187:b.key="Add";break;case 189:b.key="Subtract"; -break;case 107:b.key="Add";break;case 109:b.key="Subtract";break;case 27:b.key="Esc"}this.ba.doKeyDown();return 187!==a.which&&189!==a.which&&48!==a.which&&107!==a.which&&109!==a.which||!0!==a.ctrlKey?Rh(this.ba,b,a):(a.cancelBubble=!0,void 0!==a.preventDefault?a.preventDefault():a.returnValue=!1,Event.stop&&(t.l("Event.stop can fire for this browser"),Event.stop(a)),void 0!==a.stopPropagation&&a.stopPropagation(),!1)}}; -z.prototype.WH=function(a){if(this.ba.isEnabled){var b=this.ba.hc;Ph(this.ba,this.ba,a,b,!1);b.key=String.fromCharCode(a.which);b.Ni=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del"}this.ba.doKeyUp();return Rh(this.ba,b,a)}}; -z.prototype.ah=function(a){var b=this.Sa;if(null===b)return new v(0,0);var c=b.getBoundingClientRect(),d=a.clientX-b.width/c.width*c.left;a=a.clientY-b.height/c.height*c.top;return null!==this.rd?(d=new v(d,a),Oa(d,this.rd),d):new v(d,a)};t.g(z,"renderingHints",z.prototype.HE);t.defineProperty(z,{HE:"renderingHints"},function(){return this.gC},function(a){this.gC=a;this.sA()});z.prototype.invalidateDocumentBounds=z.prototype.Jc=function(){this.dj=!0;this.Gf()}; -function fi(a){a.zd||Yh(a);a.dj&&ci(a,a.df());$h(a);for(a=a.On.m;a.next();)fi(a.value)}z.prototype.redraw=z.prototype.sA=function(){this.gc||this.zd||(this.na(),gi(this),Wh(this),this.Jc(),this.zh())};z.prototype.isUpdateRequested=function(){return this.Uf};z.prototype.delayInitialization=function(a){hi(this);this.Mf=!1;a&&setTimeout(a,1)}; -z.prototype.requestUpdate=z.prototype.Gf=function(a){void 0===a&&(a=!1);if(!0!==this.Uf&&!(this.gc||!1===a&&this.zd)){this.Uf=!0;var b=this;requestAnimationFrame(function(){b.Uf&&b.zh()})}};z.prototype.maybeUpdate=z.prototype.zh=function(){if(!this.mq||this.Uf)this.mq&&(this.mq=!1),hi(this)}; -function hi(a){if(!a.zd&&(a.Uf=!1,null!==a.vb)){a.zd=!0;a.aA();!a.gc&&a.ej&&(Xh(a)||Xh(a));null!==a.Pc&&(a.Pc.visible&&!a.Zt&&(ni(a),a.Zt=!0),!a.Pc.visible&&a.Zt&&(a.Zt=!1));Yh(a);var b=!1;if(!a.Mf||a.Bt)a.Mf?oi(a,!a.St):(a.mc("Initial Layout"),oi(a,!1)),b=!0;a.St=!1;Yh(a);a.Ky||fi(a);b&&(a.Mf||(pi(a),ni(a)),a.Ea("LayoutCompleted"));qi(a);Yh(a);a.gc||!a.ej||Xh(a)||(Xh(a),Yh(a));b&&!a.Mf&&(a.Mf=!0,a.ye("Initial Layout"),a.va.clear(),setTimeout(function(){a.Uj=!1},1));a.Me();a.zd=!1}} -function pi(a){if(a.wk!==Je)a.scale=ai(a,a.wk);else if(a.rl!==Je)a.scale=ai(a,a.rl);else{var b=a.SD;isFinite(b)&&0b;b++){var c=a.Nf.m;if(null===c||0===a.Nf.count)break;a.Nf=new la(Q);var d=a,e=a.Nf;for(c.reset();c.next();){var g=c.value;!g.Kd()||g instanceof V||(g.$k()?(mh(g,Infinity,Infinity),g.xc()):e.add(g))}for(c.reset();c.next();)g=c.value,g instanceof V&&ri(d,g);for(c.reset();c.next();)d=c.value,d instanceof X&&(d.$k()?(mh(d,Infinity,Infinity),d.xc(),d.iw()):e.add(d));for(c.reset();c.next();)d=c.value,d instanceof Fe&&(d.$k()?(mh(d,Infinity,Infinity),d.xc()): -e.add(d))}}function ri(a,b){for(var c=b.Kc,d=t.yb();c.next();){var e=c.value;e instanceof V?(si(e)||ti(e)||ui(e))&&ri(a,e):e instanceof X?d.push(e):(mh(e,Infinity,Infinity),e.xc())}c=d.length;for(e=0;e=l[0]&&c>=l[1]&&b+d<=l[0]+l[2]&&c+e<=l[1]+l[3])return!1;b<=l[0]&&c<=l[1]&&b+d>=l[0]+l[2]&&c+e>=l[1]+l[3]?(g[k][2]=0,g[k][3]=0):b>=l[0]&&b=l[1]&&c+e<=l[1]+l[3]?(d=b+d-(l[0]+l[2]),b=l[0]+l[2],k=-1):b+d>l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c+e<=l[1]+l[3]?(d=l[0]-b,k=-1):b>=l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c= -l[0]&&b+d<=l[0]+l[2]&&c+e>l[1]&&c+e<=l[1]+l[3]?(e=l[1]-c,k=-1):g[k][0]>=b&&g[k][0]=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]-=b+d-g[k][0],g[k][0]=b+d,k=-1):g[k][0]+g[k][2]>b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]=b-g[k][0],k=-1):g[k][0]>=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]+g[k][3]>c&&g[k][1]+g[k][3]<=c+e&&(g[k][3]=c-g[k][1],k=-1)}for(k=0;kk&&c/W>l||(a.MD&&a.bf&&(q+1E+1&&(n=(x-E)*W+a.oc+"px",a.uj.scrollLeft=a.position.x*W)),a.ND&&a.cf&&(r+1M+1&&(p=(L-M)*W+a.nc+"px",a.vj.scrollTop=a.position.y*W)));m="1px"!==n;c="1px"!==p;m!==a.Al&&(a.nc="1px"===n?a.nc+a.af:Math.max(a.nc-a.af,1),b.height=a.nc,h=!0);a.Al=m;a.Hy.style.width=n;c!==a.Bl&&(a.oc= -"1px"===p?a.oc+a.af:Math.max(a.oc-a.af,1),b.width=a.oc,h=!0);a.Bl=c;a.Iy.style.height=p;h&&Th(a);m=a.oc;c=a.nc;a.vj.style.height=c+"px";a.vj.style.width=m+(a.Bl?a.af:0)+"px";a.uj.style.width=m+"px";a.uj.style.height=c+(a.Al?a.af:0)+"px";a.Gy=!1;return d!==m||e!==c?(n=a.lb,a.Us(g,n,h?!0:void 0),!1):!0}}} -z.prototype.add=z.prototype.add=function(a){t.k(a,B,z,"add:part");var b=a.h;if(b!==this){null!==b&&t.l("Cannot add part "+a.toString()+" to "+this.toString()+". It is already a part of "+b.toString());var c=a.he,b=this.rs(c);null===b&&(b=this.rs(""));null===b&&t.l('Cannot add a Part when unable find a Layer named "'+c+'" and there is no default Layer');a.layer!==b&&(c=a.h===this?b.zm(99999999,a,!0):b.zm(99999999,a),0<=c&&this.Mc(td,"parts",b,null,a,null,c),b.kc||this.Jc(),a.J(Di),c=a.Po,null!==c&& -c(a,null,b))}};z.prototype.zm=function(a){if(a instanceof S){if(this.Du.add(a),a instanceof V){var b=a.ib;null===b?this.Hk.add(a):b.Jn.add(a);b=a.Vb;null!==b&&(b.h=this)}}else a instanceof X?this.mu.add(a):a instanceof Fe||this.qb.add(a);a.rb&&a.Y();if(b=a.data){a instanceof Fe||(a instanceof X?this.pk.add(b,a):this.Qh.add(b,a));var c=this;Ei(a,function(a){Fi(c,a)})}!0!==ti(a)&&!0!==ui(a)||this.Nf.add(a);Gi(a,!0,this);a.ub()&&(a.ua.P()&&this.na(Ch(a,a.ua)),this.Jc())}; -z.prototype.Oe=function(a){a.ve();if(a instanceof S){if(this.Du.remove(a),a instanceof V){var b=a.ib;null===b?this.Hk.remove(a):b.Jn.remove(a);b=a.Vb;null!==b&&(b.h=null)}}else a instanceof X?this.mu.remove(a):a instanceof Fe||this.qb.remove(a);if(b=a.data){a instanceof Fe||(a instanceof X?this.pk.remove(b):this.Qh.remove(b));var c=this;Ei(a,function(a){Hi(c,a)})}this.Nf.remove(a);a.ub()&&(a.ua.P()&&this.na(Ch(a,a.ua)),this.Jc())}; -z.prototype.remove=z.prototype.remove=function(a){t.k(a,B,z,"remove:part");a.Za=!1;var b=a.layer;if(null!==b&&b.h===this){a.J(Ii);a.sm();var c=b.Oe(-1,a);0<=c&&this.Mc(ud,"parts",b,a,null,c,null);c=a.Po;null!==c&&c(a,b,null);b.kc||this.Jc()}};z.prototype.removeParts=z.prototype.wA=function(a,b){if(a===this.selection){var c=new la;c.He(a);a=c}for(c=a.m;c.next();){var d=c.value;d.h===this&&(b&&!d.canDelete()||this.remove(d))}}; -z.prototype.copyParts=z.prototype.copyParts=function(a,b,c){return this.Yf.copyParts(a,b,c)};z.prototype.moveParts=z.prototype.moveParts=function(a,b,c){t.k(b,v,z,"moveParts:offset");var d=this.zb;if(null!==d){d=d.ce;null===d&&(d=new $e,d.h=this);var e=new ia(B,Object);if(a)a=a.m;else{for(a=this.gp;a.next();)ff(d,e,a.value,c);for(a=this.Ki;a.next();)ff(d,e,a.value,c);a=this.links}for(;a.next();)ff(d,e,a.value,c);d.moveParts(e,b,c)}}; -function Ji(a,b,c){t.k(b,Zd,z,"addLayer:layer");null!==b.h&&b.h!==a&&t.l("Cannot share a Layer with another Diagram: "+b+" of "+b.h);null===c?null!==b.h&&t.l("Cannot add an existing Layer to this Diagram again: "+b):(t.k(c,Zd,z,"addLayer:existingLayer"),c.h!==a&&t.l("Existing Layer must be in this Diagram: "+c+" not in "+c.h),b===c&&t.l("Cannot move a Layer before or after itself: "+b));if(b.h!==a){b=b.name;a=a.Lb;c=a.count;for(var d=0;dd&&this.Jc()}; -z.prototype.addLayerAfter=function(a,b){Ji(this,a,b);a.le(this);var c=this.Lb,d=c.indexOf(a);0<=d&&(c.remove(a),null!==this.Cd&&this.Mc(ud,"layers",this,a,null,d,null));for(var e=c.count,g=0;gd&&this.Jc()}; -z.prototype.removeLayer=function(a){t.k(a,Zd,z,"removeLayer:layer");a.h!==this&&t.l("Cannot remove a Layer from another Diagram: "+a+" of "+a.h);if(""!==a.name){var b=this.Lb,c=b.indexOf(a);if(b.remove(a)){for(b=a.qb.copy().m;b.next();){var d=b.value,e=d.he;d.he=e!==a.name?e:""}null!==this.Cd&&this.Mc(ud,"layers",this,a,null,c,null);this.na();this.Jc()}}};z.prototype.findLayer=z.prototype.rs=function(a){for(var b=this.ew;b.next();){var c=b.value;if(c.name===a)return c}return null}; -z.prototype.addChangedListener=z.prototype.jz=function(a){t.j(a,"function",z,"addChangedListener:listener");null===this.Si&&(this.Si=new A("function"));this.Si.add(a)};z.prototype.removeChangedListener=z.prototype.uA=function(a){t.j(a,"function",z,"removeChangedListener:listener");null!==this.Si&&(this.Si.remove(a),0===this.Si.count&&(this.Si=null))}; -z.prototype.vv=function(a){this.xb||this.va.KD(a);a.fd!==rd&&(this.Uj=!0);if(null!==this.Si){var b=this.Si,c=b.length;if(1===c)b=b.ta(0),b(a);else if(0!==c)for(var d=b.Ve(),e=0;em||("LineV"===l.Db?g=g*m/D.BD(g,m):e=e*m/D.BD(e,m))}h=c.xs;d.q(g*h.width,e*h.height);if(b)k=b.width,l=b.height,g=b.x,h=b.y;else{e=t.qf();g=a.lb;e.q(g.x,g.y,g.width,g.height);for(h=a.On.m;h.next();)g=h.value.lb,cb(e,g.x,g.y,g.width,g.height);k=e.width;l=e.height;g=e.x;h=e.y;if(!e.P())return}c.width=k+2*d.width;c.height=l+2*d.height;e=t.M();D.ss(g,h,0,0,d.width,d.height, -e);e.offset(-d.width,-d.height);t.Qj(d);c.Q.location=e;t.B(e)}}z.prototype.clearSelection=z.prototype.xv=function(){var a=0a&&t.ia(a,">= zero",z,"linkSpacing"),this.hj=a,this.i("linkSpacing",b,a))});t.A(z,{ew:"layers"},function(){return this.Lb.m});t.g(z,"isModelReadOnly",z.prototype.Pe);t.defineProperty(z,{Pe:"isModelReadOnly"},function(){var a=this.Cd;return null===a?!1:a.Wa},function(a){var b=this.Cd;null!==b&&(b.Wa=a)});t.g(z,"isReadOnly",z.prototype.Wa); -t.defineProperty(z,{Wa:"isReadOnly"},function(){return this.yk},function(a){var b=this.yk;b!==a&&(t.j(a,"boolean",z,"isReadOnly"),this.yk=a,this.i("isReadOnly",b,a))});t.g(z,"isEnabled",z.prototype.isEnabled);t.defineProperty(z,{isEnabled:"isEnabled"},function(){return this.Vh},function(a){var b=this.Vh;b!==a&&(t.j(a,"boolean",z,"isEnabled"),this.Vh=a,this.i("isEnabled",b,a))});t.g(z,"allowClipboard",z.prototype.pv); -t.defineProperty(z,{pv:"allowClipboard"},function(){return this.tt},function(a){var b=this.tt;b!==a&&(t.j(a,"boolean",z,"allowClipboard"),this.tt=a,this.i("allowClipboard",b,a))});t.g(z,"allowCopy",z.prototype.Ej);t.defineProperty(z,{Ej:"allowCopy"},function(){return this.bk},function(a){var b=this.bk;b!==a&&(t.j(a,"boolean",z,"allowCopy"),this.bk=a,this.i("allowCopy",b,a))});t.g(z,"allowDelete",z.prototype.Mk); -t.defineProperty(z,{Mk:"allowDelete"},function(){return this.ck},function(a){var b=this.ck;b!==a&&(t.j(a,"boolean",z,"allowDelete"),this.ck=a,this.i("allowDelete",b,a))});t.g(z,"allowDragOut",z.prototype.qv);t.defineProperty(z,{qv:"allowDragOut"},function(){return this.ut},function(a){var b=this.ut;b!==a&&(t.j(a,"boolean",z,"allowDragOut"),this.ut=a,this.i("allowDragOut",b,a))});t.g(z,"allowDrop",z.prototype.lz); -t.defineProperty(z,{lz:"allowDrop"},function(){return this.vt},function(a){var b=this.vt;b!==a&&(t.j(a,"boolean",z,"allowDrop"),this.vt=a,this.i("allowDrop",b,a))});t.g(z,"allowTextEdit",z.prototype.mo);t.defineProperty(z,{mo:"allowTextEdit"},function(){return this.lk},function(a){var b=this.lk;b!==a&&(t.j(a,"boolean",z,"allowTextEdit"),this.lk=a,this.i("allowTextEdit",b,a))});t.g(z,"allowGroup",z.prototype.ho); -t.defineProperty(z,{ho:"allowGroup"},function(){return this.dk},function(a){var b=this.dk;b!==a&&(t.j(a,"boolean",z,"allowGroup"),this.dk=a,this.i("allowGroup",b,a))});t.g(z,"allowUngroup",z.prototype.no);t.defineProperty(z,{no:"allowUngroup"},function(){return this.mk},function(a){var b=this.mk;b!==a&&(t.j(a,"boolean",z,"allowUngroup"),this.mk=a,this.i("allowUngroup",b,a))});t.g(z,"allowInsert",z.prototype.fm); -t.defineProperty(z,{fm:"allowInsert"},function(){return this.xt},function(a){var b=this.xt;b!==a&&(t.j(a,"boolean",z,"allowInsert"),this.xt=a,this.i("allowInsert",b,a))});t.g(z,"allowLink",z.prototype.gm);t.defineProperty(z,{gm:"allowLink"},function(){return this.ek},function(a){var b=this.ek;b!==a&&(t.j(a,"boolean",z,"allowLink"),this.ek=a,this.i("allowLink",b,a))});t.g(z,"allowRelink",z.prototype.Fj); -t.defineProperty(z,{Fj:"allowRelink"},function(){return this.gk},function(a){var b=this.gk;b!==a&&(t.j(a,"boolean",z,"allowRelink"),this.gk=a,this.i("allowRelink",b,a))});t.g(z,"allowMove",z.prototype.Nk);t.defineProperty(z,{Nk:"allowMove"},function(){return this.fk},function(a){var b=this.fk;b!==a&&(t.j(a,"boolean",z,"allowMove"),this.fk=a,this.i("allowMove",b,a))});t.g(z,"allowReshape",z.prototype.io); -t.defineProperty(z,{io:"allowReshape"},function(){return this.hk},function(a){var b=this.hk;b!==a&&(t.j(a,"boolean",z,"allowReshape"),this.hk=a,this.i("allowReshape",b,a))});t.g(z,"allowResize",z.prototype.jo);t.defineProperty(z,{jo:"allowResize"},function(){return this.ik},function(a){var b=this.ik;b!==a&&(t.j(a,"boolean",z,"allowResize"),this.ik=a,this.i("allowResize",b,a))});t.g(z,"allowRotate",z.prototype.lo); -t.defineProperty(z,{lo:"allowRotate"},function(){return this.jk},function(a){var b=this.jk;b!==a&&(t.j(a,"boolean",z,"allowRotate"),this.jk=a,this.i("allowRotate",b,a))});t.g(z,"allowSelect",z.prototype.Ie);t.defineProperty(z,{Ie:"allowSelect"},function(){return this.kk},function(a){var b=this.kk;b!==a&&(t.j(a,"boolean",z,"allowSelect"),this.kk=a,this.i("allowSelect",b,a))});t.g(z,"allowUndo",z.prototype.mz); -t.defineProperty(z,{mz:"allowUndo"},function(){return this.yt},function(a){var b=this.yt;b!==a&&(t.j(a,"boolean",z,"allowUndo"),this.yt=a,this.i("allowUndo",b,a))});t.g(z,"allowZoom",z.prototype.fs);t.defineProperty(z,{fs:"allowZoom"},function(){return this.At},function(a){var b=this.At;b!==a&&(t.j(a,"boolean",z,"allowZoom"),this.At=a,this.i("allowZoom",b,a))});t.g(z,"hasVerticalScrollbar",z.prototype.ND); -t.defineProperty(z,{ND:"hasVerticalScrollbar"},function(){return this.cu},function(a){var b=this.cu;b!==a&&(t.j(a,"boolean",z,"hasVerticalScrollbar"),this.cu=a,gi(this),this.na(),this.i("hasVerticalScrollbar",b,a),$h(this))});t.g(z,"hasHorizontalScrollbar",z.prototype.MD);t.defineProperty(z,{MD:"hasHorizontalScrollbar"},function(){return this.bu},function(a){var b=this.bu;b!==a&&(t.j(a,"boolean",z,"hasHorizontalScrollbar"),this.bu=a,gi(this),this.na(),this.i("hasHorizontalScrollbar",b,a),$h(this))}); -t.g(z,"allowHorizontalScroll",z.prototype.bf);t.defineProperty(z,{bf:"allowHorizontalScroll"},function(){return this.wt},function(a){var b=this.wt;b!==a&&(t.j(a,"boolean",z,"allowHorizontalScroll"),this.wt=a,this.i("allowHorizontalScroll",b,a),$h(this))});t.g(z,"allowVerticalScroll",z.prototype.cf);t.defineProperty(z,{cf:"allowVerticalScroll"},function(){return this.zt},function(a){var b=this.zt;b!==a&&(t.j(a,"boolean",z,"allowVerticalScroll"),this.zt=a,this.i("allowVerticalScroll",b,a),$h(this))}); -t.g(z,"scrollHorizontalLineChange",z.prototype.np);t.defineProperty(z,{np:"scrollHorizontalLineChange"},function(){return this.Qu},function(a){var b=this.Qu;b!==a&&(t.j(a,"number",z,"scrollHorizontalLineChange"),0>a&&t.ia(a,">= 0",z,"scrollHorizontalLineChange"),this.Qu=a,this.i("scrollHorizontalLineChange",b,a))});t.g(z,"scrollVerticalLineChange",z.prototype.op); -t.defineProperty(z,{op:"scrollVerticalLineChange"},function(){return this.Ru},function(a){var b=this.Ru;b!==a&&(t.j(a,"number",z,"scrollVerticalLineChange"),0>a&&t.ia(a,">= 0",z,"scrollVerticalLineChange"),this.Ru=a,this.i("scrollVerticalLineChange",b,a))});t.g(z,"lastInput",z.prototype.S);t.defineProperty(z,{S:"lastInput"},function(){return this.hc},function(a){f&&t.k(a,od,z,"lastInput");this.hc=a});t.g(z,"firstInput",z.prototype.yc); -t.defineProperty(z,{yc:"firstInput"},function(){return this.tg},function(a){f&&t.k(a,od,z,"firstInput");this.tg=a});t.g(z,"currentCursor",z.prototype.Uc);t.defineProperty(z,{Uc:"currentCursor"},function(){return this.Ot},function(a){t.j(a,"string",z,"currentCursor");null===this.Sa||this.Ot===a||""===a&&this.Ot===this.fq||(this.Ot=a,""!==a?(this.Sa.style.cursor=a,this.vb.style.cursor=a):(this.Sa.style.cursor=this.zz,this.vb.style.cursor=this.zz))});t.g(z,"defaultCursor",z.prototype.zz); -t.defineProperty(z,{zz:"defaultCursor"},function(){return this.fq},function(a){t.j(a,"string",z,"defaultCursor");var b=this.fq;b!==a&&(this.fq=a,this.i("defaultCursor",b,a))});t.g(z,"hasGestureZoom",z.prototype.DH);t.defineProperty(z,{DH:"hasGestureZoom"},function(){return this.Uh},function(a){var b=this.Uh;b!==a&&(t.j(a,"boolean",z,"hasGestureZoom"),this.Uh=a,this.i("hasGestureZoom",b,a))});t.g(z,"click",z.prototype.click); -t.defineProperty(z,{click:"click"},function(){return this.Mh},function(a){var b=this.Mh;b!==a&&(null!==a&&t.j(a,"function",z,"click"),this.Mh=a,this.i("click",b,a))});t.g(z,"doubleClick",z.prototype.tm);t.defineProperty(z,{tm:"doubleClick"},function(){return this.Sh},function(a){var b=this.Sh;b!==a&&(null!==a&&t.j(a,"function",z,"doubleClick"),this.Sh=a,this.i("doubleClick",b,a))});t.g(z,"contextClick",z.prototype.ns); -t.defineProperty(z,{ns:"contextClick"},function(){return this.Oh},function(a){var b=this.Oh;b!==a&&(null!==a&&t.j(a,"function",z,"contextClick"),this.Oh=a,this.i("contextClick",b,a))});t.g(z,"mouseOver",z.prototype.Os);t.defineProperty(z,{Os:"mouseOver"},function(){return this.bi},function(a){var b=this.bi;b!==a&&(null!==a&&t.j(a,"function",z,"mouseOver"),this.bi=a,this.i("mouseOver",b,a))});t.g(z,"mouseHover",z.prototype.Ns); -t.defineProperty(z,{Ns:"mouseHover"},function(){return this.ai},function(a){var b=this.ai;b!==a&&(null!==a&&t.j(a,"function",z,"mouseHover"),this.ai=a,this.i("mouseHover",b,a))});t.g(z,"mouseHold",z.prototype.Ms);t.defineProperty(z,{Ms:"mouseHold"},function(){return this.$h},function(a){var b=this.$h;b!==a&&(null!==a&&t.j(a,"function",z,"mouseHold"),this.$h=a,this.i("mouseHold",b,a))});t.g(z,"mouseDragOver",z.prototype.tE); -t.defineProperty(z,{tE:"mouseDragOver"},function(){return this.wu},function(a){var b=this.wu;b!==a&&(null!==a&&t.j(a,"function",z,"mouseDragOver"),this.wu=a,this.i("mouseDragOver",b,a))});t.g(z,"mouseDrop",z.prototype.Ls);t.defineProperty(z,{Ls:"mouseDrop"},function(){return this.Zh},function(a){var b=this.Zh;b!==a&&(null!==a&&t.j(a,"function",z,"mouseDrop"),this.Zh=a,this.i("mouseDrop",b,a))});t.g(z,"toolTip",z.prototype.mt); -t.defineProperty(z,{mt:"toolTip"},function(){return this.li},function(a){var b=this.li;b!==a&&(null!==a&&t.k(a,Fe,z,"toolTip"),this.li=a,this.i("toolTip",b,a))});t.g(z,"contextMenu",z.prototype.contextMenu);t.defineProperty(z,{contextMenu:"contextMenu"},function(){return this.Ph},function(a){var b=this.Ph;b!==a&&(null!==a&&t.k(a,Fe,z,"contextMenu"),this.Ph=a,this.i("contextMenu",b,a))});t.g(z,"commandHandler",z.prototype.Yf); -t.defineProperty(z,{Yf:"commandHandler"},function(){return this.qx},function(a){var b=this.qx;b!==a&&(t.k(a,oa,z,"commandHandler"),null!==a.h&&t.l("Cannot share CommandHandlers between Diagrams: "+a.toString()),null!==b&&b.le(null),this.qx=a,a.le(this))});t.g(z,"toolManager",z.prototype.zb); -t.defineProperty(z,{zb:"toolManager"},function(){return this.fv},function(a){var b=this.fv;b!==a&&(t.k(a,De,z,"toolManager"),null!==a.h&&t.l("Cannot share ToolManagers between Diagrams: "+a.toString()),null!==b&&b.le(null),this.fv=a,a.le(this))});t.g(z,"defaultTool",z.prototype.Gv);t.defineProperty(z,{Gv:"defaultTool"},function(){return this.Fx},function(a){var b=this.Fx;b!==a&&(t.k(a,$d,z,"defaultTool"),this.Fx=a,this.Va===b&&(this.Va=a))});t.g(z,"currentTool",z.prototype.Va); -t.defineProperty(z,{Va:"currentTool"},function(){return this.Ax},function(a){var b=this.Ax;null!==b&&(b.oa&&b.doDeactivate(),b.cancelWaitAfter(),b.doStop());null===a&&(a=this.Gv);null!==a&&(t.k(a,$d,z,"currentTool"),this.Ax=a,a.le(this),a.doStart())});t.A(z,{selection:"selection"},function(){return this.Uu});t.g(z,"maxSelectionCount",z.prototype.mE); -t.defineProperty(z,{mE:"maxSelectionCount"},function(){return this.ru},function(a){var b=this.ru;if(b!==a)if(t.j(a,"number",z,"maxSelectionCount"),0<=a&&!isNaN(a)){if(this.ru=a,this.i("maxSelectionCount",b,a),!this.va.kb&&(a=this.selection.count-a,0= 0",z,"maxSelectionCount")});t.g(z,"nodeSelectionAdornmentTemplate",z.prototype.yE); -t.defineProperty(z,{yE:"nodeSelectionAdornmentTemplate"},function(){return this.Cu},function(a){var b=this.Cu;b!==a&&(t.k(a,Fe,z,"nodeSelectionAdornmentTemplate"),this.Cu=a,this.i("nodeSelectionAdornmentTemplate",b,a))});t.g(z,"groupSelectionAdornmentTemplate",z.prototype.HD);t.defineProperty(z,{HD:"groupSelectionAdornmentTemplate"},function(){return this.$t},function(a){var b=this.$t;b!==a&&(t.k(a,Fe,z,"groupSelectionAdornmentTemplate"),this.$t=a,this.i("groupSelectionAdornmentTemplate",b,a))}); -t.g(z,"linkSelectionAdornmentTemplate",z.prototype.jE);t.defineProperty(z,{jE:"linkSelectionAdornmentTemplate"},function(){return this.lu},function(a){var b=this.lu;b!==a&&(t.k(a,Fe,z,"linkSelectionAdornmentTemplate"),this.lu=a,this.i("linkSelectionAdornmentTemplate",b,a))});t.g(z,"isModified",z.prototype.Uj); -t.defineProperty(z,{Uj:"isModified"},function(){var a=this.va;return null===a?this.ey:null!==a.Uk?!0:this.ey&&this.vk!==a.Tj},function(a){if(this.ey!==a){t.j(a,"boolean",z,"isModified");this.ey=a;var b=this.va;!a&&b&&(this.vk=b.Tj);a||Ki(this)}});function Ki(a){var b=a.Uj;a.yC!==b&&(a.yC=b,a.Ea("Modified"))}t.g(z,"model",z.prototype.da); -t.defineProperty(z,{da:"model"},function(){return this.Cd},function(a){var b=this.Cd;if(b!==a){t.k(a,C,z,"model");null!==b&&b.va!==a.va&&b.va.LH&&t.l("Do not replace a Diagram.model while a transaction is in progress.");this.xv();this.Mf=!1;this.mq=!0;this.Uf=!1;var c=this.zd;this.zd=!0;null!==b&&(b.uA(this.UB),b instanceof P&&Li(this,b.Hi),Li(this,b.eg));this.Cd=a;a.jz(this.TB);Mi(this,a.eg);a instanceof P&&Ni(this,a.Hi);a.uA(this.TB);a.jz(this.UB);this.zd=c;this.gc||this.na();null!==b&&(a.va.isEnabled= -b.va.isEnabled)}});t.defineProperty(z,{Ra:null},function(){return this.NB},function(a){this.NB=a}); -function Ih(a,b){if(b.da===a.da&&a.Ra){a.Ra=!1;try{var c=b.fd,d=b.kf;if(""!==d)if(c===sd){if("linkFromKey"===d){var e=b.object,g=a.zf(e);if(null!==g){var h=b.newValue,k=a.$f(h);g.ca=k}}else if("linkToKey"===d)e=b.object,g=a.zf(e),null!==g&&(h=b.newValue,k=a.$f(h),g.ga=k);else if("linkFromPortId"===d){if(e=b.object,g=a.zf(e),null!==g){var l=b.newValue;"string"===typeof l&&(g.Af=l)}}else if("linkToPortId"===d)e=b.object,g=a.zf(e),null!==g&&(l=b.newValue,"string"===typeof l&&(g.ng=l));else if("nodeGroupKey"=== -d){var e=b.object,m=a.Ai(e);if(null!==m){var n=b.newValue;if(void 0!==n){var p=a.$f(n);m.ib=p instanceof V?p:null}else m.ib=null}}else if("linkLabelKeys"===d){if(e=b.object,g=a.zf(e),null!==g){var q=b.oldValue,r=b.newValue;if(t.isArray(q))for(var s=t.wb(q),u=0;uthis.bg&&(a=this.bg);if(b!==a){var c=this.Xb=a;if(!this.gc&&!this.zd&&(this.gc=!0,null!==this.Sa)){a=this.lb.copy();var d=this.oc/c,e=this.nc/c;a.width=this.oc/b;a.height=this.nc/b;var g=this.Ih.copy();if(isNaN(g.x))switch(this.Cv){case $b:g.x=0;break;case ac:g.x=d-1;break;case Fb:g.x=d/2;break;case vb:case cc:g.x=d/2}if(isNaN(g.y))switch(this.Cv){case Yb:g.y=0;break;case bc:g.y= -e-1;break;case Fb:g.y=e/2;break;case vb:case cc:g.y=e/2}var h=this.position,b=new v(h.x+g.x/b-g.x/c,h.y+g.y/b-g.y/c);bi(this,b,this.hd,d,e,this.ul);this.position=b;this.gc=!1;this.Us(a,this.lb)}this.na();gi(this)}});t.g(z,"autoScale",z.prototype.jm);t.defineProperty(z,{jm:"autoScale"},function(){return this.rl},function(a){var b=this.rl;b!==a&&(t.nb(a,z,z,"autoScale"),this.rl=a,this.i("autoScale",b,a),a!==Je&&$h(this))});t.g(z,"initialAutoScale",z.prototype.HH); -t.defineProperty(z,{HH:"initialAutoScale"},function(){return this.wk},function(a){var b=this.wk;b!==a&&(t.nb(a,z,z,"initialAutoScale"),this.wk=a,this.i("initialAutoScale",b,a))});t.g(z,"initialViewportSpot",z.prototype.TD);t.defineProperty(z,{TD:"initialViewportSpot"},function(){return this.eu},function(a){var b=this.eu;b!==a&&(t.k(a,H,z,"initialViewportSpot"),a.kd()||t.l("initialViewportSpot must be a real Spot: "+a),this.eu=a,this.i("initialViewportSpot",b,a))});t.g(z,"initialDocumentSpot",z.prototype.QD); -t.defineProperty(z,{QD:"initialDocumentSpot"},function(){return this.du},function(a){var b=this.du;b!==a&&(t.k(a,H,z,"initialDocumentSpot"),a.kd()||t.l("initialViewportSpot must be a real Spot: "+a),this.du=a,this.i("initialDocumentSpot",b,a))});t.g(z,"minScale",z.prototype.cg);t.defineProperty(z,{cg:"minScale"},function(){return this.tu},function(a){t.o(a,z,"minScale");var b=this.tu;b!==a&&0this.scale&&(this.scale=a)):t.ia(a,"> 0",z,"minScale")}); -t.g(z,"maxScale",z.prototype.bg);t.defineProperty(z,{bg:"maxScale"},function(){return this.qu},function(a){t.o(a,z,"maxScale");var b=this.qu;b!==a&&0 0",z,"maxScale")});t.g(z,"zoomPoint",z.prototype.Ih);t.defineProperty(z,{Ih:"zoomPoint"},function(){return this.kv},function(a){this.kv.K(a)||(t.k(a,v,z,"zoomPoint"),this.kv=a=a.W())});t.g(z,"contentAlignment",z.prototype.Cv); -t.defineProperty(z,{Cv:"contentAlignment"},function(){return this.ul},function(a){var b=this.ul;b.K(a)||(t.k(a,H,z,"contentAlignment"),this.ul=a=a.W(),this.i("contentAlignment",b,a),$h(this))});t.g(z,"initialContentAlignment",z.prototype.IH);t.defineProperty(z,{IH:"initialContentAlignment"},function(){return this.un},function(a){var b=this.un;b.K(a)||(t.k(a,H,z,"initialContentAlignment"),this.un=a=a.W(),this.i("initialContentAlignment",b,a))});t.g(z,"padding",z.prototype.padding); -t.defineProperty(z,{padding:"padding"},function(){return this.Ge},function(a){"number"===typeof a?a=new Va(a):t.k(a,Va,z,"padding");var b=this.Ge;b.K(a)||(this.Ge=a=a.W(),this.Jc(),this.i("padding",b,a))});t.A(z,{Ki:"nodes"},function(){return this.Du.m});t.A(z,{links:"links"},function(){return this.mu.m});t.A(z,{gp:"parts"},function(){return this.qb.m});z.prototype.findTopLevelGroups=function(){return this.Hk.m};t.g(z,"layout",z.prototype.Vb); -t.defineProperty(z,{Vb:"layout"},function(){return this.Bd},function(a){var b=this.Bd;b!==a&&(t.k(a,ke,z,"layout"),null!==b&&(b.h=null,b.group=null),this.Bd=a,a.h=this,a.group=null,this.Bt=!0,this.i("layout",b,a),this.Gf())});z.prototype.layoutDiagram=function(a){Yh(this);a&&Xi(this,!0);oi(this,!1)};function Xi(a,b){for(var c=a.Hk.m;c.next();)Yi(a,c.value,b);null!==a.Vb&&(b?a.Vb.gf=!1:a.Vb.J())} -function Yi(a,b,c){if(null!==b){for(var d=b.Jn.m;d.next();)Yi(a,d.value,c);null!==b.Vb&&(c?b.Vb.gf=!1:b.Vb.J())}}function oi(a,b){for(var c=a.Hk.m;c.next();)Zi(a,c.value,b);c=a.Vb;if(null!==c&&!c.gf){if(b&&!c.Wz)return;c.doLayout(a);Yh(a);c.gf=!0}a.Bt=!1}function Zi(a,b,c){if(null!==b){for(var d=b.Jn.m;d.next();)Zi(a,d.value,c);d=b.Vb;null===d||d.gf||c&&!d.Wz||(b.$B=!b.location.P(),d.doLayout(b),b.J($i),d.gf=!0,ri(a,b))}}t.g(z,"isTreePathToChildren",z.prototype.Yc); -t.defineProperty(z,{Yc:"isTreePathToChildren"},function(){return this.iu},function(a){var b=this.iu;if(b!==a&&(t.j(a,"boolean",z,"isTreePathToChildren"),this.iu=a,this.i("isTreePathToChildren",b,a),!this.va.kb))for(a=this.Ki;a.next();)aj(a.value)});z.prototype.findTreeRoots=function(){for(var a=new A(S),b=this.Ki.m;b.next();){var c=b.value;c.Oo&&null===c.vs()&&a.add(c)}return a.m};t.g(z,"isCollapsingExpanding",z.prototype.Hd); -t.defineProperty(z,{Hd:null},function(){return this.GB},function(a){this.GB=a}); -function Gh(a){function b(a){var b=a.toLowerCase(),h=new A("function");c.add(a,h);c.add(b,h);d.add(a,a);d.add(b,a)}var c=new ia("string",A),d=new ia("string","string");b("BackgroundSingleClicked");b("BackgroundDoubleClicked");b("BackgroundContextClicked");b("ClipboardChanged");b("ClipboardPasted");b("DocumentBoundsChanged");b("ExternalObjectsDropped");b("InitialLayoutCompleted");b("LayoutCompleted");b("LinkDrawn");b("LinkRelinked");b("LinkReshaped");b("Modified");b("ObjectSingleClicked");b("ObjectDoubleClicked"); -b("ObjectContextClicked");b("PartCreated");b("PartResized");b("PartRotated");b("SelectionMoved");b("SelectionCopied");b("SelectionDeleting");b("SelectionDeleted");b("SelectionGrouped");b("SelectionUngrouped");b("ChangingSelection");b("ChangedSelection");b("SubGraphCollapsed");b("SubGraphExpanded");b("TextEdited");b("TreeCollapsed");b("TreeExpanded");b("ViewportBoundsChanged");a.Hx=c;a.Gx=d}function ka(a,b){var c=a.Gx.wa(b);return null!==c?c:a.Gx.wa(b.toLowerCase())} -function bj(a,b){var c=a.Hx.wa(b);if(null!==c)return c;c=a.Hx.wa(b.toLowerCase());if(null!==c)return c;t.l("Unknown DiagramEvent name: "+b);return null}z.prototype.addDiagramListener=z.prototype.kz=function(a,b){t.j(a,"string",z,"addDiagramListener:name");t.j(b,"function",z,"addDiagramListener:listener");var c=bj(this,a);null!==c&&c.add(b)}; -z.prototype.removeDiagramListener=z.prototype.FE=function(a,b){t.j(a,"string",z,"removeDiagramListener:name");t.j(b,"function",z,"addDiagramListener:listener");var c=bj(this,a);null!==c&&c.remove(b)};z.prototype.raiseDiagramEvent=z.prototype.Ea=function(a,b,c){f&&t.j(a,"string",z,"raiseDiagramEvent:name");var d=bj(this,a),e=new pd;e.h=this;e.name=ka(this,a);void 0!==b&&(e.Cw=b);void 0!==c&&(e.ow=c);a=d.length;if(1===a)d=d.ta(0),d(e);else if(0!==a)for(b=d.Ve(),c=0;c=d.top&&0>=d.left&&0>=d.right&&0>=d.bottom)return c;var e=a.lb,g=a.scale,e=t.Yj(0,0,e.width*g,e.height*g),h=t.cc(0,0);if(b.x>=e.x&&b.xe.x+e.width-d.right&&(k=Math.max(a.np,1),k|=0,h.x+=k,b.x>e.x+e.width-d.right/2&&(h.x+=k),b.x>e.x+e.width-d.right/4&&(h.x+=4*k));b.y>=e.y&&b.ye.y+e.height-d.bottom&&(k=Math.max(a.op,1),k|=0,h.y+=k,b.y>e.y+e.height-d.bottom/2&&(h.y+=k),b.y>e.y+e.height-d.bottom/4&&(h.y+=4*k));h.zi(D.ak)||(c=new v(c.x+h.x/g,c.y+h.y/g));t.Ic(e);t.B(h);return c}z.prototype.makeSVG=function(a){void 0===a&&(a={});a.context="svg";a=yj(this,a);return null!==a?a.jt:null}; -z.prototype.makeImage=function(a){var b=document.createElement("img");b.src=this.$H(a);return b instanceof HTMLImageElement?b:null};z.prototype.makeImageData=z.prototype.$H=function(a){void 0===a&&(a={});var b=yj(this,a);return null!==b?b.toDataURL(a.type,a.details):""}; -function yj(a,b){a.zh();if(null===a.Sa)return null;"object"!==typeof b&&t.l("properties argument must be an Object.");var c=!1,d=b.size||null,e=b.scale||null;void 0!==b.scale&&isNaN(b.scale)&&(e="NaN");var g=b.maxSize||new ea(2E3,2E3);void 0===b.maxSize&&(c=!0);var h=b.position||null,k=b.parts||null,l=void 0===b.padding?1:b.padding,m=b.background||null,n=b.omitTemporary;void 0===n&&(n=!0);var p=b.showTemporary;void 0===p&&(p=!n);n=b.showGrid;void 0===n&&(n=p);null!==d&&isNaN(d.width)&&isNaN(d.height)&& -(d=null);l&&"number"===typeof l&&(l=new Va(l));l||(l=new Va(0));l.left=Math.max(l.left,0);l.right=Math.max(l.right,0);l.top=Math.max(l.top,0);l.bottom=Math.max(l.bottom,0);a.mn=!1;Th(a);var q=document.createElement("canvas"),r=q.getContext("2d"),s=q;if(!(d||e||k||h))return q.width=a.Sa.width+Math.ceil(l.left+l.right),q.height=a.Sa.height+Math.ceil(l.top+l.bottom),"svg"===b.context&&(r=s=new nc(q),r instanceof nc&&(a.mn=!0)),yi(a,r,l,new ea(q.width,q.height),a.Xb,a.sb,k,m,p,n),a.mn=!0,s;var u,x=new v(0, -0);u=a.hd.copy();u.EI(a.padding);null!==h&&h.P()?(x=h,e||(e=1)):(x.x=u.x,x.y=u.y);if(k){var E,h=!0,k=k.m;for(k.reset();k.next();){var F=k.value;if(F instanceof B){var G=F.layer;G&&!G.visible||G&&G.kc||!F.ub()||(F=F.ua,F.P()&&(h?(h=!1,E=F.copy()):E.$j(F)))}}h&&(E=new w(0,0,0,0));u.width=E.width;u.height=E.height;x.x=E.x;x.y=E.y}h=E=0;l&&(E=l.left+l.right,h=l.top+l.bottom);F=G=0;d&&(G=d.width,F=d.height,isFinite(G)&&(G=Math.max(0,G-E)),isFinite(F)&&(F=Math.max(0,F-h)));d&&e?("NaN"===e&&(e=1),d.P()? -(d=G,u=F):isNaN(F)?(d=G,u=u.height*e):(d=u.width*e,u=F)):d?d.P()?(e=Math.min(G/u.width,F/u.height),d=G,u=F):isNaN(F)?(e=G/u.width,d=G,u=u.height*e):(e=F/u.height,d=u.width*e,u=F):e?"NaN"===e&&g.P()?(e=Math.min((g.width-E)/u.width,(g.height-h)/u.height),1E||u>g)&&(t.trace("Diagram.makeImage(data): Diagram width or height is larger than the default max size. ("+ -Math.ceil(d)+"x"+Math.ceil(u)+" vs 2000x2000) Consider increasing the max size."),t.IF=!0),isNaN(E)&&(E=2E3),isNaN(g)&&(g=2E3),isFinite(E)&&(d=Math.min(d,E)),isFinite(g)&&(u=Math.min(u,g)));q.width=Math.ceil(d);q.height=Math.ceil(u);"svg"===b.context&&(r=s=new nc(q),r instanceof nc&&(a.mn=!0));yi(a,r,l,new ea(Math.ceil(d),Math.ceil(u)),e,x,k,m,p,n);a.mn=!0;return s} -z.inherit=function(a,b){t.j(a,"function",z,"inherit");t.j(b,"function",z,"inherit");b.jG&&t.l("Cannot inherit from "+t.Gg(b));t.Ja(a,b)};function zj(a){1a)&&t.ia(a,"0 <= loc <= 1",Ud,"addColorStop:loc");t.j(b,"string",Ud,"addColorStop:color");null===this.qg&&(this.qg=new ia("number","string"));this.qg.add(a,b);this.Z===Wd&&(this.type=Xd);this.rg=null};t.g(Ud,"type",Ud.prototype.type); -t.defineProperty(Ud,{type:"type"},function(){return this.Z},function(a){t.L(this,a);t.nb(a,Ud,Ud,"type");this.Z=a;this.start.jd()&&(a===Xd?this.start=Db:a===Yd&&(this.start=Fb));this.end.jd()&&(a===Xd?this.end=Nb:a===Yd&&(this.end=Fb));this.rg=null});t.g(Ud,"color",Ud.prototype.color);t.defineProperty(Ud,{color:"color"},function(){return this.an},function(a){t.L(this,a);t.j(a,"string",Ud,"color");this.an=a;this.rg=null});t.g(Ud,"start",Ud.prototype.start); -t.defineProperty(Ud,{start:"start"},function(){return this.Tn},function(a){t.L(this,a);a instanceof H||t.Nb(a,"Spot",Ud,"start");this.Tn=a.W();this.rg=null});t.g(Ud,"end",Ud.prototype.end);t.defineProperty(Ud,{end:"end"},function(){return this.on},function(a){t.L(this,a);a instanceof H||t.Nb(a,"Spot",Ud,"end");this.on=a.W();this.rg=null});t.g(Ud,"startRadius",Ud.prototype.tp); -t.defineProperty(Ud,{tp:"startRadius"},function(){return this.Yu},function(a){t.L(this,a);t.o(a,Ud,"startRadius");0>a&&t.ia(a,">= zero",Ud,"startRadius");this.Yu=a;this.rg=null});t.g(Ud,"endRadius",Ud.prototype.wo);t.defineProperty(Ud,{wo:"endRadius"},function(){return this.Wt},function(a){t.L(this,a);t.o(a,Ud,"endRadius");0>a&&t.ia(a,">= zero",Ud,"endRadius");this.Wt=a;this.rg=null});t.g(Ud,"colorStops",Ud.prototype.qo); -t.defineProperty(Ud,{qo:"colorStops"},function(){return this.qg},function(a){t.L(this,a);f&&t.k(a,ia,Ud,"colorStops");this.qg=a;this.rg=null});t.g(Ud,"pattern",Ud.prototype.pattern);t.defineProperty(Ud,{pattern:"pattern"},function(){return this.Ju},function(a){t.L(this,a);this.Ju=a;this.rg=null}); -Ud.randomColor=function(a,b){void 0===a&&(a=128);f&&(t.o(a,Ud,"randomColor:min"),(0>a||255d.length&&(d="0"+d);2>e.length&&(e="0"+e);2>c.length&&(c="0"+c);return"#"+ -d+e+c}; -function Q(){t.uc(this);this.ha=30723;this.fi=null;this.Mb="";this.dc=this.Bb=null;this.sb=(new v(NaN,NaN)).freeze();this.Ye=(new ea(NaN,NaN)).freeze();this.Wd=D.Rm;this.mj=D.WF;this.rd=new fa;this.ql=new fa;this.Ak=new fa;this.Xb=1;this.Wm=0;this.nh=Rg;this.Rq=D.Fp;this.Dc=(new w(NaN,NaN,NaN,NaN)).freeze();this.Ob=(new w(NaN,NaN,NaN,NaN)).freeze();this.Qc=(new w(0,0,NaN,NaN)).freeze();this.Sr=this.nq=this.T=this.lr=this.Xd=null;this.Tr=this.oq=Infinity;this.Mp=this.me=vb;this.wr=0;this.tj=1;this.Tp= -0;this.Ti=1;this.zr=-Infinity;this.yr=0;this.Ar=D.ak;this.Br=sg;this.$p="";this.Sl=this.Nh=this.vl=this.vc=this.O=null}t.ea("GraphObject",Q);t.th(Q); -Q.prototype.cloneProtected=function(a){a.ha=this.ha|6144;a.Mb=this.Mb;a.Bb=this.Bb;a.dc=this.dc;a.sb.assign(this.sb);a.Ye.assign(this.Ye);a.Wd=this.Wd.W();a.mj=this.mj.W();a.Ak=this.Ak.copy();a.Xb=this.Xb;a.Wm=this.Wm;a.nh=this.nh;a.Rq=this.Rq.W();a.Dc.assign(this.Dc);a.Ob.assign(this.Ob);a.Qc.assign(this.Qc);a.lr=this.lr;a.me=this.me.W();a.Mp=this.Mp.W();a.wr=this.wr;a.tj=this.tj;a.Tp=this.Tp;a.Ti=this.Ti;a.zr=this.zr;a.yr=this.yr;a.Ar=this.Ar.W();a.Br=this.Br;a.$p=this.$p;if(null!==this.O){var b= -this.O;a.O={Mh:b.Mh,Sh:b.Sh,Oh:b.Oh,br:b.br,cr:b.cr,bi:b.bi,ai:b.ai,$h:b.$h,$q:b.$q,ar:b.ar,Zh:b.Zh,Hp:b.Hp,Ip:b.Ip,Jp:b.Jp,Gp:b.Gp,li:b.li,Ph:b.Ph}}null!==this.T&&(b=this.T,a.T={aj:b.aj.W(),Cj:b.Cj.W(),Zi:b.Zi,Aj:b.Aj,Yi:b.Yi,zj:b.zj,$i:b.$i,Bj:b.Bj});a.nq=this.nq;a.oq=this.oq;a.Sr=this.Sr;a.Tr=this.Tr;a.vc=this.vc;if(Array.isArray(this.vl))for(a.vl=this.vl.slice(0),b=0;bk;)k+=g[n++%l],p=!p;q=!1}else k=g[n++%l];k>m&&(k=m);var r=Math.sqrt(k*k/(1+e*e));0>d&&(r=-r);b+=r;c+=e*r;p?a.lineTo(b,c):a.moveTo(b,c);m-=k;p=!p}}aa.Mc=function(a,b,c,d,e,g,h){var k=this.Q;null!==k&&(k.Im(a,b,c,d,e,g,h),0!==(this.ha&1024)&&c===this&&a===sd&&Jj(this,k,b))}; -function Jj(a,b,c){var d=a.Bo();if(null!==d)for(var e=a.vc.m;e.next();){var g=e.value,h=d.data,k=g.ht;null!==k&&(h=d.de(k));if(null!==h&&(g.EF(a,h,c,null!==k?null:b.h),null!==k&&(h=d,""!==k&&(h=d.de(k)),null!==h))){var k=g.Nm,l=d;""!==k&&(l=d.de(k));null!==l&&g.FF(l,h,c)}}}aa.i=function(a,b,c){this.Mc(sd,a,this,b,c)};function Kj(a,b,c,d,e){var g=a.Dc,h=a.Ak;h.reset();Lj(a,h,b,c,d,e);a.Ak=h;g.x=b;g.y=c;g.width=d;g.height=e;h.Es()||h.yF(g)} -function Mj(a,b,c,d){if(!1===a.mf)return!1;d.multiply(a.transform);return c?a.Bf(b,d):a.om(b,d)}aa.tD=function(a,b,c){if(!1===this.mf)return!1;var d=this.Na;b=a.Mj(b);var e=!1;c&&(e=Pa(a.x,a.y,0,0,0,d.height)d.width*e&&10>d.height*e)return a=eb(c.x-5*g,c.y-5*g,c.width+10*g,c.height+10*g,b.x,b.y),t.B(b),a}if(void 0!==this.Gc||this instanceof Y?eb(c.x-5,c.y-5,c.width+10,c.height+10,b.x,b.y):c.Da(b)){if(this.Nh&&!this.Nh.Da(b))return!1;if(null!==this.dc&&c.Da(b)||null!== -this.Bb&&this.Qc.Da(a))return!0;t.B(b);return this.Hj(a)}t.B(b);return!1};Q.prototype.Hj=function(a){var b=this.Na;return eb(0,0,b.width,b.height,a.x,a.y)}; -Q.prototype.containsRect=Q.prototype.Ij=function(a){f&&t.k(a,w,Q,"containsRect:r");if(0===this.angle)return this.ua.Ij(a);var b=this.Na,b=t.Yj(0,0,b.width,b.height),c=this.transform,d=!1,e=t.cc(a.x,a.y);b.Da(c.Ci(e))&&(e.q(a.x,a.bottom),b.Da(c.Ci(e))&&(e.q(a.right,a.bottom),b.Da(c.Ci(e))&&(e.q(a.right,a.y),b.Da(c.Ci(e))&&(d=!0))));t.B(e);t.Ic(b);return d}; -Q.prototype.containedInRect=Q.prototype.om=function(a,b){f&&t.k(a,w,Q,"containedInRect:r");if(void 0===b)return a.Ij(this.ua);var c=this.Na,d=!1,e=t.cc(0,0);a.Da(b.Qa(e))&&(e.q(0,c.height),a.Da(b.Qa(e))&&(e.q(c.width,c.height),a.Da(b.Qa(e))&&(e.q(c.width,0),a.Da(b.Qa(e))&&(d=!0))));return d}; -Q.prototype.intersectsRect=Q.prototype.Bf=function(a,b){f&&t.k(a,w,Q,"intersectsRect:r");if(void 0===b&&(b=this.transform,0===this.angle))return a.Bf(this.ua);var c=this.Na,d=b,e=t.cc(0,0),g=t.cc(0,c.height),h=t.cc(c.width,c.height),k=t.cc(c.width,0),l=!1;if(a.Da(d.Qa(e))||a.Da(d.Qa(g))||a.Da(d.Qa(h))||a.Da(d.Qa(k)))l=!0;else{var c=t.Yj(0,0,c.width,c.height),m=t.cc(a.x,a.y);c.Da(d.Ci(m))?l=!0:(m.q(a.x,a.bottom),c.Da(d.Ci(m))?l=!0:(m.q(a.right,a.bottom),c.Da(d.Ci(m))?l=!0:(m.q(a.right,a.y),c.Da(d.Ci(m))&& -(l=!0))));t.B(m);t.Ic(c);!l&&(D.Xv(a,e,g)||D.Xv(a,g,h)||D.Xv(a,h,k)||D.Xv(a,k,e))&&(l=!0)}t.B(e);t.B(g);t.B(h);t.B(k);return l};Q.prototype.getDocumentPoint=Q.prototype.$a=function(a,b){void 0===b&&(b=new v);a.jd()&&t.l("Spot must be real");var c=this.Na;b.q(a.x*c.width+a.offsetX,a.y*c.height+a.offsetY);this.$d.Qa(b);return b};Q.prototype.getDocumentAngle=Q.prototype.Wk=function(){var a=this.$d,a=180/Math.PI*Math.atan2(a.m12,a.m11);0>a&&(a+=360);return a}; -Q.prototype.getDocumentScale=Q.prototype.Sj=function(){var a=this.Xb;return null!==this.fa?a*this.fa.Sj():a};Q.prototype.getLocalPoint=Q.prototype.DD=function(a,b){void 0===b&&(b=new v);b.assign(a);this.$d.Ci(b);return b};Q.prototype.getNearestIntersectionPoint=Q.prototype.Zk=function(a,b,c){return this.Go(a.x,a.y,b.x,b.y,c)};aa=Q.prototype; -aa.Go=function(a,b,c,d,e){var g=this.transform,h=1/(g.m11*g.m22-g.m12*g.m21),k=g.m22*h,l=-g.m12*h,m=-g.m21*h,n=g.m11*h,p=h*(g.m21*g.dy-g.m22*g.dx),q=h*(g.m12*g.dx-g.m11*g.dy);if(null!==this.Ok)return g=this.ua,D.Zk(g.left,g.top,g.right,g.bottom,a,b,c,d,e);h=a*k+b*m+p;a=a*l+b*n+q;b=c*k+d*m+p;c=c*l+d*n+q;e.q(0,0);d=this.Na;c=D.Zk(0,0,d.width,d.height,h,a,b,c,e);e.transform(g);return c}; -function mh(a,b,c,d,e){if(!1!==si(a)){var g=a.margin,h=g.top+g.bottom;b=Math.max(b-(g.right+g.left),0);c=Math.max(c-h,0);g=a.angle;if(90===g||270===g)g=b,b=c,c=g,g=d,d=e,e=g;g=a.ya;h=0;a.bb&&(h=a.bb);b=isFinite(g.width)?g.width+h:b;c=isFinite(g.height)?g.height+h:c;var g=d||0,h=e||0,k=a instanceof y;switch(Nj(a)){case Qg:h=g=0;k&&(c=b=Infinity);break;case Ic:isFinite(b)&&b>d&&(g=b);isFinite(c)&&c>e&&(h=c);break;case Fj:isFinite(b)&&b>d&&(g=b);h=0;k&&(c=Infinity);break;case Ej:isFinite(c)&&c>e&&(h= -c),g=0,k&&(b=Infinity)}var k=a.Ce,l=a.Te;g>k.width&&l.widthk.height&&l.heighta.height||this.Gn.Ii>a.width))&&(c=!0);this.ha=c?this.ha|256:this.ha&-257;this.Ob.P()||t.l("Non-real actualBounds has been set. Object "+ -this+", actualBounds: "+this.Ob.toString());Qj(this,g,this.Ob);t.Ic(g)};aa.Gj=function(){};function Rj(a,b,c,d,e){var g=a.ua;g.x=b;g.y=c;g.width=d;g.height=e;if(!a.ya.P()){g=a.Dc;c=a.margin;b=c.right+c.left;var h=c.top+c.bottom;c=g.width+b;g=g.height+h;d+=b;e+=h;b=Nj(a);c===d&&g===e&&(b=Qg);switch(b){case Qg:if(c>d||g>e)Oj(a,!0),mh(a,c>d?d:c,g>e?e:g);break;case Ic:Oj(a,!0);mh(a,d,e,0,0);break;case Fj:Oj(a,!0);mh(a,d,g,0,0);break;case Ej:Oj(a,!0),mh(a,c,e,0,0)}}} -function Qj(a,b,c){Sj(a,!1);var d=a.Q;if(null!==d){var e=d.h;if(null!==e)if(Tj(d),a instanceof B){var g=!1,d=b.P();if(!1===e.dj){var h=e.hd,k=e.padding,l=h.x+k.left,m=h.y+k.top,n=h.width-2*k.right,h=h.height-2*k.bottom;d&&b.x>l&&b.y>m&&b.rightl&&c.y>m&&c.rightc.width+c.x||c.x>h.width+h.x||m>c.height+c.y||c.y>h.height+h.y)break a;h=!0;xc(a,1,0,0,1,0,0);a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}l=!1;if(this instanceof B&&(l=!0,!this.ub()))break a;m=!1;this.Q&&(m=this.Q.Gi);a.vi.Se=[1,0,0,1,0,0];null!==this.dc&&(ak(this,a,this.dc,!0,!0),this.dc instanceof Ud&&this.dc.type===Yd?(a.beginPath(),a.rect(c.x,c.y,c.width,c.height),bk(a,this.dc,!0)):a.fillRect(c.x, -c.y,c.width,c.height));l&&this.Gi&&(xc(a,1,0,0,1,0,0),c=this.am,a.shadowOffsetX=c.x,a.shadowOffsetY=c.y,a.shadowColor=this.$l,a.shadowBlur=this.Zl/b.scale,a.Xa());this instanceof y?xc(a,d.m11,d.m12,d.m21,d.m22,d.dx,d.dy):a.vi.Se=[d.m11,d.m12,d.m21,d.m22,d.dx,d.dy];if(null!==this.Bb){var k=this.Na,c=d=0,n=k.width,k=k.height,p=0;this instanceof Y&&(k=this.La.Gb,d=k.x,c=k.y,n=k.width,k=k.height,p=this.Dg);ak(this,a,this.Bb,!0);this.Bb instanceof Ud&&this.Bb.type===Yd?(a.beginPath(),a.rect(d-p/2,c-p/ -2,n+p,k+p),bk(a,this.Bb,!0)):a.fillRect(d-p/2,c-p/2,n+p,k+p)}if(m&&(null!==this.Bb||null!==this.dc||null!==e&&0!==(e.ha&512)||null!==e&&e.type===Oh&&e.Pv()!==this)){ck(this,!0);var q=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}else ck(this,!1);this.Vk(a,b);m&&0!==(this.ha&512)===!0&&(a.shadowOffsetX=q[0],a.shadowOffsetY=q[1],a.shadowBlur=q[2]);l&&m&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);g?(a.restore(),h&&a.ag.pop(),Th(b,a)):this instanceof -y&&a.ag.pop();l&&m&&a.ag.pop()}}}else if(this instanceof y&&(this.type===Wj||this.type===Xj))Yj(this,a,b);else if(d=this.Ob,0!==d.width&&0!==d.height&&!isNaN(d.x)&&!isNaN(d.y)){q=this.transform;g=this.fa;h=this.ql;h.reset();null!==g&&(g.og()?h.multiply(g.$d):null!==g.fa&&h.multiply(g.fa.$d));h.multiply(this.rd);h=0!==(this.ha&256);this instanceof ma&&Zj(this,a);if(h){f&&f.pH&&t.trace("clip"+this.toString());c=g.og()?g.Na:g.ua;this.Nh?(k=this.Nh,l=k.x,m=k.y,n=k.width,k=k.height):(l=Math.max(d.x,c.x), -m=Math.max(d.y,c.y),n=Math.min(d.right,c.right)-l,k=Math.min(d.bottom,c.bottom)-m);if(l>d.width+d.x||d.x>c.width+c.x||m>d.height+d.y||d.y>c.height+c.y)return;a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}c=!1;if(this instanceof B){c=!0;if(!this.ub())return;this.Gi&&(l=this.am,a.shadowOffsetX=l.x*b.scale,a.shadowOffsetY=l.y*b.scale,a.shadowColor=this.$l,a.shadowBlur=this.Zl)}l=!1;this.Q&&(l=this.Q.Gi);null!==this.dc&&(ak(this,a,this.dc,!0,!0),this.dc instanceof Ud&&this.dc.type===Yd?(a.beginPath(), -a.rect(d.x,d.y,d.width,d.height),bk(a,this.dc,!0)):a.fillRect(d.x,d.y,d.width,d.height));q.Es()||a.transform(q.m11,q.m12,q.m21,q.m22,q.dx,q.dy);null!==this.Bb&&(k=this.Na,m=d=0,n=k.width,k=k.height,p=0,this instanceof Y&&(k=this.La.Gb,d=k.x,m=k.y,n=k.width,k=k.height,p=this.Dg),ak(this,a,this.Bb,!0),this.Bb instanceof Ud&&this.Bb.type===Yd?(a.beginPath(),a.rect(d-p/2,m-p/2,n+p,k+p),bk(a,this.Bb,!0)):a.fillRect(d-p/2,m-p/2,n+p,k+p));l&&(null!==this.Bb||null!==this.dc||null!==g&&0!==(g.ha&512)||null!== -g&&g.type===Oh&&g.Pv()!==this)?(ck(this,!0),e=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0):ck(this,!1);this.Vk(a,b);l&&0!==(this.ha&512)===!0&&(a.shadowOffsetX=e[0],a.shadowOffsetY=e[1],a.shadowBlur=e[2]);c&&l&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);h?(a.restore(),this instanceof y?Th(b,a,!0):Th(b,a,!1)):q.Es()||(e=1/(q.m11*q.m22-q.m12*q.m21),a.transform(q.m22*e,-q.m12*e,-q.m21*e,q.m11*e,e*(q.m21*q.dy-q.m22*q.dx),e*(q.m12*q.dx-q.m11* -q.dy)))}};function Yj(a,b,c){var d=a.Ob;0===d.width||0===d.height||isNaN(d.x)||isNaN(d.y)||(null!==a.dc&&(ak(a,b,a.dc,!0,!0),a.dc instanceof Ud&&a.dc.type===Yd?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),bk(b,a.dc,!0)):b.fillRect(d.x,d.y,d.width,d.height)),null!==a.Bb&&(ak(a,b,a.Bb,!0),a.Bb instanceof Ud&&a.Bb.type===Yd?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),bk(b,a.Bb,!0)):b.fillRect(d.x,d.y,d.width,d.height)),a.Vk(b,c))}aa.Vk=function(){}; -function bk(a,b,c){if(c)if(a instanceof CanvasRenderingContext2D&&b instanceof Ud&&b.type===Yd){var d=b.ux;b=b.tx;b>d?(a.scale(d/b,1),a.translate((b-d)/2,0),c?a.fill():a.stroke(),a.translate(-(b-d)/2,0),a.scale(1/(d/b),1)):d>b?(a.scale(1,b/d),a.translate(0,(d-b)/2),c?a.fill():a.stroke(),a.translate(0,-(d-b)/2),a.scale(1,1/(b/d))):c?a.fill():a.stroke()}else c?a.fill():a.stroke();else a.stroke()} -function ak(a,b,c,d,e){if(null!==c){var g=1,h=1;if("string"===typeof c)d?b.Sm!==c&&(b.fillStyle=c,b.Sm=c):b.Tm!==c&&(b.strokeStyle=c,b.Tm=c);else if(c.type===Wd)c=c.color,d?b.Sm!==c&&(b.fillStyle=c,b.Sm=c):b.Tm!==c&&(b.strokeStyle=c,b.Tm=c);else{var k,h=a.Na,g=h.width,h=h.height;if(e)var l=a.ua,g=l.width,h=l.height;var m=b instanceof CanvasRenderingContext2D;if(m&&(c.rg&&c.type===Dj||c.ux===g&&c.tx===h))k=c.rg;else{var n,p,q=p=0;e&&(l=a.ua,g=l.width,h=l.height,p=l.x,q=l.y);c.start instanceof v?(a= -c.start.x,e=c.start.y):c.start instanceof H?(a=c.start.x*g,e=c.start.y*h):(a=Fb.x*g,e=Fb.y*h);c.end instanceof v?(l=c.end.x,n=c.end.y):c.end instanceof H?(l=c.end.x*g,n=c.end.y*h):c.type===Xd?(l=Nb.x*g,n=Nb.y*h):(l=Fb.x*g,n=Fb.y*h);a+=p;l+=p;e+=q;n+=q;c.type===Xd?k=b.createLinearGradient(a,e,l,n):c.type===Yd?(p=isNaN(c.wo)?Math.max(g,h)/2:c.wo,isNaN(c.tp)?(k=0,p=Math.max(g,h)/2):k=c.tp,k=b.createRadialGradient(a,e,k,l,n,p)):c.type===Dj?k=b.createPattern(c.pattern,"repeat"):t.Nb(c.type,"Brush type"); -if(c.type!==Dj&&(p=c.qo))for(p=p.m;p.next();)k.addColorStop(p.key,p.value);m&&(c.rg=k,c.ux=g,c.tx=h)}d?b.Sm!==k&&(b.fillStyle=k,b.Sm=k):b.Tm!==k&&(b.strokeStyle=k,b.Tm=k)}}}Q.prototype.isContainedBy=Q.prototype.Ei=function(a){if(a instanceof y)a:{if(this!==a&&null!==a)for(var b=this.fa;null!==b;){if(b===a){a=!0;break a}b=b.fa}a=!1}else a=!1;return a};Q.prototype.isVisibleObject=Q.prototype.bl=function(){if(!this.visible)return!1;var a=this.fa;return null!==a?a.bl():!0}; -function dk(a){if(0!==(a.ha&2048)===!0){var b=a.rd;b.reset();if(!a.Ob.P()||!a.Dc.P()){ek(a,!1);return}b.translate(a.Ob.x,a.Ob.y);b.translate(-a.Ba.x,-a.Ba.y);var c=a.Na;Lj(a,b,c.x,c.y,c.width,c.height);ek(a,!1);fk(a,!0)}0!==(a.ha&4096)===!0&&(null===a.fa?(a.ql.set(a.rd),fk(a,!1)):null!==a.fa.$d&&(b=a.ql,b.reset(),b.multiply(a.fa.ql),b.multiply(a.rd),fk(a,!1)))} -function Lj(a,b,c,d,e,g){1!==a.scale&&b.scale(a.scale);if(0!==a.angle){var h=Fb;a.Re&&a.Re.kd()&&(h=a.Re);var k=t.M();if(a instanceof B&&a.Zb!==a)for(c=a.Zb,d=c.Na,k.ft(d.x,d.y,d.width,d.height,h),c.Ak.Qa(k),k.offset(-c.Ba.x,-c.Ba.y),h=c.fa;null!==h&&h!==a;)h.Ak.Qa(k),k.offset(-h.Ba.x,-h.Ba.y),h=h.fa;else k.ft(c,d,e,g,h);b.rotate(a.angle,k.x,k.y);t.B(k)}} -Q.prototype.Y=function(a){if(!0!==si(this)){Oj(this,!0);Sj(this,!0);var b=this.fa;null!==b?a||b.Y():(a=this.h,null!==a&&(a.Nf.add(this),this instanceof S&&(a.va.kb||this.Ig(),null!==this.ld&&gk(this.ld)),a.Gf()));if(this instanceof y){var c=null;a=this.za;b=a.length;this.Z===Oh&&(c=hk(this,a,b))&&c.Y(!0);a=a.p;for(c=0;ca?a=0:1=a&&t.l("GraphObject.scale must be greater than zero"),this.Xb=a,Pj(this),this.Y(),this.i("scale",b,a))});t.g(Q,"angle",Q.prototype.angle);t.defineProperty(Q,{angle:"angle"},function(){return this.Wm},function(a){var b=this.Wm;b!==a&&(f&&t.o(a,Q,"angle"),a%=360,0>a&&(a+=360),b!==a&&(this.Wm=a,this.Y(),Pj(this),this.i("angle",b,a)))}); -t.g(Q,"desiredSize",Q.prototype.ya);t.defineProperty(Q,{ya:"desiredSize"},function(){return this.Ye},function(a){var b=this.Ye;b.K(a)||(f&&t.k(a,ea,Q,"desiredSize"),this.Ye=a=a.W(),this.Y(),this instanceof Y&&this.Cf(),this.i("desiredSize",b,a),a=this.Q,null!==a&&0!==(this.ha&1024)&&(Jj(this,a,"width"),Jj(this,a,"height")))});t.g(Q,"width",Q.prototype.width); -t.defineProperty(Q,{width:"width"},function(){return this.Ye.width},function(a){if(this.Ye.width!==a){f&&t.j(a,"number",Q,"width");var b=this.Ye;this.Ye=a=(new ea(a,this.Ye.height)).freeze();this.Y();this instanceof Y&&this.Cf();this.i("desiredSize",b,a);b=this.Q;null!==b&&0!==(this.ha&1024)&&Jj(this,b,"width")}});t.g(Q,"height",Q.prototype.height); -t.defineProperty(Q,{height:"height"},function(){return this.Ye.height},function(a){if(this.Ye.height!==a){f&&t.j(a,"number",Q,"height");var b=this.Ye;this.Ye=a=(new ea(this.Ye.width,a)).freeze();this.Y();this instanceof Y&&this.Cf();this.i("desiredSize",b,a);b=this.Q;null!==b&&0!==(this.ha&1024)&&Jj(this,b,"height")}});t.g(Q,"minSize",Q.prototype.Te); -t.defineProperty(Q,{Te:"minSize"},function(){return this.Wd},function(a){var b=this.Wd;b.K(a)||(f&&t.k(a,ea,Q,"minSize"),a=a.copy(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.Wd=a,this.Y(),this.i("minSize",b,a))});t.g(Q,"maxSize",Q.prototype.Ce); -t.defineProperty(Q,{Ce:"maxSize"},function(){return this.mj},function(a){var b=this.mj;b.K(a)||(f&&t.k(a,ea,Q,"maxSize"),a=a.copy(),isNaN(a.width)&&(a.width=Infinity),isNaN(a.height)&&(a.height=Infinity),a.freeze(),this.mj=a,this.Y(),this.i("maxSize",b,a))});t.A(Q,{Ba:"measuredBounds"},function(){return this.Dc});t.A(Q,{Na:"naturalBounds"},function(){return this.Qc},{configurable:!0});t.g(Q,"margin",Q.prototype.margin); -t.defineProperty(Q,{margin:"margin"},function(){return this.Rq},function(a){"number"===typeof a?a=new Va(a):f&&t.k(a,Va,Q,"margin");var b=this.Rq;b.K(a)||(this.Rq=a=a.W(),this.Y(),this.i("margin",b,a))});t.A(Q,{transform:null},function(){0!==(this.ha&2048)===!0&&dk(this);return this.rd});t.A(Q,{$d:null},function(){0!==(this.ha&4096)===!0&&dk(this);return this.ql});t.g(Q,"alignment",Q.prototype.alignment); -t.defineProperty(Q,{alignment:"alignment"},function(){return this.me},function(a){var b=this.me;b.K(a)||(f?t.k(a,H,Q,"alignment"):a.jd()&&!a.zc()&&t.l("alignment must be a real Spot or Spot.Default"),this.me=a=a.W(),gk(this),this.i("alignment",b,a))});t.g(Q,"column",Q.prototype.column);t.defineProperty(Q,{column:"column"},function(){return this.Tp},function(a){f&&t.o(a,Q,"column");a=Math.round(a);var b=this.Tp;b!==a&&(0>a&&t.ia(a,">= 0",Q,"column"),this.Tp=a,this.Y(),this.i("column",b,a))}); -t.g(Q,"columnSpan",Q.prototype.TC);t.defineProperty(Q,{TC:"columnSpan"},function(){return this.Ti},function(a){f&&t.o(a,Q,"columnSpan");a=Math.round(a);var b=this.Ti;b!==a&&(1>a&&t.ia(a,">= 1",Q,"columnSpan"),this.Ti=a,this.Y(),this.i("columnSpan",b,a))});t.g(Q,"row",Q.prototype.ac);t.defineProperty(Q,{ac:"row"},function(){return this.wr},function(a){f&&t.o(a,Q,"row");a=Math.round(a);var b=this.wr;b!==a&&(0>a&&t.ia(a,">= 0",Q,"row"),this.wr=a,this.Y(),this.i("row",b,a))});t.g(Q,"rowSpan",Q.prototype.rowSpan); -t.defineProperty(Q,{rowSpan:"rowSpan"},function(){return this.tj},function(a){f&&t.o(a,Q,"rowSpan");a=Math.round(a);var b=this.tj;b!==a&&(1>a&&t.ia(a,">= 1",Q,"rowSpan"),this.tj=a,this.Y(),this.i("rowSpan",b,a))});t.g(Q,"alignmentFocus",Q.prototype.Dj); -t.defineProperty(Q,{Dj:"alignmentFocus"},function(){return this.Mp},function(a){var b=this.Mp;b.K(a)||(f?t.k(a,H,Q,"alignmentFocus"):a.jd()&&!a.zc()&&t.l("alignmentFocus must be a real Spot or Spot.Default"),this.Mp=a=a.W(),this.Y(),this.i("alignmentFocus",b,a))});t.g(Q,"portId",Q.prototype.md); -t.defineProperty(Q,{md:"portId"},function(){return this.lr},function(a){var b=this.lr;if(b!==a){f&&null!==a&&t.j(a,"string",Q,"portId");var c=this.Q;null===c||c instanceof S||(t.l("portID being set on a Link: "+a),c=null);null!==b&&c&&qk(c,this);this.lr=a;if(null!==a&&c){c.cj=!0;null===c.Yd&&rk(c);var d=this.md;null!==d&&c.Yd.add(d,this)}this.i("portId",b,a)}});function sk(a){var b={value:null};tk(a,b);return b.value} -function tk(a,b){var c=a.fa;return null===c||!tk(c,b)&&a.visible?(b.value=a,!1):!0}function mk(a){var b=a.Q;b instanceof S&&(a=a.h)&&!a.va.kb&&b.Ig()}t.g(Q,"toSpot",Q.prototype.gb);t.defineProperty(Q,{gb:"toSpot"},function(){return null!==this.T?this.T.Cj:ub},function(a){null===this.T&&this.Be();var b=this.T.Cj;b.K(a)||(f&&t.k(a,H,Q,"toSpot"),a=a.W(),this.T.Cj=a,this.i("toSpot",b,a),mk(this))});t.g(Q,"toEndSegmentLength",Q.prototype.Zj); -t.defineProperty(Q,{Zj:"toEndSegmentLength"},function(){return null!==this.T?this.T.Aj:10},function(a){null===this.T&&this.Be();var b=this.T.Aj;b!==a&&(f&&t.j(a,"number",Q,"toEndSegmentLength"),0>a&&t.ia(a,">= 0",Q,"toEndSegmentLength"),this.T.Aj=a,this.i("toEndSegmentLength",b,a),mk(this))});t.g(Q,"toEndSegmentDirection",Q.prototype.vp); -t.defineProperty(Q,{vp:"toEndSegmentDirection"},function(){return null!==this.T?this.T.zj:Hj},function(a){null===this.T&&this.Be();var b=this.T.zj;b!==a&&(f&&t.nb(a,S,Q,"toEndSegmentDirection"),this.T.zj=a,this.i("toEndSegmentDirection",b,a),mk(this))});t.g(Q,"toShortLength",Q.prototype.wp); -t.defineProperty(Q,{wp:"toShortLength"},function(){return null!==this.T?this.T.Bj:0},function(a){null===this.T&&this.Be();var b=this.T.Bj;b!==a&&(f&&t.j(a,"number",Q,"toShortLength"),this.T.Bj=a,this.i("toShortLength",b,a),mk(this))});t.g(Q,"toLinkable",Q.prototype.NA);t.defineProperty(Q,{NA:"toLinkable"},function(){return this.Sr},function(a){var b=this.Sr;b!==a&&(f&&null!==a&&t.j(a,"boolean",Q,"toLinkable"),this.Sr=a,this.i("toLinkable",b,a))});t.g(Q,"toMaxLinks",Q.prototype.sF); -t.defineProperty(Q,{sF:"toMaxLinks"},function(){return this.Tr},function(a){var b=this.Tr;b!==a&&(f&&t.o(a,Q,"toMaxLinks"),0>a&&t.ia(a,">= 0",Q,"toMaxLinks"),this.Tr=a,this.i("toMaxLinks",b,a))});t.g(Q,"fromSpot",Q.prototype.fb);t.defineProperty(Q,{fb:"fromSpot"},function(){return null!==this.T?this.T.aj:ub},function(a){null===this.T&&this.Be();var b=this.T.aj;b.K(a)||(f&&t.k(a,H,Q,"fromSpot"),a=a.W(),this.T.aj=a,this.i("fromSpot",b,a),mk(this))});t.g(Q,"fromEndSegmentLength",Q.prototype.Rj); -t.defineProperty(Q,{Rj:"fromEndSegmentLength"},function(){return null!==this.T?this.T.Zi:10},function(a){null===this.T&&this.Be();var b=this.T.Zi;b!==a&&(f&&t.j(a,"number",Q,"fromEndSegmentLength"),0>a&&t.ia(a,">= 0",Q,"fromEndSegmentLength"),this.T.Zi=a,this.i("fromEndSegmentLength",b,a),mk(this))});t.g(Q,"fromEndSegmentDirection",Q.prototype.Co); -t.defineProperty(Q,{Co:"fromEndSegmentDirection"},function(){return null!==this.T?this.T.Yi:Hj},function(a){null===this.T&&this.Be();var b=this.T.Yi;b!==a&&(f&&t.nb(a,S,Q,"fromEndSegmentDirection"),this.T.Yi=a,this.i("fromEndSegmentDirection",b,a),mk(this))});t.g(Q,"fromShortLength",Q.prototype.Do); -t.defineProperty(Q,{Do:"fromShortLength"},function(){return null!==this.T?this.T.$i:0},function(a){null===this.T&&this.Be();var b=this.T.$i;b!==a&&(f&&t.j(a,"number",Q,"fromShortLength"),this.T.$i=a,this.i("fromShortLength",b,a),mk(this))});t.g(Q,"fromLinkable",Q.prototype.Hz);t.defineProperty(Q,{Hz:"fromLinkable"},function(){return this.nq},function(a){var b=this.nq;b!==a&&(f&&null!==a&&t.j(a,"boolean",Q,"fromLinkable"),this.nq=a,this.i("fromLinkable",b,a))});t.g(Q,"fromMaxLinks",Q.prototype.AD); -t.defineProperty(Q,{AD:"fromMaxLinks"},function(){return this.oq},function(a){var b=this.oq;b!==a&&(f&&t.o(a,Q,"fromMaxLinks"),0>a&&t.ia(a,">= 0",Q,"fromMaxLinks"),this.oq=a,this.i("fromMaxLinks",b,a))});t.g(Q,"cursor",Q.prototype.cursor);t.defineProperty(Q,{cursor:"cursor"},function(){return this.$p},function(a){var b=this.$p;b!==a&&(t.j(a,"string",Q,"cursor"),this.$p=a,this.i("cursor",b,a))});t.g(Q,"click",Q.prototype.click); -t.defineProperty(Q,{click:"click"},function(){return null!==this.O?this.O.Mh:null},function(a){null===this.O&&Gj(this);var b=this.O.Mh;b!==a&&(null!==a&&t.j(a,"function",Q,"click"),this.O.Mh=a,this.i("click",b,a))});t.g(Q,"doubleClick",Q.prototype.tm);t.defineProperty(Q,{tm:"doubleClick"},function(){return null!==this.O?this.O.Sh:null},function(a){null===this.O&&Gj(this);var b=this.O.Sh;b!==a&&(null!==a&&t.j(a,"function",Q,"doubleClick"),this.O.Sh=a,this.i("doubleClick",b,a))}); -t.g(Q,"contextClick",Q.prototype.ns);t.defineProperty(Q,{ns:"contextClick"},function(){return null!==this.O?this.O.Oh:null},function(a){null===this.O&&Gj(this);var b=this.O.Oh;b!==a&&(null!==a&&t.j(a,"function",Q,"contextClick"),this.O.Oh=a,this.i("contextClick",b,a))});t.g(Q,"mouseEnter",Q.prototype.dA); -t.defineProperty(Q,{dA:"mouseEnter"},function(){return null!==this.O?this.O.br:null},function(a){null===this.O&&Gj(this);var b=this.O.br;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseEnter"),this.O.br=a,this.i("mouseEnter",b,a))});t.g(Q,"mouseLeave",Q.prototype.eA);t.defineProperty(Q,{eA:"mouseLeave"},function(){return null!==this.O?this.O.cr:null},function(a){null===this.O&&Gj(this);var b=this.O.cr;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseLeave"),this.O.cr=a,this.i("mouseLeave",b,a))}); -t.g(Q,"mouseOver",Q.prototype.Os);t.defineProperty(Q,{Os:"mouseOver"},function(){return null!==this.O?this.O.bi:null},function(a){null===this.O&&Gj(this);var b=this.O.bi;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseOver"),this.O.bi=a,this.i("mouseOver",b,a))});t.g(Q,"mouseHover",Q.prototype.Ns); -t.defineProperty(Q,{Ns:"mouseHover"},function(){return null!==this.O?this.O.ai:null},function(a){null===this.O&&Gj(this);var b=this.O.ai;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseHover"),this.O.ai=a,this.i("mouseHover",b,a))});t.g(Q,"mouseHold",Q.prototype.Ms);t.defineProperty(Q,{Ms:"mouseHold"},function(){return null!==this.O?this.O.$h:null},function(a){null===this.O&&Gj(this);var b=this.O.$h;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseHold"),this.O.$h=a,this.i("mouseHold",b,a))}); -t.g(Q,"mouseDragEnter",Q.prototype.sE);t.defineProperty(Q,{sE:"mouseDragEnter"},function(){return null!==this.O?this.O.$q:null},function(a){null===this.O&&Gj(this);var b=this.O.$q;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseDragEnter"),this.O.$q=a,this.i("mouseDragEnter",b,a))});t.g(Q,"mouseDragLeave",Q.prototype.cA); -t.defineProperty(Q,{cA:"mouseDragLeave"},function(){return null!==this.O?this.O.ar:null},function(a){null===this.O&&Gj(this);var b=this.O.ar;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseDragLeave"),this.O.ar=a,this.i("mouseDragLeave",b,a))});t.g(Q,"mouseDrop",Q.prototype.Ls);t.defineProperty(Q,{Ls:"mouseDrop"},function(){return null!==this.O?this.O.Zh:null},function(a){null===this.O&&Gj(this);var b=this.O.Zh;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseDrop"),this.O.Zh=a,this.i("mouseDrop",b,a))}); -t.g(Q,"actionDown",Q.prototype.gz);t.defineProperty(Q,{gz:"actionDown"},function(){return null!==this.O?this.O.Hp:null},function(a){null===this.O&&Gj(this);var b=this.O.Hp;b!==a&&(null!==a&&t.j(a,"function",Q,"actionDown"),this.O.Hp=a,this.i("actionDown",b,a))});t.g(Q,"actionUp",Q.prototype.iz); -t.defineProperty(Q,{iz:"actionUp"},function(){return null!==this.O?this.O.Jp:null},function(a){null===this.O&&Gj(this);var b=this.O.Jp;b!==a&&(null!==a&&t.j(a,"function",Q,"actionUp"),this.O.Jp=a,this.i("actionUp",b,a))});t.g(Q,"actionMove",Q.prototype.hz);t.defineProperty(Q,{hz:"actionMove"},function(){return null!==this.O?this.O.Ip:null},function(a){null===this.O&&Gj(this);var b=this.O.Ip;b!==a&&(null!==a&&t.j(a,"function",Q,"actionMove"),this.O.Ip=a,this.i("actionMove",b,a))}); -t.g(Q,"actionCancel",Q.prototype.fz);t.defineProperty(Q,{fz:"actionCancel"},function(){return null!==this.O?this.O.Gp:null},function(a){null===this.O&&Gj(this);var b=this.O.Gp;b!==a&&(null!==a&&t.j(a,"function",Q,"actionCancel"),this.O.Gp=a,this.i("actionCancel",b,a))});t.g(Q,"toolTip",Q.prototype.mt); -t.defineProperty(Q,{mt:"toolTip"},function(){return null!==this.O?this.O.li:null},function(a){null===this.O&&Gj(this);var b=this.O.li;b!==a&&(null!==a&&t.k(a,Fe,Q,"toolTip"),this.O.li=a,this.i("toolTip",b,a))});t.g(Q,"contextMenu",Q.prototype.contextMenu);t.defineProperty(Q,{contextMenu:"contextMenu"},function(){return null!==this.O?this.O.Ph:null},function(a){null===this.O&&Gj(this);var b=this.O.Ph;b!==a&&(null!==a&&t.k(a,Fe,Q,"contextMenu"),this.O.Ph=a,this.i("contextMenu",b,a))}); -Q.prototype.bind=Q.prototype.bind=function(a){a.Sf=this;var b=this.Bo();null!==b&&uk(b)&&t.l("Cannot add a Binding to a template that has already been copied: "+a);null===this.vc&&(this.vc=new A(ze));this.vc.add(a)};Q.prototype.findTemplateBinder=Q.prototype.Bo=function(){for(var a=this instanceof y?this:this.fa;null!==a;){if(null!==a.sl&&a instanceof y)return a;a=a.fa}return null};Q.fromSvg=function(a){return vk(a)};Q.prototype.setProperties=function(a){t.xw(this,a)};var wk; -Q.make=wk=function(a,b){var c=arguments,d=null,e=null;if("function"===typeof a)e=a;else if("string"===typeof a){var g=xk.wa(a);"function"===typeof g?(c=Array.prototype.slice.call(arguments),d=g(c)):e=ba[a]}null===d&&(void 0===e&&(d=window.$,void 0!==d&&void 0!==d.noop&&t.l("GraphObject.make failed to complete. Is it conflicting with another $ var? (such as jQuery)"),t.l("GraphObject.make failed to complete, it may be conflicting with another var.")),null!==e&&e.constructor||t.l("GraphObject.make requires a class function or class name, not: "+ -a),d=new e);g=1;d instanceof z&&1d)&&t.l("Must specify non-negative integer row for RowColumnDefinition "+b),c.Fl=!0,c.oe=d):void 0!==b.column?(d=b.column,(void 0===d||null===d||Infinity===d||isNaN(d)||0>d)&&t.l("Must specify non-negative integer column for RowColumnDefinition "+b),c.Fl=!1,c.oe=d):t.l("Must specify row or column value in a RowColumnDefinition "+b),d=t.XG(b,"row","column"),t.xw(c,d)):t.xw(c,b);else t.l('Unknown initializer "'+b+'" for object being constructed by GraphObject.make: '+ -a)}var xk;Q.Builders=xk=new ia("string","function"); -xk.add("Button",function(){var a=new Ud(Xd);a.addColorStop(0,"white");a.addColorStop(1,"lightgray");var b=new Ud(Xd);b.addColorStop(0,"white");b.addColorStop(1,"dodgerblue");var c=wk(y,Oh,{Yv:!0},wk(Y,{name:"ButtonBorder",Db:"RoundedRectangle",fill:a,stroke:"gray"}));c.dA=function(a,c){var g=c.ta(0),h=c._buttonFillOver;void 0===h&&(h=b);c._buttonFillNormal=g.fill;g.fill=h;h=c._buttonStrokeOver;void 0===h&&(h="blue");c._buttonStrokeNormal=g.stroke;g.stroke=h};c.eA=function(b,c){var g=c.ta(0),h=c._buttonFillNormal; -void 0===h&&(h=a);g.fill=h;h=c._buttonStrokeNormal;void 0===h&&(h="gray");g.stroke=h};return c}); -xk.add("TreeExpanderButton",function(){var a=wk("Button",wk(Y,{name:"ButtonIcon",Db:"MinusLine",ya:D.Dp},(new ze("figure","isTreeExpanded",function(a,c){var d=null,e=c.fa;e&&(d=a?e._treeExpandedFigure:e._treeCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).jA("")),{visible:!1},(new ze("visible","isTreeLeaf",function(a){return!a})).jA(""));a.click=function(a,c){var d=c.Q;d instanceof Fe&&(d=d.rh);if(d instanceof S){var e=d.h;if(null!==e){e=e.Yf;if(d.Ac){if(!e.canCollapseTree(d))return}else if(!e.canExpandTree(d))return; -a.Ae=!0;d.Ac?e.collapseTree(d):e.expandTree(d)}}};return a}); -xk.add("SubGraphExpanderButton",function(){var a=wk("Button",wk(Y,{name:"ButtonIcon",Db:"MinusLine",ya:D.Dp},(new ze("figure","isSubGraphExpanded",function(a,c){var d=null,e=c.fa;e&&(d=a?e._subGraphExpandedFigure:e._subGraphCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).jA("")));a.click=function(a,c){var d=c.Q;d instanceof Fe&&(d=d.rh);if(d instanceof V){var e=d.h;if(null!==e){e=e.Yf;if(d.Qe){if(!e.canCollapseSubGraph(d))return}else if(!e.canExpandSubGraph(d))return;a.Ae=!0;d.Qe?e.collapseSubGraph(d): -e.expandSubGraph(d)}}};return a});xk.add("ContextMenuButton",function(){var a=wk("Button");a.Eh=Fj;var b=a.de("ButtonBorder");b instanceof Y&&(b.Db="Rectangle",b.G=new H(0,0,2,2),b.H=new H(1,1,-2,-2));return a}); -function y(a){Q.call(this);void 0===a?0===arguments.length?this.Z=Vg:t.l("invalid argument to Panel constructor: undefined"):(t.nb(a,y,y,"type"),this.Z=a);this.za=new A(Q);this.Ge=D.Fp;this.ug=!1;this.Z===Vh&&(this.ug=!0);this.vf=1;this.cq=vb;this.fc=Rg;this.Z===kk&&dl(this);this.ao=Sg;this.sq=(new ea(10,10)).freeze();this.tq=D.ak;this.sl=this.xl=null;this.ky="";this.vg=this.fj=null;this.An="category";this.Of=null;this.ni=new w(NaN,NaN,NaN,NaN);this.Xn=null;this.cj=!1}t.ea("Panel",y);t.th(y); -t.Ja(y,Q);function dl(a){a.Vi=D.Fp;a.Xg=1;a.Rh=null;a.zl=null;a.Wg=1;a.Vg=null;a.yl=null;a.Sc=[];a.Nc=[];a.Xl=el;a.tl=el;a.mi=0;a.Xh=0} -y.prototype.cloneProtected=function(a){Q.prototype.cloneProtected.call(this,a);a.Z=this.Z;a.Ge=this.Ge.W();a.ug=this.ug;a.vf=this.vf;a.cq=this.cq.W();a.fc=this.fc;if(a.Z===kk){a.Vi=this.Vi.W();a.Xg=this.Xg;a.Rh=this.Rh;a.zl=this.zl;a.Wg=this.Wg;a.Vg=this.Vg;a.yl=this.yl;var b=[];if(0a&&t.ia(a,">= 0",y,"padding"),a=new Va(a)):(t.k(a,Va,y,"padding"),0>a.left&&t.ia(a.left,">= 0",y,"padding:val.left"),0>a.right&&t.ia(a.right,">= 0",y,"padding:val.right"),0>a.top&&t.ia(a.top,">= 0",y,"padding:val.top"),0>a.bottom&&t.ia(a.bottom,">= 0",y,"padding:val.bottom"));var b=this.Ge;b.K(a)||(this.Ge=a=a.W(),this.Y(),this.i("padding",b,a))});t.g(y,"defaultAlignment",y.prototype.Kj); -t.defineProperty(y,{Kj:"defaultAlignment"},function(){return this.cq},function(a){var b=this.cq;b.K(a)||(f&&t.k(a,H,y,"defaultAlignment"),this.cq=a=a.W(),this.Y(),this.i("defaultAlignment",b,a))});t.g(y,"defaultStretch",y.prototype.Az);t.defineProperty(y,{Az:"defaultStretch"},function(){return this.fc},function(a){var b=this.fc;b!==a&&(t.nb(a,Q,y,"defaultStretch"),this.fc=a,this.Y(),this.i("defaultStretch",b,a))});t.g(y,"defaultSeparatorPadding",y.prototype.iH); -t.defineProperty(y,{iH:"defaultSeparatorPadding"},function(){return void 0===this.Vi?D.Fp:this.Vi},function(a){if(void 0!==this.Vi){"number"===typeof a?a=new Va(a):f&&t.k(a,Va,y,"defaultSeparatorPadding");var b=this.Vi;b.K(a)||(this.Vi=a=a.W(),this.i("defaultSeparatorPadding",b,a))}});t.g(y,"defaultRowSeparatorStroke",y.prototype.gH); -t.defineProperty(y,{gH:"defaultRowSeparatorStroke"},function(){return void 0===this.Rh?null:this.Rh},function(a){var b=this.Rh;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Rh=a,this.i("defaultRowSeparatorStroke",b,a))});t.g(y,"defaultRowSeparatorStrokeWidth",y.prototype.hH); -t.defineProperty(y,{hH:"defaultRowSeparatorStrokeWidth"},function(){return void 0===this.Xg?1:this.Xg},function(a){if(void 0!==this.Xg){var b=this.Xg;b!==a&&(this.Xg=a,this.i("defaultRowSeparatorStrokeWidth",b,a))}});t.g(y,"defaultRowSeparatorDashArray",y.prototype.fH); -t.defineProperty(y,{fH:"defaultRowSeparatorDashArray"},function(){return void 0===this.zl?null:this.zl},function(a){if(void 0!==this.zl){var b=this.zl;b!==a&&(Array.isArray(a)||t.Nb(a,"Array",y,"defaultRowSeparatorDashArray:val"),this.zl=a,this.i("defaultRowSeparatorDashArray",b,a))}});t.g(y,"defaultColumnSeparatorStroke",y.prototype.bH); -t.defineProperty(y,{bH:"defaultColumnSeparatorStroke"},function(){return void 0===this.Vg?null:this.Vg},function(a){if(void 0!==this.Vg){var b=this.Vg;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Vg=a,this.i("defaultColumnSeparatorStroke",b,a))}});t.g(y,"defaultColumnSeparatorStrokeWidth",y.prototype.cH); -t.defineProperty(y,{cH:"defaultColumnSeparatorStrokeWidth"},function(){return void 0===this.Wg?1:this.Wg},function(a){if(void 0!==this.Wg){var b=this.Wg;b!==a&&(this.Wg=a,this.i("defaultColumnSeparatorStrokeWidth",b,a))}});t.g(y,"defaultColumnSeparatorDashArray",y.prototype.aH); -t.defineProperty(y,{aH:"defaultColumnSeparatorDashArray"},function(){return void 0===this.yl?null:this.yl},function(a){if(void 0!==this.yl){var b=this.yl;b!==a&&(Array.isArray(a)||t.Nb(a,"Array",y,"defaultColumnSeparatorDashArray:val"),this.yl=a,this.i("defaultColumnSeparatorDashArray",b,a))}});t.g(y,"viewboxStretch",y.prototype.KI); -t.defineProperty(y,{KI:"viewboxStretch"},function(){return this.ao},function(a){var b=this.ao;b!==a&&(t.nb(a,Q,y,"viewboxStretch"),this.ao=a,this.i("viewboxStretch",b,a))});t.g(y,"gridCellSize",y.prototype.xs); -t.defineProperty(y,{xs:"gridCellSize"},function(){return this.sq},function(a){var b=this.sq;b.K(a)||(t.k(a,ea,y,"gridCellSize"),a.P()&&0!==a.width&&0!==a.height||t.l("Invalid Panel.gridCellSize: "+a),this.sq=a.W(),null!==this.h&&this===this.h.Io&&ni(this.h),this.na(),this.i("gridCellSize",b,a))});t.g(y,"gridOrigin",y.prototype.Kz); -t.defineProperty(y,{Kz:"gridOrigin"},function(){return this.tq},function(a){var b=this.tq;b.K(a)||(t.k(a,v,y,"gridOrigin"),a.P()||t.l("Invalid Panel.gridOrigin: "+a),this.tq=a.W(),this.h&&ni(this.h),this.na(),this.i("gridOrigin",b,a))}); -y.prototype.Vk=function(a,b){var c=this.opacity,d=1;1!==c&&(d=a.globalAlpha,a.globalAlpha=d*c);if(this.Z===Vh){c=this.Sj()*b.scale;0>=c&&(c=1);var e=this.xs,d=e.width,e=e.height,g=this.Na,h=g.width,g=g.height,k=Math.ceil(h/d),l=Math.ceil(g/e),m=this.Kz;a.save();a.beginPath();a.rect(0,0,h,g);a.clip();for(var n=[],p=this.za.p,q=this.za.length,r=0;rd*u*c))break}else for(L=G=Math.floor(-m.y/e);L<=G+l&&!(M=L*e+m.y,0<=M&&M<=g&&jl(L,u,s)&&(x&&!F?Ij(a,0,M,h,M,E,r.Tc):(a.moveTo(0,M),a.lineTo(h,M)),2>e*u*c));L++);a.stroke();x&&(void 0!==a.setLineDash?(a.setLineDash(t.Jh),a.lineDashOffset=0):void 0!==a.webkitLineDash?(a.webkitLineDash=t.Jh,a.webkitLineDashOffset=0):void 0!==a.mozDash&&(a.mozDash=null,a.mozDashOffset=0))}a.restore();Th(b,a,!1)}else{this.Z===kk&&(a.lineCap="butt",kl(this,a,!0,this.Sc,!0),kl(this, -a,!1,this.Nc,!0),ll(this,a,!0,this.Sc),ll(this,a,!1,this.Nc),kl(this,a,!0,this.Sc,!1),kl(this,a,!1,this.Nc,!1));F=this.za.length;for(e=0;e -h.height&&(m-=r-h.height):r>h.width&&(m-=r-h.width);g=g.position+m/2;b.lineWidth=m;r=a.padding;c?(g+=r.top,m=r.left,r=h.width-r.right,n&&!q?Ij(b,m,g,r,g,p,0):(b.moveTo(m,g),b.lineTo(r,g))):(g+=r.left,m=r.top,r=h.height-r.bottom,n&&!q?Ij(b,g,m,g,r,p,0):(b.moveTo(g,m),b.lineTo(g,r)));b.stroke();n&&(void 0!==b.setLineDash?(b.setLineDash(t.Jh),b.lineDashOffset=0):void 0!==b.webkitLineDash?(b.webkitLineDash=t.Jh,b.webkitLineDashOffset=0):void 0!==b.mozDash&&(b.mozDash=null,b.mozDashOffset=0))}}} -function kl(a,b,c,d,e){for(var g=d.length,h,k=a.ua,l=0;lm)){var n=ml(h),p=h.Lm;isNaN(p)&&(p=c?a.Xg:a.Wg);var q=h.Km;null===q&&(q=c?a.Rh:a.Vg);null===q&&(p=0);n-=p;p=h.position+p;n+=h.Rb;p+n>m&&(n=m-p);0>=n||(m=a.padding,ak(a,b,h.background,!0),c?b.fillRect(m.left,p+m.top,k.width-(m.left+m.right),n):b.fillRect(p+m.left,m.top,n,k.height-(m.top+m.bottom)))}}} -function jl(a,b,c){if(0!==a%b)return!1;b=c.length;for(var d=0;dGc&&(mc=Gc),ql(ga,ga.Rb+mc),Gc=Math.max(Gc-mc,0));1!==na.Ti||!qh&&Od!==Qg&&Od!==Ej||(ga=this.fe(rc),mc=Math.max(Qe-ga.Rb,0),mc>wc&&(mc=wc),ql(ga,ga.Rb+mc),wc=Math.max(wc-mc,0));dg&&ik(na)}}}t.xa(ph);for(var ee=0,fe=0,tb=this.Av,ja=0;ja=this.tw);hc++)ga=this.ge(na.ac+hc),Qd.height+=Math.max(ga.Ah,isNaN(ga.wf)?ga.jf:Math.min(ga.wf,ga.jf));for(hc=1;hc=this.Av);hc++)ga=this.fe(na.column+hc),Qd.width+=Math.max(ga.Ah,isNaN(ga.wf)?ga.jf:Math.min(ga.wf,ga.jf));yb.width+=Qd.width;yb.height+=Qd.height;Rb=na.margin;Lf=Rb.right+Rb.left;Mf=Rb.top+Rb.bottom;mh(na,yb.width,yb.height,lf,bb);for(var te=na.Ba,Qe=Math.max(te.width+Lf,0),Re=Math.max(te.height+Mf,0),Dg=0,hc=0;hcsc&&(ql(ga,Math.min(ga.jf,sc+Rd)),ga.Ab!==sc&&(Rd-=ga.Ab-sc));if(-1===ga.index-1)break;ga=this.ge(ga.index-1)}for(var Se=0,hc=0;hcsc&&(ql(ga,Math.min(ga.jf,sc+Rd)),ga.Ab!==sc&&(Rd-=ga.Ab-sc));if(-1===ga.index-1)break;ga=this.fe(ga.index-1)}}t.xa(zg);t.Qj(Qd);t.Qj(yb);for(var of=0,he=0,Od=Nj(this),Eg= -this.ya,eg=this.Ce,Hc=fe=ee=0,ie=0,tb=this.Av,ja=0;jash)mh(Sb, -Infinity,Infinity),Sd=Sb.Ba,ue.$j(Sd),this.Lh.add(Sd);else{var Pf=Sb.nf,so=Sb.bt,hl=Sb.Dj;hl.jd()&&(hl=Fb);var rj=Sb.ct,oq=Sb.zA,ki,li,sj=0;if(Pf<-sh||Pf>=sh){var to=oj.qE,tj=oj.pE;rj!==sg&&(sj=oj.computeAngle(Sb,rj,tj),Sb.angle=sj);ki=to.x-Ue.x;li=to.y-Ue.y}else{var pf,uh;if(0<=Pf)pf=ji.p[Pf],uh=Pfc||q>d)this.Y(),mh(this,p>c?c:p,q>d?d:q);break;case Ic:Oj(this,!0);mh(this,c+s,d+u,0,0);break;case Fj:Oj(this,!0);mh(this,c+s,q+u,0,0);break;case Ej:Oj(this,!0),mh(this,p+s,d+u,0,0)}}l=this.ua;l.x=a;l.y= -b;l.width=c;l.height=d;var x=this.Z.Mb;switch(x){case "Position":for(var E=e.x-this.padding.left,F=e.y-this.padding.top,G=0;G=this.tw);ja++){var na=this.ge(Bb+ja);Cb.height+=na.total}for(ja=1;ja=this.Av);ja++){var hj=this.fe(Dd+ja);Cb.width+=hj.total}var yg=fc.Ab+Cb.width,rc=Cd.Ab+Cb.height;k.x=be;k.y=Bc;k.width=yg;k.height=rc;Bc+rc>e.height&&(rc=Math.max(e.height- -Bc,0));be+yg>e.width&&(yg=Math.max(e.width-be,0));var oh=be,gc=Bc,ph=yg,zg=rc,Dc=bb.alignment,Ec,Fc,wc,Gc;if(Dc.zc()){Dc=this.Kj;Dc.kd()||(Dc=Fb);Ec=Dc.x;Fc=Dc.y;wc=Dc.offsetX;Gc=Dc.offsetY;var Kf=fc.alignment,ga=Cd.alignment;Kf.kd()&&(Ec=Kf.x,wc=Kf.offsetX);ga.kd()&&(Fc=ga.y,Gc=ga.offsetY)}else Ec=Dc.x,Fc=Dc.y,wc=Dc.offsetX,Gc=Dc.offsetY;if(isNaN(Ec)||isNaN(Fc))Fc=Ec=0.5,Gc=wc=0;var Nd=ce.width,Ed=ce.height,ij=bb.Ce,jj=bb.Te,Nd=Math.min(ij.width,Nd),Ed=Math.min(ij.height,Ed),Nd=Math.max(jj.width, -Nd),Ed=Math.max(jj.height,Ed),mc=bb.margin,lb=mc.left+mc.right,mb=mc.top+mc.bottom,Ag=lk(bb,Cd,fc);if(isNaN(bb.ya.width)&&isNaN(fc.width)&&Ag===Ic||Ag===Fj)Nd=Math.max(yg-lb,0);if(isNaN(bb.ya.height)&&isNaN(Cd.height)&&Ag===Ic||Ag===Ej)Ed=Math.max(rc-mb,0);var fl=Ed+mb;k.x+=k.width*Ec-(Nd+lb)*Ec+wc+mc.left;k.y+=k.height*Fc-fl*Fc+Gc+mc.top;bb.visible&&(eb(oh,gc,ph,zg,k.x,k.y,Nd,Ed)?bb.xc(k.x,k.y,Nd,Ed):bb.xc(k.x,k.y,Nd,Ed,new w(oh,gc,ph,zg)))}}}}t.Qj(Cb);for(Bb=0;Bb=rh){var Dg=this.qE,Rd=this.pE;ge!==sg&&(hc= -this.computeAngle(ld,ge,Rd),ld.angle=hc);nf=Dg.x;Qd=Dg.y}else{var sc=void 0,Se=void 0;if(0<=Pd)sc=Bg.p[Pd],Se=Pdn.width||m.y>n.height||0>m.x+m.width||0>m.y+m.height)){m=t.Og();m.set(h);if(l instanceof y?l.Pj(a,b,c,d,e,m):Mj(l,a,d,m))null!==b&&(l=b(l)),l&& -(null===c||c(l))&&e.add(l);t.Ne(m)}}}void 0===g&&t.Ne(h);return d}void 0===g&&t.Ne(h);return!1};function Bl(a,b,c,d){for(var e=a.za.length;e--;){var g=a.za.p[e];if(g.visible){var h=g.ua,k=a.Na;h.x>k.width||h.y>k.height||0>h.x+h.width||0>h.y+h.height||(g instanceof y&&Bl(g,b,c,d),null!==b&&(g=b(g)),g&&(null===c||c(g))&&d.add(g))}}} -aa.vm=function(a,b,c,d,e,g){if(!1===this.mf)return!1;void 0===c&&(c=null);void 0===d&&(d=null);var h=this.Na,k=this.og(),l=k?a:Oa(t.cc(a.x,a.y),this.transform),m=k?b:Oa(t.cc(b.x,b.y),this.transform),n=l.Mj(m),p=0r.width||q.y>r.height||0>q.x+q.width||0>q.y+q.height||(n.og()?(q=n.transform,Oa(k.set(a),q),Oa(l.set(b),q)):(k.set(a),l.set(b)),n instanceof y?!n.vm(k,l,c,d,e,g):!n.tD(k,l,e))||(null!==c&&(n=c(n)),n&&(null===d||d(n))&&g.add(n))}t.B(k);t.B(l)}return e?p:h}return!1}; -function nl(a){var b=a.G;if(void 0===b||b===vb)b=null;null===b&&a instanceof Y&&(a=a.La,null!==a&&(b=a.G));null===b&&(b=wb);return b}function ol(a){var b=a.H;if(void 0===b||b===vb)b=null;null===b&&a instanceof Y&&(a=a.La,null!==a&&(b=a.H));null===b&&(b=Ob);return b}y.prototype.add=y.prototype.add=function(a){t.k(a,Q,y,"add:element");this.td(this.za.count,a)};y.prototype.elt=y.prototype.ta=function(a){return this.za.ta(a)}; -y.prototype.insertAt=y.prototype.td=function(a,b){b instanceof B&&t.l("Cannot add a Part to a Panel: "+b);if(this===b||this.Ei(b))this===b&&t.l("Cannot make a Panel contain itself: "+this.toString()),t.l("Cannot make a Panel indirectly contain itself: "+this.toString()+" already contains "+b.toString());var c=b.fa;null!==c&&c!==this&&t.l("Cannot add a GraphObject that already belongs to another Panel to this Panel: "+b.toString()+", already contained by "+c.toString()+", cannot be shared by this Panel: "+ -this.toString());this.Z!==Vh||b instanceof Y||t.l("Can only add Shapes to a Grid Panel, not: "+b);b.hl(this);b.Sl=null;if(null!==this.Xz){var d=b.data;null!==d&&"object"===typeof d&&(null===this.Of&&(this.Of=new ia(Object,y)),this.Of.add(d,b))}var e=this.za,d=-1;if(c===this){for(var g=-1,h=e.count,k=0;k=e.count&&a>=e.count)return;e.Zc(g);d=g}else t.l("element "+b.toString()+" has panel "+c.toString()+" but is not contained by it.")}if(0>a|| -a>e.count)a=e.count;e.td(a,b);this.Y();b.Y();null!==b.md&&(this.cj=!0);b instanceof y&&!0===b.cj&&(this.cj=!0);c=this.Q;null!==c&&(c.nj=null,c.lj=NaN,null!==b.md&&c instanceof S&&(c.cj=!0),e=this.h,null!==e&&e.va.kb||(-1!==d&&c.Mc(ud,"elements",this,b,null,d,null),c.Mc(td,"elements",this,null,b,null,a)))};y.prototype.remove=y.prototype.remove=function(a){t.k(a,Q,y,"remove:element");for(var b=this.za,c=b.count,d=-1,e=0;ea&&t.ia(a,">= 0",y,"getRowDefinition:idx");a=Math.round(a);var b=this.Sc;if(void 0===b[a]){var c=new Ak;c.hl(this);c.Fl=!0;c.oe=a;b[a]=c}return b[a]};y.prototype.removeRowDefinition=function(a){if(void 0!==this.Sc){f&&t.o(a,y,"removeRowDefinition:idx");0>a&&t.ia(a,">= 0",y,"removeRowDefinition:idx");a=Math.round(a);var b=this.Sc;b[a]&&(b[a]=void 0)}}; -t.A(y,{Av:"columnCount"},function(){return void 0===this.Nc?0:this.Nc.length});y.prototype.getColumnDefinition=y.prototype.fe=function(a){if(void 0===this.Nc)return null;f&&t.o(a,y,"getColumnDefinition:idx");0>a&&t.ia(a,">= 0",y,"getColumnDefinition:idx");a=Math.round(a);var b=this.Nc;if(void 0===b[a]){var c=new Ak;c.hl(this);c.Fl=!1;c.oe=a;b[a]=c}return b[a]}; -y.prototype.removeColumnDefinition=function(a){if(void 0!==this.Nc){f&&t.o(a,y,"removeColumnDefinition:idx");0>a&&t.ia(a,">= 0",y,"removeColumnDefinition:idx");a=Math.round(a);var b=this.Nc;b[a]&&(b[a]=void 0)}};t.g(y,"rowSizing",y.prototype.UE); -t.defineProperty(y,{UE:"rowSizing"},function(){return void 0===this.Xl?el:this.Xl},function(a){if(void 0!==this.Xl){var b=this.Xl;b!==a&&(a!==el&&a!==sl&&t.l("rowSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.Xl=a,this.Y(),this.i("rowSizing",b,a))}});t.g(y,"columnSizing",y.prototype.SC); -t.defineProperty(y,{SC:"columnSizing"},function(){return void 0===this.tl?el:this.tl},function(a){if(void 0!==this.tl){var b=this.tl;b!==a&&(a!==el&&a!==sl&&t.l("columnSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.tl=a,this.Y(),this.i("columnSizing",b,a))}});t.g(y,"topIndex",y.prototype.JI); -t.defineProperty(y,{JI:"topIndex"},function(){return void 0===this.mi?0:this.mi},function(a){if(void 0!==this.mi){var b=this.mi;b!==a&&((!isFinite(a)||0>a)&&t.l("topIndex must be greater than zero and a real number. Was "+a),this.mi=a,this.Y(),this.i("topIndex",b,a))}});t.g(y,"leftIndex",y.prototype.YH); -t.defineProperty(y,{YH:"leftIndex"},function(){return void 0===this.Xh?0:this.Xh},function(a){if(void 0!==this.Xh){var b=this.Xh;b!==a&&((!isFinite(a)||0>a)&&t.l("leftIndex must be greater than zero and a real number. Was "+a),this.Xh=a,this.Y(),this.i("leftIndex",b,a))}});y.prototype.findRowForLocalY=function(a){if(0>a)return-1;if(this.type!==kk)return NaN;for(var b=0,c=this.Sc,d=c.length,e=this.mi;ea)return-1;if(this.type!==kk)return NaN;for(var b=0,c=this.Nc,d=c.length,e=this.Xh;ea;)this.Oe(a);a=this.Xz;if(null!==a)for(var b=t.wb(a),c=0;ca||1a&&t.ia(a,">= 0",Ak,"height"),this.wf=a,ql(this,this.Ab),this.Ec("size",b,a))});t.g(Ak,"width",Ak.prototype.width);t.defineProperty(Ak,{width:"width"},function(){return this.wf},function(a){var b=this.wf;b!==a&&(f&&t.j(a,"number",Ak,"width"),0>a&&t.ia(a,">= 0",Ak,"width"),this.wf=a,ql(this,this.Ab),this.Ec("size",b,a))});t.g(Ak,"minimum",Ak.prototype.Ah); -t.defineProperty(Ak,{Ah:"minimum"},function(){return this.Nl},function(a){var b=this.Nl;b!==a&&(f&&t.j(a,"number",Ak,"minimum"),(0>a||!isFinite(a))&&t.ia(a,">= 0",Ak,"minimum"),this.Nl=a,ql(this,this.Ab),this.Ec("minimum",b,a))});t.g(Ak,"maximum",Ak.prototype.jf);t.defineProperty(Ak,{jf:"maximum"},function(){return this.Ml},function(a){var b=this.Ml;b!==a&&(f&&t.j(a,"number",Ak,"maximum"),0>a&&t.ia(a,">= 0",Ak,"maximum"),this.Ml=a,ql(this,this.Ab),this.Ec("maximum",b,a))});t.g(Ak,"alignment",Ak.prototype.alignment); -t.defineProperty(Ak,{alignment:"alignment"},function(){return this.me},function(a){var b=this.me;b.K(a)||(f&&t.k(a,H,Ak,"alignment"),this.me=a.W(),this.Ec("alignment",b,a))});t.g(Ak,"stretch",Ak.prototype.Eh);t.defineProperty(Ak,{Eh:"stretch"},function(){return this.nh},function(a){var b=this.nh;b!==a&&(f&&t.nb(a,Q,Ak,"stretch"),this.nh=a,this.Ec("stretch",b,a))});t.g(Ak,"separatorPadding",Ak.prototype.AA); -t.defineProperty(Ak,{AA:"separatorPadding"},function(){return this.wj},function(a){"number"===typeof a?a=new Va(a):null!==a&&f&&t.k(a,Va,Ak,"separatorPadding");var b=this.wj;null!==a&&null!==b&&b.K(a)||(null!==a&&(a=a.W()),this.wj=a,this.Ec("separatorPadding",b,a))});t.g(Ak,"separatorStroke",Ak.prototype.Km); -t.defineProperty(Ak,{Km:"separatorStroke"},function(){return this.Gr},function(a){var b=this.Gr;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Gr=a,this.fa&&this.fa.na(),this.Ec("separatorStroke",b,a))});t.g(Ak,"separatorStrokeWidth",Ak.prototype.Lm);t.defineProperty(Ak,{Lm:"separatorStrokeWidth"},function(){return this.Hr},function(a){var b=this.Hr;b!==a&&(this.Hr=a,this.fa&&this.fa.na(),this.Ec("separatorStrokeWidth",b,a))}); -t.g(Ak,"separatorDashArray",Ak.prototype.aF);t.defineProperty(Ak,{aF:"separatorDashArray"},function(){return this.jh},function(a){var b=this.jh;b!==a&&(Array.isArray(a)||t.Nb(a,"Array",Ak,"separatorDashArray:val"),this.jh=a,this.fa&&this.fa.na(),this.Ec("separatorDashArray",b,a))});t.g(Ak,"background",Ak.prototype.background); -t.defineProperty(Ak,{background:"background"},function(){return this.Bb},function(a){var b=this.Bb;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Bb=a,this.fa&&this.fa.na(),this.Ec("background",b,a))});t.g(Ak,"coversSeparators",Ak.prototype.Fv);t.defineProperty(Ak,{Fv:"coversSeparators"},function(){return this.Zp},function(a){var b=this.Zp;b!==a&&(t.j(a,"boolean",Ak,"coversSeparators"),this.Zp=a,this.Ec("coversSeparators",b,a))});t.g(Ak,"sizing",Ak.prototype.gt); -t.defineProperty(Ak,{gt:"sizing"},function(){return this.Jr},function(a){var b=this.Jr;b!==a&&(f&&t.nb(a,Ak,Ak,"sizing"),this.Jr=a,this.Ec("sizing",b,a))});function rl(a){if(a.gt===Dl){var b=a.fi;return a.xh?b.UE:b.SC}return a.gt}t.A(Ak,{Rb:"actual"},function(){return this.Ab});t.A(Ak,{total:"total"},function(){return this.Ab+ml(this)});t.A(Ak,{position:"position"},function(){return this.sb}); -Ak.prototype.bind=Ak.prototype.bind=function(a){a.Sf=this;var b=this.fa;null!==b&&(b=b.Bo(),null!==b&&uk(b)&&t.l("Cannot add a Binding to a RowColumnDefinition that is already frozen: "+a));null===this.vc&&(this.vc=new A(ze));this.vc.add(a)}; -function Y(){Q.call(this);this.La=null;this.pn="None";this.Cg=!1;this.qq=Rg;this.nk=null;this.tb=this.Cc="black";this.Dg=1;this.Vn="butt";this.Wn="miter";this.cm=10;this.bm=null;this.Tc=0;this.ki=this.ji=vb;this.ir=this.hr=0;this.vq=!1;this.Aq=!0;this.kr=null;this.rn=this.Yn="None";this.uq=1}t.ea("Shape",Y);t.Ja(Y,Q); -Y.prototype.cloneProtected=function(a){Q.prototype.cloneProtected.call(this,a);a.La=this.La;a.pn=this.pn;a.Cg=this.Cg;a.qq=this.qq;a.nk=this.nk;a.Cc=this.Cc;a.tb=this.tb;a.Dg=this.Dg;a.Vn=this.Vn;a.Wn=this.Wn;a.cm=this.cm;a.bm=null;this.bm&&(a.bm=this.bm.slice(0));a.Tc=this.Tc;a.ji=this.ji.W();a.ki=this.ki.W();a.hr=this.hr;a.ir=this.ir;a.vq=this.vq;a.Aq=this.Aq;a.kr=this.kr;a.Yn=this.Yn;a.rn=this.rn;a.uq=this.uq}; -Y.prototype.toString=function(){return"Shape("+("None"!==this.Db?this.Db:"None"!==this.Om?this.Om:this.Sv)+")#"+t.jc(this)}; -function El(a,b,c,d){var e=0.001,g=d.Ba,h=g.width,g=g.height,k,l,m,n=c.length;if(!(2>n)){k=c[0][0];l=c[0][1];for(var p,q,r,s,u=0,x=t.yb(),E=1;Eu){t.xa(x);return}e>r?(F=e-r,e=r):F=0;var G=Math.sqrt(e* -e/(1+q*q));0>p&&(G=-G);k+=G;l+=q*G;a.translate(k,l);a.rotate(s);a.translate(-(h/2),-(g/2));0===F&&d.Vk(a,b);a.translate(h/2,g/2);a.rotate(-s);a.translate(-k,-l);u-=e;r-=e;if(0!==F){m++;if(m===x.length){t.xa(x);return}r=x[m];p=r[0];s=r[1];q=r[2];r=r[3];e=F}}t.xa(x)}} -Y.prototype.Vk=function(a,b){if(null!==this.tb||null!==this.Cc){null!==this.Cc&&ak(this,a,this.Cc,!0);null!==this.tb&&ak(this,a,this.tb,!1);var c=this.Dg;if(0===c){var d=this.Q;d instanceof Fe&&d.type===pg&&d.Gc instanceof Y&&(c=d.Gc.bb)}a.lineWidth=c;a.lineJoin=this.Wn;a.lineCap=this.Vn;a.miterLimit=this.cm;var e=!1;this.Q&&(e=this.Q.Gi);var g=!0;null!==this.tb&&null===this.Cc&&(g=!1);var d=!1,h=this.Bw;if(null!==h){var k=d=!0;void 0!==a.setLineDash?(a.setLineDash(h),a.lineDashOffset=this.Tc):void 0!== -a.webkitLineDash?(a.webkitLineDash=h,a.webkitLineDashOffset=this.Tc):void 0!==a.mozDash?(a.mozDash=h,a.mozDashOffset=this.Tc):k=!1}var l=this.La;if(null!==l){if(l.Z===Jc)a.beginPath(),d&&!k?Ij(a,l.Yb,l.ic,l.dd,l.qd,h,this.Tc):(a.moveTo(l.Yb,l.ic),a.lineTo(l.dd,l.qd)),null!==this.Cc&&bk(a,this.Cc,!0),0!==c&&null!==this.tb&&bk(a,this.tb,!1);else if(l.Z===Kc){var m=l.Yb,n=l.ic,p=l.dd,l=l.qd,q=Math.min(m,p),r=Math.min(n,l),m=Math.abs(p-m),n=Math.abs(l-n);null!==this.Cc&&(this.Cc instanceof Ud&&this.Cc.type=== -Yd?(a.beginPath(),a.rect(q,r,m,n),bk(a,this.Cc,!0)):a.fillRect(q,r,m,n));if(null!==this.tb){if(g&&e){var s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}d&&!k?(k=[[q,r],[q+m,r],[q+m,r+n],[q,r+n],[q,r]],a.beginPath(),Fl(a,k,h,this.Tc),bk(a,this.tb,!1)):0!==c&&(this.tb instanceof Ud&&this.tb.type===Yd?(a.beginPath(),a.rect(q,r,m,n),bk(a,this.tb,!1)):a.strokeRect(q,r,m,n));g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2])}}else if(l.Z=== -Lc)m=l.Yb,n=l.ic,p=l.dd,l=l.qd,q=Math.abs(p-m)/2,r=Math.abs(l-n)/2,m=Math.min(m,p)+q,n=Math.min(n,l)+r,a.beginPath(),a.moveTo(m,n-r),a.bezierCurveTo(m+D.sa*q,n-r,m+q,n-D.sa*r,m+q,n),a.bezierCurveTo(m+q,n+D.sa*r,m+D.sa*q,n+r,m,n+r),a.bezierCurveTo(m-D.sa*q,n+r,m-q,n+D.sa*r,m-q,n),a.bezierCurveTo(m-q,n-D.sa*r,m-D.sa*q,n-r,m,n-r),a.closePath(),null!==this.Cc&&bk(a,this.Cc,!0),d&&!k&&(k=t.yb(),D.ue(m,n-r,m+D.sa*q,n-r,m+q,n-D.sa*r,m+q,n,0.5,k),D.ue(m+q,n,m+q,n+D.sa*r,m+D.sa*q,n+r,m,n+r,0.5,k),D.ue(m,n+ -r,m-D.sa*q,n+r,m-q,n+D.sa*r,m-q,n,0.5,k),D.ue(m-q,n,m-q,n-D.sa*r,m-D.sa*q,n-r,m,n-r,0.5,k),a.beginPath(),Fl(a,k,h,this.Tc),t.xa(k)),0!==c&&null!==this.tb&&(g&&e&&(s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0),bk(a,this.tb,!1),g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2]));else if(l.Z===zc){for(var q=l.rk,r=q.length,u=0;uM.Fh);else for(var G=ed(M,x),W=G.length,T=0;Tm))if(h=b[0][0],k=b[0][1],2===m)Ij(a,h,k,b[1][0],b[1][1],c,d);else{a.moveTo(h,k);for(var n,p,q,r=0,s=t.yb(),u=1;ur&&(e=r);e>q?(x=e-q,e=q):x=0;var E=Math.sqrt(e*e/(1+p*p));0>n&&(E= --E);h+=E;k+=p*E;m?a.lineTo(h,k):a.moveTo(h,k);r-=e;q-=e;if(0!==x){l++;if(l===s.length){t.xa(s);return}q=s[l];n=q[0];p=q[1];q=q[2];e=x}else m=!m}t.xa(s)}}Y.prototype.getDocumentPoint=Y.prototype.$a=function(a,b){void 0===b&&(b=new v);a.jd()&&t.l("Spot must be real");var c=this.Na,d=this.bb;b.q(a.x*(c.width+d)-d/2+c.x+a.offsetX,a.y*(c.height+d)-d/2+c.y+a.offsetY);this.$d.Qa(b);return b}; -Y.prototype.Hj=function(a,b){var c=this.La;if(null===c||null===this.fill&&null===this.stroke)return!1;var d=c.Gb,e=this.bb/2;c.type!==Jc||b||(e+=2);var g=t.qf();g.assign(d);g.Hg(e+2,e+2);if(!g.Da(a))return t.Ic(g),!1;d=e+1E-4;if(c.type===Jc){if(null===this.stroke)return!1;g=(c.D-c.la)*(a.x-c.la)+(c.F-c.ma)*(a.y-c.ma);return 0>(c.la-c.D)*(a.x-c.D)+(c.ma-c.F)*(a.y-c.F)||0>g?!1:D.vd(c.la,c.ma,c.D,c.F,e,a.x,a.y)}if(c.type===Kc){var h=c.la,k=c.ma,l=c.D,m=c.F,c=Math.min(h,l),n=Math.min(k,m),h=Math.abs(l- -h),k=Math.abs(m-k);g.x=c;g.y=n;g.width=h;g.height=k;if(null===this.fill){g.Hg(-d,-d);if(g.Da(a))return!1;g.Hg(d,d)}null!==this.stroke&&g.Hg(e,e);e=g.Da(a);t.Ic(g);return e}if(c.type===Lc){h=c.la;k=c.ma;l=c.D;m=c.F;c=Math.min(h,l);n=Math.min(k,m);h=Math.abs(l-h);k=Math.abs(m-k);g=h/2;k/=2;c=a.x-(c+g);n=a.y-(n+k);if(null===this.fill){g-=d;k-=d;if(0>=g||0>=k||1>=c*c/(g*g)+n*n/(k*k))return!1;g+=d;k+=d}null!==this.stroke&&(g+=e,k+=e);return 0>=g||0>=k?!1:1>=c*c/(g*g)+n*n/(k*k)}if(c.type===zc)return null=== -this.fill?nd(c,a.x,a.y,e):c.Da(a,e,1=this.bb)n=D.Mg(p.Yb,p.ic,p.dd,p.qd,g,h,k,l,e);else{var r,s;p.Yb===p.dd?(r=m,s=0):(b=(p.qd-p.ic)/(p.dd-p.Yb),s=m/Math.sqrt(1+b*b),r=s*b);d=t.yb();b=new v;D.Mg(p.Yb+ -r,p.ic+s,p.dd+r,p.qd+s,g,h,k,l,b)&&d.push(b);b=new v;D.Mg(p.Yb-r,p.ic-s,p.dd-r,p.qd-s,g,h,k,l,b)&&d.push(b);b=new v;D.Mg(p.Yb+r,p.ic+s,p.Yb-r,p.ic-s,g,h,k,l,b)&&d.push(b);b=new v;D.Mg(p.dd+r,p.qd+s,p.dd-r,p.qd-s,g,h,k,l,b)&&d.push(b);b=d.length;if(0===b)return t.xa(d),!1;n=!0;s=Infinity;for(r=0;rMath.abs(c)){n=h-b-c*(g-d);if(0>a*a*c*c+x*x-n*n){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(a*a*c*c+x*x-n*n);k=(-(a*a*c*n)+a*x*m)/(x*x+a*a*c*c)+d;a=(-(a*a*c*n)-a*x*m)/(x*x+a*a*c*c)+d;l=c*(k-d)+n+b;b=c*(a-d)+n+b;d=Math.abs((g-k)*(g-k))+Math.abs((h-l)*(h-l));h=Math.abs((g-a)*(g-a))+Math.abs((h-b)* -(h-b));dk){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(k);l=b+m;b-=m;d=Math.abs(l-h);h=Math.abs(b-h);dc?a-c:c-a)<(b>d?b-d:d-b)?(e=be||D.Fa(l.y,e))&&(l.ye||D.Fa(l.x,e))&&(l.x=h&&d<=a}a=h&&c<=a} -Y.prototype.tD=function(a,b,c){function d(a,b){for(var c=a.length,d=0;de)return!0}return!1}if(c&&null!==this.fill&&this.Hj(a,!0))return!0;var e=a.Mj(b);b=e;1.5=e||Qa(b,g,0,-p)>=e||Qa(b,g,0,p)>=e||Qa(b,g,n,0)>=e?!1: -!0}else if(g.type===zc){h=g.Gb;k=h.x;l=h.y;m=h.x+h.width;h=h.y+h.height;if(a.x>m&&a.xh&&a.ye&&Pa(a.x,a.y,k,l,m,l)>e&&Pa(a.x,a.y,m,h,k,h)>e&&Pa(a.x,a.y,m,h,m,l)>e)return!1;b=Math.sqrt(e);if(c){if(null===this.fill?nd(g,a.x,a.y,b):g.Da(a,b,!0))return!0}else{c=g.ob;for(b=0;be)return!1;l=k.Ca.p;m=l.length;for(h=0;he)return!1;break;case ad:g=t.yb(); -D.ue(n,p,q.pb,q.Fb,q.je,q.ke,q.D,q.F,0.8,g);n=d(g,a);t.xa(g);if(n)return!1;n=q.D;p=q.F;if(a.ps(n,p)>e)return!1;break;case bd:g=t.yb();D.hp(n,p,q.pb,q.Fb,q.D,q.F,0.8,g);n=d(g,a);t.xa(g);if(n)return!1;n=q.D;p=q.F;if(a.ps(n,p)>e)return!1;break;case cd:case dd:var q=q.type===cd?ed(q,k):kd(q,k,n,p),r=q.length,s=null,g=t.yb();for(b=0;b= 0",Y,"strokeWidth:val")});t.g(Y,"strokeCap",Y.prototype.lF); -t.defineProperty(Y,{lF:"strokeCap"},function(){return this.Vn},function(a){var b=this.Vn;b!==a&&("string"!==typeof a||"butt"!==a&&"round"!==a&&"square"!==a?t.ia(a,'"butt", "round", or "square"',Y,"strokeCap"):(this.Vn=a,this.na(),this.i("strokeCap",b,a)))});t.g(Y,"strokeJoin",Y.prototype.CI); -t.defineProperty(Y,{CI:"strokeJoin"},function(){return this.Wn},function(a){var b=this.Wn;b!==a&&("string"!==typeof a||"miter"!==a&&"bevel"!==a&&"round"!==a?t.ia(a,'"miter", "bevel", or "round"',Y,"strokeJoin"):(this.Wn=a,this.na(),this.i("strokeJoin",b,a)))});t.g(Y,"strokeMiterLimit",Y.prototype.DI); -t.defineProperty(Y,{DI:"strokeMiterLimit"},function(){return this.cm},function(a){var b=this.cm;if(b!==a)if(f&&t.o(a,Y,"strokeMiterLimit"),0 0",Y,"strokeWidth:val")});t.g(Y,"strokeDashArray",Y.prototype.Bw); -t.defineProperty(Y,{Bw:"strokeDashArray"},function(){return this.bm},function(a){var b=this.bm;if(b!==a){null===a||Array.isArray(a)||t.Nb(a,"Array",Y,"strokeDashArray:val");if(null!==a)for(var c=a.length,d=0;de||!isFinite(e))&&t.l("strokeDashArray:val "+e+" is a negative number or not a real number.")}this.bm=a;this.na();this.i("strokeDashArray",b,a)}});t.g(Y,"strokeDashOffset",Y.prototype.mF); -t.defineProperty(Y,{mF:"strokeDashOffset"},function(){return this.Tc},function(a){var b=this.Tc;b!==a&&(f&&t.o(a,Y,"strokeDashOffset"),0<=a&&(this.Tc=a,this.na(),this.i("strokeDashOffset",b,a)))});t.g(Y,"figure",Y.prototype.Db); -t.defineProperty(Y,{Db:"figure"},function(){return this.pn},function(a){var b=this.pn;if(b!==a){f&&t.j(a,"string",Y,"figure");var c=D.Bi[a];"function"===typeof c?c=a:(c=D.Bi[a.toLowerCase()])||t.l("Unknown Shape.figure: "+a);if(b!==c){if(a=this.Q)a.lj=NaN;this.pn=c;this.Cg=!1;this.Cf();this.i("figure",b,c)}}});t.g(Y,"toArrow",Y.prototype.Om); -t.defineProperty(Y,{Om:"toArrow"},function(){return this.Yn},function(a){var b=this.Yn;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"toArrow");var c=D.yo(a);c instanceof I?c=a:(c=D.yo(a.toLowerCase()))||t.l("Unknown Shape.toArrow: "+a);b!==c&&(this.Yn=c,this.Cg=!1,this.Cf(),Jl(this,c),this.i("toArrow",b,c))}});t.g(Y,"fromArrow",Y.prototype.Sv); -t.defineProperty(Y,{Sv:"fromArrow"},function(){return this.rn},function(a){var b=this.rn;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"fromArrow");var c=D.yo(a);c instanceof I?c=a:(c=D.yo(a.toLowerCase()))||t.l("Unknown Shape.fromArrow: "+a);b!==c&&(this.rn=c,this.Cg=!1,this.Cf(),Jl(this,c),this.i("fromArrow",b,c))}}); -function Jl(a,b){var c=a.h;if(null===c||!c.va.kb){a.ct=Kl;c=Ub;switch(b){case "halfarrowtop":c=Ob;break;case "halftriangletop":c=Ob;break;case "openrighttriangletop":c=Ob;break;case "opentriangletop":c=Ob}"None"!==a.Yn?(a.nf=-1,a.Dj=c):"None"!==a.rn&&(a.nf=0,a.Dj=new H(1-c.x,c.y))}}t.defineProperty(Y,{G:"spot1"},function(){return this.ji},function(a){t.k(a,H,Y,"spot1");var b=this.ji;b.K(a)||(this.ji=a=a.W(),this.Y(),this.i("spot1",b,a))}); -t.defineProperty(Y,{H:"spot2"},function(){return this.ki},function(a){t.k(a,H,Y,"spot2");var b=this.ki;b.K(a)||(this.ki=a=a.W(),this.Y(),this.i("spot2",b,a))});t.defineProperty(Y,{tc:"parameter1"},function(){return this.hr},function(a){var b=this.hr;b!==a&&(this.hr=a,this.Y(),this.i("parameter1",b,a))});t.defineProperty(Y,{Vs:"parameter2"},function(){return this.ir},function(a){var b=this.ir;b!==a&&(this.ir=a,this.Y(),this.i("parameter2",b,a))}); -t.A(Y,{Na:"naturalBounds"},function(){if(null!==this.La)return this.Qc.assign(this.La.Gb),this.Qc;var a=this.ya;return new w(0,0,a.width,a.height)});t.g(Y,"isRectangular",Y.prototype.OH);t.defineProperty(Y,{OH:"isRectangular"},function(){return this.Aq},function(a){var b=this.Aq;b!==a&&(f&&t.j(a,"boolean",Y,"isRectangular"),this.Aq=a,this.Y(),this.i("isRectangular",b,a))});t.g(Y,"pathObject",Y.prototype.kA); -t.defineProperty(Y,{kA:"pathObject"},function(){return this.kr},function(a){var b=this.kr;b!==a&&(f&&t.k(a,Q,Y,"pathObject"),this.kr=a,this.na(),this.i("pathObject",b,a))});t.g(Y,"geometryStretch",Y.prototype.Tv);t.defineProperty(Y,{Tv:"geometryStretch"},function(){return this.qq},function(a){var b=this.qq;b!==a&&(t.nb(a,Q,Y,"geometryStretch"),this.qq=a,this.i("geometryStretch",b,a))});t.g(Y,"interval",Y.prototype.interval); -t.defineProperty(Y,{interval:"interval"},function(){return this.uq},function(a){var b=this.uq;f&&t.o(a,Y,"interval");a=Math.floor(a);b!==a&&0<=a&&(this.uq=a,this.h&&ni(this.h),this.Y(),this.i("interval",b,a))});function ma(){Q.call(this);this.Zd="";this.tb="black";this.Zg="13px sans-serif";this.Fd="start";this.xq=!0;this.Gl=this.Hl=!1;this.Nn=Ll;this.dm=Ml;this.pu=this.Jq=0;this.qn=this.ny=this.oy=null;this.Gn={};this.jq=!1;this.Ze=this.yj=this.Rr=null}t.ea("TextBlock",ma);t.Ja(ma,Q); -ma.prototype.cloneProtected=function(a){Q.prototype.cloneProtected.call(this,a);a.Zd=this.Zd;a.tb=this.tb;a.Zg=this.Zg;a.Fd=this.Fd;a.xq=this.xq;a.Hl=this.Hl;a.Gl=this.Gl;a.dm=this.dm;a.Nn=this.Nn;a.Jq=this.Jq;a.pu=this.pu;a.oy=this.oy;a.ny=this.ny;a.qn=this.qn;a.Gn=this.Gn;a.jq=this.jq;a.Rr=this.Rr;a.yj=this.yj;a.Ze=this.Ze};ma.prototype.toString=function(){return 22m*k*k&&(h=!0);m=e.pi.length;for(k=0;kc&&(n=c);var p=l,l=a,q=g,r=c,s=d,u=0;h?("start"===this.Fd||"left"===this.Fd?u=0:"end"===this.Fd||"right"===this.Fd? -u=r-n:"center"===this.Fd?u=(r-n)/2:t.l("textAlign must be start, end, left, right, or center"),l.fillRect(0+u,q+0.25*s,n,1)):("start"===this.Fd||"left"===this.Fd?u=0:"end"===this.Fd||"right"===this.Fd?u=r:"center"===this.Fd?u=r/2:t.l("textAlign must be start, end, left, right, or center"),l.fillText(p,0+u,q+s-0.25*s),p=s/20|0,this.Hl&&("end"===this.Fd||"right"===this.Fd?u-=n:"center"===this.Fd&&(u-=n/2),l.beginPath(),l.lineWidth=p,l.moveTo(0+u,q+s-0.2*s),l.lineTo(0+u+n,q+s-0.2*s),l.stroke()),this.Gl&& -(l.beginPath(),l.lineWidth=p,q=q+s-s/2.2|0,0!==p%2&&(q+=0.5),l.moveTo(0,q),l.lineTo(0+n,q),l.stroke()));g+=d}}}; -ma.prototype.Js=function(a,b,c,d){var e={},g=0,h=0;if(isNaN(this.ya.width)){g=this.Zd;if(0===g.length)g=0;else if(this.bw){for(var k=h=0,l=!1,m={Hh:0};!l;){var n=Sl(g,k,m);-1===n&&(n=g.length,l=!0);k=Tl(g.substr(k,n-k).replace(/^\s+|\s+$/g,""),this.Zg);k>h&&(h=k);k=m.Hh}g=h}else h=Sl(g,0,{}),0<=h&&(g=g.substr(0,h)),g=k=Tl(g,this.Zg);g=Math.min(g,a/this.scale);g=Math.max(8,g)}else g=this.ya.width;this.fa&&(g=Math.min(g,this.fa.Ce.width),g=Math.max(g,this.fa.Te.width));h=Rl(this,g,e);h=isNaN(this.ya.height)? -Math.min(h,b/this.scale):this.ya.height;if(this.SA===Ol||isNaN(this.ya.width))g=e.Ii,isNaN(this.ya.width)&&(g=Math.max(8,g));g=Math.max(c,g);h=Math.max(d,h);Sa(this.Qc,g,h);Kj(this,0,0,g,h);this.Gn=e};ma.prototype.Gj=function(a,b,c,d){Rj(this,a,b,c,d)}; -function Ql(a,b,c,d){b=b.replace(/^\s+|\s+$/g,"");void 0===c.Ii&&(c.Ii=0);void 0===c.pi&&(c.pi=[]);void 0===c.hm&&(c.hm=[]);var e=0,g,h,k=a.Zg;a.Nn===Pl?(t.rp!==k&&(t.qp.font=k,t.rp=k),g=0,void 0!==t.Fz[k]&&5E3>t.wD?g=t.Fz[k]:(g=t.qp.measureText(t.rD).width,t.Fz[k]=g,t.wD++)):g=0;var l=g;if(a.dm===Nl){c.Hh=1;g=Tl(b,k);if(0===l||g<=d)return c.Ii=g,c.pi.push(c.Ii),c.hm.push(b),new ea(g,nh(a));var m=Ul(b);b=b.substr(m.length);h=Ul(b);for(g=Tl(m+h,k);0d&&1d;){var n=1;g=Tl(m.substr(0,n),k);for(h=0;g<=d;)n++,h=g,g=Tl(m.substr(0,n),k);1===n?(c.pi[l]=g,e=Math.max(e,g)):(c.pi[l]=h,e=Math.max(e,h));n--;1>n&&(n=1);c.hm[l]=m.substr(0,n);l++; -m=m.substr(n)}h=Ul(b);for(g=Tl(m+h,k);0=b?a:a.substr(0,c)} -function Tl(a,b){t.rp!==b&&(t.qp.font=b,t.rp=b);return t.qp.measureText(a).width}function nh(a){if(null!==a.qn)return a.qn;var b=a.Zg;t.rp!==b&&(t.qp.font=b,t.rp=b);var c=0;void 0!==t.Gz[b]&&5E3>t.xD?c=t.Gz[b]:(c=1.3*t.qp.measureText("M").width,t.Gz[b]=c,t.xD++);return a.qn=c}function Sl(a,b,c){void 0===c.Hh&&(c.Hh=0);var d=a.indexOf("\r",b);-1===d&&(d=a.indexOf("\n",b));0<=d&&(c.Hh="\r"===a[d]&&d+1e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.2,0.22);b.H=new H(0.8,0.9);t.v(a);return b},DataTransmission:"Hexagon", -Hexagon:function(a,b,c){var d=D.Sk(6);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;6>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.07,0.25);b.H=new H(0.93,0.75);t.v(a);return b},Heptagon:function(a,b,c){var d=D.Sk(7);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;7>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.2,0.15);b.H=new H(0.8,0.85);t.v(a);return b},Octagon:function(a,b,c){var d=D.Sk(8);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;8>e;e++)a.lineTo(d[e].x* -b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.15,0.15);b.H=new H(0.85,0.85);t.v(a);return b},Nonagon:function(a,b,c){var d=D.Sk(9);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;9>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.17,0.13);b.H=new H(0.82,0.82);t.v(a);return b},Decagon:function(a,b,c){var d=D.Sk(10);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.16,0.16);b.H=new H(0.84,0.84);t.v(a);return b},Dodecagon:function(a, -b,c){var d=D.Sk(12);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.16,0.16);b.H=new H(0.84,0.84);t.v(a);return b},FivePointedStar:function(a,b,c){var d=D.qm(5);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.312,0.383);b.H=new H(0.693,0.765);t.v(a);return b},SixPointedStar:function(a,b,c){var d=D.qm(6);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x* -b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.17,0.251);b.H=new H(0.833,0.755);t.v(a);return b},SevenPointedStar:function(a,b,c){var d=D.qm(7);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;14>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.363,0.361);b.H=new H(0.641,0.709);t.v(a);return b},EightPointedStar:function(a,b,c){var d=D.qm(8);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;16>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.252,0.255);b.H=new H(0.75,0.75);t.v(a); -return b},NinePointedStar:function(a,b,c){var d=D.qm(9);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;18>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.355,0.361);b.H=new H(0.645,0.651);t.v(a);return b},TenPointedStar:function(a,b,c){var d=D.qm(10);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;20>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.281,0.261);b.H=new H(0.723,0.748);t.v(a);return b},FivePointedBurst:function(a,b,c){var d=D.ro(5);a=t.u();J(a,d[0].x*b,d[0].y* -c,!0);for(var e=1;e=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=d*D.sa;var e=t.u();J(e,d,0,!0); -e.lineTo(b-d,0);K(e,b-a,0,b,a,b,d);e.lineTo(b,c-d);K(e,b,c-a,b-a,c,b-d,c);e.lineTo(d,c);K(e,a,c,0,c-a,0,c-d);e.lineTo(0,d);K(e,0,a,a,0,d,0);N(e);b=e.s;1=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=t.u();J(a,d,0,!0);a.lineTo(b-d,0);K(a,b-0,0,b,0,b,d);a.lineTo(b,c-d);K(a,b,c-0,b-0,c,b-d,c);a.lineTo(d,c);K(a,0,c,0,c-0,0,c-d);a.lineTo(0,d);K(a,0,0,0,0,d,0);N(a);b=a.s;b.G=wb;b.H=Ob; -t.v(a);return b},SquareIBeam:function(a,b,c){var d=a?a.tc:0;0===d&&(d=0.2);a=t.u();J(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,d*c);a.lineTo((0.5+d/2)*b,d*c);a.lineTo((0.5+d/2)*b,(1-d)*c);a.lineTo(1*b,(1-d)*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,(1-d)*c);a.lineTo((0.5-d/2)*b,(1-d)*c);a.lineTo((0.5-d/2)*b,d*c);a.lineTo(0,d*c);N(a);b=a.s;t.v(a);return b},Trapezoid:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.2);var d=t.u();J(d,a*b,0,!0);d.lineTo((1-a)*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);b=d.s; -b.G=new H(a,0);b.H=new H(1-a,1);t.v(d);return b},ManualLoop:"ManualOperation",ManualOperation:function(a,b,c){var d=a?a.tc:0;a=t.u();J(a,d,0,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);N(a);b=a.s;b.G=new H(0.1,0);b.H=new H(0.9,1);t.v(a);return b},GenderMale:function(a,b,c){a=t.u();var d=D.sa,e=0.4*d,g=0.4,h=t.M(),k=t.M(),l=t.M(),m=t.M();J(a,(0.5-g)*b,0.5*c,!0);K(a,(0.5-g)*b,(0.5-e)*c,(0.5-e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5, -0.44,l,m,k,h,h);K(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);var n=t.cc(k.x,k.y);D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.56,h,h,k,l,m);var p=t.cc(k.x,k.y);a.lineTo((0.1*n.x+0.855)*b,0.1*n.y*c);a.lineTo(0.85*b,0.1*n.y*c);a.lineTo(0.85*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,(0.1*p.y+0.05*0.9)*c);a.lineTo(p.x*b,p.y*c);K(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);K(a,(0.5+g)*b,(0.5+e)*c,(0.5+e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5-e)* -b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);g=0.35;e=0.35*d;J(a,0.5*b,(0.5-g)*c,!0,!0);K(a,(0.5-e)*b,(0.5-g)*c,(0.5-g)*b,(0.5-e)*c,(0.5-g)*b,0.5*c);K(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);K(a,(0.5+g)*b,(0.5-e)*c,(0.5+e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);J(a,(0.5-g)*b,0.5*c,!0);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);t.B(p);b=a.s;b.G=new H(0.202,0.257);b.H=new H(0.692,0.839);b.fc=Sg;t.v(a);return b},GenderFemale:function(a, -b,c){a=t.u();var d=0.375,e=0,g=-0.125,h=4*(Math.SQRT2-1)/3*d;J(a,(0.525+e)*b,(0.5+d+g)*c,!0);K(a,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+d+e)*b,(0.5+g)*c);K(a,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);K(a,(0.5-h+e)*b,(0.5-d+g)*c,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-d+e)*b,(0.5+g)*c);K(a,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-h+e)*b,(0.5+d+g)*c,(0.475+e)*b,(0.5+d+g)*c);a.lineTo(0.475*b,0.85*c);a.lineTo(0.425*b,0.85*c);a.lineTo(0.425*b,0.9*c);a.lineTo(0.475*b,0.9*c);a.lineTo(0.475* -b,1*c);a.lineTo(0.525*b,1*c);a.lineTo(0.525*b,0.9*c);a.lineTo(0.575*b,0.9*c);a.lineTo(0.575*b,0.85*c);a.lineTo(0.525*b,0.85*c);N(a);d=0.325;e=0;g=-0.125;h=4*(Math.SQRT2-1)/3*d;J(a,(0.5+d+e)*b,(0.5+g)*c,!0,!0);K(a,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+e)*b,(0.5+d+g)*c);K(a,(0.5-h+e)*b,(0.5+d+g)*c,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-d+e)*b,(0.5+g)*c);K(a,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);K(a,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+d+e)*b,(0.5+ -g)*c);J(a,(0.525+e)*b,(0.5+d+g)*c,!0);b=a.s;b.G=new H(0.232,0.136);b.H=new H(0.782,0.611);b.fc=Sg;t.v(a);return b},PlusLine:function(a,b,c){a=t.u();J(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},XLine:function(a,b,c){a=t.u();J(a,0,1*c,!1);a.lineTo(1*b,0);a.moveTo(0,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},AsteriskLine:function(a,b,c){a=t.u();var d=0.2/Math.SQRT2;J(a,d*b,(1-d)*c,!1);a.lineTo((1-d)*b,d*c);a.moveTo(d*b,d*c);a.lineTo((1-d)*b,(1-d)* -c);a.moveTo(0*b,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0*c);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},CircleLine:function(a,b,c){var d=0.5*D.sa;a=t.u();J(a,1*b,0.5*c,!1);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new H(0.146,0.146);b.H=new H(0.853,0.853);b.fc=Sg;t.v(a);return b},Pie:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;J(a,(0.5*Math.SQRT2/2+0.5)*b,(0.5- -0.5*Math.SQRT2/2)*c,!0);K(a,0.7*b,0*c,0.5*b,0*c,0.5*b,0*c);K(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);K(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.5*b,1*c);K(a,(0.5+d+0)*b,1*c,1*b,(0.5+d+0)*c,1*b,0.5*c);a.lineTo(0.5*b,0.5*c);N(a);b=a.s;t.v(a);return b},PiePiece:function(a,b,c){var d=D.sa/Math.SQRT2*0.5,e=Math.SQRT2/2,g=1-Math.SQRT2/2;a=t.u();J(a,b,c,!0);K(a,b,(1-d)*c,(e+d)*b,(g+d)*c,e*b,g*c);a.lineTo(0,c);N(a);b=a.s;t.v(a);return b},StopSign:function(a,b,c){a=1/(Math.SQRT2+2);var d=t.u();J(d,a*b,0,!0); -d.lineTo((1-a)*b,0);d.lineTo(1*b,a*c);d.lineTo(1*b,(1-a)*c);d.lineTo((1-a)*b,1*c);d.lineTo(a*b,1*c);d.lineTo(0,(1-a)*c);d.lineTo(0,a*c);N(d);b=d.s;b.G=new H(a/2,a/2);b.H=new H(1-a/2,1-a/2);t.v(d);return b},LogicImplies:function(a,b,c){var d=a?a.tc:0;0===d&&(d=0.2);a=t.u();J(a,(1-d)*b,0*c,!1);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);b=a.s;b.G=wb;b.H=new H(0.8,0.5);t.v(a);return b},LogicIff:function(a,b,c){var d=a?a.tc:0;0===d&&(d=0.2);a=t.u();J(a,(1-d)*b,0*c,!1); -a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(d*b,0);a.lineTo(0,0.5*c);a.lineTo(d*b,c);b=a.s;b.G=new H(0.2,0);b.H=new H(0.8,0.5);t.v(a);return b},LogicNot:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},LogicAnd:function(a,b,c){a=t.u();J(a,0,1*c,!1);a.lineTo(0.5*b,0);a.lineTo(1*b,1*c);b=a.s;b.G=new H(0.25,0.5);b.H=new H(0.75,1);t.v(a);return b},LogicOr:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1* -b,0);b=a.s;b.G=new H(0.219,0);b.H=new H(0.78,0.409);t.v(a);return b},LogicXor:function(a,b,c){a=t.u();J(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);var d=0.5*D.sa;K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.fc=Sg;t.v(a);return b},LogicTruth:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b}, -LogicFalsity:function(a,b,c){a=t.u();J(a,0,1*c,!1);a.lineTo(1*b,1*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);b=a.s;t.v(a);return b},LogicThereExists:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);b=a.s;t.v(a);return b},LogicForAll:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1*b,0);a.moveTo(0.25*b,0.5*c);a.lineTo(0.75*b,0.5*c);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,0.5);t.v(a);return b}, -LogicIsDefinedAs:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(b,0);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(0,c);a.lineTo(b,c);b=a.s;b.G=new H(0.01,0.01);b.H=new H(0.99,0.49);t.v(a);return b},LogicIntersect:function(a,b,c){var d=0.5*D.sa;a=t.u();J(a,0,1*c,!1);a.lineTo(0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new H(0,0.5);b.H=Ob;t.v(a);return b},LogicUnion:function(a,b,c){var d=0.5*D.sa;a=t.u();J(a,1*b,0,!1);a.lineTo(1*b, -0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);a.lineTo(0,0);b=a.s;b.G=wb;b.H=new H(1,0.5);t.v(a);return b},Arrow:function(a,b,c){var d=a?a.tc:0,e=a?a.Vs:0;0===d&&(d=0.3);0===e&&(e=0.3);a=t.u();J(a,0,(0.5-e/2)*c,!0);a.lineTo((1-d)*b,(0.5-e/2)*c);a.lineTo((1-d)*b,0);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,1*c);a.lineTo((1-d)*b,(0.5+e/2)*c);a.lineTo(0,(0.5+e/2)*c);N(a);b=a.s;b.G=new H(0,0.5-e/2);d=D.Xk(0,0.5+e/2,1,0.5+e/2,1-d,1,1,0.5,t.M());b.H=new H(d.x,d.y); -t.B(d);t.v(a);return b},ISOProcess:"Chevron",Chevron:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.5*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);N(a);b=a.s;t.v(a);return b},DoubleArrow:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.3*b,0.214*c);a.lineTo(0.3*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.3*b,1*c);a.lineTo(0.3*b,0.786*c);a.lineTo(0,1*c);N(a);J(a,0.3*b,0.214*c,!1);a.lineTo(0.3*b,0.786*c);a.Xa(!1);b=a.s;t.v(a);return b},DoubleEndArrow:function(a,b,c){a=t.u(); -J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.3*b,0.7*c);a.lineTo(0.3*b,1*c);a.lineTo(0,0.5*c);a.lineTo(0.3*b,0);a.lineTo(0.3*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);N(a);b=a.s;c=D.Xk(0,0.5,0.3,0,0,0.3,0.3,0.3,t.M());b.G=new H(c.x,c.y);c=D.Xk(0.7,1,1,0.5,0.7,0.7,1,0.7,c);b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},IBeamArrow:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.2*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0,1*c); -a.lineTo(0,0);a.lineTo(0.2*b,0);a.lineTo(0.2*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);N(a);b=a.s;b.G=new H(0,0.3);c=D.Xk(0.7,1,1,0.5,0.7,0.7,1,0.7,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},Pointer:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0);N(a);b=a.s;b.G=new H(0.2,0.35);c=D.Xk(0.2,0.65,1,0.65,0,1,1,0.5,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},RoundedPointer:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0,1*c);K(a,0.5* -b,0.75*c,0.5*b,0.25*c,0,0);N(a);b=a.s;b.G=new H(0.4,0.35);c=D.Xk(0.2,0.65,1,0.65,0,1,1,0.5,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},SplitEndArrow:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0,0.7*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);N(a);b=a.s;b.G=new H(0.2,0.3);c=D.Xk(0.7,1,1,0.5,0.7,0.7,1,0.7,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},MessageToUser:"SquareArrow",SquareArrow:function(a, -b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.7*b,0);N(a);b=a.s;b.G=wb;b.H=new H(0.7,1);t.v(a);return b},Cone1:function(a,b,c){var d=D.sa;a=0.5*d;var e=0.1*d,d=t.u();J(d,0,0.9*c,!0);d.lineTo(0.5*b,0);d.lineTo(1*b,0.9*c);K(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);K(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);N(d);b=d.s;b.G=new H(0.25,0.5);b.H=new H(0.75,0.97);t.v(d);return b},Cone2:function(a,b,c){a=t.u();J(a,0,0.9*c,!0);K(a,(1-0.85/0.9)*b,1*c,0.85/0.9*b,1*c, -1*b,0.9*c);a.lineTo(0.5*b,0);a.lineTo(0,0.9*c);N(a);J(a,0,0.9*c,!1);K(a,(1-0.85/0.9)*b,0.8*c,0.85/0.9*b,0.8*c,1*b,0.9*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.5);b.H=new H(0.75,0.82);t.v(a);return b},Cube1:function(a,b,c){a=t.u();J(a,0.5*b,1*c,!0);a.lineTo(1*b,0.85*c);a.lineTo(1*b,0.15*c);a.lineTo(0.5*b,0*c);a.lineTo(0*b,0.15*c);a.lineTo(0*b,0.85*c);N(a);J(a,0.5*b,1*c,!1);a.lineTo(0.5*b,0.3*c);a.lineTo(0,0.15*c);a.moveTo(0.5*b,0.3*c);a.lineTo(1*b,0.15*c);a.Xa(!1);b=a.s;b.G=new H(0,0.3);b.H=new H(0.5,0.85); -t.v(a);return b},Cube2:function(a,b,c){a=t.u();J(a,0,0.3*c,!0);a.lineTo(0*b,1*c);a.lineTo(0.7*b,c);a.lineTo(1*b,0.7*c);a.lineTo(1*b,0*c);a.lineTo(0.3*b,0*c);N(a);J(a,0,0.3*c,!1);a.lineTo(0.7*b,0.3*c);a.lineTo(1*b,0*c);a.moveTo(0.7*b,0.3*c);a.lineTo(0.7*b,1*c);a.Xa(!1);b=a.s;b.G=new H(0,0.3);b.H=new H(0.7,1);t.v(a);return b},MagneticData:"Cylinder1",Cylinder1:function(a,b,c){var d=D.sa;a=0.5*d;var e=0.1*d,d=t.u();J(d,0,0.1*c,!0);K(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);K(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1* -b,0.1*c);d.lineTo(b,0.9*c);K(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);K(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);d.lineTo(0,0.1*c);J(d,0,0.1*c,!1);K(d,0,(0.1+e)*c,(0.5-a)*b,0.2*c,0.5*b,0.2*c);K(d,(0.5+a)*b,0.2*c,1*b,(0.1+e)*c,1*b,0.1*c);d.Xa(!1);b=d.s;b.G=new H(0,0.2);b.H=new H(1,0.9);t.v(d);return b},Cylinder2:function(a,b,c){var d=D.sa;a=0.5*d;var e=0.1*d,d=t.u();J(d,0,0.9*c,!0);d.lineTo(0,0.1*c);K(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);K(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1*b,0.1*c);d.lineTo(1*b,0.9*c);K(d,1* -b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);K(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);J(d,0,0.9*c,!1);K(d,0,(0.9-e)*c,(0.5-a)*b,0.8*c,0.5*b,0.8*c);K(d,(0.5+a)*b,0.8*c,1*b,(0.9-e)*c,1*b,0.9*c);d.Xa(!1);b=d.s;b.G=new H(0,0.1);b.H=new H(1,0.8);t.v(d);return b},Cylinder3:function(a,b,c){var d=D.sa;a=0.1*d;var e=0.5*d,d=t.u();J(d,0.1*b,0,!0);d.lineTo(0.9*b,0);K(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);K(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);K(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);K(d,0,(0.5- -e)*c,(0.1-a)*b,0,0.1*b,0);J(d,0.1*b,0,!1);K(d,(0.1+a)*b,0,0.2*b,(0.5-e)*c,0.2*b,0.5*c);K(d,0.2*b,(0.5+e)*c,(0.1+a)*b,1*c,0.1*b,1*c);d.Xa(!1);b=d.s;b.G=new H(0.2,0);b.H=new H(0.9,1);t.v(d);return b},DirectData:"Cylinder4",Cylinder4:function(a,b,c){var d=D.sa;a=0.1*d;var e=0.5*d,d=t.u();J(d,0.9*b,0,!0);K(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);K(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);K(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);K(d,0,(0.5-e)*c,(0.1-a)*b,0,0.1*b,0);d.lineTo(0.9*b,0);J(d, -0.9*b,0,!1);K(d,(0.9-a)*b,0,0.8*b,(0.5-e)*c,0.8*b,0.5*c);K(d,0.8*b,(0.5+e)*c,(0.9-a)*b,1*c,0.9*b,1*c);d.Xa(!1);b=d.s;b.G=new H(0.1,0);b.H=new H(0.8,1);t.v(d);return b},Prism1:function(a,b,c){a=t.u();J(a,0.25*b,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(b,0.5*c);a.lineTo(0.5*b,c);a.lineTo(0,c);N(a);J(a,0.25*b,0.25*c,!1);a.lineTo(0.5*b,c);a.Xa(!1);b=a.s;b.G=new H(0.408,0.172);b.H=new H(0.833,0.662);t.v(a);return b},Prism2:function(a,b,c){a=t.u();J(a,0,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c); -a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);N(a);J(a,0,c,!1);a.lineTo(0.25*b,0.5*c);a.lineTo(b,0.25*c);a.moveTo(0,0.25*c);a.lineTo(0.25*b,0.5*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.5);b.H=new H(0.75,0.75);t.v(a);return b},Pyramid1:function(a,b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(b,0.75*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.75*c);N(a);J(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.367);b.H=new H(0.75,0.875);t.v(a);return b},Pyramid2:function(a,b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(b,0.85* -c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.85*c);N(a);J(a,0.5*b,0,!1);a.lineTo(0.5*b,0.7*c);a.lineTo(0,0.85*c);a.moveTo(0.5*b,0.7*c);a.lineTo(1*b,0.85*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.367);b.H=new H(0.75,0.875);t.v(a);return b},Actor:function(a,b,c){var d=D.sa,e=0.2*d,g=0.1*d,h=0.5,k=0.1;a=t.u();J(a,h*b,(k+0.1)*c,!0);K(a,(h-e)*b,(k+0.1)*c,(h-0.2)*b,(k+g)*c,(h-0.2)*b,k*c);K(a,(h-0.2)*b,(k-g)*c,(h-e)*b,(k-0.1)*c,h*b,(k-0.1)*c);K(a,(h+e)*b,(k-0.1)*c,(h+0.2)*b,(k-g)*c,(h+0.2)*b,k*c);K(a,(h+0.2)*b,(k+g)*c, -(h+e)*b,(k+0.1)*c,h*b,(k+0.1)*c);e=0.05;g=d*e;J(a,0.5*b,0.2*c,!0);a.lineTo(0.95*b,0.2*c);h=0.95;k=0.25;K(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);a.lineTo(1*b,0.6*c);a.lineTo(0.85*b,0.6*c);a.lineTo(0.85*b,0.35*c);e=0.025;g=d*e;h=0.825;k=0.35;K(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.8*b,1*c);a.lineTo(0.55*b,1*c);a.lineTo(0.55*b,0.7*c);e=0.05;g=d*e;h=0.5;k=0.7;K(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h-g)*b,(k-e)* -c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.45*b,1*c);a.lineTo(0.2*b,1*c);a.lineTo(0.2*b,0.35*c);e=0.025;g=d*e;h=0.175;k=0.35;K(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.15*b,0.6*c);a.lineTo(0*b,0.6*c);a.lineTo(0*b,0.25*c);e=0.05;g=d*e;h=0.05;k=0.25;K(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);a.lineTo(0.5*b,0.2*c);b=a.s;b.G=new H(0.2,0.2);b.H=new H(0.8,0.65);t.v(a);return b},Card:function(a,b,c){a=t.u();J(a,1*b,0*c,!0);a.lineTo(1* -b,1*c);a.lineTo(0*b,1*c);a.lineTo(0*b,0.2*c);a.lineTo(0.2*b,0*c);N(a);b=a.s;b.G=new H(0,0.2);b.H=Ob;t.v(a);return b},Collate:function(a,b,c){a=t.u();J(a,0.5*b,0.5*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);J(a,0.5*b,0.5*c,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,0.25);t.v(a);return b},CreateRequest:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,0,a* -c,!1);d.lineTo(1*b,a*c);d.moveTo(0,(1-a)*c);d.lineTo(1*b,(1-a)*c);d.Xa(!1);b=d.s;b.G=new H(0,a);b.H=new H(1,1-a);t.v(d);return b},Database:function(a,b,c){a=t.u();var d=D.sa,e=0.5*d,d=0.1*d;J(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);K(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);K(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);K(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);K(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);J(a,1*b,0.1*c,!1);K(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);K(a,(0.5-e)*b,0.2*c,0,(0.1+d)* -c,0,0.1*c);a.moveTo(1*b,0.2*c);K(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);K(a,(0.5-e)*b,0.3*c,0,(0.2+d)*c,0,0.2*c);a.moveTo(1*b,0.3*c);K(a,1*b,(0.3+d)*c,(0.5+e)*b,0.4*c,0.5*b,0.4*c);K(a,(0.5-e)*b,0.4*c,0,(0.3+d)*c,0,0.3*c);a.Xa(!1);b=a.s;b.G=new H(0,0.4);b.H=new H(1,0.9);t.v(a);return b},StoredData:"DataStorage",DataStorage:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0);K(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0,1*c);K(a,0.25*b,0.9*c,0.25*b,0.1*c,0,0);N(a);b=a.s;b.G=new H(0.226,0);b.H=new H(0.81, -1);t.v(a);return b},DiskStorage:function(a,b,c){a=t.u();var d=D.sa,e=0.5*d,d=0.1*d;J(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);K(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);K(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);K(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);K(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);J(a,1*b,0.1*c,!1);K(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);K(a,(0.5-e)*b,0.2*c,0,(0.1+d)*c,0,0.1*c);a.moveTo(1*b,0.2*c);K(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);K(a,(0.5-e)*b,0.3*c,0,(0.2+d)* -c,0,0.2*c);a.Xa(!1);b=a.s;b.G=new H(0,0.3);b.H=new H(1,0.9);t.v(a);return b},Display:function(a,b,c){a=t.u();J(a,0.25*b,0,!0);a.lineTo(0.75*b,0);K(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0.25*b,1*c);a.lineTo(0,0.5*c);N(a);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,1);t.v(a);return b},DividedEvent:function(a,b,c){a=a?a.tc:0;0===a?a=0.2:0.15>a&&(a=0.15);var d=t.u(),e=0.2*D.sa;J(d,0,0.2*c,!0);K(d,0,(0.2-e)*c,(0.2-e)*b,0,0.2*b,0);d.lineTo(0.8*b,0);K(d,(0.8+e)*b,0,1*b,(0.2-e)*c,1*b,0.2*c);d.lineTo(1*b,0.8*c); -K(d,1*b,(0.8+e)*c,(0.8+e)*b,1*c,0.8*b,1*c);d.lineTo(0.2*b,1*c);K(d,(0.2-e)*b,1*c,0,(0.8+e)*c,0,0.8*c);d.lineTo(0,0.2*c);J(d,0,a*c,!1);d.lineTo(1*b,a*c);d.Xa(!1);b=d.s;b.G=new H(0,a);b.H=new H(1,1-a);t.v(d);return b},DividedProcess:function(a,b,c){a=a?a.tc:0;0.1>a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,0,a*c,!1);d.lineTo(1*b,a*c);d.Xa(!1);b=d.s;b.G=new H(0,a);b.H=Ob;t.v(d);return b},Document:function(a,b,c){c/=0.8;a=t.u();J(a,0,0.7*c,!0);a.lineTo(0, -0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);K(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);N(a);b=a.s;b.G=wb;b.H=new H(1,0.6);t.v(a);return b},ExternalOrganization:function(a,b,c){a=a?a.tc:0;0.2>a&&(a=0.2);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,a*b,0,!1);d.lineTo(0,a*c);d.moveTo(1*b,a*c);d.lineTo((1-a)*b,0);d.moveTo(0,(1-a)*c);d.lineTo(a*b,1*c);d.moveTo((1-a)*b,1*c);d.lineTo(1*b,(1-a)*c);d.Xa(!1);b=d.s;b.G=new H(a/2,a/2);b.H=new H(1-a/2,1-a/2);t.v(d);return b},ExternalProcess:function(a, -b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);N(a);J(a,0.1*b,0.4*c,!1);a.lineTo(0.1*b,0.6*c);a.moveTo(0.9*b,0.6*c);a.lineTo(0.9*b,0.4*c);a.moveTo(0.6*b,0.1*c);a.lineTo(0.4*b,0.1*c);a.moveTo(0.4*b,0.9*c);a.lineTo(0.6*b,0.9*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.25);b.H=new H(0.75,0.75);t.v(a);return b},File:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);N(a);J(a,0.75*b,0,!1);a.lineTo(0.75*b,0.25*c); -a.lineTo(1*b,0.25*c);a.Xa(!1);b=a.s;b.G=new H(0,0.25);b.H=Ob;t.v(a);return b},Interrupt:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);J(a,1*b,0.5*c,!1);a.lineTo(1*b,1*c);J(a,1*b,0.5*c,!1);a.lineTo(1*b,0);b=a.s;b.G=new H(0,0.25);b.H=new H(0.5,0.75);t.v(a);return b},InternalStorage:function(a,b,c){var d=a?a.tc:0;a=a?a.Vs:0;0===d&&(d=0.1);0===a&&(a=0.1);var e=t.u();J(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(1*b,1*c);e.lineTo(0,1*c);N(e);J(e,d*b,0,!1);e.lineTo(d* -b,1*c);e.moveTo(0,a*c);e.lineTo(1*b,a*c);e.Xa(!1);b=e.s;b.G=new H(d,a);b.H=Ob;t.v(e);return b},Junction:function(a,b,c){a=t.u();var d=1/Math.SQRT2,e=(1-1/Math.SQRT2)/2,g=0.5*D.sa;J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+g)*c,(0.5+g)*b,1*c,0.5*b,1*c);K(a,(0.5-g)*b,1*c,0,(0.5+g)*c,0,0.5*c);K(a,0,(0.5-g)*c,(0.5-g)*b,0,0.5*b,0);K(a,(0.5+g)*b,0,1*b,(0.5-g)*c,1*b,0.5*c);J(a,(e+d)*b,(e+d)*c,!1);a.lineTo(e*b,e*c);a.moveTo(e*b,(e+d)*c);a.lineTo((e+d)*b,e*c);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b},LinedDocument:function(a, -b,c){c/=0.8;a=t.u();J(a,0,0.7*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);K(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);N(a);J(a,0.1*b,0,!1);a.lineTo(0.1*b,0.75*c);a.Xa(!1);b=a.s;b.G=new H(0.1,0);b.H=new H(1,0.6);t.v(a);return b},LoopLimit:function(a,b,c){a=t.u();J(a,0,1*c,!0);a.lineTo(0,0.25*c);a.lineTo(0.25*b,0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=Ob;t.v(a);return b},SequentialData:"MagneticTape",MagneticTape:function(a,b,c){a=t.u();var d= -0.5*D.sa;J(a,0.5*b,1*c,!0);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,0.9*c,0.6*b,0.9*c);a.lineTo(1*b,0.9*c);a.lineTo(1*b,1*c);a.lineTo(0.5*b,1*c);b=a.s;b.G=new H(0.15,0.15);b.H=new H(0.85,0.8);t.v(a);return b},ManualInput:function(a,b,c){a=t.u();J(a,1*b,0,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.25*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=Ob;t.v(a);return b},MessageFromUser:function(a,b,c){a= -a?a.tc:0;0===a&&(a=0.7);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(a*b,0.5*c);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);b=d.s;b.G=wb;b.H=new H(a,1);t.v(d);return b},MicroformProcessing:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.25);var d=t.u();J(d,0,0,!0);d.lineTo(0.5*b,a*c);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.5*b,(1-a)*c);d.lineTo(0,1*c);N(d);b=d.s;b.G=new H(0,a);b.H=new H(1,1-a);t.v(d);return b},MicroformRecording:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0.25*c);a.lineTo(1*b, -0.15*c);a.lineTo(1*b,0.85*c);a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=new H(1,0.75);t.v(a);return b},MultiDocument:function(a,b,c){c/=0.8;a=t.u();J(a,b,0,!0);a.lineTo(b,0.5*c);K(a,0.96*b,0.47*c,0.93*b,0.45*c,0.9*b,0.44*c);a.lineTo(0.9*b,0.6*c);K(a,0.86*b,0.57*c,0.83*b,0.55*c,0.8*b,0.54*c);a.lineTo(0.8*b,0.7*c);K(a,0.4*b,0.4*c,0.4*b,1*c,0,0.7*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);a.lineTo(0.1*b,0.1*c);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);N(a);J(a,0.1*b,0.2*c, -!1);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.54*c);a.moveTo(0.2*b,0.1*c);a.lineTo(0.9*b,0.1*c);a.lineTo(0.9*b,0.44*c);a.Xa(!1);b=a.s;b.G=new H(0,0.25);b.H=new H(0.8,0.77);t.v(a);return b},MultiProcess:function(a,b,c){a=t.u();J(a,0.1*b,0.1*c,!0);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.8*c);a.lineTo(0.9*b,0.8*c);a.lineTo(0.9*b,0.9*c);a.lineTo(0.8*b,0.9*c);a.lineTo(0.8*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);N(a);J(a,0.2*b,0.1*c,!1);a.lineTo(0.9*b, -0.1*c);a.lineTo(0.9*b,0.8*c);a.moveTo(0.1*b,0.2*c);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.9*c);a.Xa(!1);b=a.s;b.G=new H(0,0.2);b.H=new H(0.8,1);t.v(a);return b},OfflineStorage:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=1-a,e=t.u();J(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(0.5*b,1*c);N(e);J(e,0.5*a*b,a*c,!1);e.lineTo((1-0.5*a)*b,a*c);e.Xa(!1);b=e.s;b.G=new H(d/4+0.5*a,a);b.H=new H(3*d/4+0.5*a,a+0.5*d);t.v(e);return b},OffPageConnector:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1* -b,0.5*c);a.lineTo(0.75*b,1*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=wb;b.H=new H(0.75,1);t.v(a);return b},Or:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);J(a,1*b,0.5*c,!1);a.lineTo(0,0.5*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b},PaperTape:function(a,b,c){c/=0.8;a=t.u();J(a,0,0.7*c,!0);a.lineTo(0, -0.3*c);K(a,0.5*b,0.6*c,0.5*b,0,1*b,0.3);a.lineTo(1*b,0.7*c);K(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);N(a);b=a.s;b.G=new H(0,0.49);b.H=new H(1,0.75);t.v(a);return b},PrimitiveFromCall:function(a,b,c){var d=a?a.tc:0;a=a?a.Vs:0;0===d&&(d=0.1);0===a&&(a=0.3);var e=t.u();J(e,0,0,!0);e.lineTo(1*b,0);e.lineTo((1-a)*b,0.5*c);e.lineTo(1*b,1*c);e.lineTo(0,1*c);N(e);b=e.s;b.G=new H(d,0);b.H=new H(1-a,1);t.v(e);return b},PrimitiveToCall:function(a,b,c){var d=a?a.tc:0;a=a?a.Vs:0;0===d&&(d=0.1);0===a&&(a=0.3);var e= -t.u();J(e,0,0,!0);e.lineTo((1-a)*b,0);e.lineTo(1*b,0.5*c);e.lineTo((1-a)*b,1*c);e.lineTo(0,1*c);N(e);b=e.s;b.G=new H(d,0);b.H=new H(1-a,1);t.v(e);return b},Subroutine:"Procedure",Procedure:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,(1-a)*b,0,!1);d.lineTo((1-a)*b,1*c);d.moveTo(a*b,0);d.lineTo(a*b,1*c);d.Xa(!1);b=d.s;b.G=new H(a,0);b.H=new H(1-a,1);t.v(d);return b},Process:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d= -t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,a*b,0,!1);d.lineTo(a*b,1*c);d.Xa(!1);b=d.s;b.G=new H(a,0);b.H=Ob;t.v(d);return b},Sort:function(a,b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);N(a);J(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.25);b.H=new H(0.75,0.5);t.v(a);return b},Start:function(a,b,c){a=t.u();J(a,0.25*b,0,!0);J(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25* -b,0.5*c,0.25*b,0.5*c);J(a,0.25*b,0,!1);a.lineTo(0.25*b,1*c);a.moveTo(0.75*b,0);a.lineTo(0.75*b,1*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,1);t.v(a);return b},Terminator:function(a,b,c){a=t.u();J(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25*b,0.5*c,0.25*b,0.5*c);b=a.s;b.G=new H(0.23,0);b.H=new H(0.77,1);t.v(a);return b},TransmittalTape:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.75*b,(1-a)* -c);d.lineTo(0,(1-a)*c);N(d);b=d.s;b.G=wb;b.H=new H(1,1-a);t.v(d);return b},AndGate:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0,0,!0);a.lineTo(0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=wb;b.H=new H(0.55,1);t.v(a);return b},Buffer:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=new H(0.5,0.75);t.v(a);return b},Clock:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,1* -b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);J(a,1*b,0.5*c,!1);a.lineTo(1*b,0.5*c);J(a,0.8*b,0.75*c,!1);a.lineTo(0.8*b,0.25*c);a.lineTo(0.6*b,0.25*c);a.lineTo(0.6*b,0.75*c);a.lineTo(0.4*b,0.75*c);a.lineTo(0.4*b,0.25*c);a.lineTo(0.2*b,0.25*c);a.lineTo(0.2*b,0.75*c);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b},Ground:function(a,b,c){a=t.u();J(a,0.5*b,0,!1);a.lineTo(0.5*b,0.4*c); -a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.3*b,0.8*c);a.lineTo(0.7*b,0.8*c);a.moveTo(0.4*b,1*c);a.lineTo(0.6*b,1*c);b=a.s;t.v(a);return b},Inverter:function(a,b,c){a=t.u();var d=0.1*D.sa;J(a,0.8*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.8*b,0.5*c);J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);K(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);K(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);K(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new H(0,0.25); -b.H=new H(0.4,0.75);t.v(a);return b},NandGate:function(a,b,c){a=t.u();var d=D.sa,e=0.5*d,g=0.4*d,d=0.1*d;J(a,0.8*b,0.5*c,!0);K(a,0.8*b,(0.5+g)*c,(0.4+e)*b,1*c,0.4*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.4*b,0);K(a,(0.4+e)*b,0,0.8*b,(0.5-g)*c,0.8*b,0.5*c);J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);K(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);K(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);K(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new H(0,0.05);b.H=new H(0.55, -0.95);t.v(a);return b},NorGate:function(a,b,c){a=t.u();var d=D.sa,e=0.5,g=d*e,h=0,k=0.5;J(a,0.8*b,0.5*c,!0);K(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0,1*c);K(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);K(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;J(a,(h-e)*b,k*c,!0);K(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);K(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);K(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new H(0.2,0.25); -b.H=new H(0.6,0.75);t.v(a);return b},OrGate:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0,0,!0);K(a,(0+d+d)*b,0*c,0.8*b,(0.5-d)*c,1*b,0.5*c);K(a,0.8*b,(0.5+d)*c,(0+d+d)*b,1*c,0,1*c);K(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);N(a);b=a.s;b.G=new H(0.2,0.25);b.H=new H(0.75,0.75);t.v(a);return b},XnorGate:function(a,b,c){a=t.u();var d=D.sa,e=0.5,g=d*e,h=0.2,k=0.5;J(a,0.1*b,0,!1);K(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);J(a,0.8*b,0.5*c,!0);K(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0.2*b,1*c);K(a,0.45*b,0.75*c,0.45* -b,0.25*c,0.2*b,0);K(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;J(a,(h-e)*b,k*c,!0);K(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);K(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);K(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new H(0.4,0.25);b.H=new H(0.65,0.75);t.v(a);return b},XorGate:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0.1*b,0,!1);K(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);J(a,0.2*b,0,!0);K(a,(0.2+ -d)*b,0*c,0.9*b,(0.5-d)*c,1*b,0.5*c);K(a,0.9*b,(0.5+d)*c,(0.2+d)*b,1*c,0.2*b,1*c);K(a,0.45*b,0.75*c,0.45*b,0.25*c,0.2*b,0);N(a);b=a.s;b.G=new H(0.4,0.25);b.H=new H(0.8,0.75);t.v(a);return b},Capacitor:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Resistor:function(a,b,c){a=t.u();J(a,0,0.5*c,!1);a.lineTo(0.1*b,0);a.lineTo(0.2*b,1*c);a.lineTo(0.3*b,0);a.lineTo(0.4*b,1*c);a.lineTo(0.5*b,0);a.lineTo(0.6*b,1*c);a.lineTo(0.7*b,0.5*c);b=a.s;t.v(a); -return b},Inductor:function(a,b,c){a=t.u();var d=0.1*D.sa,e=0.1,g=0.5;J(a,(e-0.5*d)*b,(g+0.1)*c,!1);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.3;g=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);g=e=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.7;g=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)* -b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.9;g=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,(e+0.5*d)*b,(g+0.1)*c);b=a.s;t.v(a);return b},ACvoltageSource:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0*b,0.5*c,!1);K(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);K(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);a.moveTo(0.1*b,0.5*c);K(a,0.5*b,0*c,0.5*b,1*c,0.9*b,0.5*c);b=a.s;b.fc=Sg;t.v(a);return b},DCvoltageSource:function(a,b,c){a=t.u(); -J(a,0,0.75*c,!1);a.lineTo(0,0.25*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Diode:function(a,b,c){a=t.u();J(a,1*b,0,!1);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new H(0,0.25);b.H=new H(0.5,0.75);t.v(a);return b},Wifi:function(a,b,c){var d=b,e=c;b*=0.38;c*=0.6;a=t.u();var g=D.sa,h=0.8*g,k=0.8,l=0,m=0.5,d=(d-b)/2,e=(e-c)/2;J(a,l*b+d,(m+k)*c+e,!0);K(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);K(a,(l-k)*b+d,(m-h)* -c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);K(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);K(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);N(a);h=0.4*g;k=0.4;l=0.2;m=0.5;J(a,l*b+d,(m+k)*c+e,!0);K(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);K(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);K(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);K(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);N(a);h=0.2*g;k=0.2; -m=l=0.5;J(a,(l-k)*b+d,m*c+e,!0);K(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);K(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);K(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);K(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);h=0.4*g;k=0.4;l=0.8;m=0.5;J(a,l*b+d,(m-k)*c+e,!0);K(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);K(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);K(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5* -h)*b+d,m*c+e);K(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);N(a);h=0.8*g;k=0.8;l=1;m=0.5;J(a,l*b+d,(m-k)*c+e,!0);K(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);K(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);K(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5*h)*b+d,m*c+e);K(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);N(a);b=a.s;t.v(a);return b},Email:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,1*c);a.lineTo(0,1* -c);a.lineTo(0,0);N(a);J(a,0,0,!1);a.lineTo(0.5*b,0.6*c);a.lineTo(1*b,0);a.moveTo(0,1*c);a.lineTo(0.45*b,0.54*c);a.moveTo(1*b,1*c);a.lineTo(0.55*b,0.54*c);a.Xa(!1);b=a.s;t.v(a);return b},Ethernet:function(a,b,c){a=t.u();J(a,0.35*b,0,!0);a.lineTo(0.65*b,0);a.lineTo(0.65*b,0.4*c);a.lineTo(0.35*b,0.4*c);a.lineTo(0.35*b,0);N(a);J(a,0.1*b,1*c,!0,!0);a.lineTo(0.4*b,1*c);a.lineTo(0.4*b,0.6*c);a.lineTo(0.1*b,0.6*c);a.lineTo(0.1*b,1*c);N(a);J(a,0.6*b,1*c,!0,!0);a.lineTo(0.9*b,1*c);a.lineTo(0.9*b,0.6*c);a.lineTo(0.6* -b,0.6*c);a.lineTo(0.6*b,1*c);N(a);J(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.5*b,0.4*c);a.moveTo(0.75*b,0.5*c);a.lineTo(0.75*b,0.6*c);a.moveTo(0.25*b,0.5*c);a.lineTo(0.25*b,0.6*c);a.Xa(!1);b=a.s;t.v(a);return b},Power:function(a,b,c){a=t.u();var d=D.sa,e=0.4*d,g=0.4,h=t.M(),k=t.M(),l=t.M(),m=t.M();D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.5,h,h,k,l,m);var n=t.cc(k.x,k.y);J(a,k.x*b,k.y*c,!0);K(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);K(a,(0.5+g)*b,(0.5+e)*c,(0.5+ -e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5-e)*b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);D.si(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);K(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);e=0.3*d;g=0.3;D.si(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);a.lineTo(k.x*b,k.y*c);K(a,m.x*b,m.y*c,l.x*b,l.y*c,(0.5-g)*b,0.5*c);K(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5- -e,0.5+g,0.5,0.5,h,h,k,l,m);K(a,m.x*b,m.y*c,l.x*b,l.y*c,k.x*b,k.y*c);N(a);J(a,0.45*b,0,!0);a.lineTo(0.45*b,0.5*c);a.lineTo(0.55*b,0.5*c);a.lineTo(0.55*b,0);N(a);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);b=a.s;b.G=new H(0.25,0.55);b.H=new H(0.75,0.8);t.v(a);return b},Fallout:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0*b,0.5*c,!0);K(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);K(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);var e= -d=0;J(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.4;e=0;N(a);J(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.2;e=-0.3;N(a);J(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);N(a);b=a.s;b.fc=Sg;t.v(a);return b},IrritationHazard:function(a,b,c){a=t.u();J(a,0.2*b,0*c,!0);a.lineTo(0.5* -b,0.3*c);a.lineTo(0.8*b,0*c);a.lineTo(1*b,0.2*c);a.lineTo(0.7*b,0.5*c);a.lineTo(1*b,0.8*c);a.lineTo(0.8*b,1*c);a.lineTo(0.5*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0*b,0.8*c);a.lineTo(0.3*b,0.5*c);a.lineTo(0*b,0.2*c);N(a);b=a.s;b.G=new H(0.3,0.3);b.H=new H(0.7,0.7);t.v(a);return b},ElectricalHazard:function(a,b,c){a=t.u();J(a,0.37,0*c,!0);a.lineTo(0.5*b,0.11*c);a.lineTo(0.77*b,0.04*c);a.lineTo(0.33*b,0.49*c);a.lineTo(1*b,0.37*c);a.lineTo(0.63*b,0.86*c);a.lineTo(0.77*b,0.91*c);a.lineTo(0.34*b,1*c);a.lineTo(0.34* -b,0.78*c);a.lineTo(0.44*b,0.8*c);a.lineTo(0.65*b,0.56*c);a.lineTo(0*b,0.68*c);N(a);b=a.s;t.v(a);return b},FireHazard:function(a,b,c){a=t.u();J(a,0.1*b,1*c,!0);K(a,-0.25*b,0.63*c,0.45*b,0.44*c,0.29*b,0*c);K(a,0.48*b,0.17*c,0.54*b,0.35*c,0.51*b,0.42*c);K(a,0.59*b,0.29*c,0.58*b,0.28*c,0.59*b,0.18*c);K(a,0.8*b,0.34*c,0.88*b,0.43*c,0.75*b,0.6*c);K(a,0.87*b,0.48*c,0.88*b,0.43*c,0.88*b,0.31*c);K(a,1.17*b,0.76*c,0.82*b,0.8*c,0.9*b,1*c);N(a);b=a.s;b.G=new H(0.05,0.645);b.H=new H(0.884,0.908);t.v(a);return b}, -BpmnActivityLoop:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;J(a,(0.5*Math.SQRT2/2+0.5)*b,(1-(0.5-0.5*Math.SQRT2/2))*c,!1);K(a,1*b,0.7*c,1*b,0.5*c,1*b,0.5*c);K(a,1*b,(0.5-d+0)*c,(0.5+d+0)*b,0*c,0.5*b,0*c);K(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);K(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.35*b,0.98*c);a.moveTo(0.35*b,0.8*c);a.lineTo(0.35*b,1*c);a.lineTo(0.15*b,1*c);b=a.s;t.v(a);return b},BpmnActivityParallel:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(0.5*b,0);a.lineTo(0.5* -b,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivitySequential:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0,1*c);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivityAdHoc:function(a,b,c){a=t.u();J(a,0,0,!1);J(a,1*b,1*c,!1);J(a,0,0.5*c,!1);K(a,0.2*b,0.35*c,0.3*b,0.35*c,0.5*b,0.5*c);K(a,0.7*b,0.65*c,0.8*b,0.65*c,1*b,0.5*c);b=a.s;t.v(a);return b},BpmnActivityCompensation:function(a,b,c){a=t.u();J(a,0,0.5*c,!0);a.lineTo(0.5* -b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(0.5*b,1*c);N(a);b=a.s;t.v(a);return b},BpmnTaskMessage:function(a,b,c){a=t.u();J(a,0,0.2*c,!0);a.lineTo(1*b,0.2*c);a.lineTo(1*b,0.8*c);a.lineTo(0,0.8*c);a.lineTo(0,0.8*c);N(a);J(a,0,0.2*c,!1);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,0.2*c);a.Xa(!1);b=a.s;t.v(a);return b},BpmnTaskScript:function(a,b,c){a=t.u();J(a,0.7*b,1*c,!0);a.lineTo(0.3*b,1*c);K(a,0.6*b,0.5*c,0,0.5*c,0.3*b,0);a.lineTo(0.7*b,0);K(a,0.4*b,0.5*c, -1*b,0.5*c,0.7*b,1*c);N(a);J(a,0.45*b,0.73*c,!1);a.lineTo(0.7*b,0.73*c);a.moveTo(0.38*b,0.5*c);a.lineTo(0.63*b,0.5*c);a.moveTo(0.31*b,0.27*c);a.lineTo(0.56*b,0.27*c);a.Xa(!1);b=a.s;t.v(a);return b},BpmnTaskUser:function(a,b,c){a=t.u();J(a,0,0,!1);J(a,0.335*b,(1-0.555)*c,!0);a.lineTo(0.335*b,0.595*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.665*b,(1-0.555)*c);K(a,0.88*b,0.46*c,0.98*b,0.54*c,1*b,0.68*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.68*c);K(a,0.02*b,0.54*c,0.12*b,0.46*c,0.335*b,(1-0.555)* -c);a.lineTo(0.365*b,0.405*c);var d=0.5-0.285,e=Math.PI/4,g=4*(1-Math.cos(e))/(3*Math.sin(e)),e=g*d,g=g*d;K(a,(0.5-(e+d)/2)*b,(d+(d+g)/2)*c,(0.5-d)*b,(d+g)*c,(0.5-d)*b,d*c);K(a,(0.5-d)*b,(d-g)*c,(0.5-e)*b,(d-d)*c,0.5*b,(d-d)*c);K(a,(0.5+e)*b,(d-d)*c,(0.5+d)*b,(d-g)*c,(0.5+d)*b,d*c);K(a,(0.5+d)*b,(d+g)*c,(0.5+(e+d)/2)*b,(d+(d+g)/2)*c,0.635*b,0.405*c);a.lineTo(0.635*b,0.405*c);a.lineTo(0.665*b,(1-0.555)*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.335*b,0.595*c);J(a,0.2*b,1*c,!1);a.lineTo(0.2*b,0.8*c);J(a, -0.8*b,1*c,!1);a.lineTo(0.8*b,0.8*c);b=a.s;t.v(a);return b},BpmnEventConditional:function(a,b,c){a=t.u();J(a,0.1*b,0,!0);a.lineTo(0.9*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);N(a);J(a,0.2*b,0.2*c,!1);a.lineTo(0.8*b,0.2*c);a.moveTo(0.2*b,0.4*c);a.lineTo(0.8*b,0.4*c);a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.2*b,0.8*c);a.lineTo(0.8*b,0.8*c);a.Xa(!1);b=a.s;t.v(a);return b},BpmnEventError:function(a,b,c){a=t.u();J(a,0,1*c,!0);a.lineTo(0.33*b,0);a.lineTo(0.66*b,0.5*c);a.lineTo(1*b,0);a.lineTo(0.66* -b,1*c);a.lineTo(0.33*b,0.5*c);N(a);b=a.s;t.v(a);return b},BpmnEventEscalation:function(a,b,c){a=t.u();J(a,0,0,!1);J(a,1*b,1*c,!1);J(a,0.1*b,1*c,!0);a.lineTo(0.5*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.5*b,0.5*c);N(a);b=a.s;t.v(a);return b},BpmnEventTimer:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);J(a,0.5*b,0,!1);a.lineTo(0.5*b,0.15* -c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0.85*c);a.moveTo(0,0.5*c);a.lineTo(0.15*b,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(0.85*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.58*b,0.1*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.78*b,0.54*c);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b}};for(var Vl in D.Bi)D.Bi[Vl.toLowerCase()]=Vl; -D.sv={"":"",Standard:"F1 m 0,0 l 8,4 -8,4 2,-4 z",Backward:"F1 m 8,0 l -2,4 2,4 -8,-4 z",Triangle:"F1 m 0,0 l 8,4.62 -8,4.62 z",BackwardTriangle:"F1 m 8,4 l 0,4 -8,-4 8,-4 0,4 z",Boomerang:"F1 m 0,0 l 8,4 -8,4 4,-4 -4,-4 z",BackwardBoomerang:"F1 m 8,0 l -8,4 8,4 -4,-4 4,-4 z",SidewaysV:"m 0,0 l 8,4 -8,4 0,-1 6,-3 -6,-3 0,-1 z",BackwardV:"m 8,0 l -8,4 8,4 0,-1 -6,-3 6,-3 0,-1 z",OpenTriangle:"m 0,0 l 8,4 -8,4",BackwardOpenTriangle:"m 8,0 l -8,4 8,4",OpenTriangleLine:"m 0,0 l 8,4 -8,4 m 8.5,0 l 0,-8", -BackwardOpenTriangleLine:"m 8,0 l -8,4 8,4 m -8.5,0 l 0,-8",OpenTriangleTop:"m 0,0 l 8,4 m 0,4",BackwardOpenTriangleTop:"m 8,0 l -8,4 m 0,4",OpenTriangleBottom:"m 0,8 l 8,-4",BackwardOpenTriangleBottom:"m 0,4 l 8,4",HalfTriangleTop:"F1 m 0,0 l 0,4 8,0 z m 0,8",BackwardHalfTriangleTop:"F1 m 8,0 l 0,4 -8,0 z m 0,8",HalfTriangleBottom:"F1 m 0,4 l 0,4 8,-4 z",BackwardHalfTriangleBottom:"F1 m 8,4 l 0,4 -8,-4 z",ForwardSemiCircle:"m 4,0 b 270 180 0 4 4",BackwardSemiCircle:"m 4,8 b 90 180 0 -4 4",Feather:"m 0,0 l 3,4 -3,4", -BackwardFeather:"m 3,0 l -3,4 3,4",DoubleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardDoubleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4",TripleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardTripleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4 m 3,-8 l -3,4 3,4",ForwardSlash:"m 0,8 l 5,-8",BackSlash:"m 0,0 l 5,8",DoubleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8",DoubleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8",TripleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8 m -2,8 l 4,-8", -TripleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8 m -2,-8 l 4,8",Fork:"m 0,4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4",LineFork:"m 0,0 l 0,8 m 0,-4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardLineFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4 m 8,-8 l 0,8",CircleFork:"F1 m 6,4 b 0 360 -3 0 3 z m 0,0 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4",BackwardCircleFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 6,0 b 0 360 -3 0 3",CircleLineFork:"F1 m 6,4 b 0 360 -3 0 3 z m 1,-4 l 0,8 m 0,-4 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4", -BackwardCircleLineFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 0,-4 l 0,8 m 7,-4 b 0 360 -3 0 3",Circle:"F1 m 8,4 b 0 360 -4 0 4 z",Block:"F1 m 0,0 l 0,8 8,0 0,-8 z",StretchedDiamond:"F1 m 0,3 l 5,-3 5,3 -5,3 -5,-3 z",Diamond:"F1 m 0,4 l 4,-4 4,4 -4,4 -4,-4 z",Chevron:"F1 m 0,0 l 5,0 3,4 -3,4 -5,0 3,-4 -3,-4 z",StretchedChevron:"F1 m 0,0 l 8,0 3,4 -3,4 -8,0 3,-4 -3,-4 z",NormalArrow:"F1 m 0,2 l 4,0 0,-2 4,4 -4,4 0,-2 -4,0 z",X:"m 0,0 l 8,8 m 0,-8 l -8,8",TailedNormalArrow:"F1 m 0,0 l 2,0 1,2 3,0 0,-2 2,4 -2,4 0,-2 -3,0 -1,2 -2,0 1,-4 -1,-4 z", -DoubleTriangle:"F1 m 0,0 l 4,4 -4,4 0,-8 z m 4,0 l 4,4 -4,4 0,-8 z",BigEndArrow:"F1 m 0,0 l 5,2 0,-2 3,4 -3,4 0,-2 -5,2 0,-8 z",ConcaveTailArrow:"F1 m 0,2 h 4 v -2 l 4,4 -4,4 v -2 h -4 l 2,-2 -2,-2 z",RoundedTriangle:"F1 m 0,1 a 1,1 0 0 1 1,-1 l 7,3 a 0.5,1 0 0 1 0,2 l -7,3 a 1,1 0 0 1 -1,-1 l 0,-6 z",SimpleArrow:"F1 m 1,2 l -1,-2 2,0 1,2 -1,2 -2,0 1,-2 5,0 0,-2 2,2 -2,2 0,-2 z",AccelerationArrow:"F1 m 0,0 l 0,8 0.2,0 0,-8 -0.2,0 z m 2,0 l 0,8 1,0 0,-8 -1,0 z m 3,0 l 2,0 2,4 -2,4 -2,0 0,-8 z",BoxArrow:"F1 m 0,0 l 4,0 0,2 2,0 0,-2 2,4 -2,4 0,-2 -2,0 0,2 -4,0 0,-8 z", -TriangleLine:"F1 m 8,4 l -8,-4 0,8 8,-4 z m 0.5,4 l 0,-8",CircleEndedArrow:"F1 m 10,4 l -2,-3 0,2 -2,0 0,2 2,0 0,2 2,-3 z m -4,0 b 0 360 -3 0 3 z",DynamicWidthArrow:"F1 m 0,3 l 2,0 2,-1 2,-2 2,4 -2,4 -2,-2 -2,-1 -2,0 0,-2 z",EquilibriumArrow:"m 0,3 l 8,0 -3,-3 m 3,5 l -8,0 3,3",FastForward:"F1 m 0,0 l 3.5,4 0,-4 3.5,4 0,-4 1,0 0,8 -1,0 0,-4 -3.5,4 0,-4 -3.5,4 0,-8 z",Kite:"F1 m 0,4 l 2,-4 6,4 -6,4 -2,-4 z",HalfArrowTop:"F1 m 0,0 l 4,4 4,0 -8,-4 z m 0,8",HalfArrowBottom:"F1 m 0,8 l 4,-4 4,0 -8,4 z", -OpposingDirectionDoubleArrow:"F1 m 0,4 l 2,-4 0,2 4,0 0,-2 2,4 -2,4 0,-2 -4,0 0,2 -2,-4 z",PartialDoubleTriangle:"F1 m 0,0 4,3 0,-3 4,4 -4,4 0,-3 -4,3 0,-8 z",LineCircle:"F1 m 0,0 l 0,8 m 7 -4 b 0 360 -3 0 3 z",DoubleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",TripleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",CircleLine:"F1 m 6 4 b 0 360 -3 0 3 z m 1,-4 l 0,8",DiamondCircle:"F1 m 8,4 l -4,4 -4,-4 4,-4 4,4 m 8,0 b 0 360 -4 0 4 z",PlusCircle:"F1 m 8,4 b 0 360 -4 0 4 l -8 0 z m -4 -4 l 0 8", -OpenRightTriangleTop:"m 8,0 l 0,4 -8,0 m 0,4",OpenRightTriangleBottom:"m 8,8 l 0,-4 -8,0",Line:"m 0,0 l 0,8",DoubleLine:"m 0,0 l 0,8 m 2,0 l 0,-8",TripleLine:"m 0,0 l 0,8 m 2,0 l 0,-8 m 2,0 l 0,8",PentagonArrow:"F1 m 8,4 l -4,-4 -4,0 0,8 4,0 4,-4 z",None:""};D.mA={};D.tv={};D.yo=function(a){if(D.sv){for(var b in D.sv){var c=Qc(D.sv[b],!1);D.tv[b]=c;b.toLowerCase()!==b&&(D.tv[b.toLowerCase()]=b)}D.sv=void 0}return D.tv[a]};Y.FigureGenerators=D.Bi;Y.ArrowheadGeometries=D.tv; -function B(a){0===arguments.length?y.call(this):y.call(this,a);this.aa=49663;this.Dn=this.Sg="";this.ur=this.rr=this.Dr=this.Hq=null;this.Fr="";this.Kh=this.Er=this.Yl=null;this.tr="";this.Rn=null;this.sr=(new ea(NaN,NaN)).freeze();this.vr="";this.Sn=null;this.Zd="";this.Cn=this.Xp=this.ok=null;this.Yh=(new v(NaN,NaN)).freeze();this.Pq="";this.Bk=null;this.Qq=wb;this.Zq=D.TF;this.Sq=D.SF;this.gq=null;this.Iq=Wl;this.am=(new v(6,6)).freeze();this.$l="gray";this.Zl=4;this.fG=-1;this.cG=new w;this.nj= -null;this.lj=NaN}t.ea("Part",B);t.Ja(B,y);B.prototype.cloneProtected=function(a){y.prototype.cloneProtected.call(this,a);a.aa=this.aa&-4097|49152;a.Sg=this.Sg;a.Dn=this.Dn;a.Hq=this.Hq;a.Dr=this.Dr;a.rr=this.rr;a.ur=this.ur;a.Fr=this.Fr;a.Er=this.Er;a.Kh=null;a.tr=this.tr;a.sr.assign(this.sr);a.vr=this.vr;a.Zd=this.Zd;a.Xp=this.Xp;a.Yh.assign(this.Yh);a.Pq=this.Pq;a.Qq=this.Qq.W();a.Zq=this.Zq.W();a.Sq=this.Sq.W();a.gq=this.gq;a.Iq=this.Iq;a.am.assign(this.am);a.$l=this.$l;a.Zl=this.Zl}; -B.prototype.uh=function(a){y.prototype.uh.call(this,a);Tj(a);a.Yl=null;a.Rn=null;a.Sn=null;a.Bk=null;a.nj=null};B.prototype.toString=function(){var a=t.Gg(Object.getPrototypeOf(this))+"#"+t.jc(this);this.data&&(a+="("+vd(this.data)+")");return a};B.LayoutNone=0;var Di;B.LayoutAdded=Di=1;var Ii;B.LayoutRemoved=Ii=2;var Dh;B.LayoutShown=Dh=4;var Eh;B.LayoutHidden=Eh=8;B.LayoutNodeSized=16;var $i;B.LayoutGroupLayout=$i=32;B.LayoutNodeReplaced=64;var Wl;B.LayoutStandard=Wl=Di|Ii|Dh|Eh|16|$i|64; -B.prototype.Im=function(a,b,c,d,e,g,h){var k=this.h;null!==k&&(a===td&&"elements"===b?e instanceof y&&Ei(e,function(a){Fi(k,a)}):a===ud&&"elements"===b&&e instanceof y&&Ei(e,function(a){Hi(k,a)}),k.Mc(a,b,c,d,e,g,h))};B.prototype.updateTargetBindings=B.prototype.Eb=function(a){y.prototype.Eb.call(this,a);if(null!==this.data)for(a=this.elements;a.next();){var b=a.value;b instanceof y&&Ei(b,function(a){null!==a.data&&a.Eb()})}};t.A(B,{nv:"adornments"},function(){return null===this.Kh?t.Pg:this.Kh.m}); -B.prototype.findAdornment=B.prototype.xo=function(a){f&&t.j(a,"string",B,"findAdornment:category");var b=this.Kh;return null===b?null:b.wa(a)};B.prototype.addAdornment=B.prototype.Jk=function(a,b){if(null!==b){f&&(t.j(a,"string",B,"addAdornment:category"),t.k(b,Fe,B,"addAdornment:ad"));var c=null,d=this.Kh;null!==d&&(c=d.wa(a));if(c!==b){if(null!==c){var e=c.h;null!==e&&e.remove(c)}null===d&&(this.Kh=d=new ia("string",Fe));b.Sg!==a&&(b.Hc=a);d.add(a,b);c=this.h;null!==c&&(c.add(b),b.data=this.data)}}}; -B.prototype.removeAdornment=B.prototype.fl=function(a){f&&t.j(a,"string",B,"removeAdornment:category");var b=this.Kh;if(null!==b){var c=b.wa(a);if(null!==c){var d=c.h;null!==d&&d.remove(c)}b.remove(a);0===b.count&&(this.Kh=null)}};B.prototype.clearAdornments=B.prototype.ve=function(){var a=this.Kh;if(null!==a){for(var b=t.yb(),a=a.m;a.next();)b.push(a.key);for(var a=b.length,c=0;c=c.mE)){this.aa^=4096;var d=!1;if(null!==c){d=c.xb;c.xb=!0;var e=c.selection;e.Pa();a?e.add(this):e.remove(this);e.freeze()}this.i("isSelected",b,a);Yl(this);a=this.$E;null!==a&&a(this);null!==c&&(c.Gf(),c.xb=d)}}});t.g(B,"isShadowed",B.prototype.Gi); -t.defineProperty(B,{Gi:"isShadowed"},function(){return 0!==(this.aa&8192)},function(a){var b=0!==(this.aa&8192);b!==a&&(f&&t.j(a,"boolean",B,"isShadowed"),this.aa^=8192,this.i("isShadowed",b,a),this.na())});function ui(a){return 0!==(a.aa&32768)}function Zl(a,b){a.aa=b?a.aa|32768:a.aa&-32769}function Vj(a,b){a.aa=b?a.aa|65536:a.aa&-65537}function yh(a){return 0!==(a.aa&131072)}B.prototype.Hf=function(a){this.aa=a?this.aa|131072:this.aa&-131073};t.g(B,"selectionObjectName",B.prototype.vw); -t.defineProperty(B,{vw:"selectionObjectName"},function(){return this.Fr},function(a){var b=this.Fr;b!==a&&(f&&t.j(a,"string",B,"selectionObjectName"),this.Fr=a,this.Yl=null,this.i("selectionObjectName",b,a))});t.g(B,"selectionAdornmentTemplate",B.prototype.ZE);t.defineProperty(B,{ZE:"selectionAdornmentTemplate"},function(){return this.Dr},function(a){var b=this.Dr;b!==a&&(f&&t.k(a,Fe,B,"selectionAdornmentTemplate"),this instanceof X&&(a.type=pg),this.Dr=a,this.i("selectionAdornmentTemplate",b,a))}); -t.A(B,{dt:"selectionObject"},function(){if(null===this.Yl){var a=this.vw;null!==a&&""!==a?(a=this.de(a),this.Yl=null!==a?a:this):this instanceof X?(a=this.path,this.Yl=null!==a?a:this):this.Yl=this}return this.Yl});t.g(B,"selectionChanged",B.prototype.$E);t.defineProperty(B,{$E:"selectionChanged"},function(){return this.Er},function(a){var b=this.Er;b!==a&&(null!==a&&t.j(a,"function",B,"selectionChanged"),this.Er=a,this.i("selectionChanged",b,a))});t.g(B,"resizeAdornmentTemplate",B.prototype.KE); -t.defineProperty(B,{KE:"resizeAdornmentTemplate"},function(){return this.rr},function(a){var b=this.rr;b!==a&&(f&&t.k(a,Fe,B,"resizeAdornmentTemplate"),this.rr=a,this.i("resizeAdornmentTemplate",b,a))});t.g(B,"resizeObjectName",B.prototype.NE);t.defineProperty(B,{NE:"resizeObjectName"},function(){return this.tr},function(a){var b=this.tr;b!==a&&(f&&t.j(a,"string",B,"resizeObjectName"),this.tr=a,this.Rn=null,this.i("resizeObjectName",b,a))}); -t.A(B,{ME:"resizeObject"},function(){if(null===this.Rn){var a=this.NE;null!==a&&""!==a?(a=this.de(a),this.Rn=null!==a?a:this):this.Rn=this}return this.Rn});t.g(B,"resizeCellSize",B.prototype.LE);t.defineProperty(B,{LE:"resizeCellSize"},function(){return this.sr},function(a){var b=this.sr;b.K(a)||(f&&t.k(a,ea,B,"resizeCellSize"),this.sr=a=a.W(),this.i("resizeCellSize",b,a))});t.g(B,"rotateAdornmentTemplate",B.prototype.QE); -t.defineProperty(B,{QE:"rotateAdornmentTemplate"},function(){return this.ur},function(a){var b=this.ur;b!==a&&(f&&t.k(a,Fe,B,"rotateAdornmentTemplate"),this.ur=a,this.i("rotateAdornmentTemplate",b,a))});t.g(B,"rotateObjectName",B.prototype.SE);t.defineProperty(B,{SE:"rotateObjectName"},function(){return this.vr},function(a){var b=this.vr;b!==a&&(f&&t.j(a,"string",B,"rotateObjectName"),this.vr=a,this.Sn=null,this.i("rotateObjectName",b,a))}); -t.A(B,{RE:"rotateObject"},function(){if(null===this.Sn){var a=this.SE;null!==a&&""!==a?(a=this.de(a),this.Sn=null!==a?a:this):this.Sn=this}return this.Sn});t.g(B,"text",B.prototype.text);t.defineProperty(B,{text:"text"},function(){return this.Zd},function(a){var b=this.Zd;b!==a&&(f&&t.j(a,"string",B,"text"),this.Zd=a,this.i("text",b,a))});t.g(B,"containingGroup",B.prototype.ib); -t.defineProperty(B,{ib:"containingGroup"},function(){return this.ok},function(a){if(this.Kd()){var b=this.ok;if(b!==a){f&&null!==a&&t.k(a,V,B,"containingGroup");null===a||this!==a&&!a.Fs(this)||(this===a&&t.l("Cannot make a Group a member of itself: "+this.toString()),t.l("Cannot make a Group indirectly contain itself: "+this.toString()+" already contains "+a.toString()));this.J(Ii);var c=this.h;null!==b?em(b,this):this instanceof V&&null!==c&&c.Hk.remove(this);this.ok=a;null!==a?fm(a,this):this instanceof -V&&null!==c&&c.Hk.add(this);this.J(Di);if(null!==c){var d=this.data,e=c.da;null!==d&&e instanceof P&&e.DA(d,e.Hb(null!==a?a.data:null))}d=this.wz;null!==d&&(e=!0,null!==c&&(e=c.Ra,c.Ra=!0),d(this,b,a),null!==c&&(c.Ra=e));if(this instanceof V)for(c=new la(B),Ee(c,this,!0,0),c=c.m;c.next();)if(d=c.value,d instanceof S)for(d=d.ie;d.next();)e=d.value,Wi(e);if(this instanceof S)for(d=this.ie;d.next();)e=d.value,Wi(e);this.i("containingGroup",b,a);null!==a&&a.zw()}}else t.l("cannot set the Part.containingGroup of a Link or Adornment")}); -function Tj(a){a=a.ib;null!==a&&(a.Y(),null!==a.rb&&a.rb.Y(),a.Ig())}B.prototype.As=function(){var a=this.ok;null!==a&&fm(a,this)};B.prototype.Bs=function(){var a=this.ok;null!==a&&em(a,this)};B.prototype.sm=function(){var a=this.data;if(null!==a){var b=this.h;null!==b&&(b=b.da,null!==b&&b.rw(a))}};t.g(B,"containingGroupChanged",B.prototype.wz); -t.defineProperty(B,{wz:"containingGroupChanged"},function(){return this.Xp},function(a){var b=this.Xp;b!==a&&(null!==a&&t.j(a,"function",B,"containingGroupChanged"),this.Xp=a,this.i("containingGroupChanged",b,a))});B.prototype.findTopLevelPart=function(){return gm(this,this)};function gm(a,b){var c=b.ib;return null!==c?gm(a,c):b instanceof S&&(c=b.ld,null!==c)?gm(a,c):b}t.A(B,{Oo:"isTopLevel"},function(){return null!==this.ib||this instanceof S&&this.wh?!1:!0}); -B.prototype.isMemberOf=B.prototype.Fs=function(a){return a instanceof V?hm(this,this,a):!1};function hm(a,b,c){if(b===c||null===c)return!1;var d=b.ib;return null===d||d!==c&&!hm(a,d,c)?b instanceof S&&(b=b.ld,null!==b)?hm(a,b,c):!1:!0}B.prototype.findCommonContainingGroup=B.prototype.sH=function(a){return im(this,this,a)}; -function im(a,b,c){if(null===b||null===c)return null;var d=b.ib;if(null===d)return null;if(b===c)return d;var e=c.ib;return null===e?null:d===e?e:hm(a,c,d)?d:hm(a,b,e)?e:im(a,d,e)}t.g(B,"layoutConditions",B.prototype.eE);t.defineProperty(B,{eE:"layoutConditions"},function(){return this.Iq},function(a){var b=this.Iq;b!==a&&(f&&t.j(a,"number",B,"layoutConditions"),this.Iq=a,this.i("layoutConditions",b,a))}); -B.prototype.canLayout=function(){if(!this.Vz||!this.ub())return!1;var a=this.layer;return null!==a&&a.kc||this instanceof S&&this.wh?!1:!0};B.prototype.invalidateLayout=B.prototype.J=function(a){void 0===a&&(a=16777215);var b;this.Vz&&0!==(a&this.eE)?(b=this.layer,null!==b&&b.kc||this instanceof S&&this.wh?b=!1:(b=this.h,b=null!==b&&b.va.kb?!1:!0)):b=!1;if(b)if(b=this.ok,null!==b){var c=b.Vb;null!==c?c.J():b.J(a)}else a=this.h,null!==a&&(c=a.Vb,null!==c&&c.J())};t.g(B,"dragComputation",B.prototype.Bz); -t.defineProperty(B,{Bz:"dragComputation"},function(){return this.gq},function(a){var b=this.gq;b!==a&&(null!==a&&t.j(a,"function",B,"dragComputation"),this.gq=a,this.i("dragComputation",b,a))});t.g(B,"shadowOffset",B.prototype.dF);t.defineProperty(B,{dF:"shadowOffset"},function(){return this.am},function(a){var b=this.am;b.K(a)||(f&&t.k(a,v,B,"shadowOffset"),this.am=a=a.W(),this.na(),this.i("shadowOffset",b,a))});t.g(B,"shadowColor",B.prototype.shadowColor); -t.defineProperty(B,{shadowColor:"shadowColor"},function(){return this.$l},function(a){var b=this.$l;b!==a&&(f&&t.j(a,"string",B,"shadowColor"),this.$l=a,this.na(),this.i("shadowColor",b,a))});t.g(B,"shadowBlur",B.prototype.shadowBlur);t.defineProperty(B,{shadowBlur:"shadowBlur"},function(){return this.Zl},function(a){var b=this.Zl;b!==a&&(f&&t.j(a,"number",B,"shadowBlur"),this.Zl=a,this.na(),this.i("shadowBlur",b,a))}); -function Fe(a){0===arguments.length?B.call(this,Vg):B.call(this,a);this.he="Adornment";this.Ga=null;this.aa&=-257;this.Yh=new v(NaN,NaN);this.Lh=new A(w);this.rb=null;this.hy=!1}t.ea("Adornment",Fe);t.Ja(Fe,B);aa=Fe.prototype;aa.toString=function(){var a=this.rh;return"Adornment("+this.Hc+")"+(null!==a?a.toString():"")};aa.bj=function(){return this.Ga&&this.Ga.Q instanceof X?this.Ga.Q.bj():null};aa.rq=function(){return null}; -aa.iw=function(){var a=this.Gc.Q,b=this.Gc;if(a instanceof X&&b instanceof Y){var c=a.path,b=c.La;a.iw();for(var b=c.La,a=this.za,c=a.length,d=0;da&&(a=1);var b=this.h;if(null!==b&&!b.Hd){b.Hd=!0;var c=b.Yc,d=new la(S);d.add(this);qm(this,d,c,a,this.Ac);b.Hd=!1;b.na()}}; -function qm(a,b,c,d,e){if(1a&&(a=2);var b=this.h;if(null!==b&&!b.Hd){b.Hd=!0;var c=b.Yc,d=new la(S);d.add(this);sm(this,d,c,a,this.Ac);b.Hd=!1}};function sm(a,b,c,d,e){a.Ac=!0;for(var g=c?a.Ov():a.Zf();g.next();){var h=g.value;h.sc&&(e||(h.Eg||h.Tb(),h.updateAdornments()),h=h.Jz(a),null!==h&&h!==a&&!b.contains(h)&&(b.add(h),e||(h.na(),h.updateAdornments(),Tj(h),h.J(Dh)),2a&&(a=2),null===c||c.Hd||(c.Hd=!0,b=c.Yc,d=new la(S),d.add(this),sm(this,d,b,a,!1),c.Hd=!1)):(a=1,1>a&&(a=1),null===c||c.Hd||(c.Hd=!0,b=c.Yc,d=new la(S),d.add(this),qm(this,d,b,a,!0),c.Hd=!1)))}}); -t.g(S,"wasTreeExpanded",S.prototype.Pm);t.defineProperty(S,{Pm:"wasTreeExpanded"},function(){return this.$r},function(a){var b=this.$r;b!==a&&(f&&t.j(a,"boolean",S,"wasTreeExpanded"),this.$r=a,this.i("wasTreeExpanded",b,a))});t.g(S,"treeExpandedChanged",S.prototype.AF);t.defineProperty(S,{AF:"treeExpandedChanged"},function(){return this.Vr},function(a){var b=this.Vr;b!==a&&(null!==a&&t.j(a,"function",S,"treeExpandedChanged"),this.Vr=a,this.i("treeExpandedChanged",b,a))});t.g(S,"isTreeLeaf",S.prototype.yh); -t.defineProperty(S,{yh:"isTreeLeaf"},function(){return this.Dq},function(a){var b=this.Dq;b!==a&&(f&&t.j(a,"boolean",S,"isTreeLeaf"),this.Dq=a,this.i("isTreeLeaf",b,a))}); -function X(){B.call(this,pg);this.Lf=null;this.$g="";this.Tf=this.pq=null;this.oh="";this.Ur=null;this.qr=this.pr=this.or=!1;this.Eq=!0;this.Lp=sg;this.Yp=0;this.aq=sg;this.bq=NaN;this.Ul=Ek;this.Kr=0.5;this.gi=this.$e=null;this.qc=(new A(v)).freeze();this.pe=null;this.Eg=!1;this.Ey=null;this.Qy=!1;this.Ym=this.Th=this.La=null;this.Xe=0;this.hn=this.dn=null;this.Lh=new A(w);this.Vy=new v;this.rC=this.pC=null;this.sx=!1;this.T=null}t.ea("Link",X);t.Ja(X,B); -X.prototype.cloneProtected=function(a){B.prototype.cloneProtected.call(this,a);a.$g=this.$g;a.pq=this.pq;a.oh=this.oh;a.Ur=this.Ur;a.or=this.or;a.pr=this.pr;a.qr=this.qr;a.Eq=this.Eq;a.Lp=this.Lp;a.Yp=this.Yp;a.aq=this.aq;a.bq=this.bq;a.Ul=this.Ul;a.Kr=this.Kr};X.prototype.uh=function(a){B.prototype.uh.call(this,a);this.$g=a.$g;this.oh=a.oh;a.gi=null;a.pe=null;a.Tb();a.Ym=this.Ym;a.Xe=this.Xe};var Ek;X.Normal=Ek=t.w(X,"Normal",1);X.Orthogonal=t.w(X,"Orthogonal",2); -X.AvoidsNodes=t.w(X,"AvoidsNodes",6);var tm;X.AvoidsNodesStraight=tm=t.w(X,"AvoidsNodesStraight",7);var sg;X.None=sg=t.w(X,"None",0);var Kg;X.Bezier=Kg=t.w(X,"Bezier",9);var rg;X.JumpGap=rg=t.w(X,"JumpGap",10);var qg;X.JumpOver=qg=t.w(X,"JumpOver",11);var Bk;X.End=Bk=t.w(X,"End",17);var Ck;X.Scale=Ck=t.w(X,"Scale",18);var Dk;X.Stretch=Dk=t.w(X,"Stretch",19);var Kl;X.OrientAlong=Kl=t.w(X,"OrientAlong",21);var um;X.OrientPlus90=um=t.w(X,"OrientPlus90",22);var vm; -X.OrientMinus90=vm=t.w(X,"OrientMinus90",23);var wm;X.OrientOpposite=wm=t.w(X,"OrientOpposite",24);var xm;X.OrientUpright=xm=t.w(X,"OrientUpright",25);var ym;X.OrientPlus90Upright=ym=t.w(X,"OrientPlus90Upright",26);var zm;X.OrientMinus90Upright=zm=t.w(X,"OrientMinus90Upright",27);var Am;X.OrientUpright45=Am=t.w(X,"OrientUpright45",28);X.prototype.Be=function(){this.T={aj:vb,Cj:vb,Zi:NaN,Aj:NaN,Yi:jm,zj:jm,$i:NaN,Bj:NaN}}; -X.prototype.$k=function(){var a=this.ca;if(null!==a&&(ti(a)||ui(a)))return!1;a=this.ga;return null!==a&&(ti(a)||ui(a))?!1:!0};X.prototype.Kd=function(){return!1}; -X.prototype.computeAngle=function(a,b,c){switch(b){default:case sg:a=0;break;case Kl:a=c;break;case um:a=c+90;break;case vm:a=c-90;break;case wm:a=c+180;break;case xm:a=D.Ts(c);90a&&(a-=180);break;case ym:a=D.Ts(c+90);90a&&(a-=180);break;case zm:a=D.Ts(c-90);90a&&(a-=180);break;case Am:a=D.Ts(c);if(45a||225a)return 0;90a&&(a-=180)}return D.Ts(a)};t.g(X,"fromNode",X.prototype.ca); -t.defineProperty(X,{ca:"fromNode"},function(){return this.Lf},function(a){var b=this.Lf;if(b!==a){f&&null!==a&&t.k(a,S,X,"fromNode");var c=this.Wc;null!==b&&(this.Tf!==b&&om(b,this,c),null!==c&&(c.Xd=null),Bm(this),b.J(Ii));this.Lf=a;this.Th=null;this.Tb();var d=this.h;if(null!==d){var e=this.data,g=d.da;if(null!==e)if(g instanceof P){var h=null!==a?a.data:null;g.BA(e,g.Hb(h))}else g instanceof Jd&&(h=null!==a?a.data:null,d.Yc?g.Ch(e,g.Hb(h)):(null!==b&&g.Ch(b.data,void 0),g.Ch(h,g.Hb(null!==this.Tf? -this.Tf.data:null))))}e=this.Wc;g=this.Iz;null!==g&&(h=!0,null!==d&&(h=d.Ra,d.Ra=!0),g(this,c,e),null!==d&&(d.Ra=h));null!==a&&(this.Tf!==a&&nm(a,this,e),null!==e&&(e.Xd=null),Cm(this),a.J(Di));this.i("fromNode",b,a);Wi(this)}});t.g(X,"fromPortId",X.prototype.Af); -t.defineProperty(X,{Af:"fromPortId"},function(){return this.$g},function(a){var b=this.$g;if(b!==a){f&&t.j(a,"string",X,"fromPortId");var c=this.Wc;null!==c&&(c.Xd=null);Bm(this);this.$g=a;var d=this.Wc;null!==d&&(d.Xd=null);var e=this.h;if(null!==e){var g=this.data,h=e.da;null!==g&&h instanceof P&&h.CA(g,a)}c!==d&&(this.Th=null,this.Tb(),g=this.Iz,null!==g&&(h=!0,null!==e&&(h=e.Ra,e.Ra=!0),g(this,c,d),null!==e&&(e.Ra=h)));Cm(this);this.i("fromPortId",b,a)}}); -t.A(X,{Wc:"fromPort"},function(){var a=this.Lf;return null===a?null:a.us(this.$g)});t.g(X,"fromPortChanged",X.prototype.Iz);t.defineProperty(X,{Iz:"fromPortChanged"},function(){return this.pq},function(a){var b=this.pq;b!==a&&(null!==a&&t.j(a,"function",X,"fromPortChanged"),this.pq=a,this.i("fromPortChanged",b,a))});t.g(X,"toNode",X.prototype.ga); -t.defineProperty(X,{ga:"toNode"},function(){return this.Tf},function(a){var b=this.Tf;if(b!==a){f&&null!==a&&t.k(a,S,X,"toNode");var c=this.Qd;null!==b&&(this.Lf!==b&&om(b,this,c),null!==c&&(c.Xd=null),Bm(this),b.J(Ii));this.Tf=a;this.Th=null;this.Tb();var d=this.h;if(null!==d){var e=this.data,g=d.da;if(null!==e)if(g instanceof P){var h=null!==a?a.data:null;g.GA(e,g.Hb(h))}else g instanceof Jd&&(h=null!==a?a.data:null,d.Yc?(null!==b&&g.Ch(b.data,void 0),g.Ch(h,g.Hb(null!==this.Lf?this.Lf.data:null))): -g.Ch(e,g.Hb(h)))}e=this.Qd;g=this.OA;null!==g&&(h=!0,null!==d&&(h=d.Ra,d.Ra=!0),g(this,c,e),null!==d&&(d.Ra=h));null!==a&&(this.Lf!==a&&nm(a,this,e),null!==e&&(e.Xd=null),Cm(this),a.J(Di));this.i("toNode",b,a);Wi(this)}});t.g(X,"toPortId",X.prototype.ng); -t.defineProperty(X,{ng:"toPortId"},function(){return this.oh},function(a){var b=this.oh;if(b!==a){f&&t.j(a,"string",X,"toPortId");var c=this.Qd;null!==c&&(c.Xd=null);Bm(this);this.oh=a;var d=this.Qd;null!==d&&(d.Xd=null);var e=this.h;if(null!==e){var g=this.data,h=e.da;null!==g&&h instanceof P&&h.HA(g,a)}c!==d&&(this.Th=null,this.Tb(),g=this.OA,null!==g&&(h=!0,null!==e&&(h=e.Ra,e.Ra=!0),g(this,c,d),null!==e&&(e.Ra=h)));Cm(this);this.i("toPortId",b,a)}}); -t.A(X,{Qd:"toPort"},function(){var a=this.Tf;return null===a?null:a.us(this.oh)});t.g(X,"toPortChanged",X.prototype.OA);t.defineProperty(X,{OA:"toPortChanged"},function(){return this.Ur},function(a){var b=this.Ur;b!==a&&(null!==a&&t.j(a,"function",X,"toPortChanged"),this.Ur=a,this.i("toPortChanged",b,a))}); -t.defineProperty(X,{fb:"fromSpot"},function(){return null!==this.T?this.T.aj:vb},function(a){null===this.T&&this.Be();var b=this.T.aj;b.K(a)||(f&&t.k(a,H,X,"fromSpot"),a=a.W(),this.T.aj=a,this.i("fromSpot",b,a),this.Tb())}); -t.defineProperty(X,{Rj:"fromEndSegmentLength"},function(){return null!==this.T?this.T.Zi:NaN},function(a){null===this.T&&this.Be();var b=this.T.Zi;b!==a&&(f&&t.j(a,"number",X,"fromEndSegmentLength"),0>a&&t.ia(a,">= 0",X,"fromEndSegmentLength"),this.T.Zi=a,this.i("fromEndSegmentLength",b,a),this.Tb())}); -t.defineProperty(X,{Co:"fromEndSegmentDirection"},function(){return null!==this.T?this.T.Yi:jm},function(a){null===this.T&&this.Be();var b=this.T.Yi;b!==a&&(f&&t.nb(a,S,X,"fromEndSegmentDirection"),this.T.Yi=a,this.i("fromEndSegmentDirection",b,a),this.Tb())});t.defineProperty(X,{Do:"fromShortLength"},function(){return null!==this.T?this.T.$i:NaN},function(a){null===this.T&&this.Be();var b=this.T.$i;b!==a&&(f&&t.j(a,"number",X,"fromShortLength"),this.T.$i=a,this.i("fromShortLength",b,a),this.Tb())}); -t.defineProperty(X,{gb:"toSpot"},function(){return null!==this.T?this.T.Cj:vb},function(a){null===this.T&&this.Be();var b=this.T.Cj;b.K(a)||(f&&t.k(a,H,X,"toSpot"),a=a.W(),this.T.Cj=a,this.i("toSpot",b,a),this.Tb())}); -t.defineProperty(X,{Zj:"toEndSegmentLength"},function(){return null!==this.T?this.T.Aj:NaN},function(a){null===this.T&&this.Be();var b=this.T.Aj;b!==a&&(f&&t.j(a,"number",X,"toEndSegmentLength"),0>a&&t.ia(a,">= 0",X,"toEndSegmentLength"),this.T.Aj=a,this.i("toEndSegmentLength",b,a),this.Tb())}); -t.defineProperty(X,{vp:"toEndSegmentDirection"},function(){return null!==this.T?this.T.zj:jm},function(a){null===this.T&&this.Be();var b=this.T.zj;b!==a&&(f&&t.nb(a,S,X,"toEndSegmentDirection"),this.T.zj=a,this.i("toEndSegmentDirection",b,a),this.Tb())});t.defineProperty(X,{wp:"toShortLength"},function(){return null!==this.T?this.T.Bj:NaN},function(a){null===this.T&&this.Be();var b=this.T.Bj;b!==a&&(f&&t.j(a,"number",X,"toShortLength"),this.T.Bj=a,this.i("toShortLength",b,a),this.Tb())}); -function Wi(a){var b=a.ca,c=a.ga;null!==b&&null!==c?Dm(a,b.sH(c)):Dm(a,null)}function Dm(a,b){var c=a.ok;if(c!==b){null!==c&&em(c,a);a.ok=b;null!==b&&fm(b,a);var d=a.wz;if(null!==d){var e=!0,g=a.h;null!==g&&(e=g.Ra,g.Ra=!0);d(a,c,b);null!==g&&(g.Ra=e)}!a.Eg||a.pC!==c&&a.rC!==c||a.Tb()}}X.prototype.getOtherNode=X.prototype.Jz=function(a){f&&t.k(a,S,X,"getOtherNode:node");var b=this.ca;return a===b?this.ga:b}; -X.prototype.getOtherPort=function(a){f&&t.k(a,Q,X,"getOtherPort:port");var b=this.Wc;return a===b?this.Qd:b};t.A(X,{fJ:"isLabeledLink"},function(){return null===this.$e?!1:0=d&&(l=d-1),k=this.n(l-1),g=this.n(l),D.oo(e.x,e.y,h.x,h.y,k.x,k.y,g.x,g.y,0.5,a),b=Math.min(g.x,b),c=Math.min(g.y,c),e=g;else for(e=this.n(0),g=this.n(1),b=Math.min(e.x,g.x),c=Math.min(e.y,g.y),a.q(e.x,e.y,0,0),a.Mi(g),l=2;lc&&(c=-c)):D.Fa(c.y,d.y)?(c=d.x-c.x,0>c&&(c=-c)):c=Math.sqrt(c.Mj(d)),g.push(c),e+=c;for(d=h=c=0;ce/2)break;c+=d;h++}t.xa(g);b=this.n(h);g=this.n(h+1);b.x===g.x?b.y>g.y?a.q(b.x,b.y-(e/2-c)):a.q(b.x,b.y+(e/2-c)):b.y===g.y?b.x>g.x?a.q(b.x-(e/2-c),b.y):a.q(b.x+(e/2-c),b.y):(e=(e/2-c)/d,a.q(b.x+e*(g.x-b.x),b.y+e*(g.y-b.y)));return a};t.A(X,{pE:"midAngle"},function(){this.updateRoute();return this.computeMidAngle()}); -X.prototype.computeMidAngle=function(){var a=this.ka;if(2>a)return NaN;if(this.computeCurve()===Kg&&4<=a&&!this.Ub){var b=(a-1)/3|0,c=3*(b/2|0);if(1===b%2){var c=Math.floor(c),a=this.n(c),b=this.n(c+1),d=this.n(c+2),c=this.n(c+3);return D.QG(a.x,a.y,b.x,b.y,d.x,d.y,c.x,c.y)}if(0e?a.wi(b):b.wi(d)};t.g(X,"points",X.prototype.points); -t.defineProperty(X,{points:"points"},function(){return this.qc},function(a){f&&(Array.isArray(a)||a instanceof A||t.l("Link.points value is not an instance of List or Array"));var b=this.qc;if(b!==a){if(Array.isArray(a)){for(var c=0===a.length%2,d=0;dp&&(u-=180));0>u?u+=360:360<=u&&(u-=360);k&&(x+=Math.abs(p));0===u?r=x:90===u?s=x:180===u?r=-x:270===u?s=-x:(r=x*Math.cos(u*Math.PI/180),s=x*Math.sin(u*Math.PI/180));if(g.jd()&&k){var E=c.$a(Fb,t.M()),F=t.cc(E.x+1E3*r,E.y+1E3*s);this.getLinkPointFromPoint(b,c,E,F,!0,q);t.B(E);t.B(F)}}var x=this.getLinkPoint(d,e,h,!1,l,b,c),G=0,L=0,M=0;if(l||h!==ub||k)E=this.computeEndSegmentLength(d,e,h, -!1),M=this.getLinkDirection(d,e,x,h,!1,l,b,c),k&&(M+=l?0:30,0>p&&(M+=180)),0>M?M+=360:360<=M&&(M-=360),k&&(E+=Math.abs(p)),0===M?G=E:90===M?L=E:180===M?G=-E:270===M?L=-E:(G=E*Math.cos(M*Math.PI/180),L=E*Math.sin(M*Math.PI/180)),h.jd()&&k&&(E=e.$a(Fb,t.M()),F=t.cc(E.x+1E3*G,E.y+1E3*L),this.getLinkPointFromPoint(d,e,E,F,!1,x),t.B(E),t.B(F));e=q;if(l||g!==ub||k)e=new v(q.x+r,q.y+s);c=x;if(l||h!==ub||k)c=new v(x.x+G,x.y+L);!n&&!l&&g.jd()&&3k&&(m=-m),r=(0>h?-1:1)*m+q,s=l*(r-q)+u),q=a.x+2*g/3,u=a.y+2*h/3,x=q,G=u,D.I(h,0)?G=0h?-1:1)*m+q,G=l*(x-q)+u),this.po(),this.qh(a),this.Kk(r,s),this.Kk(x,G),this.qh(n),this.of(0,this.getLinkPoint(b,c,ub,!0,!1,d,e)),this.of(3,this.getLinkPoint(d,e,ub,!1,!1,b,c))):(a=d,d=this.getLinkPoint(b,c,ub,!0,!1,a,e),e=this.getLinkPoint(a, -e,ub,!1,!1,b,c),this.hasCurviness()?(h=e.x-d.x,b=e.y-d.y,c=this.computeCurviness(),a=d.x+h/2,n=d.y+b/2,g=a,k=n,D.I(b,0)?k=0c&&(g=-g),g=(0>b?-1:1)*g+a,k=h*(g-a)+n),this.qh(d),this.Kk(g,k)):this.qh(d),this.qh(e)));return!0};function Jm(a,b){Math.abs(b.x-a.x)>Math.abs(b.y-a.y)?(b.x=b.x>=a.x?a.x+9E9:a.x-9E9,b.y=a.y):(b.y=b.y>=a.y?a.y+9E9:a.y-9E9,b.x=a.x);return b} -X.prototype.getLinkPointFromPoint=function(a,b,c,d,e,g){void 0===g&&(g=new v);if(null===a||null===b)return g.assign(c),g;a.ub()||(e=bm(a),null!==e&&e!==a&&(b=e.port));var h;a=null;if(null===b.fa)e=d.x,d=d.y,h=c.x,c=c.y;else{a=b.fa.$d;e=1/(a.m11*a.m22-a.m12*a.m21);h=a.m22*e;var k=-a.m12*e,l=-a.m21*e,m=a.m11*e,n=e*(a.m21*a.dy-a.m22*a.dx),p=e*(a.m12*a.dx-a.m11*a.dy);e=d.x*h+d.y*l+n;d=d.x*k+d.y*m+p;h=c.x*h+c.y*l+n;c=c.x*k+c.y*m+p}b.Go(e,d,h,c,g);a&&g.transform(a);return g}; -function Km(a,b){var c=b.Xd;null===c&&(c=new Lm,c.port=b,c.Bc=b.Q,b.Xd=c);return Mm(c,a)} -X.prototype.getLinkPoint=function(a,b,c,d,e,g,h,k){void 0===k&&(k=new v);if(c.kd())return b.$a(c,k),k;if(c.No()&&(c=Km(this,b),null!==c)){k.assign(c.Uo);if(e&&this.at===tm){var l=Km(this,h);if(c.pm=m.x&&a.x<=m.x+m.width?k.x=a.x:a.y>=m.y&&a.y<=m.y+m.height&&(k.y=a.y);t.B(c);t.B(l)}}return k}g=b.$a(Fb,t.M());c=null;this.ka>(e?6:2)?(h=d?this.n(1):this.n(this.ka-2),e&&(h=Jm(g,h.copy()))): -(c=t.M(),h=h.$a(Fb,c),e&&(h=Jm(g,h)));this.getLinkPointFromPoint(a,b,g,h,d,k);t.B(g);null!==c&&t.B(c);return k}; -X.prototype.getLinkDirection=function(a,b,c,d,e,g,h,k){a:if(d.kd())c=d.x>d.y?d.x>1-d.y?0:d.x<1-d.y?270:315:d.x1-d.y?90:d.x<1-d.y?180:135:0.5>d.x?225:0.5(g?6:2)?(k=e?this.n(1):this.n(this.ka-2),k=g?Jm(a,k.copy()):c):(d=t.M(),k=k.$a(Fb,d));c=Math.abs(k.x-a.x)>Math.abs(k.y-a.y)?k.x>=a.x?0:180:k.y>= -a.y?90:270;t.B(a);null!==d&&t.B(d)}g=jm;g=e?this.Co:this.vp;g===jm&&(g=e?b.Co:b.vp);switch(g){case km:b=b.Wk();c+=b;360<=c&&(c-=360);break;case jm:case Hj:b=b.Wk();if(0===b)break;45<=b&&135>b?c+=90:135<=b&&225>b?c+=180:225<=b&&315>b&&(c+=270);360<=c&&(c-=360)}return c};X.prototype.computeEndSegmentLength=function(a,b,c,d){if(c.No()&&(a=Km(this,b),null!==a))return a.Lv;a=NaN;a=d?this.Rj:this.Zj;isNaN(a)&&(a=d?b.Rj:b.Zj);isNaN(a)&&(a=10);return a}; -X.prototype.computeSpot=function(a){return a?Hm(this,this.Wc):Im(this,this.Qd)};function Hm(a,b){var c=a.fb;c.zc()&&(void 0===b&&(b=a.Wc),null!==b&&(c=b.fb));return c===vb?ub:c}function Im(a,b){var c=a.gb;c.zc()&&(void 0===b&&(b=a.Qd),null!==b&&(c=b.gb));return c===vb?ub:c}X.prototype.computeOtherPoint=function(a,b){var c=b.$a(Fb),d;d=b.Xd;d=null!==d?Mm(d,this):null;null!==d&&(c=d.Uo);return c};X.prototype.computeShortLength=function(a){return a?Nm(this):Om(this)}; -function Nm(a){var b=a.Do;isNaN(b)&&(a=a.Wc,null!==a&&(b=a.Do));return isNaN(b)?0:b}function Om(a){var b=a.wp;isNaN(b)&&(a=a.Qd,null!==a&&(b=a.wp));return isNaN(b)?0:b} -X.prototype.Pj=function(a,b,c,d,e,g){if(!1===this.mf)return!1;void 0===b&&(b=null);void 0===c&&(c=null);var h=g;void 0===g&&(h=t.Og(),h.reset());h.multiply(this.transform);if(this.om(a,h))return Bl(this,b,c,e),void 0===g&&t.Ne(h),!0;if(this.Bf(a,h)){var k=!1;if(!this.ug)for(var l=this.za.length;l--;){var m=this.za.p[l];if(m.visible||m===this.Zb){var n=m.ua,p=this.Na;if(!(n.x>p.width||n.y>p.height||0>n.x+n.width||0>n.y+n.height)){n=t.Og();n.set(h);if(m instanceof y)k=m.Pj(a,b,c,d,e,n);else if(this.path=== -m){var k=m,q=a,r=d,p=n;if(!1===k.mf)k=!1;else if(p.multiply(k.transform),r)b:{var s=q,u=p;if(k.om(s,u))k=!0;else{if(void 0===u&&(u=k.transform,s.Ij(k.ua))){k=!0;break b}var p=s.left,q=s.right,r=s.top,s=s.bottom,x=t.M(),E=t.M(),F=t.M(),G=t.Og();G.set(u);G.vE(k.transform);G.Qz();E.x=q;E.y=r;E.transform(G);x.x=p;x.y=r;x.transform(G);u=!1;Il(k,x,E,F)?u=!0:(x.x=q,x.y=s,x.transform(G),Il(k,x,E,F)?u=!0:(E.x=p,E.y=s,E.transform(G),Il(k,x,E,F)?u=!0:(x.x=p,x.y=r,x.transform(G),Il(k,x,E,F)&&(u=!0))));t.Ne(G); -t.B(x);t.B(E);t.B(F);k=u}}else k=k.om(q,p)}else k=Mj(m,a,d,n);k&&(null!==b&&(m=b(m)),m&&(null===c||c(m))&&e.add(m));t.Ne(n)}}}void 0===g&&t.Ne(h);return k||null!==this.background||null!==this.Ok}void 0===g&&t.Ne(h);return!1};t.A(X,{Ub:"isOrthogonal"},function(){return 2===(this.Ul.value&2)});t.A(X,{Di:"isAvoiding"},function(){return 4===(this.Ul.value&4)});X.prototype.computeCurve=function(){if(null===this.Th){var a=this.Ub;this.Th=this.Wc===this.Qd&&!a}return this.Th?Kg:this.ze}; -X.prototype.computeCorner=function(){if(this.ze===Kg)return 0;var a=this.Ev;if(isNaN(a)||0>a)a=10;return a};X.prototype.computeCurviness=function(){var a=this.os;if(isNaN(a)){var b=this.Xe;if(0!==b){var a=10,c=this.h;null!==c&&(a=c.Vo);c=Math.abs(b);a=a/2+((c-1)/2|0)*a;0===c%2&&(a=-a);0>b&&(a=-a)}else a=10}return a};X.prototype.hasCurviness=function(){return!isNaN(this.os)||0!==this.Xe&&!this.Ub}; -X.prototype.adjustPoints=function(a,b,c,d){var e=this.fo;if(this.Ub){if(e===Ck)return!1;e===Dk&&(e=Bk)}switch(e){case Ck:var g=this.n(a),h=this.n(c);if(!g.K(b)||!h.K(d)){var e=g.x,g=g.y,k=h.x-e,l=h.y-g,m=Math.sqrt(k*k+l*l);if(!D.I(m,0)){var n;D.I(k,0)?n=0>l?-Math.PI/2:Math.PI/2:(n=Math.atan(l/Math.abs(k)),0>k&&(n=Math.PI-n));var h=b.x,p=b.y,k=d.x-h,q=d.y-p,l=Math.sqrt(k*k+q*q);D.I(k,0)?q=0>q?-Math.PI/2:Math.PI/2:(q=Math.atan(q/Math.abs(k)),0>k&&(q=Math.PI-q));m=l/m;n=q-n;this.of(a,b);for(a+=1;al?-Math.PI/2:Math.PI/2:(l=Math.atan(l/Math.abs(k)),0>k&&(l=Math.PI-l)),k=l+n,b*=m,this.U(a,h+b*Math.cos(k),p+b*Math.sin(k)));this.of(c,d)}}return!0;case Dk:g=this.n(a);p=this.n(c);if(!g.K(b)||!p.K(d)){e=g.x;g=g.y;h=p.x;p=p.y;m=(h-e)*(h-e)+(p-g)*(p-g);k=b.x;n=b.y;var l=d.x,q=d.y,r=0,s=1,r=0!==l-k?(q-n)/(l-k):9E9;0!==r&&(s=Math.sqrt(1+1/(r*r)));this.of(a,b);for(a+=1;ab?0:45<=b&&135>b?90:135<=b&&225>b?180:270;d=-45<=d&&45>d?0:45<=d&&135>d?90:135<=d&&225>d?180:270;var h=e.ua.copy(),k=g.ua.copy();if(h.P()&&k.P()){h.Hg(8,8);k.Hg(8,8);h.Mi(a);k.Mi(c);var l,m;if(0===b)if(c.x>a.x||270===d&&c.ya.x||90===d&&c.y>a.y&&k.right>a.x)l=new v(c.x,a.y),m=new v(c.x,(a.y+c.y)/2),180===d?(l.x=this.computeMidOrthoPosition(a.x,c.x,!1),m.x=l.x,m.y=c.y):270===d&&c.ya.y?(l.x=a.xk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.right,m.x=l.x,m.y=c.y):0===d&&a.xk.top&&a.yh.bottom)180===d&&(k.Da(a)||h.Da(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(180===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=h.left&&c.x<=a.x||a.x<=k.right&&a.x>=c.x){if(90===d||270===d)l=new v(Math.max((a.x+c.x)/2,a.x),a.y),m=new v(l.x,c.y)}else l.y=270===d||(0===d||180===d)&&c.ya.y&&k.lefta.y?(l.x=a.x>k.right?this.computeMidOrthoPosition(a.x,k.right,!1):a.x>k.left&&(270===d&&a.yk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.left,m.x=l.x,m.y=c.y):180===d&&a.x>k.right&&a.y>k.top&&a.yh.bottom)0===d&&(k.Da(a)||h.Da(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(0===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=a.x||a.x>=k.left&&a.x<=c.x){if(90===d||270===d)l=new v(Math.min((a.x+c.x)/2,a.x),a.y),m=new v(l.x,c.y)}else l.y=270=== -d||(0===d||180===d)&&c.ya.y||180===d&&c.xa.y||0===d&&c.x>a.x&&k.bottom>a.y)l=new v(a.x,c.y),m=new v((a.x+c.x)/2,c.y),270===d?(l.y=this.computeMidOrthoPosition(a.y,c.y,!0),m.x=c.x,m.y=l.y):180===d&&c.xa.x?(l.y=a.yk.right)? -this.computeMidOrthoPosition(a.y,c.y,!0):k.bottom,m.x=c.x,m.y=l.y):90===d&&a.yk.left&&a.xh.right)270===d&&(k.Da(a)||h.Da(c))?l.x=this.computeMidOrthoPosition(a.x,c.x,!1):c.xa.x&&(270===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right, -Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=h.top&&c.y<=a.y||a.y<=k.bottom&&a.y>=c.y){if(0===d||180===d)l=new v(a.x,Math.max((a.y+c.y)/2,a.y)),m=new v(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xa.x&&k.top=a.x?(l.y=a.y>k.bottom?this.computeMidOrthoPosition(a.y,k.bottom,!0):a.y>k.top&&(180===d&&a.xk.right)?this.computeMidOrthoPosition(a.y,c.y,!0):k.top,m.x=c.x,m.y=l.y):270===d&&a.y>k.bottom&&a.x>k.left&&a.xh.right)90===d&&(k.Da(a)||h.Da(c))?l.x=this.computeMidOrthoPosition(a.x, -c.x,!1):c.xa.x&&(90===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right,Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=a.y||a.y>=k.top&&a.y<=c.y){if(0===d||180===d)l=new v(a.x,Math.min((a.y+c.y)/2,a.y)),m=new v(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xthis.ka)0===b||180===b?(d.x=a.x,d.y=c.y):(d.x=c.x,d.y=a.y),this.U(2,d.x,d.y),this.C(3,d.x,d.y);else if(c=this.n(3),0===b||180===b)D.I(d.x,c.x)?(b=0===b?Math.max(d.x,a.x):Math.min(d.x,a.x),this.U(2,b,a.y),this.U(3,b,c.y)):D.I(d.y,c.y)? -(Math.abs(a.y-d.y)<=e.km/2&&(this.U(2,d.x,a.y),this.U(3,c.x,a.y)),this.C(2,d.x,a.y)):this.U(2,a.x,d.y);else if(90===b||270===b)D.I(d.y,c.y)?(b=90===b?Math.max(d.y,a.y):Math.min(d.y,a.y),this.U(2,a.x,b),this.U(3,c.x,b)):D.I(d.x,c.x)?(Math.abs(a.x-d.x)<=e.lm/2&&(this.U(2,a.x,d.y),this.U(3,a.x,c.y)),this.C(2,a.x,d.y)):this.U(2,d.x,a.y);a=!0}else a=!1}else a=!1;a||(this.qh(l),this.qh(m))}}; -X.prototype.computeMidOrthoPosition=function(a,b){if(this.hasCurviness()){var c=this.computeCurviness();return(a+b)/2+c}return(a+b)/2};function xf(a){if(!a.Di)return!1;var b=a.points.p,c=b.length;if(4>c)return!1;a=cj(a.h,a);for(var d=1;dUm&&Rm(b,m,n)===l-Vm;)c=m,d=n,0===e?m+=h:90===e?n+=k:180===e?m-=h:n-=k,l-=Vm;if(g){if(l>Um)if(180===e||0===e)c=Math.floor(c/h)*h+h/2;else if(90===e||270===e)d=Math.floor(d/k)*k+k/2}else c=Math.floor(c/h)*h+h/2,d=Math.floor(d/k)*k+k/2;l>Um&&(g=e,m=c,n=d,0===e?(g=90,n+=k):90===e?(g=180,m-=h):180===e?(g=270,n-=k):270===e&&(g=0,m+=h),Rm(b,m,n)===l-Vm?Tm(a,b,m,n,g,!1):(m=c,n=d,0===e?(g=270,n-= -k):90===e?(g=0,m+=h):180===e?(g=90,n+=k):270===e&&(g=180,m-=h),Rm(b,m,n)===l-Vm&&Tm(a,b,m,n,g,!1)));a.Kk(c,d)}X.prototype.findClosestSegment=function(a){f&&t.k(a,v,X,"findClosestSegment:p");var b=a.x;a=a.y;for(var c=this.n(0),d=this.n(1),e=Pa(b,a,c.x,c.y,d.x,d.y),g=0,h=1;ha){var b=new I(zc),c=new Ac(0,0);b.ob.add(c);return b}var d=this.n(0).copy(),e=d.copy(),g=this.computeCurve();if(g===Kg&&3<=a&&!D.Fa(this.Mm,0))if(3===a)var h=this.n(1),b=Math.min(d.x,h.x),c=Math.min(d.y,h.y),h=this.n(2),b=Math.min(b,h.x),c=Math.min(c,h.y);else{if(this.Ub)for(h=0;h=a&&(h=a-1),k=this.n(h),e.x=Math.min(k.x,e.x),e.y=Math.min(k.y,e.y); -b=e.x;c=e.y}else{for(h=0;hE?r>q?(u.x=F-L,u.y=q-L,x.x=F+s,x.y=q+s):(u.x=F-L,u.y=q+L,x.x=F+s,x.y=q-s):r>q?(u.x=F+L,u.y=q-L,x.x= -F-s,x.y=q+s):(u.x=F+L,u.y=q+L,x.x=F-s,x.y=q-s));D.Fa(E,F)&&D.Fa(q,r)&&(q>p?(G>F?(u.x=F-L,u.y=q-L,x.x=F+s):(u.x=F+L,u.y=q-L,x.x=F-s),x.y=q+s):(G>F?(u.x=F-L,u.y=q+L,x.x=F+s):(u.x=F+L,u.y=q+L,x.x=F-s),x.y=q-s));if(D.Fa(E,F)&&D.Fa(F,G)||D.Fa(p,q)&&D.Fa(q,r))E=0.5*(E+G),p=0.5*(p+r),u.x=E,u.y=p,x.x=E,x.y=p;1===h?(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y)):2===h&&D.Fa(e.x,this.n(0).x)&&D.Fa(e.y,this.n(0).y)&&(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y));K(l,g.x-b,g.y-c,k.x-b,k.y-c,m.x-b,m.y-c);d.set(k);g.set(a);e=m}}h= -e.x;e=e.y;d=this.n(this.ka-1);h=0.5*(h+d.x);e=0.5*(e+d.y);K(l,a.x-b,a.y-c,h-b,e-c,d.x-b,d.y-c)}else for(h=3;h=a&&(h=a-1),d=this.n(h-1),k=this.n(h),h===a-1&&0!==Om(this)&&(k=k.copy(),Wm(this,k,!1,D.ak)),K(l,e.x-b,e.y-c,d.x-b,d.y-c,k.x-b,k.y-c);else{e=t.M();e.assign(this.n(0));for(h=1;h=a-1){e!==n&&(0!==Om(this)&&(n=n.copy(),Wm(this,n,!1,D.ak)),Zm(this,l,-b,-c,e,n));break}h=Xm(this,n,h+1,hm.x?n.x-E:n.x+E,G=u.y>n.y?n.y+p:n.y-p,Zm(this,d,g,k,m,new v(s,F)),Vc(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):D.I(m.x,n.x)&&D.I(n.y,u.y)?(E=this.computeCorner(),p=Math.min(E,Math.abs(n.y-m.y)/2),p=E=Math.min(p,Math.abs(u.x-n.x)/2),D.I(E,0)?(Zm(this,d,g,k,m,n),x.assign(n)):(s=n.x,G=F=n.y,F=n.y>m.y?n.y-p:n.y+p,q=u.x>n.x?n.x+E: -n.x-E,Zm(this,d,g,k,m,new v(s,F)),Vc(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):(Zm(this,d,g,k,m,n),x.assign(n))}t.B(e)}b=l.s;t.v(l)}return b};function Ym(a,b,c,d){a=c-a;if(isNaN(a)||Infinity===a||-Infinity===a)return NaN;0>a&&(a=-a);b=d-b;if(isNaN(b)||Infinity===b||-Infinity===b)return NaN;0>b&&(b=-b);return D.Fa(a,0)?b:D.Fa(b,0)?a:Math.sqrt(a*a+b*b)} -function Wm(a,b,c,d){var e=a.ka;if(!(2>e))if(c){var g=a.n(1);c=g.x-d.x;d=g.y-d.y;g=Ym(b.x,b.y,c,d);0!==g&&(e=2===e?0.5*g:g,a=Nm(a),a>e&&(a=e),c=a*(c-b.x)/g,a=a*(d-b.y)/g,b.x+=c,b.y+=a)}else g=a.n(e-2),c=g.x-d.x,d=g.y-d.y,g=Ym(b.x,b.y,c,d),0!==g&&(e=2===e?0.5*g:g,a=Om(a),a>e&&(a=e),c=a*(b.x-c)/g,a=a*(b.y-d)/g,b.x-=c,b.y-=a)} -function Xm(a,b,c,d){for(var e=a.ka,g=b;D.Fa(b.x,g.x)&&D.Fa(b.y,g.y);){if(c>=e)return e-1;g=a.n(c++)}if(!D.Fa(b.x,g.x)&&!D.Fa(b.y,g.y))return c-1;for(var h=g;D.Fa(b.x,g.x)&&D.Fa(g.x,h.x)&&(!d||(b.y>=g.y?g.y>=h.y:g.y<=h.y))||D.Fa(b.y,g.y)&&D.Fa(g.y,h.y)&&(!d||(b.x>=g.x?g.x>=h.x:g.x<=h.x));){if(c>=e)return e-1;h=a.n(c++)}return c-2} -function Zm(a,b,c,d,e,g){if(Em(a)){var h=new A("number"),k=$m(a,e,g,h),l=e.x,l=e.y;if(0p-10)m--,p=Math.max(q-5,g.x);else break;q=g.y-10+d;n=p+c;p=g.y+d;a.ze===rg?J(b,n,p,!1,!1):K(b,l,q,n,q,n,p)}else if(D.I(e.x,g.x))if(e.yp-10)m--,p=Math.max(q-5,g.y);else break;q=g.x-10+c;n=g.x+c;p+=d;a.ze===rg?J(b,n,p,!1,!1):K(b,q,l,q,p,n,p)}}b.lineTo(g.x+c,g.y+d)} -function $m(a,b,c,d){var e=a.h;if(null===e)return 0;Math.min(b.x,c.x);Math.min(b.y,c.y);Math.max(b.x,c.x);Math.max(b.y,c.y);for(e=e.ew;e.next();){var g=e.value;if(null!==g&&g.visible)for(var g=g.qb.p,h=g.length,k=0;k=h.x&&Math.min(h.y,k.y)<=m.y&&Math.max(h.y,k.y)>=m.y&&!D.I(h.y,k.y)){p.x=h.x;p.y=m.y;m=!0;break a}}else if(D.I(h.y,k.y)&&Math.min(m.y,n.y)<=h.y&&Math.max(m.y,n.y)>=h.y&&Math.min(h.x,k.x)<=m.x&&Math.max(h.x,k.x)>=m.x&&!D.I(h.x,k.x)){p.x=m.x;p.y=h.y;m=!0;break a}p.x=0;p.y=0;m=!1}m&&(D.I(a.y,b.y)?c.add(l.x):c.add(l.y));t.B(l)}} -t.A(X,{ws:"firstPickIndex"},function(){return 2>=this.ka?0:this.Ub||Hm(this)!==ub?1:0});t.A(X,{dw:"lastPickIndex"},function(){var a=this.ka;return 0===a?0:2>=a?a-1:this.Ub||Im(this)!==ub?a-2:a-1});function Em(a){a=a.ze;return a===qg||a===rg}function Gm(a,b){if(b||Em(a)){var c=a.h;null===c||c.ln.contains(a)||null===a.Ey||c.ln.add(a,a.Ey)}} -function tg(a,b){var c=a.layer;if(null!==c&&c.visible&&!c.kc){var d=c.h;if(null!==d)for(var e=!1,d=d.ew;d.next();){var g=d.value;if(g.visible)if(g===c)for(var e=!0,h=!1,g=g.qb.p,k=g.length,l=0;lb.links.count)1===b.links.count&&(c=b.links.p[0],c.Ym=null,c.Xe=0,c.Tb()),c=b.cp,null!==b&&null!==c.Rg&&c.Rg.remove(b),c=b.Qs,null!==b&&null!==c.Rg&&c.Rg.remove(b);else for(c=Math.abs(c),a=0===c%2,b=b.links.m;b.next();){var d=b.value,e=Math.abs(d.Xe),g=0===e%2;e>c&&a===g&&(d.Xe=0=a.width||0>=a.height)){var b=a.y,c=a.x+a.width,d=a.y+a.height;this.Pf=Math.floor((a.x-this.Td)/this.Td)*this.Td;this.Qf=Math.floor((b-this.Ud)/this.Ud)*this.Ud;this.Tq=Math.ceil((c+2*this.Td)/this.Td)*this.Td;this.Uq=Math.ceil((d+2*this.Ud)/this.Ud)*this.Ud;a=1+(Math.ceil((this.Tq-this.Pf)/this.Td)|0);b=1+(Math.ceil((this.Uq-this.Qf)/this.Ud)|0);if(null===this.ec||this.Zn=Um&&(a.ec[b][c]|=Sm)} -function Pm(a,b,c,d,e){if(b>a.Tq||b+da.Uq||c+eb&&(d+=b,b=0);0>c&&(g+=c,c=0);if(0>d||0>g)return!0;e=Math.min(b+d-1,a.Zn)|0;for(d=Math.min(c+g-1,a.$n)|0;b<=e;b++)for(g=c;g<=d;g++)if(0===a.ec[b][g])return!1;return!0} -function en(a,b,c,d,e,g,h,k,l){if(!(bh||cl)){var m,n;m=b|0;n=c|0;var p=a.ec[m][n];if(p>=Um&&p=a.ec[m][n]);)a.ec[m][n]=p,p+=Vm,e?n+=d:m+=d;m=e?n:m;if(e)if(0m;c+=d)en(a,b,c,1,!e,g,h,k,l),en(a,b,c,-1,!e,g,h,k,l);else if(0m;b+=d)en(a,b,c,1,!e,g,h,k,l),en(a,b,c,-1,!e,g,h, -k,l)}}function fn(a,b,c,d,e,g,h,k,l,m,n){for(var p=b|0,q=c|0,r=a.ec[p][q];0===r&&p>k&&pm&&q=Math.abs(p-d)&&1>=Math.abs(q-e))return a.abort=!0,0;p=b|0;q=c|0;r=a.ec[p][q];b=Um;for(a.ec[p][q]=b;0===r&&p>k&&pm&&q=Math.abs(h-l)&&1>=Math.abs(k-m))a.abort=!0;else{var n=g.x;b=g.y;d=g.x+g.width;var p=g.y+g.height,n=n-a.Pf,n=n/a.Td;b-=a.Qf;b/=a.Ud;d-=a.Pf;d/=a.Td;p-=a.Qf;p/=a.Ud;g=Math.max(0,Math.min(a.Zn,n|0));d=Math.min(a.Zn,Math.max(0,d|0));b=Math.max(0,Math.min(a.$n,b|0));var p=Math.min(a.$n,Math.max(0,p|0)),h=h|0,k=k|0,l=l|0, -m=m|0,n=h,q=k,r=0===c||90===c?1:-1;(c=90===c||270===c)?q=fn(a,h,k,l,m,r,c,g,d,b,p):n=fn(a,h,k,l,m,r,c,g,d,b,p);if(!a.abort){a:{c=0===e||90===e?1:-1;e=90===e||270===e;for(var r=l|0,s=m|0,u=a.ec[r][s];0===u&&r>g&&rb&&s=Math.abs(r-h)&&1>=Math.abs(s-k)){a.abort=!0;break a}r=l|0;s=m|0;u=a.ec[r][s];for(a.ec[r][s]=cn;0===u&&r>g&&rb&&s=c?180:0}a=180*Math.atan2(a.height,a.width)/Math.PI;switch(b){case t.ad|t.wd:return c>a&&c<=180+a?180:270;case t.wd|t.od:return c>180-a&&c<=360-a?270:0;case t.od|t.nd:return c>a&&c<=180+a?90:0;case t.nd|t.ad:return c>180-a&&c<=360-a?180:90;case t.ad|t.wd|t.od:return 90180+a&&c<=360- -a?270:0;case t.wd|t.od|t.nd:return 180a&&180>=c?90:0;case t.od|t.nd|t.ad:return c>a&&c<=180-a?90:c>180-a&&270>=c?180:0;case t.nd|t.ad|t.wd:return c>180-a&&c<=180+a?180:c>180+a?270:90}d&&b!==(t.ad|t.wd|t.od|t.nd)&&(c-=15,0>c&&(c+=360));return c>a&&c<180-a?90:c>=180-a&&c<=180+a?180:c>180+a&&c<360-a?270:0} -function Mm(a,b){var c=a.dg;if(0===c.length){if(!a.Ps){c=a.Ps;a.Ps=!0;var d=a.Bc.ie,e=a.dg.length=0,g=a.port.$a(wb,t.M()),h=a.port.$a(Ob,t.M()),k=t.Yj(g.x,g.y,0,0);k.Mi(h);t.B(g);t.B(h);g=t.cc(k.x+k.width/2,k.y+k.height/2);for(d=d.m;d.next();)if(h=d.value,h.ub()){var l=ub,l=h.Wc===a.port?Hm(h,a.port):Im(h,a.port);if(l.No()){var m;m=h.Wc===a.port?h.Qd:h.Wc;if(null!==m){var n=m.Q;if(null!==n){m=h.computeOtherPoint(n,m);var n=g.wi(m),l=gn(k,l,n,h.Ub),p;0===l?(p=t.od,180b.De?1:a.angleb.angle?1:0}; -Lm.prototype.computeEndSegmentLength=function(a){var b=a.link,c=b.computeEndSegmentLength(this.Bc,this.port,ub,b.Wc===this.port),d=a.Jo;if(0>d)return c;var e=a.pm;if(1>=e||!b.Ub)return c;var b=a.lw,g=a.Uo;if(a.De===t.ad||a.De===t.nd)d=e-1-d;return((a=a.De===t.ad||a.De===t.od)?b.ye&&(e=k.right);k.bottom>g&&(g=k.bottom)}}isFinite(c)&&isFinite(d)?a.q(c,d,e-c,g-d):(b=b.location,c=this.padding,a.q(b.x+c.left,b.y+c.top,0,0));return a}; -t.g(Pg,"padding",Pg.prototype.padding);t.defineProperty(Pg,{padding:"padding"},function(){return this.Ge},function(a){"number"===typeof a?(0>a&&t.ia(a,">= 0",Pg,"padding"),a=new Va(a)):(t.k(a,Va,Pg,"padding"),0>a.left&&t.ia(a.left,">= 0",Pg,"padding:val.left"),0>a.right&&t.ia(a.right,">= 0",Pg,"padding:val.right"),0>a.top&&t.ia(a.top,">= 0",Pg,"padding:val.top"),0>a.bottom&&t.ia(a.bottom,">= 0",Pg,"padding:val.bottom"));var b=this.Ge;b.K(a)||(this.Ge=a=a.W(),this.i("padding",b,a))}); -function ke(){0=c-1?(h=0,e=d,g+=k+20,k=0):h++}null!==a&&a.ye("Layout")}this.gf=!0};ke.prototype.fA=function(a){return!a.location.P()||a instanceof V&&a.$B?!0:!1};function mn(a,b,c,d,e,g,h,k){for(c=c.m;c.next();){var l=c.value;d&&!l.Oo||e&&!e(l)||l.canLayout()&&(g&&l instanceof S?l.wh||(l instanceof V&&null===l.Vb?mn(a,b,l.Kc,!1,e,g,h,k):b.add(l)):h&&l instanceof X?b.add(l):!k||!l.Kd()||l instanceof S||b.add(l))}} -t.g(ke,"arrangementOrigin",ke.prototype.sd);t.defineProperty(ke,{sd:"arrangementOrigin"},function(){return this.Np},function(a){this.Np.K(a)||(t.k(a,v,ke,"arrangementOrigin"),this.Np.assign(a),this.J())});ke.prototype.initialOrigin=ke.prototype.Pz=function(a){var b=this.group;if(null!==b){var c=b.location;if(isNaN(c.x)||isNaN(c.y))return a;a=b.placeholder;null!==a?(c=a.$a(wb),c.x+=a.padding.left,c.y+=a.padding.top):c=b.position.copy();return c}return a}; -function ra(){t.uc(this);this.Bd=null;this.clear()}t.ea("LayoutNetwork",ra);ra.prototype.clear=function(){if(this.vertexes)for(var a=this.vertexes.m;a.next();){var b=a.value;b.clear();b.network=null}if(this.edges)for(a=this.edges.m;a.next();)b=a.value,b.clear(),b.network=null;this.vertexes=new la(sa);this.edges=new la(ta);this.iA=new ia(S,sa);this.Yz=new ia(X,ta)};ra.prototype.toString=function(){return"LayoutNetwork"+(null!==this.Vb?"("+this.Vb.toString()+")":"")};t.A(ra,{Vb:"layout"},function(){return this.Bd}); -function ln(a,b){f&&null!==b&&t.k(b,ke,ra,"setLayout");a.Bd=b}ra.prototype.createVertex=function(){return new sa};ra.prototype.createEdge=function(){return new ta}; -ra.prototype.addParts=ra.prototype.ds=function(a,b){if(null!==a){void 0===b&&(b=!1);t.j(b,"boolean",ra,"addParts:toplevelonly");for(var c=a.m;c.next();){var d=c.value;if(d instanceof S&&(!b||d.Oo)&&d.canLayout()&&!d.wh)if(d instanceof V&&null===d.Vb)this.ds(d.Kc,!1);else if(null===this.wm(d)){var e=this.createVertex();e.Bc=d;this.Lk(e)}}for(c.reset();c.next();)if(d=c.value,d instanceof X&&(!b||d.Oo)&&d.canLayout()&&null===this.Mv(d)){var g=d.ca,e=d.ga;g!==e&&(g=this.Nv(g),e=this.Nv(e),null!==g&&null!== -e&&this.Dm(g,e,d))}}};ra.prototype.findGroupVertex=ra.prototype.Nv=function(a){if(null===a)return null;a=bm(a);if(null===a)return null;var b=this.wm(a);if(null!==b)return b;a=a.ib;return null!==a&&(b=this.wm(a),null!==b)?b:null};ra.prototype.addVertex=ra.prototype.Lk=function(a){if(null!==a){f&&t.k(a,sa,ra,"addVertex:vertex");this.vertexes.add(a);var b=a.Bc;null!==b&&this.iA.add(b,a);a.network=this}}; -ra.prototype.addNode=ra.prototype.eo=function(a){if(null===a)return null;f&&t.k(a,S,ra,"addNode:node");var b=this.wm(a);null===b&&(b=this.createVertex(),b.Bc=a,this.Lk(b));return b};ra.prototype.deleteVertex=ra.prototype.lD=function(a){if(null!==a&&(f&&t.k(a,sa,ra,"deleteVertex:vertex"),nn(this,a))){for(var b=a.Ue,c=b.count-1;0<=c;c--){var d=b.ta(c);this.uo(d)}b=a.Le;for(c=b.count-1;0<=c;c--)d=b.ta(c),this.uo(d)}}; -function nn(a,b){if(null===b)return!1;var c=a.vertexes.remove(b);c&&(a.iA.remove(b.Bc),b.network=null);return c}ra.prototype.deleteNode=function(a){null!==a&&(f&&t.k(a,S,ra,"deleteNode:node"),a=this.wm(a),null!==a&&this.lD(a))};ra.prototype.findVertex=ra.prototype.wm=function(a){if(null===a)return null;f&&t.k(a,S,ra,"findVertex:node");return this.iA.wa(a)}; -ra.prototype.addEdge=ra.prototype.co=function(a){if(null!==a){f&&t.k(a,ta,ra,"addEdge:edge");this.edges.add(a);var b=a.link;null!==b&&null===this.Mv(b)&&this.Yz.add(b,a);b=a.toVertex;null!==b&&b.EC(a);b=a.fromVertex;null!==b&&b.CC(a);a.network=this}}; -ra.prototype.addLink=function(a){if(null===a)return null;f&&t.k(a,X,ra,"addLink:link");var b=a.ca,c=a.ga,d=this.Mv(a);null===d?(d=this.createEdge(),d.link=a,null!==b&&(d.fromVertex=this.eo(b)),null!==c&&(d.toVertex=this.eo(c)),this.co(d)):(d.fromVertex=null!==b?this.eo(b):null,d.toVertex=null!==c?this.eo(c):null);return d};ra.prototype.deleteEdge=ra.prototype.uo=function(a){if(null!==a){f&&t.k(a,ta,ra,"deleteEdge:edge");var b=a.toVertex;null!==b&&b.kD(a);b=a.fromVertex;null!==b&&b.jD(a);on(this,a)}}; -function on(a,b){null!==b&&a.edges.remove(b)&&(a.Yz.remove(b.link),b.network=null)}ra.prototype.deleteLink=function(a){null!==a&&(f&&t.k(a,X,ra,"deleteLink:link"),a=this.Mv(a),null!==a&&this.uo(a))};ra.prototype.findEdge=ra.prototype.Mv=function(a){if(null===a)return null;f&&t.k(a,X,ra,"findEdge:link");return this.Yz.wa(a)}; -ra.prototype.linkVertexes=ra.prototype.Dm=function(a,b,c){if(null===a||null===b)return null;f&&(t.k(a,sa,ra,"linkVertexes:fromVertex"),t.k(b,sa,ra,"linkVertexes:toVertex"),null!==c&&t.k(c,X,ra,"linkVertexes:link"));if(a.network===this&&b.network===this){var d=this.createEdge();d.link=c;d.fromVertex=a;d.toVertex=b;this.co(d);return d}return null}; -ra.prototype.reverseEdge=ra.prototype.sw=function(a){if(null!==a){f&&t.k(a,ta,ra,"reverseEdge:edge");var b=a.fromVertex,c=a.toVertex;null!==b&&null!==c&&(b.jD(a),c.kD(a),a.sw(),b.EC(a),c.CC(a))}};ra.prototype.deleteSelfEdges=ra.prototype.Iv=function(){for(var a=t.yb(),b=this.edges.m;b.next();){var c=b.value;c.fromVertex===c.toVertex&&a.push(c)}b=a.length;for(c=0;cd?1:0):1:null!==d?-1:0}; -sa.smartComparer=function(a,b){f&&t.k(a,sa,sa,"smartComparer:m");f&&t.k(b,sa,sa,"smartComparer:n");if(null!==a){if(null!==b){var c=a.ed,d=b.ed;if(null!==c){if(null!==d){var c=c.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=d.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=d&&0>=a&&(d=1);var e=this.spacing.width;isFinite(e)||(e=0);var g=this.spacing.height;isFinite(g)||(g=0);b.mc("Layout");switch(this.alignment){case Nk:var h= -Math.max(this.Pk.width,1);if(!isFinite(h))for(var k=h=0;kd-1||0a)u=0,r=q,s+=x,x=0;x=Math.max(x,F);switch(p){case Lk:m=-m.width;break;default:m=0}l.moveTo(r+m,s);switch(p){case Lk:r-=E;break;default:r+=E}u++}break;case Mk:h=Math.max(this.Pk.width,1);k=x=u=0;l=t.M();for(n=0;nd-1||0a){for(L=0;Ld?1:0}; -Aj.smartComparer=function(a,b){f&&t.k(a,B,Aj,"standardComparer:a");f&&t.k(b,B,Aj,"standardComparer:b");if(null!==a){if(null!==b){var c=a.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=b.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=a.count)1===a.count&&(a=a.Ya(),a.Aa=0,a.Ma=0);else{var b=new A(vn);b.He(a.m);a=new A(vn);var c=new A(vn),b=this.sort(b);a=new A(vn);var c=new A(vn),d=this.Kx,e=this.zB,g=this.pd,h=this.nn,k=this.Lx,l=this.iq,m=this.qk,n=this.uC,p=this.Wf,q=this.Kt,d=this.Je,e=this.Rs,g= -this.CE;if(!isFinite(g)||0>=g)g=NaN;h=this.JC;if(!isFinite(h)||0>=h)h=1;k=this.kg;isFinite(k)||(k=0);l=this.Fh;if(!isFinite(l)||360l)l=360;m=this.spacing;isFinite(m)||(m=NaN);d===al&&e===bl?d=$k:d===al&&e!==bl&&(e=bl,d=this.Je);if((this.direction===Uk||this.direction===Vk)&&this.sorting!==Tk){for(var r=0;!(r>=b.length);r+=2){a.add(b.ta(r));if(r+1>=b.length)break;c.add(b.ta(r+1))}this.direction===Uk?(this.Je===al&&a.reverse(),b=new A(vn),b.He(a),b.He(c)):(this.Je===al&&c.reverse(),b=new A(vn), -b.He(c),b.He(a))}for(var s=b.length,u=n=0,r=0;rl&&(0===r||r===b.length-1)&&(x/=2);n+=x;u++}if(isNaN(g)||d===al){isNaN(m)&&(m=6);if(d!==$k&&d!==al){x=-Infinity;for(r=0;rg?(g=r,p=g*h):q=u/(360<=l?s:s-1)}this.Kx=d;this.zB=e;this.pd=g;this.nn=h;this.Lx=k;this.iq=l;this.qk=m;this.uC=n;this.Wf=p;this.Kt=q;c=[b,a,c];b=c[0];a=c[1];c=c[2];d=this.Kx;e=this.pd;h=this.Lx;k=this.iq;l=this.qk;m=this.Wf;n=this.Kt;if(this.direction!==Uk&&this.direction!==Vk||d!==al)if(this.direction===Uk||this.direction===Vk){g=0;switch(d){case Zk:g=180*zn(this,e,m,h,n)/Math.PI;break;case $k:n=b=0;g=a.Ya();null!==g&&(b=wn(g,Math.PI/2));g=c.Ya();null!== -g&&(n=wn(g,Math.PI/2));g=180*zn(this,e,m,h,l+(b+n)/2)/Math.PI;break;case Yk:g=k/b.length}if(this.direction===Uk){switch(d){case Zk:An(this,a,h,Xk);break;case $k:Bn(this,a,h,Xk);break;case Yk:Cn(this,a,k/2,h,Xk)}switch(d){case Zk:An(this,c,h+g,Wk);break;case $k:Bn(this,c,h+g,Wk);break;case Yk:Cn(this,c,k/2,h+g,Wk)}}else{switch(d){case Zk:An(this,c,h,Xk);break;case $k:Bn(this,c,h,Xk);break;case Yk:Cn(this,c,k/2,h,Xk)}switch(d){case Zk:An(this,a,h+g,Wk);break;case $k:Bn(this,a,h+g,Wk);break;case Yk:Cn(this, -a,k/2,h+g,Wk)}}}else switch(d){case Zk:An(this,b,h,this.direction);break;case $k:Bn(this,b,h,this.direction);break;case Yk:Cn(this,b,k,h,this.direction);break;case al:Dn(this,b,k,h,this.direction)}else Dn(this,b,k,h-k/2,Wk)}this.updateParts();this.network=null;this.gf=!0}; -function Cn(a,b,c,d,e){var g=a.iq,h=a.pd;a=a.Wf;d=d*Math.PI/180;c=c*Math.PI/180;for(var k=b.length,l=0;lc){for(g=d+(e===Wk?g:-g);0>g;)g+=360;g%=360;180=n.length-1)break;var p=Gn(a,l,m,n,g,e);p[0]||(p=Hn(a,l,m,n,g,e));l=p[1];m=p[2]}a.Rl++;if(!(23Math.abs(r)?Math.abs(l-g)<(n[0].width+n[n.length-1].width)/2&&(h=0):h=0Math.abs(q)?0:q;q=!1;q=Math.abs(g)>Math.abs(p)?0p:0l.Eo||Math.abs(h)h&&0a.Rl?a.pd-h/(2*Math.PI):5>n.length&&10=n.length-1)break;var q=Gn(a,l,m,n,p,e);q[0]||(q=Hn(a,l,m,n,p,e));l=q[1];m=q[2]}a.Rl++;if(!(23a.Rl?a.pd-g/(2*Math.PI):a.pd-(0h){l=b-a;if(l<-h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(l=b-a,l<-h){l=b+a;if(l>h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}m=Math.sqrt(1-Math.min(1,l*l/(h*h)))*k;0>c!==n&&(m=-m);b=Math.abs(c-m)>(d[e].height+d[e+1].height)/2?[!1]:[!0];b[1]=l;b[2]=m;return b} -function Hn(a,b,c,d,e,g){var h=a.pd,k=a.Wf,l=0,m=0;a=(d[e].height+d[e+1].height)/2+a.qk;var n=!1;if(0<=b!==(g===Wk)){if(m=c-a,m<-k){m=c+a;if(m>k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(m=c+a,m>k){m=c-a;if(m<-k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}l=Math.sqrt(1-Math.min(1,m*m/(k*k)))*h;0>b!==n&&(l=-l);b=Math.abs(b-l)>(d[e].width+d[e+1].width)/2?[!1]:[!0];b[1]=l;b[2]=m;return b}function tn(){this.Eo=-Infinity;this.zp=this.Qm=null} -tn.prototype.commit=function(a){if(null!==this.Qm&&null!==this.zp)for(var b=0;bMath.abs(a.nn-1))return void 0!==d&&void 0!==e?e*b:2*Math.PI*b;a=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c;var h=0,k;k=void 0!==d&&void 0!==e?e/(g+1):Math.PI/(2*(g+1));for(var l=0;l<=g;l++)var m=Math.sin(void 0!==d&&void 0!==e?d+l*e/g:l*Math.PI/(2*g)),h=h+Math.sqrt(1-a*a*m*m)*k;return void 0!==d&&void 0!==e?(b>c?b:c)*h:4*(b>c?b:c)*h}function xn(a,b,c,d,e){a=void 0!==d&&void 0!==e?yn(a,1,c,d,e):yn(a,1,c);return b/a} -function zn(a,b,c,d,e){if(0.001>Math.abs(a.nn-1))return e/b;var g=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c,h=0;a=2*Math.PI/(700*a.network.vertexes.count);b>c&&(d+=Math.PI/2);for(var k=0;;k++){var l=Math.sin(d+k*a),h=h+(b>c?b:c)*Math.sqrt(1-g*g*l*l)*a;if(h>=e)return k*a}return 0} -Ok.prototype.sort=function(a){switch(this.sorting){case Rk:break;case Sk:a.reverse();break;case Pk:a.sort(this.comparer);break;case Qk:a.sort(this.comparer);a.reverse();break;case Tk:for(var b=[],c=0;ce&&(e=k,g=h)}else for(h=0;he&&(e=k,g=h);d.add(a.ta(g));b[g]=-1;g=a.ta(g);e=g.bc;for(g=g.Sb;e.next();)h=e.value,h=h.fromVertex,h=a.indexOf(h),0> -h||0<=b[h]&&b[h]++;for(;g.next();)h=g.value,h=h.toVertex,h=a.indexOf(h),0>h||0<=b[h]&&b[h]++}a=[];for(b=0;ba[b].indexOf(m)&&a[b].push(m);for(;e.next();)l=e.value,m=d.indexOf(l.fromVertex),m!==b&&0>a[b].indexOf(m)&&a[b].push(m)}k=[];for(b=0;ba[c[q]].indexOf(c[q===c.length-1?0:q+1])&&x.push(q===c.length-1?0:q+1);if(0===x.length)for(q=0;qM.indexOf(da)||RM.indexOf(da)||R=E?m+1:m)),G+=m=E&&m++,L>=E&&L++,m>L&&(M=L,L=m,m=M),L-m<(c.length+2)/2===(mr||r===m||(u=r>m?r-m:m-r,s+=rp-u?1:-1);c.splice(0>s?m:m+1,0,b);e.splice(k,1);k--}else n=!1;if(n)break;else c.push(e[0]),e.splice(0,1)}for(b=0;b=a?a:360,this.J())});t.g(Ok,"arrangement",Ok.prototype.Je);t.defineProperty(Ok,{Je:"arrangement"},function(){return this.bd},function(a){this.bd!==a&&(f&&t.k(a,ca,Ok,"arrangement"),a===al||a===$k||a===Zk||a===Yk)&&(this.bd=a,this.J())});t.g(Ok,"direction",Ok.prototype.direction); -t.defineProperty(Ok,{direction:"direction"},function(){return this.pa},function(a){this.pa!==a&&(f&&t.k(a,ca,Ok,"direction"),a===Wk||a===Xk||a===Uk||a===Vk)&&(this.pa=a,this.J())});t.g(Ok,"sorting",Ok.prototype.sorting);t.defineProperty(Ok,{sorting:"sorting"},function(){return this.lh},function(a){this.lh!==a&&(f&&t.k(a,ca,Ok,"sorting"),a===Rk||a===Sk||a===Pk||Qk||a===Tk)&&(this.lh=a,this.J())});t.g(Ok,"comparer",Ok.prototype.comparer); -t.defineProperty(Ok,{comparer:"comparer"},function(){return this.Ug},function(a){this.Ug!==a&&(f&&t.j(a,"function",Ok,"comparer"),this.Ug=a,this.J())});t.g(Ok,"spacing",Ok.prototype.spacing);t.defineProperty(Ok,{spacing:"spacing"},function(){return this.mh},function(a){this.mh!==a&&(this.mh=a,this.J())});t.g(Ok,"nodeDiameterFormula",Ok.prototype.Rs); -t.defineProperty(Ok,{Rs:"nodeDiameterFormula"},function(){return this.gr},function(a){this.gr!==a&&(f&&t.k(a,ca,Ok,"nodeDiameterFormula"),a===cl||a===bl)&&(this.gr=a,this.J())});t.A(Ok,{rG:"actualXRadius"},function(){return this.pd});t.A(Ok,{sG:"actualYRadius"},function(){return this.Wf});t.A(Ok,{MI:"actualSpacing"},function(){return this.qk});t.A(Ok,{qG:"actualCenter"},function(){return isNaN(this.sd.x)||isNaN(this.sd.y)?new v(0,0):new v(this.sd.x+this.rG,this.sd.y+this.sG)});var $k; -Ok.ConstantSpacing=$k=t.w(Ok,"ConstantSpacing",0);var Zk;Ok.ConstantDistance=Zk=t.w(Ok,"ConstantDistance",1);var Yk;Ok.ConstantAngle=Yk=t.w(Ok,"ConstantAngle",2);var al;Ok.Packed=al=t.w(Ok,"Packed",3);var Wk;Ok.Clockwise=Wk=t.w(Ok,"Clockwise",4);var Xk;Ok.Counterclockwise=Xk=t.w(Ok,"Counterclockwise",5);var Uk;Ok.BidirectionalLeft=Uk=t.w(Ok,"BidirectionalLeft",6);var Vk;Ok.BidirectionalRight=Vk=t.w(Ok,"BidirectionalRight",7);var Rk;Ok.Forwards=Rk=t.w(Ok,"Forwards",8);var Sk; -Ok.Reverse=Sk=t.w(Ok,"Reverse",9);var Pk;Ok.Ascending=Pk=t.w(Ok,"Ascending",10);var Qk;Ok.Descending=Qk=t.w(Ok,"Descending",11);var Tk;Ok.Optimized=Tk=t.w(Ok,"Optimized",12);var cl;Ok.Pythagorean=cl=t.w(Ok,"Pythagorean",13);var bl;Ok.Circular=bl=t.w(Ok,"Circular",14);function un(){ra.call(this)}t.ea("CircularNetwork",un);t.Ja(un,ra);un.prototype.createVertex=function(){return new vn};un.prototype.createEdge=function(){return new In};function vn(){sa.call(this);this.actualAngle=this.diameter=NaN} -t.ea("CircularVertex",vn);t.Ja(vn,sa);function wn(a,b){var c=a.network;if(null===c)return NaN;c=c.Vb;if(null===c)return NaN;if(c.Je===al)if(c.Rs===bl)a.diameter=Math.max(a.width,a.height);else{var c=Math.abs(Math.sin(b)),d=Math.abs(Math.cos(b));if(0===c)return a.width;if(0===d)return a.height;a.diameter=Math.min(a.height/c,a.width/d)}else a.diameter=c.Rs===bl?Math.max(a.width,a.height):Math.sqrt(a.width*a.width+a.height*a.height);return a.diameter}function In(){ta.call(this)}t.ea("CircularEdge",In); -t.Ja(In,ta);function Jn(){0k?(e=l.x+l.width/2,g=l.y+l.height/2,h[0]=new v(l.x+l.width+c.width,l.y),h[1]=new v(l.x,l.y+ -l.height+c.height),k=2):(p=Mn(h,k,e,g,l.width,l.height,c),q=h[p],r=new v(q.x+l.width+c.width,q.y),s=new v(q.x,q.y+l.height+c.height),p+1this.network.vertexes.count)return!1;var a=0,b=0,c=this.network.vertexes.m;c.next();for(var d=c.value.R;c.next();){if(c.value.R.Bf(d)&&(a++,1a.network.vertexes.count)return!1;null===a.Vf?a.Vf=new A(Sn):a.Vf.clear();a.Vf.He(a.network.vertexes);var c=a.Vf;c.sort(function(a,b){return null===a||null===b||a===b?0:b.Ef-a.Ef});for(var d=c.count-1;0<=d&&1>=c.p[d].Ef;)d--;return 1=h))){for(var n=0,p=0,q=m.count-h;qs&&(s=1);n=D.sqrt((n+s+p*p*4/(h*h))/s);h=(n-1)*l/2;n=(n-1)*q/2;g.Gb=new w(m-r.x-h,k-r.y-n,l+2*h,q+2*n);g.focus=new v(r.x+h,r.y+n)}a.network=d;return c} -function Rn(a,b,c){f&&(t.k(b,Kn,Jn,"popNetwork:oldnet"),t.o(c,Jn,"popNetwork:level"));for(c=a.network.vertexes.m;c.next();){var d=c.value;d.network=b;if(null!==d.Ng){var e=d.Ng.p[d.yA];d.Ef=e.YA;var g=e.QF,h=e.RF;d.Gb=new w(d.Aa-g,d.Ma-h,e.$A,e.XA);d.focus=new v(g,h);d.yA--}}for(c=a.network.edges.m;c.next();)c.value.network=b;a.network=b} -function Tn(a,b,c){f&&(t.k(b,Sn,Jn,"surroundNode:oldnet"),t.o(c,Jn,"surroundNode:level"));var d=b.nm;if(null!==d&&0!==d.count){c=b.Aa;var e=b.Ma,g=b.width,h=b.height;null!==b.Ng&&0=p.Ef?l++:(k=!0,m++,h+=Math.atan2(b.Ma-p.Ma,b.Aa-p.Aa))}if(0!==l)for(0>1)+m)*(0==k%2?1:-1);p.Aa=c+d*Math.cos(l);p.Ma=e+d*Math.sin(l);k++}}} -function Mn(a,b,c,d,e,g,h){var k=9E19,l=-1,m=0;a:for(;mn.y&&a[q].x-n.xn.x&&a[q].y-n.yl+h?(d=d+g-k,e=e-l-h,D.sqrt(d*d+e*e)):e+ck+m?e>l+h?(d=d-k-m,e=e-l-h,D.sqrt(d*d+e*e)):e+cl+h?e-(l+h):e+c=b.length)return!1;var c=b[0];c.forceX=0;c.forceY=0;for(var d=c.Aa,e=d,g=c.Ma,h=g,c=1;ch-g)?b.sort(function(a,b){return null===a||null===b||a===b?0:a.Aa-b.Aa}):b.sort(function(a,b){return null===a||null===b||a===b?0:a.Ma-b.Ma});for(var h=a.bh,m=0,n=0,p=0,c=0;ch||p-d>h){if(g)break}else if(l-r>h||r-l>h){if(!g)break}else{var s=Un(k,e);1>s?(d>p?(n=Math.abs(e.R.right-k.R.x),n=(1+n)*Math.random()):dr?(p=Math.abs(e.R.bottom-k.R.y),p=(1+p)*Math.random()):ds?(n=(d>p?1:-1)*(1+(e.width>k.width)?e.width: -k.width)*Math.random(),p=(l>r?1:-1)*(1+(e.height>k.height)?e.height:k.height)*Math.random()):(m=g.stiffness*(s-g.length),n=(p-d)/s*m,p=(r-l)/s*m),k.forceX+=n,k.forceY+=p,e.forceX-=n,e.forceY-=p;c=0;d=Math.max(a.bh/20,50);for(e=0;ed&&(g=d),h<-d?h=-d:h>d&&(h=d),k.Aa+=g,k.Ma+=h,c=Math.max(c,g*g+h*h));return c>a.Cz*a.Cz}Jn.prototype.moveFixedVertex=function(){}; -Jn.prototype.commitLayout=function(){this.FA();this.commitNodes();this.Gs&&this.commitLinks()};Jn.prototype.FA=function(){if(this.il)for(var a=this.network.edges.m;a.next();){var b=a.value.link;null!==b&&(b.fb=vb,b.gb=vb)}};Jn.prototype.commitNodes=function(){var a=0,b=0;if(this.HC){var c=t.qf();this.df(this.network,c);b=this.sd;a=b.x-c.x;b=b.y-c.y;t.Ic(c)}for(var c=t.qf(),d=this.network.vertexes.m;d.next();){var e=d.value;if(0!==a||0!==b)c.assign(e.R),c.x+=a,c.y+=b,e.Gb=c;e.commit()}t.Ic(c)}; -Jn.prototype.commitLinks=function(){for(var a=this.network.edges.m;a.next();)a.value.commit()};Jn.prototype.springStiffness=function(a){a=a.stiffness;return isNaN(a)?this.gn:a};Jn.prototype.springLength=function(a){a=a.length;return isNaN(a)?this.fn:a};Jn.prototype.electricalCharge=function(a){a=a.charge;return isNaN(a)?this.cn:a};Jn.prototype.electricalFieldX=function(){return 0};Jn.prototype.electricalFieldY=function(){return 0}; -Jn.prototype.gravitationalMass=function(a){a=a.mass;return isNaN(a)?this.en:a};Jn.prototype.gravitationalFieldX=function(){return 0};Jn.prototype.gravitationalFieldY=function(){return 0};Jn.prototype.isFixed=function(a){return a.isFixed};t.A(Jn,{NI:"currentIteration"},function(){return this.Gq});t.g(Jn,"arrangementSpacing",Jn.prototype.rv);t.defineProperty(Jn,{rv:"arrangementSpacing"},function(){return this.Jf},function(a){this.Jf.K(a)||(this.Jf.assign(a),this.J())});t.g(Jn,"arrangesToOrigin",Jn.prototype.HC); -t.defineProperty(Jn,{HC:"arrangesToOrigin"},function(){return this.Op},function(a){this.Op!==a&&(this.Op=a,this.J())});t.g(Jn,"setsPortSpots",Jn.prototype.il);t.defineProperty(Jn,{il:"setsPortSpots"},function(){return this.kh},function(a){this.kh!==a&&(this.kh=a,this.J())});t.g(Jn,"comments",Jn.prototype.comments);t.defineProperty(Jn,{comments:"comments"},function(){return this.Tg},function(a){this.Tg!==a&&(this.Tg=a,this.J())});t.g(Jn,"maxIterations",Jn.prototype.jw); -t.defineProperty(Jn,{jw:"maxIterations"},function(){return this.In},function(a){this.In!==a&&0<=a&&(this.In=a,this.J())});t.g(Jn,"epsilonDistance",Jn.prototype.Cz);t.defineProperty(Jn,{Cz:"epsilonDistance"},function(){return this.kq},function(a){this.kq!==a&&0b.toVertex.index&&(this.network.sw(b),b.rev=!0);break;case Xn:for(b=this.network.vertexes.m;b.next();)b.value.vo=-1,b.value.finish=-1;for(a=this.network.edges.m;a.next();)a.value.forest=!1;this.dr=0;for(b.reset();b.next();)0===b.value.bc.count&&ro(this,b.value);for(b.reset();b.next();)-1===b.value.vo&&ro(this,b.value);for(a.reset();a.next();)b=a.value,b.forest|| -(c=b.fromVertex,d=c.finish,e=b.toVertex,g=e.finish,e.vos&&0s&&0b[this.uf]&&(this.ou=b[c]-1,this.uf=c),b[c]k)for(p=k+1;pl;p--)n=d[p],n.near===m&&n.im===m.im||h++;var q,r,s,u,x,E;if(0<=c)for(l=d[k].Ue,m=0;mu||n===u&&q>s)&&h++,xn||u===n&&s>q)&&h++);if(0>=c)for(l=d[k].Le,m=0;mu||n===u&&p>x)&&h++,sn||u===n&&x>p)&&h++);g[k*e+k]=h;for(l= -k+1;l=c)for(h=d[k].Le,E=d[l].Le,m=0;m=c&&(l=k.Ue);var m=null;0<=c&&(m=k.Le);var n=0,p=0,q=k.near;null!==q&&q.layer===k.layer&&(n+=q.column-1,p++);if(null!==l)for(q=0;q=c&&(l=k.Ue);var m=null;0<=c&&(m=k.Le);var n=0,p=[],q=k.near;null!==q&&q.layer===k.layer&&(p[n]=q.column-1,n++);if(null!==l)for(q=0;q>1,g[h]=n&1?p[m]:p[m-1]+p[m]>>1)}Ao(a,b,d);return g}function Jo(a,b,c,d,e,g){if(b.component===d){b.component=c;var h,k;if(e)for(var l=b.Sb;l.next();){var m=l.value.toVertex;h=b.layer-m.layer;k=Bo(l.value);h===k&&Jo(a,m,c,d,e,g)}if(g)for(l=b.bc;l.next();)m=l.value.fromVertex,h=m.layer-b.layer,k=Bo(l.value),h===k&&Jo(a,m,c,d,e,g)}} -function Ko(a,b,c,d,e,g){if(b.component===d){b.component=c;if(e)for(var h=b.Sb,k;h.next();)k=h.value.toVertex,Ko(a,k,c,d,e,g);if(g)for(b=b.bc;b.next();)h=b.value.fromVertex,Ko(a,h,c,d,e,g)}}function eo(a){for(a=a.vertexes.m;a.next();){var b=a.value;if(b.valid)return b}return null}function fo(a){for(a=a.vertexes.m;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.Sb;d.next();)if(d.value.toVertex.valid){c=!1;break}if(c)return b}}return null} -function ho(a){for(a=a.vertexes.m;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.bc;d.next();)if(d.value.fromVertex.valid){c=!1;break}if(c)return b}}return null}function ro(a,b){b.vo=a.dr;a.dr++;for(var c=b.Sb;c.next();){var d=c.value,e=d.toVertex;-1===e.vo&&(d.forest=!0,ro(a,e))}b.finish=a.dr;a.dr++} -Fk.prototype.assignLayers=function(){switch(this.Fn){case Lo:Mo(this);break;case No:for(var a,b=this.network.vertexes.m;b.next();)a=Oo(this,b.value),this.hb=Math.max(a,this.hb);for(b.reset();b.next();)a=b.value,a.layer=this.hb-a.layer;break;default:case Yn:Mo(this);for(b=this.network.vertexes.m;b.next();)b.value.valid=!1;for(b.reset();b.next();)0===b.value.bc.count&&Po(this,b.value);a=Infinity;for(b.reset();b.next();)a=Math.min(a,b.value.layer);this.hb=-1;for(b.reset();b.next();)b.value.layer-=a, -this.hb=Math.max(this.hb,b.value.layer)}};function Mo(a){for(var b=a.network.vertexes.m;b.next();){var c=Qo(a,b.value);a.hb=Math.max(c,a.hb)}}function Qo(a,b){var c=0;if(-1===b.layer){for(var d=b.Sb;d.next();)var e=d.value,g=Bo(e),c=Math.max(c,Qo(a,e.toVertex)+g);b.layer=c}else c=b.layer;return c}function Oo(a,b){var c=0;if(-1===b.layer){for(var d,e,g=b.bc;g.next();)e=g.value,d=Bo(e),c=Math.max(c,Oo(a,e.fromVertex)+d);b.layer=c}else c=b.layer;return c} -function Po(a,b){if(!b.valid){b.valid=!0;for(var c=b.Sb;c.next();)Po(a,c.value.toVertex);for(c=a.network.vertexes.m;c.next();)c.value.component=-1;for(var d=b.Ue.p,e=d.length,g=0;gk&&Jo(a,h.fromVertex,0,-1,!0,!1)}for(Jo(a,b,1,-1,!0,!0);0!==b.component;){for(var k=0,d=Infinity,l=0,m=null,n=a.network.vertexes.m;n.next();){var p=n.value;if(1===p.component){for(var q=0,r=!1,s=p.Ue.p,e=s.length,g=0;gd)&&!p&&(k=m,d=n)}if(0>g){for(c.reset();c.next();)g=c.value,1===g.component&&(g.layer-=e);b.component=0}else k.component=0}}}function yo(a,b,c){return 90===a.pa?c&&!b.rev||!c&&b.rev?270:90:180===a.pa?c&&!b.rev||!c&&b.rev?0:180:270===a.pa?c&&!b.rev||!c&&b.rev?90:270:c&&!b.rev||!c&&b.rev?180:0} -Fk.prototype.initializeIndices=function(){switch(this.vn){default:case Ro:for(var a,b=this.network.vertexes.m;b.next();){var c=b.value;a=c.layer;c.index=this.yd[a];this.yd[a]++}break;case Zn:b=this.network.vertexes.m;for(a=this.hb;0<=a;a--){for(;b.next();)b.value.layer===a&&-1===b.value.index&&So(this,b.value);b.reset()}break;case To:for(b=this.network.vertexes.m,a=0;a<=this.hb;a++){for(;b.next();)b.value.layer===a&&-1===b.value.index&&Uo(this,b.value);b.reset()}}}; -function So(a,b){var c=b.layer;b.index=a.yd[c];a.yd[c]++;for(var c=b.Le.Ve(),d=!0,e;d;)for(d=!1,e=0;eh.portFromColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;eh.portToColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;e=h;d--)g=Wo(this,d,-1)||g;e=this.countCrossings();e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,1)||g;e=this.countCrossings();e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g= -Wo(this,d,-1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this))}break;default:case $n:for(c=this.hb,h=0,k=a+1;(d=this.countCrossings())=h;d--)g=Wo(this,d,-1)||g;e=this.countCrossings();e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,1)||g;e=this.countCrossings();e>=a?Eo(this,b): -(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,-1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this))}}Eo(this,b)}; -function Vo(a,b,c){f&&(t.o(b,Fk,"medianBarycenterCrossingReduction:unfixedLayer"),t.o(c,Fk,"medianBarycenterCrossingReduction:direction"));var d=zo(a,b),e=a.yd[b],g=Io(a,b,c),h=Ho(a,b,c);for(c=0;cg+1&&(q+=4*(F-g),r+=4*(F-(g+1)))}L=d[g].Sb.m;for(L.reset();L.next();)if(G=L.value,G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g+1&&(r+=1)}L=d[g+1].bc.m;for(L.reset();L.next();)if(G=L.value,G.valid&&G.fromVertex.layer===b){G=G.fromVertex;for(F=0;d[F]!==G;)F++;Fg+1&&(q+=4*(F-(g+1)),r+=4*(F-g))}L=d[g+1].Sb.m;for(L.reset();L.next();)if(G=L.value, -G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g&&(q+=1)}var F=G=0,L=h[d[g].index],M=k[d[g].index],W=h[d[g+1].index],T=k[d[g+1].index];-1!==L&&(G+=Math.abs(L-s),F+=Math.abs(L-E));-1!==M&&(G+=Math.abs(M-s),F+=Math.abs(M-E));-1!==W&&(G+=Math.abs(W-u),F+=Math.abs(W-x));-1!==T&&(G+=Math.abs(T-u),F+=Math.abs(T-x));if(r>1)+8*g;this.Cb*=8}if(0!==(this.ei&$o))for(b=!0;b;){b=!1;for(a=this.uf+1;a<=this.hb;a++)b=ap(this,a,1)||b;for(a=this.uf- -1;0<=a;a--)b=ap(this,a,-1)||b;b=ap(this,this.uf,0)||b}if(0!==(this.ei&bp)){for(a=this.uf+1;a<=this.hb;a++)cp(this,a,1);for(a=this.uf-1;0<=a;a--)cp(this,a,-1);cp(this,this.uf,0)}c&&(dp(this,-1),dp(this,1));if(0!==(this.ei&$o))for(b=!0;b;){b=!1;b=ap(this,this.uf,0)||b;for(a=this.uf+1;a<=this.hb;a++)b=ap(this,a,0)||b;for(a=this.uf-1;0<=a;a--)b=ap(this,a,0)||b}};function ap(a,b,c){f&&(t.o(b,Fk,"bendStraighten:unfixedLayer"),t.o(c,Fk,"bendStraighten:direction"));for(var d=!1;ep(a,b,c);)d=!0;return d} -function ep(a,b,c){f&&(t.o(b,Fk,"shiftbendStraighten:unfixedLayer"),t.o(c,Fk,"shiftbendStraighten:direction"));var d,e=zo(a,b),g=a.yd[b],h=Ho(a,b,-1);if(0c)for(d=0;dd-1||n-e[d-1].column-1>p+a.nodeMinColumnSpace(e[d-1],!1)?n-1:n,q=d+1>=g||e[d+1].column-n-1>q+a.nodeMinColumnSpace(e[d+1],!0)?n+1:n,r=0,s=0,u=0,x, -E,F,G;if(0>=c)for(var L=e[d].bc.m;L.next();)x=L.value,x.valid&&x.fromVertex.layer!==b&&(E=Co(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.fromVertex.column,r+=(Math.abs(n+G-(x+F))+1)*E,s+=(Math.abs(p+G-(x+F))+1)*E,u+=(Math.abs(q+G-(x+F))+1)*E);if(0<=c)for(L=e[d].Sb.m;L.next();)x=L.value,x.valid&&x.toVertex.layer!==b&&(E=Co(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.toVertex.column,r+=(Math.abs(n+F-(x+G))+1)*E,s+=(Math.abs(p+F-(x+G))+1)*E,u+=(Math.abs(q+F-(x+G))+1)*E);G=F=E=0;x=h[e[d].index]; -L=k[e[d].index];-1!==x&&(E+=Math.abs(x-n),F+=Math.abs(x-p),G+=Math.abs(x-q));-1!==L&&(E+=Math.abs(L-n),F+=Math.abs(L-p),G+=Math.abs(L-q));if(s=h[c]?n=l:m<=h[c]&&(n=m));n!==k&&(g=!0,d[c].column=n)}Ao(a,b,d);a.normalize()} -function fp(a,b){f&&(t.o(b,Fk,"packAux:column"),t.o(1,Fk,"packAux:direction"));for(var c=!0,d=a.network.vertexes.m,e;d.next();){e=d.value;var g=a.nodeMinColumnSpace(e,!0),h=a.nodeMinColumnSpace(e,!1);if(e.column-g<=b&&e.column+h>=b){c=!1;break}}g=!1;if(c)for(d.reset();d.next();)e=d.value,e.column>b&&(e.column-=1,g=!0);return g} -function gp(a,b){f&&(t.o(b,Fk,"tightPackAux:column"),t.o(1,Fk,"tightPackAux:direction"));var c=b,c=b+1,d,e=[],g=[];for(d=0;d<=a.hb;d++)e[d]=!1,g[d]=!1;for(var h=a.network.vertexes.m;h.next();){d=h.value;var k=d.column-a.nodeMinColumnSpace(d,!0),l=d.column+a.nodeMinColumnSpace(d,!1);k<=b&&l>=b&&(e[d.layer]=!0);k<=c&&l>=c&&(g[d.layer]=!0)}k=!0;c=!1;for(d=0;d<=a.hb;d++)k=k&&!(e[d]&&g[d]);if(k)for(h.reset();h.next();)d=h.value,d.column>b&&(d.column-=1,c=!0);return c} -function dp(a,b){f&&t.o(b,Fk,"componentPack:direction");for(var c=0;c<=a.Cb;c++)for(;fp(a,c););a.normalize();for(c=0;ce?Eo(a,d):hb)for(c=a.Cb;0<=c;c--)for(d=Do(a),e=Go(a),g=e+1;ee?Eo(a,d):hc)for(d.reset();d.next();)e=d.value,e.column+a.nodeMinColumnSpace(e,!1)>=b&&(e.component=a.Rf);a.Rf++;for(d.reset();d.next();)e=d.value,-1===e.component&&(Ko(a,e,a.Rf,-1,!0,!0),a.Rf++);b=[];for(e=0;ec)for(k=a.Cb;0c)for(d.reset();d.next();)e=d.value,g[e.component]&&(e.column+=1)}Fk.prototype.commitLayout=function(){if(this.il)for(var a=xo(this,!0),b=xo(this,!1),c=this.network.edges.m,d;c.next();)d=c.value.link,null!==d&&(d.fb=a,d.gb=b);this.commitNodes();this.Gs&&this.commitLinks()}; -function xo(a,b){return 270===a.pa?b?Pb:Vb:90===a.pa?b?Vb:Pb:180===a.pa?b?Tb:Ub:b?Ub:Tb} -Fk.prototype.commitNodes=function(){this.hh=[];this.wg=[];this.sf=[];this.Ad=[];for(var a=0;a<=this.hb;a++)this.hh[a]=0,this.wg[a]=0,this.sf[a]=0,this.Ad[a]=0;for(var a=this.network.vertexes.m,b,c;a.next();)b=a.value,c=b.layer,this.hh[c]=Math.max(this.hh[c],this.nodeMinLayerSpace(b,!0)),this.wg[c]=Math.max(this.wg[c],this.nodeMinLayerSpace(b,!1));b=0;for(var d=this.En,e=0;e<=this.hb;e++)c=d,0>=this.hh[e]+this.wg[e]&&(c=0),0=Ja.R.y&&Zb<=Ja.R.bottom&&(ya=Ja.Aa+hf,Zb=Zb=Ja.R.x&&Zb<=Ja.R.right&&(ya=Ja.Ma+hf,Zb=Zbqb.y&&(hd=Rc.y>qb.y?0:Ya.xsb.x&&(Cc=se.x>sb.x?0:Sc.yb.layer?1:a.xeb.xe?1:a.Gdb.Gd?1:0:0}; -Fk.prototype.VE=function(a,b){return a instanceof ip&&b instanceof ip&&a!==b?a.Yab.Ya||a.Ghb.Gh||a.xeb.xe?1:a.Gdb.Gd?1:0:0};Fk.prototype.uw=function(a,b){return a instanceof ip&&b instanceof ip&&a!==b?a.Mdb.Md||a.Ghb.Gh||a.xeb.xe?1:a.Gdb.Gd?1:0:0};Fk.prototype.I=function(a,b){f&&(t.o(a,Fk,"isApprox:a"),t.o(b,Fk,"isApprox:b"));var c=a-b;return-1c}; -function jp(a,b,c,d){f&&(t.o(a,Fk,"isUnoccupied2:px"),t.o(b,Fk,"isUnoccupied2:py"),t.o(c,Fk,"isUnoccupied2:qx"),t.o(d,Fk,"isUnoccupied2:qy"));return!0}function zo(a,b){var c,d=a.yd[b];if(d>=a.yg.length){c=[];var e;for(e=0;ea&&(this.ei=a,this.J())});t.g(Fk,"setsPortSpots",Fk.prototype.il);t.defineProperty(Fk,{il:"setsPortSpots"},function(){return this.kh},function(a){this.kh!==a&&"boolean"===typeof a&&(this.kh=a,this.J())});t.g(Fk,"linkSpacing",Fk.prototype.Vo);t.defineProperty(Fk,{Vo:"linkSpacing"},function(){return this.hj},function(a){this.hj!==a&&(this.hj=a,this.J())});t.A(Fk,{kJ:"maxLayer"},function(){return this.hb}); -t.A(Fk,{iJ:"maxIndex"},function(){return this.ou});t.A(Fk,{hJ:"maxColumn"},function(){return this.Cb});t.A(Fk,{lJ:"minIndexLayer"},function(){return this.Yq});t.A(Fk,{jJ:"maxIndexLayer"},function(){return this.uf});var Xn;Fk.CycleDepthFirst=Xn=t.w(Fk,"CycleDepthFirst",0);var co;Fk.CycleGreedy=co=t.w(Fk,"CycleGreedy",1);var Yn;Fk.LayerOptimalLinkLength=Yn=t.w(Fk,"LayerOptimalLinkLength",0);var Lo;Fk.LayerLongestPathSink=Lo=t.w(Fk,"LayerLongestPathSink",1);var No; -Fk.LayerLongestPathSource=No=t.w(Fk,"LayerLongestPathSource",2);var Zn;Fk.InitDepthFirstOut=Zn=t.w(Fk,"InitDepthFirstOut",0);var To;Fk.InitDepthFirstIn=To=t.w(Fk,"InitDepthFirstIn",1);var Ro;Fk.InitNaive=Ro=t.w(Fk,"InitNaive",2);var Xo;Fk.AggressiveNone=Xo=t.w(Fk,"AggressiveNone",0);var $n;Fk.AggressiveLess=$n=t.w(Fk,"AggressiveLess",1);var Yo;Fk.AggressiveMore=Yo=t.w(Fk,"AggressiveMore",2);Fk.PackNone=0;var Zo;Fk.PackExpand=Zo=1;var $o;Fk.PackStraighten=$o=2;var bp;Fk.PackMedian=bp=4;var ao; -Fk.PackAll=ao=7;function bo(){ra.call(this)}t.ea("LayeredDigraphNetwork",bo);t.Ja(bo,ra);bo.prototype.createVertex=function(){return new kp};bo.prototype.createEdge=function(){return new lp};function kp(){sa.call(this);this.index=this.column=this.layer=-1;this.component=NaN;this.near=null;this.valid=!1;this.finish=this.vo=NaN;this.im=0;this.gA=this.hA=void 0}t.ea("LayeredDigraphVertex",kp);t.Ja(kp,sa); -function lp(){ta.call(this);this.forest=this.rev=this.valid=!1;this.portToPos=this.portFromPos=NaN;this.portToColOffset=this.portFromColOffset=0}t.ea("LayeredDigraphEdge",lp);t.Ja(lp,ta);function Z(){0b.level)return!1;a.removeChild(c.parent,c)}return!0} -Z.prototype.removeChild=function(a,b){f&&t.k(a,qp,Z,"removeChild:p");f&&t.k(b,qp,Z,"removeChild:c");if(null!==a&&null!==b){for(var c=a.children,d=0,e=0;eh?Zp(b,l,ab,L,M):$p(b,l,ab,L,M);ab=R[0];L=R[1];M=R[2];break;case Np:for(n=0;nu&&(xaKb&&(eq(b,-Kb,0,ua,n-1),fq(T,-Kb,0),fq(U,-Kb,0),Kb=0);p.ja.q(Kb,Na);L=Math.max(L,da);M=Math.max(M,W+(0===Ja?0:F)+ya.height);xa=da}else{0u&&(NaKb&&(eq(b,0,-Kb,ua,n-1),fq(T,0,-Kb),fq(U,0,-Kb),Kb=0);p.ja.q(xa,Kb);M=Math.max(M,R);L=Math.max(L,W+(0===Ja?0:F)+ya.width);Na=R}Ka++}0k&&(k=0),135r&&(r=0), -q===Op&&(m+=x/2+b.N.y),l+=e+d):c?(null===b.comments?e>L&&(q=jq(q,e-L,0),l=q[0],m=q[1],L=e,k=0):L=hq(b,L,k),0>k&&(l-=k,k=0),135M&&(q=jq(q,0,g-M),l=q[0],m=q[1],M=g,r=0):M=iq(b,M,r),0>r&&(m-=r,r=0),l+=e+d);if(0h[0].x?h[2].assign(h[1]):h[1].assign(h[2])),h[3].yh[0].x?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(k+e,0),q[1].q(q[0].x,g),q[2].yh[0].y?h[2].assign(h[1]):h[1].assign(h[2])),h[3].xh[0].y?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(0,r+g),q[1].q(e,q[0].y),q[2].xc?Zp(b,e,Ja,M,W):$p(b,e,Ja,M,W);Ja=W[0];M=W[1];W=W[2];break;case Np:for(k=0;kr&&(Ur&&(dap&&(p=0),135G&&(G=0));b.Ha.q(p,G);b.Ua.q(M,W)}} -function Zp(a,b,c,d,e){f&&t.k(a,qp,Z,"layoutBusChildrenPosDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ua.width;e=h.Ua.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=90===Up(a),n=0,p=0,q=0,r=0;rm&&(d-=m),e=Math.max(e,Math.max(F,q)+b+s.height),0>h.ja.x&&(c=sq(a,h.ja.x,!1,c,k))):(h.ja.q(d+b,c+k/2-h.N.y-h.Ha.y),d=Math.max(d,Math.max(E,p)+b+s.width),m=c+k/2-h.N.y-h.Ha.y,e=Math.max(e,m+s.height),0>m&&(e-=m),0>h.ja.y&&(c=sq(a,h.ja.y,!0,c,k))));a=[];a[0]=c;a[1]=d;a[2]=e;return a} -function $p(a,b,c,d,e){f&&t.k(a,qp,Z,"layoutBusChildrenNegDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ua.width;e=h.Ua.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=270===Up(a),n=0,p=0,q=0,r=0;rp&&(d-=p),e=Math.max(e,Math.abs(Math.min(F,q))+l+s.height),0>h.ja.x&&(c=sq(a,h.ja.x,!1,c,k))):(h.ja.q(-d-s.width-l,c+k/2-h.N.y-h.Ha.y),d=Math.max(d,Math.abs(Math.min(E,p))+l+s.width),p=c+k/2-h.N.y-h.Ha.y,e=Math.max(e,p+s.height),0>p&&(e-=p),0>h.ja.y&&(c=sq(a,h.ja.y,!0,c,k))));for(r=0;rd&&(d=c+a.width);0>c&&(d-=c);return d;case Vp:return a.width>b?a.width:b;case Wp:return 2*a.N.x>b?a.width:b+a.width-2*a.N.x;case Mp:case Bp:return d=Math.min(0,c),c=Math.max(b,c+a.width),Math.max(a.width,c-d);case Np:return a.width-a.N.x+a.nodeSpacing/2+b;case Op:return Math.max(a.width,a.N.x+a.nodeSpacing/2+b);default:return b}} -function iq(a,b,c){f&&t.k(a,qp,Z,"calculateSubheight:v");switch(a.alignment){case Kp:case gq:var d=b;c+a.height>d&&(d=c+a.height);0>c&&(d-=c);return d;case Vp:return a.height>b?a.height:b;case Wp:return 2*a.N.y>b?a.height:b+a.height-2*a.N.y;case Mp:case Bp:return d=Math.min(0,c),c=Math.max(b,c+a.height),Math.max(a.height,c-d);case Np:return a.height-a.N.y+a.nodeSpacing/2+b;case Op:return Math.max(a.height,a.N.y+a.nodeSpacing/2+b);default:return b}} -function jq(a,b,c){f&&t.k(a,ca,Z,"alignOffset:align");switch(a){case gq:b/=2;c/=2;break;case Kp:b/=2;c/=2;break;case Vp:c=b=0;break;case Wp:break;default:t.l("Unhandled alignment value "+a.toString())}a=[];a[0]=b;a[1]=c;return a}function bq(a,b,c,d,e,g){f&&t.k(a,qp,Z,"shiftRelPosAlign:v");f&&t.k(b,ca,Z,"shiftRelPosAlign:align");b=jq(b,c,d);eq(a,b[0],b[1],e,g)}function eq(a,b,c,d,e){f&&t.k(a,qp,Z,"shiftRelPos:v");if(0!==b||0!==c)for(a=a.children;d<=e;d++){var g=a[d].ja;g.x+=b;g.y+=c}} -function cq(a,b,c,d){f&&(t.k(b,qp,Z,"recordMidPoints:v"),t.j(c,"number",Z,"recordMidPoints:x"),t.j(d,"number",Z,"recordMidPoints:y"));var e=b.parent;switch(a.rf){case np:for(a=b.bc;a.next();)b=a.value,b.fromVertex===e&&b.nr.q(c,d);break;case up:for(a=b.Sb;a.next();)b=a.value,b.toVertex===e&&b.nr.q(c,d);break;default:t.l("Unhandled path value "+a.rf.toString())}}function fq(a,b,c){for(var d=0;dn.length||null===p||2>p.length))for(g= -e=0;eu&&k.yk.y&&ub.length||null===e||2>e.length)d=null;else{m=aq(a,b.length+e.length);for(d=l=k=0;lk;)u=e[l++],m[d++].q(u.x+g,u.y);e=aq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=aq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x, -k.y);k=aq(a,g);for(e=0;en.length||null===p||2>p.length))for(g=e=0;el&&k.xk.x&&lb.length||null===e||2>e.length)d=null;else{m=aq(a,b.length+e.length);for(d=l=k=0;lk;)u=e[l++],m[d++].q(u.x,u.y+g);e=aq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=aq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x,k.y);k=aq(a,g);for(e=0;e=a?0:135>=a?90:225>=a?180:315>=a?270:0} -function Xp(a){f&&t.k(a,qp,Z,"computeLayerSpacing:v");var b=Up(a),b=90===b||270===b,c=a.layerSpacing;if(0=a&&(this.ra.nodeIndentPastParent=a,this.J())});t.g(Z,"nodeSpacing",Z.prototype.nodeSpacing); -t.defineProperty(Z,{nodeSpacing:"nodeSpacing"},function(){return this.ra.nodeSpacing},function(a){this.ra.nodeSpacing!==a&&(this.ra.nodeSpacing=a,this.J())});t.g(Z,"layerSpacing",Z.prototype.layerSpacing);t.defineProperty(Z,{layerSpacing:"layerSpacing"},function(){return this.ra.layerSpacing},function(a){this.ra.layerSpacing!==a&&(this.ra.layerSpacing=a,this.J())});t.g(Z,"layerSpacingParentOverlap",Z.prototype.layerSpacingParentOverlap); -t.defineProperty(Z,{layerSpacingParentOverlap:"layerSpacingParentOverlap"},function(){return this.ra.layerSpacingParentOverlap},function(a){this.ra.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.ra.layerSpacingParentOverlap=a,this.J())});t.g(Z,"compaction",Z.prototype.compaction);t.defineProperty(Z,{compaction:"compaction"},function(){return this.ra.compaction},function(a){this.ra.compaction!==a&&(f&&t.k(a,ca,Z,"compaction"),a===Rp||a===Tp)&&(this.ra.compaction=a,this.J())}); -t.g(Z,"breadthLimit",Z.prototype.breadthLimit);t.defineProperty(Z,{breadthLimit:"breadthLimit"},function(){return this.ra.breadthLimit},function(a){this.ra.breadthLimit!==a&&0<=a&&(this.ra.breadthLimit=a,this.J())});t.g(Z,"rowSpacing",Z.prototype.rowSpacing);t.defineProperty(Z,{rowSpacing:"rowSpacing"},function(){return this.ra.rowSpacing},function(a){this.ra.rowSpacing!==a&&(this.ra.rowSpacing=a,this.J())});t.g(Z,"rowIndent",Z.prototype.rowIndent); -t.defineProperty(Z,{rowIndent:"rowIndent"},function(){return this.ra.rowIndent},function(a){this.ra.rowIndent!==a&&0<=a&&(this.ra.rowIndent=a,this.J())});t.g(Z,"commentSpacing",Z.prototype.commentSpacing);t.defineProperty(Z,{commentSpacing:"commentSpacing"},function(){return this.ra.commentSpacing},function(a){this.ra.commentSpacing!==a&&(this.ra.commentSpacing=a,this.J())});t.g(Z,"commentMargin",Z.prototype.commentMargin); -t.defineProperty(Z,{commentMargin:"commentMargin"},function(){return this.ra.commentMargin},function(a){this.ra.commentMargin!==a&&(this.ra.commentMargin=a,this.J())});t.g(Z,"setsPortSpot",Z.prototype.setsPortSpot);t.defineProperty(Z,{setsPortSpot:"setsPortSpot"},function(){return this.ra.setsPortSpot},function(a){this.ra.setsPortSpot!==a&&(this.ra.setsPortSpot=a,this.J())});t.g(Z,"portSpot",Z.prototype.portSpot); -t.defineProperty(Z,{portSpot:"portSpot"},function(){return this.ra.portSpot},function(a){this.ra.portSpot.K(a)||(this.ra.portSpot=a,this.J())});t.g(Z,"setsChildPortSpot",Z.prototype.setsChildPortSpot);t.defineProperty(Z,{setsChildPortSpot:"setsChildPortSpot"},function(){return this.ra.setsChildPortSpot},function(a){this.ra.setsChildPortSpot!==a&&(this.ra.setsChildPortSpot=a,this.J())});t.g(Z,"childPortSpot",Z.prototype.childPortSpot); -t.defineProperty(Z,{childPortSpot:"childPortSpot"},function(){return this.ra.childPortSpot},function(a){this.ra.childPortSpot.K(a)||(this.ra.childPortSpot=a,this.J())});t.g(Z,"alternateSorting",Z.prototype.OG);t.defineProperty(Z,{OG:"alternateSorting"},function(){return this.qa.sorting},function(a){this.qa.sorting!==a&&(f&&t.k(a,ca,Z,"alternateSorting"),a===Gp||a===Hp||a===Ip||Jp)&&(this.qa.sorting=a,this.J())});t.g(Z,"alternateComparer",Z.prototype.CG); -t.defineProperty(Z,{CG:"alternateComparer"},function(){return this.qa.comparer},function(a){this.qa.comparer!==a&&(f&&t.j(a,"function",Z,"alternateComparer"),this.qa.comparer=a,this.J())});t.g(Z,"alternateAngle",Z.prototype.wG);t.defineProperty(Z,{wG:"alternateAngle"},function(){return this.qa.angle},function(a){this.qa.angle===a||0!==a&&90!==a&&180!==a&&270!==a||(this.qa.angle=a,this.J())});t.g(Z,"alternateAlignment",Z.prototype.vG); -t.defineProperty(Z,{vG:"alternateAlignment"},function(){return this.qa.alignment},function(a){this.qa.alignment!==a&&(f&&t.nb(a,Z,Z,"alternateAlignment"),this.qa.alignment=a,this.J())});t.g(Z,"alternateNodeIndent",Z.prototype.GG);t.defineProperty(Z,{GG:"alternateNodeIndent"},function(){return this.qa.nodeIndent},function(a){this.qa.nodeIndent!==a&&0<=a&&(this.qa.nodeIndent=a,this.J())});t.g(Z,"alternateNodeIndentPastParent",Z.prototype.HG); -t.defineProperty(Z,{HG:"alternateNodeIndentPastParent"},function(){return this.qa.nodeIndentPastParent},function(a){this.qa.nodeIndentPastParent!==a&&0<=a&&1>=a&&(this.qa.nodeIndentPastParent=a,this.J())});t.g(Z,"alternateNodeSpacing",Z.prototype.IG);t.defineProperty(Z,{IG:"alternateNodeSpacing"},function(){return this.qa.nodeSpacing},function(a){this.qa.nodeSpacing!==a&&(this.qa.nodeSpacing=a,this.J())});t.g(Z,"alternateLayerSpacing",Z.prototype.EG); -t.defineProperty(Z,{EG:"alternateLayerSpacing"},function(){return this.qa.layerSpacing},function(a){this.qa.layerSpacing!==a&&(this.qa.layerSpacing=a,this.J())});t.g(Z,"alternateLayerSpacingParentOverlap",Z.prototype.FG);t.defineProperty(Z,{FG:"alternateLayerSpacingParentOverlap"},function(){return this.qa.layerSpacingParentOverlap},function(a){this.qa.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.qa.layerSpacingParentOverlap=a,this.J())});t.g(Z,"alternateCompaction",Z.prototype.BG); -t.defineProperty(Z,{BG:"alternateCompaction"},function(){return this.qa.compaction},function(a){this.qa.compaction!==a&&(f&&t.k(a,ca,Z,"alternateCompaction"),a===Rp||a===Tp)&&(this.qa.compaction=a,this.J())});t.g(Z,"alternateBreadthLimit",Z.prototype.xG);t.defineProperty(Z,{xG:"alternateBreadthLimit"},function(){return this.qa.breadthLimit},function(a){this.qa.breadthLimit!==a&&0<=a&&(this.qa.breadthLimit=a,this.J())});t.g(Z,"alternateRowSpacing",Z.prototype.LG); -t.defineProperty(Z,{LG:"alternateRowSpacing"},function(){return this.qa.rowSpacing},function(a){this.qa.rowSpacing!==a&&(this.qa.rowSpacing=a,this.J())});t.g(Z,"alternateRowIndent",Z.prototype.KG);t.defineProperty(Z,{KG:"alternateRowIndent"},function(){return this.qa.rowIndent},function(a){this.qa.rowIndent!==a&&0<=a&&(this.qa.rowIndent=a,this.J())});t.g(Z,"alternateCommentSpacing",Z.prototype.AG); -t.defineProperty(Z,{AG:"alternateCommentSpacing"},function(){return this.qa.commentSpacing},function(a){this.qa.commentSpacing!==a&&(this.qa.commentSpacing=a,this.J())});t.g(Z,"alternateCommentMargin",Z.prototype.zG);t.defineProperty(Z,{zG:"alternateCommentMargin"},function(){return this.qa.commentMargin},function(a){this.qa.commentMargin!==a&&(this.qa.commentMargin=a,this.J())});t.g(Z,"alternateSetsPortSpot",Z.prototype.NG); -t.defineProperty(Z,{NG:"alternateSetsPortSpot"},function(){return this.qa.setsPortSpot},function(a){this.qa.setsPortSpot!==a&&(this.qa.setsPortSpot=a,this.J())});t.g(Z,"alternatePortSpot",Z.prototype.JG);t.defineProperty(Z,{JG:"alternatePortSpot"},function(){return this.qa.portSpot},function(a){this.qa.portSpot.K(a)||(this.qa.portSpot=a,this.J())});t.g(Z,"alternateSetsChildPortSpot",Z.prototype.MG); -t.defineProperty(Z,{MG:"alternateSetsChildPortSpot"},function(){return this.qa.setsChildPortSpot},function(a){this.qa.setsChildPortSpot!==a&&(this.qa.setsChildPortSpot=a,this.J())});t.g(Z,"alternateChildPortSpot",Z.prototype.yG);t.defineProperty(Z,{yG:"alternateChildPortSpot"},function(){return this.qa.childPortSpot},function(a){this.qa.childPortSpot.K(a)||(this.qa.childPortSpot=a,this.J())});var mp;Z.PathDefault=mp=t.w(Z,"PathDefault",-1);var np;Z.PathDestination=np=t.w(Z,"PathDestination",0);var up; -Z.PathSource=up=t.w(Z,"PathSource",1);var Gp;Z.SortingForwards=Gp=t.w(Z,"SortingForwards",10);var Hp;Z.SortingReverse=Hp=t.w(Z,"SortingReverse",11);var Ip;Z.SortingAscending=Ip=t.w(Z,"SortingAscending",12);var Jp;Z.SortingDescending=Jp=t.w(Z,"SortingDescending",13);var gq;Z.AlignmentCenterSubtrees=gq=t.w(Z,"AlignmentCenterSubtrees",20);var Kp;Z.AlignmentCenterChildren=Kp=t.w(Z,"AlignmentCenterChildren",21);var Vp;Z.AlignmentStart=Vp=t.w(Z,"AlignmentStart",22);var Wp; -Z.AlignmentEnd=Wp=t.w(Z,"AlignmentEnd",23);var Mp;Z.AlignmentBus=Mp=t.w(Z,"AlignmentBus",24);var Bp;Z.AlignmentBusBranching=Bp=t.w(Z,"AlignmentBusBranching",25);var Np;Z.AlignmentTopLeftBus=Np=t.w(Z,"AlignmentTopLeftBus",26);var Op;Z.AlignmentBottomRightBus=Op=t.w(Z,"AlignmentBottomRightBus",27);var Rp;Z.CompactionNone=Rp=t.w(Z,"CompactionNone",30);var Tp;Z.CompactionBlock=Tp=t.w(Z,"CompactionBlock",31);var op;Z.StyleLayered=op=t.w(Z,"StyleLayered",40);var Fp; -Z.StyleLastParents=Fp=t.w(Z,"StyleLastParents",41);var Ep;Z.StyleAlternating=Ep=t.w(Z,"StyleAlternating",42);var Dp;Z.StyleRootOnly=Dp=t.w(Z,"StyleRootOnly",43);var pp;Z.ArrangementVertical=pp=t.w(Z,"ArrangementVertical",50);var uq;Z.ArrangementHorizontal=uq=t.w(Z,"ArrangementHorizontal",51);var tp;Z.ArrangementFixedRoots=tp=t.w(Z,"ArrangementFixedRoots",52);function rp(){ra.call(this)}t.ea("TreeNetwork",rp);t.Ja(rp,ra);rp.prototype.createVertex=function(){return new qp};rp.prototype.createEdge=function(){return new wq}; -function qp(){sa.call(this);this.initialized=!1;this.parent=null;this.children=[];this.maxGenerationCount=this.maxChildrenCount=this.descendantCount=this.level=0;this.comments=null;this.ja=new v(0,0);this.Ua=new ea(0,0);this.Ha=new v(0,0);this.mp=this.lp=this.yI=!1;this.Zs=this.Is=null;this.sorting=Gp;this.comparer=rn;this.angle=0;this.alignment=Kp;this.nodeIndentPastParent=this.nodeIndent=0;this.nodeSpacing=20;this.layerSpacing=50;this.layerSpacingParentOverlap=0;this.compaction=Tp;this.breadthLimit= -0;this.rowSpacing=25;this.commentSpacing=this.rowIndent=10;this.commentMargin=20;this.setsPortSpot=!0;this.portSpot=vb;this.setsChildPortSpot=!0;this.childPortSpot=vb}t.ea("TreeVertex",qp);t.Ja(qp,sa); -qp.prototype.copyInheritedPropertiesFrom=function(a){null!==a&&(this.sorting=a.sorting,this.comparer=a.comparer,this.angle=a.angle,this.alignment=a.alignment,this.nodeIndent=a.nodeIndent,this.nodeIndentPastParent=a.nodeIndentPastParent,this.nodeSpacing=a.nodeSpacing,this.layerSpacing=a.layerSpacing,this.layerSpacingParentOverlap=a.layerSpacingParentOverlap,this.compaction=a.compaction,this.breadthLimit=a.breadthLimit,this.rowSpacing=a.rowSpacing,this.rowIndent=a.rowIndent,this.commentSpacing=a.commentSpacing, -this.commentMargin=a.commentMargin,this.setsPortSpot=a.setsPortSpot,this.portSpot=a.portSpot,this.setsChildPortSpot=a.setsChildPortSpot,this.childPortSpot=a.childPortSpot)};t.A(qp,{mm:"childrenCount"},function(){return this.children.length});t.g(qp,"relativePosition",qp.prototype.sI);t.defineProperty(qp,{sI:"relativePosition"},function(){return this.ja},function(a){t.k(a,v,qp,"relativePosition");this.ja.set(a)});t.g(qp,"subtreeSize",qp.prototype.GI); -t.defineProperty(qp,{GI:"subtreeSize"},function(){return this.Ua},function(a){t.k(a,ea,qp,"subtreeSize");this.Ua.set(a)});t.g(qp,"subtreeOffset",qp.prototype.FI);t.defineProperty(qp,{FI:"subtreeOffset"},function(){return this.Ha},function(a){t.k(a,v,qp,"subtreeOffset");this.Ha.set(a)});function wq(){ta.call(this);this.nr=new v(0,0)}t.ea("TreeEdge",wq);t.Ja(wq,ta); -wq.prototype.commit=function(){var a=this.link;if(null!==a&&!a.Di){var b=this.network.Vb,c=null,d=null;switch(b.rf){case np:c=this.fromVertex;d=this.toVertex;break;case up:c=this.toVertex;d=this.fromVertex;break;default:t.l("Unhandled path value "+b.rf.toString())}if(null!==c&&null!==d)if(b=this.nr,0!==b.x||0!==b.y||c.yI){var d=c.Gb,e=Up(c),g=Xp(c),h=c.rowSpacing;a.updateRoute();var k=a.ze===Kg,l=a.Ub,m,n,p,q;a.jl();if(l||k){for(m=2;4q.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Yp(c))))):c.alignment===Vp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Yp(c))))):c.alignment===Vp?(e=d.left+b.x,0===b.x&&n.xq.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Yp(c))))):c.alignment===Vp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Yp(c))))):c.alignment===Vp?(e=d.left+b.x,0===b.x&&n.xl?h=null:(m=parseFloat(n.getAttribute("cx")),isNaN(m)&&(m=0),n=parseFloat(n.getAttribute("cy")),isNaN(n)&&(n=0),p=new I(Lc),p.la=0,p.ma=0,p.D=2*l,p.F=2*l,h.position=new v(m-l,n-l),h.Xc=p);break;case "ellipse":p=g;h=new Y;l=parseFloat(p.getAttribute("rx"));isNaN(l)||0>l?h=null:(m=parseFloat(p.getAttribute("ry")),isNaN(m)||0>m?h=null:(n=parseFloat(p.getAttribute("cx")),isNaN(n)&&(n=0),p=parseFloat(p.getAttribute("cy")), -isNaN(p)&&(p=0),q=new I(Lc),q.la=0,q.ma=0,q.D=2*l,q.F=2*m,h.position=new v(n-l,p-m),h.Xc=q));break;case "rect":q=g;h=new Y;l=parseFloat(q.getAttribute("width"));if(isNaN(l)||0>l)h=null;else if(m=parseFloat(q.getAttribute("height")),isNaN(m)||0>m)h=null;else{n=parseFloat(q.getAttribute("x"));isNaN(n)&&(n=0);p=parseFloat(q.getAttribute("y"));isNaN(p)&&(p=0);var r=q.getAttribute("rx"),s=q.getAttribute("ry"),q=parseFloat(r);if(isNaN(q)||0>q)q=0;var u=parseFloat(s);if(isNaN(u)||0>u)u=0;!r&&s?q=u:r&&!s&& -(u=q);q=Math.min(q,l/2);u=Math.min(u,m/2);s=void 0;0===q&&0===u?(s=new I(Kc),s.la=0,s.ma=0,s.D=l,s.F=m):(s=D.sa/2,r=t.u(),J(r,q,0,!0),r.lineTo(l-q,0),K(r,l-q*s,0,l,u*s,l,u),r.lineTo(l,m-u),K(r,l,m-u*s,l-q*s,m,l-q,m),r.lineTo(q,m),K(r,q*s,m,0,m-u*s,0,m-u),r.lineTo(0,u),K(r,0,u*s,q*s,0,q,0),N(r),s=r.s,t.v(r));h.position=new v(n,p);h.Xc=s}break;case "polygon":h=Bq(g);break;case "polyline":h=Bq(g)}if(null!==h){if(h instanceof Y){l=yq(a,g,"fill");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+ -1,l.length-1),l=a["_brush"+l],h.fill=l instanceof Ud?l:"black"):h.fill=null===l?"black":"none"===l?null:l;l=yq(a,g,"stroke");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+1,l.length-1),l=a["_brush"+l],h.stroke=l instanceof Ud?l:"black"):h.stroke="none"===l?null:l;l=parseFloat(yq(a,g,"stroke-width"));isNaN(l)||(h.bb=l);l=yq(a,g,"stroke-linecap");null!==l&&(h.lF=l);if(l=yq(a,g,"stroke-dasharray")){m=l.split(",");n=[];for(l=0;lg.length)return null;for(var h,d=new A(O),k,l,m=1;m=a.length?a.push(c):a.splice(b,0,c):t.l("Cannot insert an object into an HTMLCollection or NodeList: "+c+" at "+b)},ri:function(a,b){t.lc&&t.lc(a)&&(a=a());Array.isArray(a)?b>=a.length?a.pop():a.splice(b,1):t.l("Cannot remove an object from an HTMLCollection or NodeList at "+b)},gx:[],M:function(){var a=t.gx.pop();return void 0===a?new v:a},cc:function(a,b){var c=t.gx.pop();if(void 0===c)return new v(a,b);c.x=a;c.y=b;return c},B:function(a){t.gx.push(a)}, +bB:[],kl:function(){var a=t.bB.pop();return void 0===a?new ea:a},Qj:function(a){t.bB.push(a)},hx:[],qf:function(){var a=t.hx.pop();return void 0===a?new w:a},Yj:function(a,b,c,d){var e=t.hx.pop();if(void 0===e)return new w(a,b,c,d);e.x=a;e.y=b;e.width=c;e.height=d;return e},Ic:function(a){t.hx.push(a)},cB:[],Og:function(){var a=t.cB.pop();return void 0===a?new fa:a},Ne:function(a){t.cB.push(a)},ix:null,u:function(){var a=t.ix;return null!==a?(t.ix=null,a):new ha},v:function(a){a.reset();t.ix=a},aB:[], +yb:function(){var a=t.aB.pop();return void 0===a?[]:a},xa:function(a){a.length=0;t.aB.push(a)},dB:1,uc:function(a){a.__gohashid=t.dB++},zs:function(a){var b=a.__gohashid;void 0===b&&(b=t.dB++,a.__gohashid=b);return b},jc:function(a){return a.__gohashid},g:function(a,b,c){"name"!==b&&"length"!==b&&(a[b]=c)},ea:function(a,b){b.px=a;ba[a]=b},Ja:function(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a},th:function(a){a.jG=!0},defineProperty:function(a,b,c,d,e){t.j(a, +"function","Util.defineProperty:classfunc");t.j(b,"object","Util.defineProperty:propobj");t.j(c,"function","Util.defineProperty:getter");t.j(d,"function","Util.defineProperty:setter");for(var g in b){var h=b[g];b={get:c,set:d};if(void 0!==e)for(var k in e)b[k]=e[k];Object.defineProperty(a.prototype,g,b);e=Object.getOwnPropertyDescriptor(a.prototype,g);h&&e&&Object.defineProperty(a.prototype,h,e);if(f&&h){var l=h.charAt(0).toUpperCase()+h.slice(1);h==l&&t.l('Defining capitalized property "'+l+'"!?'); +Object.defineProperty(a.prototype,l,{get:function(){t.l('Getting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')},set:function(){t.l('Setting the property "'+l+'" is probably not what you intended: it is capitalized but should spelled "'+h+'"')}})}break}},A:function(a,b,c,d){t.j(a,"function","Util.defineReadOnlyProperty:classfunc");t.j(b,"object","Util.defineReadOnlyProperty:propobj");t.j(c,"function","Util.defineReadOnlyProperty:getter");for(var e in b){var g= +b[e];b={get:c,set:function(a){t.l('The property "'+g+'" is read-only and cannot be set to '+a)}};if(void 0!==d)for(var h in d)b[h]=d[h];Object.defineProperty(a.prototype,e,b);d=Object.getOwnPropertyDescriptor(a.prototype,e);g&&d&&Object.defineProperty(a.prototype,g,d);if(f&&g){var k=g.charAt(0).toUpperCase()+g.slice(1);Object.defineProperty(a.prototype,k,{get:function(){t.l('Getting the property "'+k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'"')},set:function(){t.l('Setting the read-only property "'+ +k+'" is probably not what you intended: it is capitalized but should spelled "'+g+'", and cannot be set anyway')}})}break}},be:function(a,b){for(var c in b)b[c]=!0;a.prototype.eC=b},vh:function(a){return void 0===a?"":"string"===typeof a?a:"function"===typeof a?t.Gg(a):null===a?"*":""},Gg:function(a){if("function"===typeof a){if(a.px)return a.px;if(a.name)return a.name;var b=a.toString(),c=b.indexOf("(");if(b=b.substring(9,c).trim())return a.px=b}else if("object"===typeof a&&a.constructor)return t.Gg(a.constructor); +return typeof a},w:function(a,b,c){t.j(a,"function","Util.defineEnumValue:classfunc");t.j(b,"string","Util.defineEnumValue:name");t.j(c,"number","Util.defineEnumValue:num");c=new ca(a,b,c);Object.freeze(c);a[b]=c;var d=a.rt;d||(d=new ia("string",ca),a.rt=d);d.add(b,c);return c},um:function(a,b){if(!b)return null;t.j(a,"function","Util.findEnumValueForName:classfunc");t.j(b,"string","Util.findEnumValueForName:name");var c=a.rt;return c?c.wa(b):null},XG:function(a,b,c,d){var e={},g;for(g in a){for(var h= +!1,k=1;k=d.length)){var e=t.ab(b,d);null===e||"function"===typeof e||t.Vv(b,d)||(""===c&&(c=b+"\n"),c+=' unknown property "'+d+'" has value: '+e+" at "+a+"\n")}return c},wv:function(a,b){if(b&&"number"!==typeof b&&"string"!==typeof b&&"boolean"!==typeof b&&"function"!==typeof b)if(void 0!==t.jc(b)){if(!t.Su.contains(b))if(t.Su.add(b), +t.su.add(t.NC(a,b)),b instanceof A||b instanceof la||b instanceof ia)for(var c=b.m;c.next();)t.wv(a+"["+c.key+"]",c.value);else for(c in b){var d=t.ab(b,c);if(void 0!==d&&null!==d&&t.jb(d)&&d!==b.eC){if(b instanceof ma){if(d===b.Gn)continue}else if(b instanceof y){if("data"===c||d===b.xl)continue;if("itemArray"===c||d===b.fj)continue;if(b instanceof B&&d===b.nj)continue}else if(!(b instanceof z))if(b instanceof oa){if("archetypeGroupData"===c||d===b.lx)continue}else if(b instanceof pa){if("archetypeLinkData"=== +c||d===b.Dt)continue;if("archetypeLabelNodeData"===c||d===b.Ct)continue}else if(b instanceof qa){if("archetypeNodeData"===c||d===b.Oi)continue}else if(b instanceof C){if("nodeDataArray"===c||d===b.Fe)continue;if("linkDataArray"===c||d===b.xg||d===b.Ll)continue;if(d===b.pc)continue;if(d===b.Yg)continue}else if(b instanceof ra||b instanceof sa||b instanceof ta)continue;t.wv(a+"."+c,d)}}}else if(Array.isArray(b))for(c=0;cc;c++)b[c]=c;for(var d=0,e,c=0;256>c;c++)d=(d+b[c]+119)%256,e=b[c],b[c]=b[d],b[d]=e;for(var d=c=0,g="",h=0;hc;c++)b["0123456789abcdef".charAt(c>>4)+"0123456789abcdef".charAt(c&15)]=String.fromCharCode(c); +a.length%2&&(a="0"+a);for(var d=[],e=0,c=0;cd;d++)b[t.Ka("7ca11abfd7330390")](t.Ka(c[d-1]),10,15*d+0);b[t.Ka("7ca11abfd022028846")]=t.Ka("39f046ebb36e4b");for(d=1;5>d;d++)b[t.Ka("7ca11abfd7330390")](t.Ka(c[d- +1]),10,15*d+0);if(4!==c.length||"5"!==c[0][0]||"7"!==c[3][0])t.w=function(a,b){var c=new ca(a,b,2);Object.freeze(c);a[b]=c;var d=a.rt;d||(d=new ia("string",ca),a.rt=d);d.add(b,c);return c};return a}();function ca(a,b,c){t.uc(this);this.hB=a;this.Mb=b;this.oG=c}ca.prototype.toString=function(){return t.Gg(this.hB)+"."+this.Mb};t.A(ca,{Ke:"classType"},function(){return this.hB});t.A(ca,{name:"name"},function(){return this.Mb});t.A(ca,{value:"value"},function(){return this.oG}); +function va(){this.gB=[]}va.prototype.toString=function(){return this.gB.join("")};va.prototype.add=function(a){a&&this.gB.push(a)};function wa(){}t.A(wa,{m:"iterator"},function(){return this});wa.prototype.reset=wa.prototype.reset=function(){};wa.prototype.next=wa.prototype.hasNext=wa.prototype.next=function(){return!1};wa.prototype.first=wa.prototype.Ya=function(){return null};t.A(wa,{count:"count"},function(){return 0});wa.prototype.sg=function(){};wa.prototype.toString=function(){return"EmptyIterator"}; +t.Pg=new wa;function za(a){this.key=-1;this.value=a}t.be(za,{key:!0,value:!0});t.A(za,{m:"iterator"},function(){return this});za.prototype.reset=za.prototype.reset=function(){this.key=-1};za.prototype.next=za.prototype.hasNext=za.prototype.next=function(){return-1===this.key?(this.key=0,!0):!1};za.prototype.first=za.prototype.Ya=function(){this.key=0;return this.value};t.A(za,{count:"count"},function(){return 1});za.prototype.sg=function(){this.value=null}; +za.prototype.toString=function(){return"SingletonIterator("+this.value+")"};function Aa(a){this.tf=a;this.Pn=null;this.reset()}t.be(Aa,{key:!0,value:!0});t.A(Aa,{m:"iterator"},function(){return this});t.g(Aa,"predicate",Aa.prototype.el);t.defineProperty(Aa,{el:"predicate"},function(){return this.Pn},function(a){this.Pn=a});Aa.prototype.reset=Aa.prototype.reset=function(){var a=this.tf;a.eh=null;this.eb=a.Pb;this.oe=-1}; +Aa.prototype.next=Aa.prototype.hasNext=Aa.prototype.next=function(){var a=this.tf;a.Pb!==this.eb&&t.l("the List has been modified during iteration");var a=a.p,b=a.length,c=++this.oe,d=this.Pn;if(null!==d)for(;ca||a>=b.length)&&t.ia(a,"0 <= i < length",A,"elt:i");return b[a]}; +A.prototype.setElt=A.prototype.set=A.prototype.jg=function(a,b){f&&(this.pg(b),t.o(a,A,"setElt:i"));var c=this.p;(0>a||a>=c.length)&&t.ia(a,"0 <= i < length",A,"setElt:i");t.L(this,a);c[a]=b};A.prototype.first=A.prototype.Ya=function(){var a=this.p;return 0===a.length?null:a[0]};A.prototype.insertAt=A.prototype.td=function(a,b){f&&(this.pg(b),t.o(a,A,"insertAt:i"));0>a&&t.ia(a,">= 0",A,"insertAt:i");t.L(this,a);var c=this.p;a>=c.length?c.push(b):c.splice(a,0,b);this.Dd();return!0}; +A.prototype.remove=A.prototype["delete"]=A.prototype.remove=function(a){if(null===a)return!1;f&&this.pg(a);t.L(this,a);var b=this.p;a=b.indexOf(a);if(-1===a)return!1;a===b.length-1?b.pop():b.splice(a,1);this.Dd();return!0};A.prototype.removeAt=A.prototype.Zc=function(a){f&&t.o(a,A,"removeAt:i");var b=this.p;(0>a||a>=b.length)&&t.ia(a,"0 <= i < length",A,"removeAt:i");t.L(this,a);a===b.length-1?b.pop():b.splice(a,1);this.Dd()}; +A.prototype.removeRange=A.prototype.removeRange=function(a,b){f&&(t.o(a,A,"removeRange:from"),t.o(b,A,"removeRange:to"));var c=this.p;(0>a||a>=c.length)&&t.ia(a,"0 <= from < length",A,"elt:from");(0>b||b>=c.length)&&t.ia(b,"0 <= to < length",A,"elt:to");t.L(this,a);var d=c.slice((b||a)+1||c.length);c.length=0>a?c.length+a:a;c.push.apply(c,d);this.Dd()};A.prototype.copy=function(){for(var a=new A(this.Z),b=this.p,c=this.count,d=0;d=g)return this;(0>b||b>=e-1)&&t.ia(b,"0 <= from < length",A,"sortRange:from");if(2===g)return c=d[b],e=d[b+1],0=e)d.sort(a);else for(g=d.slice(0,c),g.sort(a),a=0;a=e)for(g=d.slice(b),g.sort(a), +a=b;a=this.p.length)return t.Pg;var a=this.eh;return null!==a?(a.reset(),a):new Aa(this)}); +t.A(A,{Bm:"iteratorBackwards"},function(){if(0>=this.p.length)return t.Pg;var a=this.ly;return null!==a?(a.reset(),a):new Ba(this)});function Ca(a){this.q=a;this.reset()}t.be(Ca,{key:!0,value:!0});t.A(Ca,{m:"iterator"},function(){return this});Ca.prototype.reset=Ca.prototype.reset=function(){var a=this.q;a.eh=null;this.eb=a.Pb;this.Vd=null}; +Ca.prototype.next=Ca.prototype.hasNext=Ca.prototype.next=function(){var a=this.q;a.Pb!==this.eb&&t.l("the Set has been modified during iteration");var b=this.Vd,b=null===b?a.ne:b.oj;if(null!==b)return this.Vd=b,this.value=b.value,this.key=b.key,!0;this.sg();return!1};Ca.prototype.first=Ca.prototype.Ya=function(){var a=this.q;this.eb=a.Pb;a=a.ne;if(null!==a){this.Vd=a;var b=a.value;this.key=a.key;return this.value=b}return null};t.A(Ca,{count:"count"},function(){return this.q.cd}); +Ca.prototype.sg=function(){this.value=null;this.eb=-1;this.q.eh=this};Ca.prototype.toString=function(){return null!==this.Vd?"SetIterator@"+this.Vd.value:"SetIterator"}; +function la(a){t.uc(this);this.cb=!1;void 0===a||null===a?this.Z=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.Z=a:t.ia(a,"the string 'object', 'number' or 'string'","Set constructor: type"):"function"===typeof a?this.Z=a===Object?"object":a===String?"string":a===Number?"number":a:t.ia(a,"null, a primitive type name, or a class type","Set constructor: type");this.Oc={};this.cd=0;this.eh=null;this.Pb=0;this.gh=this.ne=null}t.ea("Set",la); +la.prototype.pg=function(a){null!==this.Z&&("string"===typeof this.Z?typeof a===this.Z&&null!==a||t.Nb(a,this.Z):a instanceof this.Z||t.Nb(a,this.Z))};la.prototype.Dd=function(){var a=this.Pb;a++;999999999=this.cd)return t.Pg;var a=this.eh;return null!==a?(a.reset(),a):new Ca(this)});function Ea(a){this.wc=a;this.reset()}t.be(Ea,{key:!0,value:!0});t.A(Ea,{m:"iterator"},function(){return this});Ea.prototype.reset=Ea.prototype.reset=function(){this.eb=this.wc.Pb;this.Vd=null}; +Ea.prototype.next=Ea.prototype.hasNext=Ea.prototype.next=function(){var a=this.wc;a.Pb!==this.eb&&t.l("the Map has been modified during iteration");var b=this.Vd,b=null===b?a.ne:b.oj;if(null!==b)return this.Vd=b,this.value=this.key=a=b.key,!0;this.sg();return!1};Ea.prototype.first=Ea.prototype.Ya=function(){var a=this.wc;this.eb=a.Pb;a=a.ne;return null!==a?(this.Vd=a,this.value=this.key=a=a.key):null};t.A(Ea,{count:"count"},function(){return this.wc.cd}); +Ea.prototype.sg=function(){this.value=null;this.eb=-1};Ea.prototype.toString=function(){return null!==this.Vd?"MapKeySetIterator@"+this.Vd.value:"MapKeySetIterator"};function Fa(a){t.uc(this);this.cb=!0;this.wc=a}t.Ja(Fa,la);Fa.prototype.freeze=function(){return this};Fa.prototype.Pa=function(){return this};Fa.prototype.toString=function(){return"MapKeySet("+this.wc.toString()+")"};Fa.prototype.add=Fa.prototype.set=Fa.prototype.add=function(){t.l("This Set is read-only: "+this.toString());return!1}; +Fa.prototype.contains=Fa.prototype.has=Fa.prototype.contains=function(a){return this.wc.contains(a)};Fa.prototype.remove=Fa.prototype["delete"]=Fa.prototype.remove=function(){t.l("This Set is read-only: "+this.toString());return!1};Fa.prototype.clear=Fa.prototype.clear=function(){t.l("This Set is read-only: "+this.toString())};Fa.prototype.first=Fa.prototype.Ya=function(){var a=this.wc.ne;return null!==a?a.key:null};Fa.prototype.copy=function(){return new Fa(this.wc)}; +Fa.prototype.toSet=function(){var a=new la(this.wc.fh),b=this.wc.Oc,c;for(c in b)a.add(b[c].key);return a};Fa.prototype.toArray=Fa.prototype.Ve=function(){var a=this.wc.Oc,b=Array(this.wc.cd),c=0,d;for(d in a)b[c]=a[d].key,c++;return b};Fa.prototype.toList=function(){var a=new A(this.Z),b=this.wc.Oc,c;for(c in b)a.add(b[c].key);return a};t.A(Fa,{count:"count"},function(){return this.wc.cd});t.A(Fa,{size:"size"},function(){return this.wc.cd}); +t.A(Fa,{m:"iterator"},function(){return 0>=this.wc.cd?t.Pg:new Ea(this.wc)});function Da(a,b){this.key=a;this.value=b;this.Qn=this.oj=null}t.be(Da,{key:!0,value:!0});Da.prototype.toString=function(){return"{"+this.key+":"+this.value+"}"};function Ia(a){this.wc=a;this.reset()}t.be(Ia,{key:!0,value:!0});t.A(Ia,{m:"iterator"},function(){return this});Ia.prototype.reset=Ia.prototype.reset=function(){var a=this.wc;a.eh=null;this.eb=a.Pb;this.Vd=null}; +Ia.prototype.next=Ia.prototype.hasNext=Ia.prototype.next=function(){var a=this.wc;a.Pb!==this.eb&&t.l("the Map has been modified during iteration");var b=this.Vd,b=null===b?a.ne:b.oj;if(null!==b)return this.Vd=b,this.key=b.key,this.value=b.value,!0;this.sg();return!1};Ia.prototype.first=Ia.prototype.Ya=function(){var a=this.wc;this.eb=a.Pb;a=a.ne;if(null!==a){this.Vd=a;var b=a.key;this.key=b;this.value=a.value;return b}return null};t.A(Ia,{count:"count"},function(){return this.wc.cd}); +Ia.prototype.sg=function(){this.value=this.key=null;this.eb=-1;this.wc.eh=this};Ia.prototype.toString=function(){return null!==this.Vd?"MapIterator@"+this.Vd:"MapIterator"}; +function ia(a,b){t.uc(this);this.cb=!1;void 0===a||null===a?this.fh=null:"string"===typeof a?"object"===a||"string"===a||"number"===a?this.fh=a:t.ia(a,"the string 'object', 'number' or 'string'","Map constructor: keytype"):"function"===typeof a?this.fh=a===Object?"object":a===String?"string":a===Number?"number":a:t.ia(a,"null, a primitive type name, or a class type","Map constructor: keytype");void 0===b||null===b?this.oi=null:"string"===typeof b?"object"===b||"string"===b||"boolean"===b||"number"=== +b||"function"===b?this.oi=b:t.ia(b,"the string 'object', 'number', 'string', 'boolean', or 'function'","Map constructor: valtype"):"function"===typeof b?this.oi=b===Object?"object":b===String?"string":b===Number?"number":b===Boolean?"boolean":b===Function?"function":b:t.ia(b,"null, a primitive type name, or a class type","Map constructor: valtype");this.Oc={};this.cd=0;this.eh=null;this.Pb=0;this.gh=this.ne=null}t.ea("Map",ia); +function La(a,b){null!==a.fh&&("string"===typeof a.fh?typeof b===a.fh&&null!==b||t.Nb(b,a.fh):b instanceof a.fh||t.Nb(b,a.fh))}ia.prototype.Dd=function(){var a=this.Pb;a++;999999999=this.count)return t.Pg;var a=this.eh;return null!==a?(a.reset(),a):new Ia(this)});function v(a,b){void 0===a||void 0===b?this.y=this.x=0:!f||"number"===typeof a&&"number"===typeof b?(this.x=a,this.y=b):t.l("Invalid arguments to Point constructor")}t.ea("Point",v);t.th(v);t.be(v,{x:!0,y:!0});v.prototype.assign=function(a){this.x=a.x;this.y=a.y};v.prototype.q=function(a,b){this.x=a;this.y=b}; +v.prototype.setTo=v.prototype.pp=function(a,b){f&&(t.j(a,"number",v,"setTo:x"),t.j(b,"number",v,"setTo:y"));t.L(this);this.x=a;this.y=b;return this};v.prototype.set=v.prototype.set=function(a){f&&t.k(a,v,v,"set:p");t.L(this);this.x=a.x;this.y=a.y;return this};v.prototype.copy=function(){var a=new v;a.x=this.x;a.y=this.y;return a};v.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};v.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; +v.prototype.freeze=function(){this.cb=!0;return this};v.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};v.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new v(c,e)}return new v};v.stringify=function(a){return a instanceof v?a.x.toString()+" "+a.y.toString():a.toString()}; +v.prototype.toString=function(){return"Point("+this.x+","+this.y+")"};v.prototype.equals=v.prototype.K=function(a){return a instanceof v?this.x===a.x&&this.y===a.y:!1};v.prototype.equalTo=function(a,b){return this.x===a&&this.y===b};v.prototype.Oj=function(a){return D.Fa(this.x,a.x)&&D.Fa(this.y,a.y)};v.prototype.zi=function(a){return D.I(this.x,a.x)&&D.I(this.y,a.y)};v.prototype.add=v.prototype.add=function(a){f&&t.k(a,v,v,"add:p");t.L(this);this.x+=a.x;this.y+=a.y;return this}; +v.prototype.subtract=v.prototype.it=function(a){f&&t.k(a,v,v,"subtract:p");t.L(this);this.x-=a.x;this.y-=a.y;return this};v.prototype.offset=v.prototype.offset=function(a,b){f&&(t.o(a,v,"offset:dx"),t.o(b,v,"offset:dy"));t.L(this);this.x+=a;this.y+=b;return this}; +v.prototype.rotate=v.prototype.rotate=function(a){f&&t.o(a,v,"rotate:angle");t.L(this);if(0===a)return this;var b=this.x,c=this.y;if(0===b&&0===c)return this;var d;90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));this.x=a*b-d*c;this.y=d*b+a*c;return this};v.prototype.scale=v.prototype.scale=function(a,b){f&&(t.o(a,v,"scale:sx"),t.o(b,v,"scale:sy"));this.x*=a;this.y*=b;return this}; +v.prototype.distanceSquaredPoint=v.prototype.Mj=function(a){f&&t.k(a,v,v,"distanceSquaredPoint:p");var b=a.x-this.x;a=a.y-this.y;return b*b+a*a};v.prototype.distanceSquared=v.prototype.ps=function(a,b){f&&(t.o(a,v,"distanceSquared:px"),t.o(b,v,"distanceSquared:py"));var c=a-this.x,d=b-this.y;return c*c+d*d};v.prototype.normalize=v.prototype.normalize=function(){t.L(this);var a=this.x,b=this.y,c=Math.sqrt(a*a+b*b);0b?270:0;if(0===b)return 0a?c=0>b?c+180:180-c:0>b&&(c=360-c);return c} +v.prototype.projectOntoLineSegment=function(a,b,c,d){f&&(t.o(a,v,"projectOntoLineSegment:px"),t.o(b,v,"projectOntoLineSegment:py"),t.o(c,v,"projectOntoLineSegment:qx"),t.o(d,v,"projectOntoLineSegment:qy"));D.Hm(a,b,c,d,this.x,this.y,this);return this};v.prototype.projectOntoLineSegmentPoint=function(a,b){f&&(t.k(a,v,v,"projectOntoLineSegmentPoint:p"),t.k(b,v,v,"projectOntoLineSegmentPoint:q"));D.Hm(a.x,a.y,b.x,b.y,this.x,this.y,this);return this}; +v.prototype.snapToGrid=function(a,b,c,d){f&&(t.o(a,v,"snapToGrid:originx"),t.o(b,v,"snapToGrid:originy"),t.o(c,v,"snapToGrid:cellwidth"),t.o(d,v,"snapToGrid:cellheight"));D.ss(this.x,this.y,a,b,c,d,this);return this};v.prototype.snapToGridPoint=function(a,b){f&&(t.k(a,v,v,"snapToGridPoint:p"),t.k(b,ea,v,"snapToGridPoint:q"));D.ss(this.x,this.y,a.x,a.y,b.width,b.height,this);return this}; +v.prototype.setRectSpot=v.prototype.et=function(a,b){f&&(t.k(a,w,v,"setRectSpot:r"),t.k(b,H,v,"setRectSpot:spot"));t.L(this);this.x=a.x+b.x*a.width+b.offsetX;this.y=a.y+b.y*a.height+b.offsetY;return this}; +v.prototype.setSpot=v.prototype.ft=function(a,b,c,d,e){f&&(t.o(a,v,"setSpot:x"),t.o(b,v,"setSpot:y"),t.o(c,v,"setSpot:w"),t.o(d,v,"setSpot:h"),(0>c||0>d)&&t.l("Point.setSpot:Width and height cannot be negative"),t.k(e,H,v,"setSpot:spot"));t.L(this);this.x=a+e.x*c+e.offsetX;this.y=b+e.y*d+e.offsetY;return this};v.prototype.transform=function(a){f&&t.k(a,fa,v,"transform:t");a.Qa(this);return this};function Oa(a,b){f&&t.k(b,fa,v,"transformInverted:t");b.Ci(a);return a}var Pa; +v.distanceLineSegmentSquared=Pa=function(a,b,c,d,e,g){f&&(t.o(a,v,"distanceLineSegmentSquared:px"),t.o(b,v,"distanceLineSegmentSquared:py"),t.o(c,v,"distanceLineSegmentSquared:ax"),t.o(d,v,"distanceLineSegmentSquared:ay"),t.o(e,v,"distanceLineSegmentSquared:bx"),t.o(g,v,"distanceLineSegmentSquared:by"));var h=e-c,k=g-d,l=h*h+k*k;c-=a;d-=b;var m=-c*h-d*k;if(0>=m||m>=l)return h=e-a,k=g-b,Math.min(c*c+d*d,h*h+k*k);a=h*d-k*c;return a*a/l};var Qa; +v.distanceSquared=Qa=function(a,b,c,d){f&&(t.o(a,v,"distanceSquared:px"),t.o(b,v,"distanceSquared:py"),t.o(c,v,"distanceSquared:qx"),t.o(d,v,"distanceSquared:qy"));a=c-a;b=d-b;return a*a+b*b};var Ra; +v.direction=Ra=function(a,b,c,d){f&&(t.o(a,v,"direction:px"),t.o(b,v,"direction:py"),t.o(c,v,"direction:qx"),t.o(d,v,"direction:qy"));a=c-a;b=d-b;if(0===a)return 0b?270:0;if(0===b)return 0a?d=0>b?d+180:180-d:0>b&&(d=360-d);return d};v.prototype.isReal=v.prototype.P=function(){return isFinite(this.x)&&isFinite(this.y)}; +function ea(a,b){void 0===a||void 0===b?this.height=this.width=0:!f||"number"===typeof a&&(0<=a||isNaN(a))&&"number"===typeof b&&(0<=b||isNaN(b))?(this.width=a,this.height=b):t.l("Invalid arguments to Size constructor")}t.ea("Size",ea);t.th(ea);t.be(ea,{width:!0,height:!0});ea.prototype.assign=function(a){this.width=a.width;this.height=a.height};ea.prototype.q=function(a,b){this.width=a;this.height=b}; +ea.prototype.setTo=ea.prototype.pp=function(a,b){f&&(t.j(a,"number",ea,"setTo:w"),t.j(b,"number",ea,"setTo:h"));0>a&&t.ia(a,">= 0",ea,"setTo:w");0>b&&t.ia(b,">= 0",ea,"setTo:h");t.L(this);this.width=a;this.height=b;return this};ea.prototype.set=ea.prototype.set=function(a){f&&t.k(a,ea,ea,"set:s");t.L(this);this.width=a.width;this.height=a.height;return this};ea.prototype.copy=function(){var a=new ea;a.width=this.width;a.height=this.height;return a}; +ea.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};ea.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()};ea.prototype.freeze=function(){this.cb=!0;return this};ea.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this}; +ea.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));return new ea(c,e)}return new ea};ea.stringify=function(a){return a instanceof ea?a.width.toString()+" "+a.height.toString():a.toString()};ea.prototype.toString=function(){return"Size("+this.width+","+this.height+")"}; +ea.prototype.equals=ea.prototype.K=function(a){return a instanceof ea?this.width===a.width&&this.height===a.height:!1};ea.prototype.equalTo=function(a,b){return this.width===a&&this.height===b};ea.prototype.Oj=function(a){return D.Fa(this.width,a.width)&&D.Fa(this.height,a.height)};ea.prototype.zi=function(a){return D.I(this.width,a.width)&&D.I(this.height,a.height)};ea.prototype.isReal=ea.prototype.P=function(){return isFinite(this.width)&&isFinite(this.height)}; +function w(a,b,c,d){void 0===a?this.height=this.width=this.y=this.x=0:a instanceof v?b instanceof v?(this.x=Math.min(a.x,b.x),this.y=Math.min(a.y,b.y),this.width=Math.abs(a.x-b.x),this.height=Math.abs(a.y-b.y)):b instanceof ea?(this.x=a.x,this.y=a.y,this.width=b.width,this.height=b.height):t.l("Incorrect arguments supplied"):!f||"number"===typeof a&&"number"===typeof b&&"number"===typeof c&&(0<=c||isNaN(c))&&"number"===typeof d&&(0<=d||isNaN(d))?(this.x=a,this.y=b,this.width=c,this.height=d):t.l("Invalid arguments to Rect constructor")} +t.ea("Rect",w);t.th(w);t.be(w,{x:!0,y:!0,width:!0,height:!0});w.prototype.assign=function(a){this.x=a.x;this.y=a.y;this.width=a.width;this.height=a.height};w.prototype.q=function(a,b,c,d){this.x=a;this.y=b;this.width=c;this.height=d};function Sa(a,b,c){a.width=b;a.height=c} +w.prototype.setTo=w.prototype.pp=function(a,b,c,d){f&&(t.j(a,"number",w,"setTo:x"),t.j(b,"number",w,"setTo:y"),t.j(c,"number",w,"setTo:w"),t.j(d,"number",w,"setTo:h"));0>c&&t.ia(c,">= 0",w,"setTo:w");0>d&&t.ia(d,">= 0",w,"setTo:h");t.L(this);this.x=a;this.y=b;this.width=c;this.height=d;return this};w.prototype.set=w.prototype.set=function(a){f&&t.k(a,w,w,"set:r");t.L(this);this.x=a.x;this.y=a.y;this.width=a.width;this.height=a.height;return this}; +w.prototype.setPoint=w.prototype.of=function(a){f&&t.k(a,v,w,"setPoint:p");t.L(this);this.x=a.x;this.y=a.y;return this};w.prototype.setSize=function(a){f&&t.k(a,ea,w,"setSize:s");t.L(this);this.width=a.width;this.height=a.height;return this};w.prototype.copy=function(){var a=new w;a.x=this.x;a.y=this.y;a.width=this.width;a.height=this.height;return a};w.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};w.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()}; +w.prototype.freeze=function(){this.cb=!0;return this};w.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};w.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new w(c,e,g,h)}return new w}; +w.stringify=function(a){return a instanceof w?a.x.toString()+" "+a.y.toString()+" "+a.width.toString()+" "+a.height.toString():a.toString()};w.prototype.toString=function(){return"Rect("+this.x+","+this.y+","+this.width+","+this.height+")"};w.prototype.equals=w.prototype.K=function(a){return a instanceof w?this.x===a.x&&this.y===a.y&&this.width===a.width&&this.height===a.height:!1};w.prototype.equalTo=function(a,b,c,d){return this.x===a&&this.y===b&&this.width===c&&this.height===d}; +w.prototype.Oj=function(a){return D.Fa(this.x,a.x)&&D.Fa(this.y,a.y)&&D.Fa(this.width,a.width)&&D.Fa(this.height,a.height)};w.prototype.zi=function(a){return D.I(this.x,a.x)&&D.I(this.y,a.y)&&D.I(this.width,a.width)&&D.I(this.height,a.height)};w.prototype.containsPoint=w.prototype.Da=function(a){f&&t.k(a,v,w,"containsPoint:p");return this.x<=a.x&&this.x+this.width>=a.x&&this.y<=a.y&&this.y+this.height>=a.y}; +w.prototype.containsRect=w.prototype.Ij=function(a){f&&t.k(a,w,w,"containsRect:r");return this.x<=a.x&&a.x+a.width<=this.x+this.width&&this.y<=a.y&&a.y+a.height<=this.y+this.height}; +w.prototype.contains=w.prototype.contains=function(a,b,c,d){f?(t.o(a,w,"contains:x"),t.o(b,w,"contains:y"),void 0===c?c=0:t.o(c,w,"contains:w"),void 0===d?d=0:t.o(d,w,"contains:h"),(0>c||0>d)&&t.l("Rect.contains:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return this.x<=a&&a+c<=this.x+this.width&&this.y<=b&&b+d<=this.y+this.height};w.prototype.reset=function(){t.L(this);this.height=this.width=this.y=this.x=0}; +w.prototype.offset=w.prototype.offset=function(a,b){f&&(t.o(a,w,"offset:dx"),t.o(b,w,"offset:dy"));t.L(this);this.x+=a;this.y+=b;return this};w.prototype.inflate=w.prototype.Hg=function(a,b){f&&(t.o(a,w,"inflate:w"),t.o(b,w,"inflate:h"));return Ua(this,b,a,b,a)};w.prototype.addMargin=w.prototype.mv=function(a){f&&t.k(a,Va,w,"addMargin:m");return Ua(this,a.top,a.right,a.bottom,a.left)}; +w.prototype.subtractMargin=w.prototype.EI=function(a){f&&t.k(a,Va,w,"subtractMargin:m");return Ua(this,-a.top,-a.right,-a.bottom,-a.left)};w.prototype.grow=function(a,b,c,d){f&&(t.o(a,w,"grow:t"),t.o(b,w,"grow:r"),t.o(c,w,"grow:b"),t.o(d,w,"grow:l"));return Ua(this,a,b,c,d)};function Ua(a,b,c,d,e){t.L(a);var g=a.width;c+e<=-g?(a.x+=g/2,a.width=0):(a.x-=e,a.width+=c+e);c=a.height;b+d<=-c?(a.y+=c/2,a.height=0):(a.y-=b,a.height+=b+d);return a} +w.prototype.intersectRect=function(a){f&&t.k(a,w,w,"intersectRect:r");return Xa(this,a.x,a.y,a.width,a.height)};w.prototype.intersect=function(a,b,c,d){f&&(t.o(a,w,"intersect:x"),t.o(b,w,"intersect:y"),t.o(c,w,"intersect:w"),t.o(d,w,"intersect:h"),(0>c||0>d)&&t.l("Rect.intersect:Width and height cannot be negative"));return Xa(this,a,b,c,d)}; +function Xa(a,b,c,d,e){t.L(a);var g=Math.max(a.x,b),h=Math.max(a.y,c);b=Math.min(a.x+a.width,b+d);c=Math.min(a.y+a.height,c+e);a.x=g;a.y=h;a.width=Math.max(0,b-g);a.height=Math.max(0,c-h);return a}w.prototype.intersectsRect=w.prototype.Bf=function(a){f&&t.k(a,w,w,"intersectsRect:r");return this.VD(a.x,a.y,a.width,a.height)}; +w.prototype.intersects=w.prototype.VD=function(a,b,c,d){f&&(t.o(a,w,"intersects:x"),t.o(b,w,"intersects:y"),t.o(a,w,"intersects:w"),t.o(b,w,"intersects:h"),(0>c||0>d)&&t.l("Rect.intersects:Width and height cannot be negative"));var e=this.width,g=this.x;if(Infinity!==e&&Infinity!==c&&(e+=g,c+=a,isNaN(c)||isNaN(e)||g>c||a>e))return!1;a=this.height;c=this.y;return Infinity!==a&&Infinity!==d&&(a+=c,d+=b,isNaN(d)||isNaN(a)||c>d||b>a)?!1:!0}; +function $a(a,b){var c=a.width,d=b.width+10+10,e=a.x,g=b.x-10;if(e>d+g||g>c+e)return!1;c=a.height;d=b.height+10+10;e=a.y;g=b.y-10;return e>d+g||g>c+e?!1:!0}w.prototype.unionPoint=w.prototype.Mi=function(a){f&&t.k(a,v,w,"unionPoint:p");return cb(this,a.x,a.y,0,0)};w.prototype.unionRect=w.prototype.$j=function(a){f&&t.k(a,w,w,"unionRect:r");return cb(this,a.x,a.y,a.width,a.height)}; +w.prototype.union=w.prototype.DF=function(a,b,c,d){t.L(this);f?(t.o(a,w,"union:x"),t.o(b,w,"union:y"),void 0===c?c=0:t.o(c,w,"union:w"),void 0===d?d=0:t.o(d,w,"union:h"),(0>c||0>d)&&t.l("Rect.union:Width and height cannot be negative")):(void 0===c&&(c=0),void 0===d&&(d=0));return cb(this,a,b,c,d)};function cb(a,b,c,d,e){var g=Math.min(a.x,b),h=Math.min(a.y,c);b=Math.max(a.x+a.width,b+d);c=Math.max(a.y+a.height,c+e);a.x=g;a.y=h;a.width=b-g;a.height=c-h;return a} +w.prototype.setSpot=w.prototype.ft=function(a,b,c){f&&(t.o(a,w,"setSpot:x"),t.o(b,w,"setSpot:y"),t.k(c,H,w,"setSpot:spot"));t.L(this);this.x=a-c.offsetX-c.x*this.width;this.y=b-c.offsetY-c.y*this.height;return this};var eb; +w.contains=eb=function(a,b,c,d,e,g,h,k){f?(t.o(a,w,"contains:rx"),t.o(b,w,"contains:ry"),t.o(c,w,"contains:rw"),t.o(d,w,"contains:rh"),t.o(e,w,"contains:x"),t.o(g,w,"contains:y"),void 0===h?h=0:t.o(h,w,"contains:w"),void 0===k?k=0:t.o(k,w,"contains:h"),(0>c||0>d||0>h||0>k)&&t.l("Rect.contains:Width and height cannot be negative")):(void 0===h&&(h=0),void 0===k&&(k=0));return a<=e&&e+h<=a+c&&b<=g&&g+k<=b+d}; +w.intersects=function(a,b,c,d,e,g,h,k){f&&(t.o(a,w,"intersects:rx"),t.o(b,w,"intersects:ry"),t.o(c,w,"intersects:rw"),t.o(d,w,"intersects:rh"),t.o(e,w,"intersects:x"),t.o(g,w,"intersects:y"),t.o(h,w,"intersects:w"),t.o(k,w,"intersects:h"),(0>c||0>d||0>h||0>k)&&t.l("Rect.intersects:Width and height cannot be negative"));c+=a;h+=e;if(a>h||e>c)return!1;a=d+b;k+=g;return b>k||g>a?!1:!0};t.g(w,"left",w.prototype.left); +t.defineProperty(w,{left:"left"},function(){return this.x},function(a){t.L(this,a);f&&t.j(a,"number",w,"left");this.x=a});t.g(w,"top",w.prototype.top);t.defineProperty(w,{top:"top"},function(){return this.y},function(a){t.L(this,a);f&&t.j(a,"number",w,"top");this.y=a});t.g(w,"right",w.prototype.right);t.defineProperty(w,{right:"right"},function(){return this.x+this.width},function(a){t.L(this,a);f&&t.o(a,w,"right");this.x+=a-(this.x+this.width)});t.g(w,"bottom",w.prototype.bottom); +t.defineProperty(w,{bottom:"bottom"},function(){return this.y+this.height},function(a){t.L(this,a);f&&t.o(a,w,"top");this.y+=a-(this.y+this.height)});t.g(w,"position",w.prototype.position);t.defineProperty(w,{position:"position"},function(){return new v(this.x,this.y)},function(a){t.L(this,a);f&&t.k(a,v,w,"position");this.x=a.x;this.y=a.y});t.g(w,"size",w.prototype.size); +t.defineProperty(w,{size:"size"},function(){return new ea(this.width,this.height)},function(a){t.L(this,a);f&&t.k(a,ea,w,"size");this.width=a.width;this.height=a.height});t.g(w,"center",w.prototype.tz);t.defineProperty(w,{tz:"center"},function(){return new v(this.x+this.width/2,this.y+this.height/2)},function(a){t.L(this,a);f&&t.k(a,v,w,"center");this.x=a.x-this.width/2;this.y=a.y-this.height/2});t.g(w,"centerX",w.prototype.Aa); +t.defineProperty(w,{Aa:"centerX"},function(){return this.x+this.width/2},function(a){t.L(this,a);f&&t.o(a,w,"centerX");this.x=a-this.width/2});t.g(w,"centerY",w.prototype.Ma);t.defineProperty(w,{Ma:"centerY"},function(){return this.y+this.height/2},function(a){t.L(this,a);f&&t.o(a,w,"centerY");this.y=a-this.height/2});w.prototype.isReal=w.prototype.P=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)}; +w.prototype.isEmpty=function(){return 0===this.width&&0===this.height};function Va(a,b,c,d){void 0===a?this.left=this.bottom=this.right=this.top=0:void 0===b?this.left=this.bottom=this.right=this.top=a:void 0===c?(d=b,this.top=a,this.right=b,this.bottom=a,this.left=d):void 0!==d?(this.top=a,this.right=b,this.bottom=c,this.left=d):t.l("Invalid arguments to Margin constructor")}t.ea("Margin",Va);t.th(Va);t.be(Va,{top:!0,right:!0,bottom:!0,left:!0}); +Va.prototype.assign=function(a){this.top=a.top;this.right=a.right;this.bottom=a.bottom;this.left=a.left};Va.prototype.setTo=Va.prototype.pp=function(a,b,c,d){f&&(t.j(a,"number",Va,"setTo:t"),t.j(b,"number",Va,"setTo:r"),t.j(c,"number",Va,"setTo:b"),t.j(d,"number",Va,"setTo:l"));t.L(this);this.top=a;this.right=b;this.bottom=c;this.left=d;return this}; +Va.prototype.set=Va.prototype.set=function(a){f&&t.k(a,Va,Va,"assign:m");t.L(this);this.top=a.top;this.right=a.right;this.bottom=a.bottom;this.left=a.left;return this};Va.prototype.copy=function(){var a=new Va;a.top=this.top;a.right=this.right;a.bottom=this.bottom;a.left=this.left;return a};Va.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};Va.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()};Va.prototype.freeze=function(){this.cb=!0;return this}; +Va.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};Va.parse=function(a){if("string"===typeof a){a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=void 0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=void 0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=void 0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new Va(c,e,g,h)}return new Va}; +Va.stringify=function(a){return a instanceof Va?a.top.toString()+" "+a.right.toString()+" "+a.bottom.toString()+" "+a.left.toString():a.toString()};Va.prototype.toString=function(){return"Margin("+this.top+","+this.right+","+this.bottom+","+this.left+")"};Va.prototype.equals=Va.prototype.K=function(a){return a instanceof Va?this.top===a.top&&this.right===a.right&&this.bottom===a.bottom&&this.left===a.left:!1}; +Va.prototype.equalTo=function(a,b,c,d){return this.top===a&&this.right===b&&this.bottom===c&&this.left===d};Va.prototype.Oj=function(a){return D.Fa(this.top,a.top)&&D.Fa(this.right,a.right)&&D.Fa(this.bottom,a.bottom)&&D.Fa(this.left,a.left)};Va.prototype.zi=function(a){return D.I(this.top,a.top)&&D.I(this.right,a.right)&&D.I(this.bottom,a.bottom)&&D.I(this.left,a.left)};Va.prototype.isReal=Va.prototype.P=function(){return isFinite(this.top)&&isFinite(this.right)&&isFinite(this.bottom)&&isFinite(this.left)}; +function fa(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}t.th(fa);t.be(fa,{m11:!0,m12:!0,m21:!0,m22:!0,dx:!0,dy:!0});fa.prototype.set=fa.prototype.set=function(a){f&&t.k(a,fa,fa,"set:t");this.m11=a.m11;this.m12=a.m12;this.m21=a.m21;this.m22=a.m22;this.dx=a.dx;this.dy=a.dy;return this};fa.prototype.copy=function(){var a=new fa;a.m11=this.m11;a.m12=this.m12;a.m21=this.m21;a.m22=this.m22;a.dx=this.dx;a.dy=this.dy;return a}; +fa.prototype.toString=function(){return"Transform("+this.m11+","+this.m12+","+this.m21+","+this.m22+","+this.dx+","+this.dy+")"};fa.prototype.equals=fa.prototype.K=function(a){return a instanceof fa?this.m11===a.m11&&this.m12===a.m12&&this.m21===a.m21&&this.m22===a.m22&&this.dx===a.dx&&this.dy===a.dy:!1};fa.prototype.reset=fa.prototype.reset=function(){this.m11=1;this.m21=this.m12=0;this.m22=1;this.dy=this.dx=0}; +fa.prototype.multiply=fa.prototype.multiply=function(a){f&&t.k(a,fa,fa,"multiply:matrix");var b=this.m12*a.m11+this.m22*a.m12,c=this.m11*a.m21+this.m21*a.m22,d=this.m12*a.m21+this.m22*a.m22,e=this.m11*a.dx+this.m21*a.dy+this.dx,g=this.m12*a.dx+this.m22*a.dy+this.dy;this.m11=this.m11*a.m11+this.m21*a.m12;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g;return this}; +fa.prototype.multiplyInverted=fa.prototype.vE=function(a){f&&t.k(a,fa,fa,"multiplyInverted:matrix");var b=1/(a.m11*a.m22-a.m12*a.m21),c=a.m22*b,d=-a.m12*b,e=-a.m21*b,g=a.m11*b,h=b*(a.m21*a.dy-a.m22*a.dx),k=b*(a.m12*a.dx-a.m11*a.dy);a=this.m12*c+this.m22*d;b=this.m11*e+this.m21*g;e=this.m12*e+this.m22*g;g=this.m11*h+this.m21*k+this.dx;h=this.m12*h+this.m22*k+this.dy;this.m11=this.m11*c+this.m21*d;this.m12=a;this.m21=b;this.m22=e;this.dx=g;this.dy=h;return this}; +fa.prototype.invert=fa.prototype.Qz=function(){var a=1/(this.m11*this.m22-this.m12*this.m21),b=-this.m12*a,c=-this.m21*a,d=this.m11*a,e=a*(this.m21*this.dy-this.m22*this.dx),g=a*(this.m12*this.dx-this.m11*this.dy);this.m11=this.m22*a;this.m12=b;this.m21=c;this.m22=d;this.dx=e;this.dy=g}; +fa.prototype.rotate=fa.prototype.rotate=function(a,b,c){f&&(t.o(a,fa,"rotate:angle"),t.o(b,fa,"rotate:rx"),t.o(c,fa,"rotate:ry"));this.translate(b,c);var d;0===a?(a=1,d=0):90===a?(a=0,d=1):180===a?(a=-1,d=0):270===a?(a=0,d=-1):(d=a*Math.PI/180,a=Math.cos(d),d=Math.sin(d));var e=this.m12*a+this.m22*d,g=this.m11*-d+this.m21*a,h=this.m12*-d+this.m22*a;this.m11=this.m11*a+this.m21*d;this.m12=e;this.m21=g;this.m22=h;this.translate(-b,-c)}; +fa.prototype.translate=fa.prototype.translate=function(a,b){f&&(t.o(a,fa,"translate:x"),t.o(b,fa,"translate:y"));this.dx+=this.m11*a+this.m21*b;this.dy+=this.m12*a+this.m22*b};fa.prototype.scale=fa.prototype.scale=function(a,b){void 0===b&&(b=a);f&&(t.o(a,fa,"translate:sx"),t.o(b,fa,"translate:sy"));this.m11*=a;this.m12*=a;this.m21*=b;this.m22*=b}; +fa.prototype.transformPoint=fa.prototype.Qa=function(a){f&&t.k(a,v,fa,"transformPoint:p");var b=a.x,c=a.y;a.x=b*this.m11+c*this.m21+this.dx;a.y=b*this.m12+c*this.m22+this.dy;return a};fa.prototype.invertedTransformPoint=fa.prototype.Ci=function(a){f&&t.k(a,v,fa,"invertedTransformPoint:p");var b=1/(this.m11*this.m22-this.m12*this.m21),c=-this.m12*b,d=this.m11*b,e=b*(this.m12*this.dx-this.m11*this.dy),g=a.x,h=a.y;a.x=g*this.m22*b+h*-this.m21*b+b*(this.m21*this.dy-this.m22*this.dx);a.y=g*c+h*d+e;return a}; +fa.prototype.transformRect=fa.prototype.yF=function(a){f&&t.k(a,w,fa,"transformRect:rect");var b=a.x,c=a.y,d=b+a.width,e=c+a.height,g=this.m11,h=this.m12,k=this.m21,l=this.m22,m=this.dx,n=this.dy,p=b*g+c*k+m,q=b*h+c*l+n,r=d*g+c*k+m,c=d*h+c*l+n,s=b*g+e*k+m,b=b*h+e*l+n,g=d*g+e*k+m,d=d*h+e*l+n,e=p,h=q,p=Math.min(p,r),e=Math.max(e,r),h=Math.min(h,c),q=Math.max(q,c),p=Math.min(p,s),e=Math.max(e,s),h=Math.min(h,b),q=Math.max(q,b),p=Math.min(p,g),e=Math.max(e,g),h=Math.min(h,d),q=Math.max(q,d);a.x=p;a.y= +h;a.width=e-p;a.height=q-h};fa.prototype.isIdentity=fa.prototype.Es=function(){return 1===this.m11&&0===this.m12&&0===this.m21&&1===this.m22&&0===this.dx&&0===this.dy};function H(a,b,c,d){void 0===a?this.offsetY=this.offsetX=this.y=this.x=0:(void 0===b&&(b=0),void 0===c&&(c=0),void 0===d&&(d=0),this.x=a,this.y=b,this.offsetX=c,this.offsetY=d)}t.ea("Spot",H);t.th(H);t.be(H,{x:!0,y:!0,offsetX:!0,offsetY:!0});H.prototype.assign=function(a){this.x=a.x;this.y=a.y;this.offsetX=a.offsetX;this.offsetY=a.offsetY}; +H.prototype.setTo=H.prototype.pp=function(a,b,c,d){f&&(kb(a,"setTo:x"),kb(b,"setTo:y"),nb(c,"setTo:offx"),nb(d,"setTo:offy"));t.L(this);this.x=a;this.y=b;this.offsetX=c;this.offsetY=d;return this};H.prototype.set=H.prototype.set=function(a){f&&t.k(a,H,H,"set:s");t.L(this);this.x=a.x;this.y=a.y;this.offsetX=a.offsetX;this.offsetY=a.offsetY;return this};H.prototype.copy=function(){var a=new H;a.x=this.x;a.y=this.y;a.offsetX=this.offsetX;a.offsetY=this.offsetY;return a}; +H.prototype.Ia=function(){this.cb=!0;Object.freeze(this);return this};H.prototype.W=function(){return Object.isFrozen(this)?this:this.copy().freeze()};H.prototype.freeze=function(){this.cb=!0;return this};H.prototype.Pa=function(){Object.isFrozen(this)&&t.l("cannot thaw constant: "+this);this.cb=!1;return this};function ob(a,b){a.x=NaN;a.y=NaN;a.offsetX=b;return a}function kb(a,b){(isNaN(a)||1a)&&t.ia(a,"0 <= "+b+" <= 1",H,b)} +function nb(a,b){(isNaN(a)||Infinity===a||-Infinity===a)&&t.ia(a,"real number, not NaN or Infinity",H,b)}var pb; +H.parse=pb=function(a){if("string"===typeof a){a=a.trim();if("None"===a)return t.NONE;if("TopLeft"===a)return t.Zw;if("Top"===a||"TopCenter"===a||"MiddleTop"===a)return t.Ep;if("TopRight"===a)return t.ax;if("Left"===a||"LeftCenter"===a||"MiddleLeft"===a)return t.Bp;if("Center"===a)return t.Nw;if("Right"===a||"RightCenter"===a||"MiddleRight"===a)return t.Cp;if("BottomLeft"===a)return t.Iw;if("Bottom"===a||"BottomCenter"===a||"MiddleBottom"===a)return t.Ap;if("BottomRight"===a)return t.Kw;if("TopSide"=== +a)return t.ex;if("LeftSide"===a)return t.Rw;if("RightSide"===a)return t.Xw;if("BottomSide"===a)return t.Mw;if("TopBottomSides"===a)return t.Yw;if("LeftRightSides"===a)return t.Qw;if("TopLeftSides"===a)return t.$w;if("TopRightSides"===a)return t.bx;if("BottomLeftSides"===a)return t.Jw;if("BottomRightSides"===a)return t.Lw;if("NotTopSide"===a)return t.Vw;if("NotLeftSide"===a)return t.Tw;if("NotRightSide"===a)return t.Uw;if("NotBottomSide"===a)return t.Sw;if("AllSides"===a)return t.Hw;if("Default"=== +a)return t.Ow;a=a.split(" ");for(var b=0,c=0;""===a[b];)b++;var d=a[b++];d&&(c=parseFloat(d));for(var e=0;""===a[b];)b++;(d=a[b++])&&(e=parseFloat(d));for(var g=0;""===a[b];)b++;(d=a[b++])&&(g=parseFloat(d));for(var h=0;""===a[b];)b++;(d=a[b++])&&(h=parseFloat(d));return new H(c,e,g,h)}return new H};H.stringify=function(a){return a instanceof H?a.kd()?a.x.toString()+" "+a.y.toString()+" "+a.offsetX.toString()+" "+a.offsetY.toString():a.toString():a.toString()}; +H.prototype.toString=function(){return this.kd()?0===this.offsetX&&0===this.offsetY?"Spot("+this.x+","+this.y+")":"Spot("+this.x+","+this.y+","+this.offsetX+","+this.offsetY+")":this.K(t.NONE)?"None":this.K(t.Zw)?"TopLeft":this.K(t.Ep)?"Top":this.K(t.ax)?"TopRight":this.K(t.Bp)?"Left":this.K(t.Nw)?"Center":this.K(t.Cp)?"Right":this.K(t.Iw)?"BottomLeft":this.K(t.Ap)?"Bottom":this.K(t.Kw)?"BottomRight":this.K(t.ex)?"TopSide":this.K(t.Rw)?"LeftSide":this.K(t.Xw)?"RightSide":this.K(t.Mw)?"BottomSide": +this.K(t.Yw)?"TopBottomSides":this.K(t.Qw)?"LeftRightSides":this.K(t.$w)?"TopLeftSides":this.K(t.bx)?"TopRightSides":this.K(t.Jw)?"BottomLeftSides":this.K(t.Lw)?"BottomRightSides":this.K(t.Vw)?"NotTopSide":this.K(t.Tw)?"NotLeftSide":this.K(t.Uw)?"NotRightSide":this.K(t.Sw)?"NotBottomSide":this.K(t.Hw)?"AllSides":this.K(t.Ow)?"Default":"None"}; +H.prototype.equals=H.prototype.K=function(a){return a instanceof H?(this.x===a.x||isNaN(this.x)&&isNaN(a.x))&&(this.y===a.y||isNaN(this.y)&&isNaN(a.y))&&this.offsetX===a.offsetX&&this.offsetY===a.offsetY:!1};H.prototype.opposite=function(){return new H(0.5-(this.x-0.5),0.5-(this.y-0.5),-this.offsetX,-this.offsetY)};H.prototype.includesSide=function(a){if(!this.No()||!a.No())return!1;a=a.offsetY;return(this.offsetY&a)===a};H.prototype.isSpot=H.prototype.kd=function(){return!isNaN(this.x)&&!isNaN(this.y)}; +H.prototype.isNoSpot=H.prototype.jd=function(){return isNaN(this.x)||isNaN(this.y)};H.prototype.isSide=H.prototype.No=function(){return this.jd()&&1===this.offsetX&&0!==this.offsetY};H.prototype.isDefault=H.prototype.zc=function(){return isNaN(this.x)&&isNaN(this.y)&&-1===this.offsetX&&0===this.offsetY};t.wd=1;t.ad=2;t.od=4;t.nd=8;t.NONE=ob(new H(0,0,0,0),0).Ia();t.Ow=ob(new H(0,0,-1,0),-1).Ia();t.Zw=(new H(0,0,0,0)).Ia();t.Ep=(new H(0.5,0,0,0)).Ia();t.ax=(new H(1,0,0,0)).Ia(); +t.Bp=(new H(0,0.5,0,0)).Ia();t.Nw=(new H(0.5,0.5,0,0)).Ia();t.Cp=(new H(1,0.5,0,0)).Ia();t.Iw=(new H(0,1,0,0)).Ia();t.Ap=(new H(0.5,1,0,0)).Ia();t.Kw=(new H(1,1,0,0)).Ia();t.ex=ob(new H(0,0,1,t.wd),1).Ia();t.Rw=ob(new H(0,0,1,t.ad),1).Ia();t.Xw=ob(new H(0,0,1,t.od),1).Ia();t.Mw=ob(new H(0,0,1,t.nd),1).Ia();t.Yw=ob(new H(0,0,1,t.wd|t.nd),1).Ia();t.Qw=ob(new H(0,0,1,t.ad|t.od),1).Ia();t.$w=ob(new H(0,0,1,t.wd|t.ad),1).Ia();t.bx=ob(new H(0,0,1,t.wd|t.od),1).Ia();t.Jw=ob(new H(0,0,1,t.nd|t.ad),1).Ia(); +t.Lw=ob(new H(0,0,1,t.nd|t.od),1).Ia();t.Vw=ob(new H(0,0,1,t.ad|t.od|t.nd),1).Ia();t.Tw=ob(new H(0,0,1,t.wd|t.od|t.nd),1).Ia();t.Uw=ob(new H(0,0,1,t.wd|t.ad|t.nd),1).Ia();t.Sw=ob(new H(0,0,1,t.wd|t.ad|t.od),1).Ia();t.Hw=ob(new H(0,0,1,t.wd|t.ad|t.od|t.nd),1).Ia();var ub;H.None=ub=t.NONE;var vb;H.Default=vb=t.Ow;var wb;H.TopLeft=wb=t.Zw;var Db;H.TopCenter=Db=t.Ep;var Eb;H.TopRight=Eb=t.ax;H.LeftCenter=t.Bp;var Fb;H.Center=Fb=t.Nw;H.RightCenter=t.Cp;var Jb;H.BottomLeft=Jb=t.Iw;var Nb; +H.BottomCenter=Nb=t.Ap;var Ob;H.BottomRight=Ob=t.Kw;var Pb;H.MiddleTop=Pb=t.Ep;var Tb;H.MiddleLeft=Tb=t.Bp;var Ub;H.MiddleRight=Ub=t.Cp;var Vb;H.MiddleBottom=Vb=t.Ap;H.Top=t.Ep;var Wb;H.Left=Wb=t.Bp;var Xb;H.Right=Xb=t.Cp;H.Bottom=t.Ap;var Yb;H.TopSide=Yb=t.ex;var $b;H.LeftSide=$b=t.Rw;var ac;H.RightSide=ac=t.Xw;var bc;H.BottomSide=bc=t.Mw;H.TopBottomSides=t.Yw;H.LeftRightSides=t.Qw;H.TopLeftSides=t.$w;H.TopRightSides=t.bx;H.BottomLeftSides=t.Jw;H.BottomRightSides=t.Lw;H.NotTopSide=t.Vw; +H.NotLeftSide=t.Tw;H.NotRightSide=t.Uw;H.NotBottomSide=t.Sw;var cc;H.AllSides=cc=t.Hw;function dc(){this.Se=[1,0,0,1,0,0]}dc.prototype.copy=function(){var a=new dc;a.Se[0]=this.Se[0];a.Se[1]=this.Se[1];a.Se[2]=this.Se[2];a.Se[3]=this.Se[3];a.Se[4]=this.Se[4];a.Se[5]=this.Se[5];return a};function ic(a){this.type=a;this.r2=this.y2=this.x2=this.r1=this.y1=this.x1=0;this.RC=[]}ic.prototype.addColorStop=function(a,b){this.RC.push({offset:a,color:b})}; +function nc(a){this.fillStyle="#000000";this.font="10px sans-serif";this.globalAlpha=1;this.lineCap="butt";this.fw=0;this.lineJoin="miter";this.lineWidth=1;this.miterLimit=10;this.shadowBlur=0;this.shadowColor="rgba(0, 0, 0, 0)";this.shadowOffsetY=this.shadowOffsetX=0;this.strokeStyle="#000000";this.textAlign="start";this.path=[];this.vi=new dc;this.stack=[];this.ag=[];this.eF=this.ED=this.zv=0;this.Kv=a;this.gI="http://www.w3.org/2000/svg";this.jt=oc(this,"svg",{width:this.Kv.width+"px",height:this.Kv.height+ +"px",vJ:"0 0 "+this.Kv.width+" "+this.Kv.height})}aa=nc.prototype;aa.arc=function(a,b,c,d,e,g){pc(this,a,b,c,d,e,g)};aa.beginPath=function(){this.path=[]};aa.bezierCurveTo=function(a,b,c,d,e,g){this.path.push(["C",a,b,c,d,e,g])};aa.clearRect=function(){};aa.clip=function(){tc(this,"clipPath",this.path,new dc)};aa.closePath=function(){this.path.push(["z"])};aa.createLinearGradient=function(a,b,c,d){var e=new ic("linear");e.x1=a;e.y1=b;e.x2=c;e.y2=d;return e};aa.createPattern=function(){}; +aa.createRadialGradient=function(a,b,c,d,e,g){var h=new ic("radial");h.x1=a;h.y1=b;h.r1=c;h.x2=d;h.y2=e;h.r2=g;return h}; +aa.drawImage=function(a,b,c,d,e,g,h,k,l){a=[b,c,d,e,g,h,k,l,a];b=this.vi;e=a[8];c={x:0,y:0,width:e.naturalWidth,height:e.naturalHeight,href:e.src};d="";g=a[6]/a[2];h=a[7]/a[3];if(0!==a[4]||0!==a[5])d+=" translate("+a[4]+", "+a[5]+")";if(1!==g||1!==h)d+=" scale("+g+", "+h+")";if(0!==a[0]||0!==a[1])d+=" translate("+-a[0]+", "+-a[1]+")";if(0!==a[0]||0!==a[1]||a[2]!==e.naturalWidth||a[3]!==e.naturalHeight)e="CLIP"+this.zv,this.zv++,g=oc(this,"clipPath",{id:e}),g.appendChild(oc(this,"rect",{x:a[0],y:a[1], +width:a[2],height:a[3]})),this.jt.appendChild(g),c["clip-path"]="url(#"+e+")";uc(this,"image",c,b,d);this.addElement("image",c)};aa.fill=function(){tc(this,"fill",this.path,this.vi)};aa.fillRect=function(a,b,c,d){vc(this,"fill",[a,b,c,d],this.vi)};aa.fillText=function(a,b,c){a=[a,b,c];b=this.textAlign;"left"===b?b="start":"right"===b?b="end":"center"===b&&(b="middle");b={x:a[1],y:a[2],style:"font: "+this.font,"text-anchor":b};uc(this,"fill",b,this.vi);this.addElement("text",b,a[0])}; +aa.lineTo=function(a,b){this.path.push(["L",a,b])};aa.moveTo=function(a,b){this.path.push(["M",a,b])};aa.quadraticCurveTo=function(a,b,c,d){this.path.push(["Q",a,b,c,d])};aa.rect=function(a,b,c,d){this.path.push(["M",a,b],["L",a+c,b],["L",a+c,b+d],["L",a,b+d],["z"])}; +aa.restore=function(){this.vi=this.stack.pop();this.path=this.stack.pop();var a=this.stack.pop();this.fillStyle=a.fillStyle;this.font=a.font;this.globalAlpha=a.globalAlpha;this.lineCap=a.lineCap;this.fw=a.fw;this.lineJoin=a.lineJoin;this.lineWidth=a.lineWidth;this.miterLimit=a.miterLimit;this.shadowBlur=a.shadowBlur;this.shadowColor=a.shadowColor;this.shadowOffsetX=a.shadowOffsetX;this.shadowOffsetY=a.shadowOffsetY;this.strokeStyle=a.strokeStyle;this.textAlign=a.textAlign}; +aa.save=function(){this.stack.push({fillStyle:this.fillStyle,font:this.font,globalAlpha:this.globalAlpha,lineCap:this.lineCap,fw:this.fw,lineJoin:this.lineJoin,lineWidth:this.lineWidth,miterLimit:this.miterLimit,shadowBlur:this.shadowBlur,shadowColor:this.shadowColor,shadowOffsetX:this.shadowOffsetX,shadowOffsetY:this.shadowOffsetY,strokeStyle:this.strokeStyle,textAlign:this.textAlign});for(var a=[],b=0;bb.offset?1:-1});for(k=0;k=2*Math.PI?(pc(a,b,c,d,e,e+Math.PI,h),pc(a,b,c,d,e+Math.PI,e+2*Math.PI,h),a.path.push(["M",l,g])):(b+=d*Math.cos(e),c+=d*Math.sin(e),k=180*k/Math.PI,e=h?0:1,h=180<=k==!!h?0:1,0!=a.path.length?a.path.push(["L",b,c]):a.path.push(["M",b,c]),a.path.push(["A",d,d,k,h,e,l,g]))}} +function xc(a,b,c,d,e,g,h){var k=new dc;k.Se=[b,c,d,e,g,h];b={};uc(a,"g",b,k);k=a.addElement("g",b);a.ag.push(k)} +aa.Xa=function(){var a="SHADOW"+this.eF;this.eF++;var b=this.addElement("filter",{id:a,width:"250%",height:"250%"},null),c,d,e,g,h;if(0!=this.shadowOffsetX||0!=this.shadowOffsetY)c=oc(this,"feGaussianBlur",{"in":"SourceAlpha",result:"blur",tJ:this.shadowBlur/2}),d=oc(this,"feFlood",{"in":"blur",result:"flood","flood-color":this.shadowColor}),e=oc(this,"feComposite",{"in":"flood",in2:"blur",operator:"in",result:"comp"}),g=oc(this,"feOffset",{"in":"comp",result:"offsetBlur",dx:this.shadowOffsetX,dy:this.shadowOffsetY}), +h=oc(this,"feMerge",{}),h.appendChild(oc(this,"feMergeNode",{"in":"offsetBlur"})),h.appendChild(oc(this,"feMergeNode",{"in":"SourceGraphic"})),b.appendChild(c),b.appendChild(d),b.appendChild(e),b.appendChild(g),b.appendChild(h);0=a)return 0;var b=D.ZA;if(null===b){for(var b=[],c=0;2E3>=c;c++)b[c]=Math.sqrt(c);D.ZA=b}return 1>a?(c=1/a,2E3>=c?1/b[c| +0]:Math.sqrt(a)):2E3>=a?b[a|0]:Math.sqrt(a)},I:function(a,b){var c=a-b;return 0.5>c&&-0.5c&&-5E-8=e&&(e=1E-6);var k,l,m,n;am-n)if(a-c>e||c-a>e){if(g=(d-b)/(c-a)*(g-a)+b,g-e<=h&&h<=g+e)return!0}else return!0;else if(b-d>e||d-b>e){if(h=(c- +a)/(d-b)*(h-b)+a,h-e<=g&&g<=h+e)return!0}else return!0;return!1},uv:function(a,b,c,d,e,g,h,k,l,m,n,p){if(D.vd(a,b,h,k,p,c,d)&&D.vd(a,b,h,k,p,e,g))return D.vd(a,b,h,k,p,m,n);var q=(a+c)/2,r=(b+d)/2,s=(c+e)/2,u=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(q+s)/2;c=(r+u)/2;var s=(s+e)/2,u=(u+g)/2,x=(d+s)/2,E=(c+u)/2;return D.uv(a,b,q,r,d,c,x,E,l,m,n,p)||D.uv(x,E,s,u,e,g,h,k,l,m,n,p)},RG:function(a,b,c,d,e,g,h,k,l){var m=(c+e)/2,n=(d+g)/2;l.x=(((a+c)/2+m)/2+(m+(e+h)/2)/2)/2;l.y=(((b+d)/2+n)/2+(n+(g+k)/2)/2)/2;return l}, +QG:function(a,b,c,d,e,g,h,k){var l=(c+e)/2,m=(d+g)/2;return Ra(((a+c)/2+l)/2,((b+d)/2+m)/2,(l+(e+h)/2)/2,(m+(g+k)/2)/2)},oo:function(a,b,c,d,e,g,h,k,l,m){if(D.vd(a,b,h,k,l,c,d)&&D.vd(a,b,h,k,l,e,g))cb(m,a,b,0,0),cb(m,h,k,0,0);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,u=(c+r)/2;D.oo(a,b,n,p,d,c,s,u,l,m);D.oo(s,u,q,r,e,g,h,k,l,m)}return m},ue:function(a,b,c,d,e,g,h,k,l,m){if(D.vd(a,b,h,k,l,c,d)&&D.vd(a,b,h,k,l,e,g))0=== +m.length&&m.push([a,b]),m.push([h,k]);else{var n=(a+c)/2,p=(b+d)/2,q=(c+e)/2,r=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(n+q)/2;c=(p+r)/2;var q=(q+e)/2,r=(r+g)/2,s=(d+q)/2,u=(c+r)/2;D.ue(a,b,n,p,d,c,s,u,l,m);D.ue(s,u,q,r,e,g,h,k,l,m)}return m},pA:function(a,b,c,d,e,g,h,k,l,m){if(D.vd(a,b,e,g,m,c,d))return D.vd(a,b,e,g,m,k,l);var n=(a+c)/2,p=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var q=(n+c)/2,r=(p+d)/2;return D.pA(a,b,n,p,q,r,h,k,l,m)||D.pA(q,r,c,d,e,g,h,k,l,m)},sJ:function(a,b,c,d,e,g,h){h.x=((a+c)/2+(c+e)/2)/2;h.y=((b+ +d)/2+(d+g)/2)/2;return h},oA:function(a,b,c,d,e,g,h,k){if(D.vd(a,b,e,g,h,c,d))cb(k,a,b,0,0),cb(k,e,g,0,0);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;D.oA(a,b,l,m,n,p,h,k);D.oA(n,p,c,d,e,g,h,k)}return k},hp:function(a,b,c,d,e,g,h,k){if(D.vd(a,b,e,g,h,c,d))0===k.length&&k.push([a,b]),k.push([e,g]);else{var l=(a+c)/2,m=(b+d)/2;c=(c+e)/2;d=(d+g)/2;var n=(l+c)/2,p=(m+d)/2;D.hp(a,b,l,m,n,p,h,k);D.hp(n,p,c,d,e,g,h,k)}return k},hs:function(a,b,c,d,e,g,h,k,l,m,n,p,q,r){0>=q&& +(q=1E-6);if(D.vd(a,b,h,k,q,c,d)&&D.vd(a,b,h,k,q,e,g)){var s=(a-h)*(m-p)-(b-k)*(l-n);if(!s)return!1;q=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/s;s=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/s;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(bh)return!1}else if(ah)return!1;r.x=q;r.y=s;return!0}var s=(a+c)/2,u=(b+d)/2;c=(c+e)/2;d=(d+g)/2;e=(e+h)/2;g=(g+k)/2;var x=(s+c)/2,E=(u+d)/2;c=(c+e)/2;d=(d+g)/2;var F=(x+c)/2,G=(E+d)/2,L=(n-l)*(n-l)+(p-m)*(p-m),M=!1;D.hs(a,b,s,u,x,E,F,G, +l,m,n,p,q,r)&&(a=(r.x-l)*(r.x-l)+(r.y-m)*(r.y-m),a=q&&(q=1E-6);if(D.vd(a,b,h,k,q,c,d)&&D.vd(a,b,h,k,q,e,g)){q=(a-h)*(m-p)-(b-k)*(l-n);if(!q)return r;var s=((a*k-b*h)*(l-n)-(a-h)*(l*p-m*n))/q,u=((a*k-b*h)*(m-p)-(b-k)*(l*p-m*n))/q;if(s>=n)return r;if((l>n?l-n:n-l)<(m>p?m-p:p-m)){if(ba)return r}else if(a< +h?(l=a,a=h):l=h,sa)return r;0q&&r--}else{var s=(a+c)/2,u=(b+d)/2,x=(c+e)/2,E=(d+g)/2;e=(e+h)/2;g=(g+k)/2;d=(s+x)/2;c=(u+E)/2;var x=(x+e)/2,E=(E+g)/2,F=(d+x)/2,G=(c+E)/2,r=r+D.is(a,b,s,u,d,c,F,G,l,m,n,p,q),r=r+D.is(F,G,x,E,e,g,h,k,l,m,n,p,q)}return r},Hm:function(a,b,c,d,e,g,h){if(D.Fa(a,c)){var k;bc)return h.x=a,h.y=c,!1;h.x=a;h.y=d;return!0}if(D.Fa(b,d)){ac)return h.x= +c,h.y=b,!1;h.x=d;h.y=b;return!0}k=((a-e)*(a-c)+(b-g)*(b-d))/((c-a)*(c-a)+(d-b)*(d-b));if(-5E-6>k)return h.x=a,h.y=b,!1;if(1.000005c)return l.x=a,l.y=c,!1;l.x=a; +l.y=g;return!0}h=(d-b)/(c-a);if(D.Fa(k,h))return D.Hm(a,b,c,d,e,g,l),!1;e=(h*a-k*e+g-b)/(h-k);if(D.Fa(h,0)){ac)return l.x=c,l.y=b,!1;l.x=e;l.y=b;return!0}g=h*(e-a)+b;return D.Hm(a,b,c,d,e,g,l)},gJ:function(a,b,c,d,e){return D.Mg(c.x,c.y,d.x,d.y,a.x,a.y,b.x,b.y,e)},eJ:function(a,b,c,d,e,g,h,k,l,m){function n(c,d){var e=(c-a)*(c-a)+(d-b)*(d-b);e(c>a?c-a:a-c)){q=1-(c-e)*(c-e)/(q*q);if(0>q)return l;q=Math.sqrt(q);d=-m*q+g;n(c,m*q+g);n(c,d)}else{c=(d-b)/(c-a);d=1/(q*q)+c*c/(m*m);k=2*c*(b-c*a)/(m*m)-2*c*g/(m*m)-2*e/(q*q);q=k*k-4*d*(2*c*a*g/(m*m)-2*b*g/(m*m)+g*g/(m*m)+e*e/(q*q)-1+(b-c*a)*(b-c*a)/(m*m));if(0>q)return l;q=Math.sqrt(q);m=(-k+q)/(2*d);n(m,c*m-c*a+b);q=(-k-q)/(2*d);n(q,c*q-c*a+b)}return l},Zk:function(a,b,c,d,e,g,h,k,l){var m=1E21,n=a,p=b;if(D.Mg(a,b,a, +d,e,g,h,k,l)){var q=(l.x-e)*(l.x-e)+(l.y-g)*(l.y-g);qm},Xv:function(a,b,c){var d=b.x,e=b.y,g=c.x,h=c.y,k=a.left,l=a.right,m=a.top,n=a.bottom;return d===g?(e=m): +e===h?(d=k):a.Da(b)||a.Da(c)||D.Wv(k,m,l,m,d,e,g,h)||D.Wv(l,m,l,n,d,e,g,h)||D.Wv(l,n,k,n,d,e,g,h)||D.Wv(k,n,k,m,d,e,g,h)?!0:!1},Wv:function(a,b,c,d,e,g,h,k){return 0>=D.Bv(a,b,c,d,e,g)*D.Bv(a,b,c,d,h,k)&&0>=D.Bv(e,g,h,k,a,b)*D.Bv(e,g,h,k,c,d)},Bv:function(a,b,c,d,e,g){c-=a;d-=b;a=e-a;b=g-b;g=a*d-b*c;0===g&&(g=a*c+b*d,0g&&(g=0)));return 0>g?-1:0a&&(a+=360);360<=a&&(a-=360);return a},aD:function(a,b,c,d,e,g){var h= +Math.PI;g||(d*=h/180,e*=h/180);g=dc,g=0>d,h,k;am;++m){b=0.5*(k+l);if(b===k||b===l)break;var n=a/(b+g),p=h/(b+e),n=n*n+p*p-1;if(0n)l=b;else break}c=g*c/(b+g)-c;d=e*d/(b+e)-d;c=Math.sqrt(c*c+d*d)}else c=Math.abs(d-b);else d=a*a-b*b,e=a*c,e=x-1?!0:null!==m[n+1].match(/[A-Za-z]/)}function d(){n++;return m[n]}function e(){var a=new v(parseFloat(d()),parseFloat(d()));p===p.toLowerCase()&&(a.x=u.x+a.x,a.y=u.y+a.y);return a}function g(){return u=e()}function h(){return s=e()}function k(){var a=[parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d()),parseFloat(d())];c()||(a.push(parseFloat(d())),c()||a.push(parseFloat(d())));p===p.toLowerCase()&&(a[2]+=u.x,a[3]+=u.y);return a}function l(){return"c"!== +q.toLowerCase()&&"s"!==q.toLowerCase()?u:new v(2*u.x-s.x,2*u.y-s.y)}void 0===b&&(b=!1);"string"!==typeof a&&t.Nb(a,"string",I,"parse:str");a=a.replace(/,/gm," ");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([UuBbMmZzLlHhVvCcSsQqTtAaFf])([^\s])/gm,"$1 $2");a=a.replace(/([^\s])([UuBbMmZzLlHhVvCcSsQqTtAaFf])/gm,"$1 $2");a=a.replace(/([0-9])([+\-])/gm,"$1 $2");a= +a.replace(/(\.[0-9]*)(\.)/gm,"$1 $2");a=a.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,"$1 $3 $4 ");a=a.replace(/[\s\r\t\n]+/gm," ");a=a.replace(/^\s+|\s+$/g,"");for(var m=a.split(" "),n=-1,p="",q="",r=new v(0,0),s=new v(0,0),u=new v(0,0),x=m.length,E=t.u(),F,G=!1,L=!1,M=!0;!(n>=x-1);)if(q=p,p=d(),""!==p)switch(p.toUpperCase()){case "X":M=!0;L=G=!1;break;case "M":F=g();null===E.Kb||!0===M?(J(E,F.x,F.y,G,!1,!L),M=!1):E.moveTo(F.x,F.y);for(r=u;!c();)F=g(),E.lineTo(F.x,F.y);break;case "L":for(;!c();)F= +g(),E.lineTo(F.x,F.y);break;case "H":for(;!c();)u=F=new v((p===p.toLowerCase()?u.x:0)+parseFloat(d()),u.y),E.lineTo(u.x,u.y);break;case "V":for(;!c();)u=F=new v(u.x,(p===p.toLowerCase()?u.y:0)+parseFloat(d())),E.lineTo(u.x,u.y);break;case "C":for(;!c();){var W=e(),T=h();F=g();K(E,W.x,W.y,T.x,T.y,F.x,F.y)}break;case "S":for(;!c();)W=l(),T=h(),F=g(),K(E,W.x,W.y,T.x,T.y,F.x,F.y);break;case "Q":for(;!c();)T=h(),F=g(),Vc(E,T.x,T.y,F.x,F.y);break;case "T":for(;!c();)s=T=l(),F=g(),Vc(E,T.x,T.y,F.x,F.y); +break;case "B":for(;!c();)F=k(),E.arcTo(F[0],F[1],F[2],F[3],F[4],F[5],F[6]);break;case "A":for(;!c();){var W=Math.abs(parseFloat(d())),T=Math.abs(parseFloat(d())),U=parseFloat(d()),da=!!parseFloat(d()),R=!!parseFloat(d());F=g();Wc(E,W,T,U,da,R,F.x,F.y)}break;case "Z":N(E);u=r;break;case "F":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Uu]/))W++;else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?G=!0:Xc(E);break;case "U":F=null;for(W=1;m[n+W];)if(null!==m[n+W].match(/[Ff]/))W++; +else if(null===m[n+W].match(/[A-Za-z]/))W++;else{F=m[n+W];break}F.match(/[Mm]/)?L=!0:E.Xa(!1)}r=E.s;t.v(E);if(b)for(E=r.ob.m;E.next();)E.value.Lo=!0;return r};function Yc(a,b){for(var c=a.length,d=t.M(),e=0;e=a&&t.ia(a,"scale must be greater than zero",I,"scale:x"),0>=b&&t.ia(b,"scale must be greater than zero",I,"scale:y"));this.transform(a,0,0,b,0,0)}; +I.prototype.rotate=I.prototype.rotate=function(a,b,c){t.L(this);void 0===b&&(b=0);void 0===c&&(c=0);f&&(t.o(a,I,"rotate:angle"),t.o(b,I,"rotate:x"),t.o(c,I,"rotate:y"));var d=t.Og();d.reset();d.rotate(a,b,c);this.transform(d.m11,d.m12,d.m21,d.m22,d.dx,d.dy);t.Ne(d)}; +I.prototype.transform=I.prototype.transform=function(a,b,c,d,e,g){var h,k;switch(this.type){case Jc:case Kc:case Lc:h=this.Yb;k=this.ic;this.Yb=h*a+k*c+e;this.ic=h*b+k*d+g;h=this.dd;k=this.qd;this.dd=h*a+k*c+e;this.qd=h*b+k*d+g;break;case zc:for(var l=this.ob,m=l.length,n=0;n=a)return 0;if((e>h?e-h:h-e)<(g>k?g-k:k-g)){if(ge)return 0}else if(ee)return 0;return 0a||1a)return n=(a-m)/l,t.xa(c),new v(b[0]+(d[0]-b[0])*n,b[1]+(d[1]-b[1])*n);m+=l}b=d}t.xa(c);return null};t.g(I,"type",I.prototype.type);t.defineProperty(I,{type:"type"},function(){return this.Z},function(a){this.Z!==a&&(f&&t.nb(a,I,I,"type"),t.L(this,a),this.Z=a,this.Ta=!0)});t.g(I,"startX",I.prototype.la);t.defineProperty(I,{la:"startX"},function(){return this.Yb},function(a){this.Yb!==a&&(f&&t.o(a,I,"startX"),t.L(this,a),this.Yb=a,this.Ta=!0)}); +t.g(I,"startY",I.prototype.ma);t.defineProperty(I,{ma:"startY"},function(){return this.ic},function(a){this.ic!==a&&(f&&t.o(a,I,"startY"),t.L(this,a),this.ic=a,this.Ta=!0)});t.g(I,"endX",I.prototype.D);t.defineProperty(I,{D:"endX"},function(){return this.dd},function(a){this.dd!==a&&(f&&t.o(a,I,"endX"),t.L(this,a),this.dd=a,this.Ta=!0)});t.g(I,"endY",I.prototype.F);t.defineProperty(I,{F:"endY"},function(){return this.qd},function(a){this.qd!==a&&(f&&t.o(a,I,"endY"),t.L(this,a),this.qd=a,this.Ta=!0)}); +t.g(I,"figures",I.prototype.ob);t.defineProperty(I,{ob:"figures"},function(){return this.rk},function(a){this.rk!==a&&(f&&t.k(a,A,I,"figures"),t.L(this,a),this.rk=a,this.Ta=!0)});t.defineProperty(I,{G:"spot1"},function(){return this.ji},function(a){f&&t.k(a,H,I,"spot1");t.L(this,a);this.ji=a.W()});t.defineProperty(I,{H:"spot2"},function(){return this.ki},function(a){f&&t.k(a,H,I,"spot2");t.L(this,a);this.ki=a.W()});t.A(I,{Gb:"bounds"},function(){this.Uz()&&(this.RA(),this.df());return this.Jt}); +t.g(I,"minSize",I.prototype.Te);t.defineProperty(I,{Te:"minSize"},function(){return this.Wd},function(a){this.Wd.K(a)||(f&&t.k(a,ea,I,"minSize"),a=a.W(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.Wd=a)});function Ac(a,b,c){t.uc(this);void 0===c&&(c=!0);this.Cl=c;this.yn=!0;void 0!==a?(f&&t.o(a,Ac,"sx"),this.Yb=a):this.Yb=0;void 0!==b?(f&&t.o(b,Ac,"sy"),this.ic=b):this.ic=0;this.Cr=new A(O);this.Tu=this.Cr.Pb;this.Ta=!0}t.ea("PathFigure",Ac);t.th(Ac); +Ac.prototype.copy=function(){var a=new Ac;a.Cl=this.Cl;a.yn=this.yn;a.Yb=this.Yb;a.ic=this.ic;for(var b=this.Cr,c=b.length,d=a.Cr,e=0;ea&&(a+=360),this.bo=a):(void 0!==b?(f&&t.o(b,O,"ex"),this.qe=b):this.qe=0,void 0!==c?(f&&t.o(c,O,"ey"),this.re=c):this.re=0,void 0!==d&&(f&&t.o(d,O,"x1"),this.Ag=d),void 0!==e&&(f&&t.o(e,O,"y1"),this.Bg=e),void 0!==g&&(f&&t.o(g,O,"x2"),this.Fk=g),void 0!==h&&"number"===typeof h&&(f&&t.o(h,O,"y2"),this.Gk=h));this.Ta=!0;this.dh= +!1;this.Pi=null}t.ea("PathSegment",O);t.th(O);O.prototype.copy=function(){var a=new O;a.Z=this.Z;this.Z===cd?(a.se=this.se,a.te=this.te,a.Zm=this.Zm,a.$m=this.$m,a.rj=this.rj,a.sj=this.sj):this.Z===dd?(a.se=this.se,a.te=this.te,a.qe=this.qe,a.re=this.re,a.rj=this.rj,a.sj=this.sj,a.bo=this.bo):(a.qe=this.qe,a.re=this.re,a.Ag=this.Ag,a.Bg=this.Bg,a.Fk=this.Fk,a.Gk=this.Gk);a.Ta=this.Ta;a.dh=this.dh;return a}; +O.prototype.equalsApprox=O.prototype.Oj=function(a){if(!(a instanceof O)||this.type!==a.type||this.Ds!==a.Ds)return!1;switch(this.type){case $c:case Nc:return D.I(this.D,a.D)&&D.I(this.F,a.F);case ad:return D.I(this.D,a.D)&&D.I(this.F,a.F)&&D.I(this.pb,a.pb)&&D.I(this.Fb,a.Fb)&&D.I(this.je,a.je)&&D.I(this.ke,a.ke);case bd:return D.I(this.D,a.D)&&D.I(this.F,a.F)&&D.I(this.pb,a.pb)&&D.I(this.Fb,a.Fb);case cd:return D.I(this.kg,a.kg)&&D.I(this.Fh,a.Fh)&&D.I(this.Aa,a.Aa)&&D.I(this.Ma,a.Ma)&&D.I(this.radiusX, +a.radiusX)&&D.I(this.radiusY,a.radiusY);case dd:return this.Zv===a.Zv&&this.aw===a.aw&&D.I(this.Gw,a.Gw)&&D.I(this.D,a.D)&&D.I(this.F,a.F)&&D.I(this.radiusX,a.radiusX)&&D.I(this.radiusY,a.radiusY);default:return!1}}; +O.prototype.toString=function(a){switch(this.type){case $c:a=void 0===a?"M"+this.D.toString()+" "+this.F.toString():"M"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case Nc:a=void 0===a?"L"+this.D.toString()+" "+this.F.toString():"L"+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case ad:a=void 0===a?"C"+this.pb.toString()+" "+this.Fb.toString()+" "+this.je.toString()+" "+this.ke.toString()+" "+this.D.toString()+" "+this.F.toString():"C"+this.pb.toFixed(a)+" "+this.Fb.toFixed(a)+" "+this.je.toFixed(a)+ +" "+this.ke.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case bd:a=void 0===a?"Q"+this.pb.toString()+" "+this.Fb.toString()+" "+this.D.toString()+" "+this.F.toString():"Q"+this.pb.toFixed(a)+" "+this.Fb.toFixed(a)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;case cd:a=void 0===a?"B"+this.kg.toString()+" "+this.Fh.toString()+" "+this.Aa.toString()+" "+this.Ma.toString()+" "+this.radiusX:"B"+this.kg.toFixed(a)+" "+this.Fh.toFixed(a)+" "+this.Aa.toFixed(a)+" "+this.Ma.toFixed(a)+ +" "+this.radiusX;break;case dd:a=void 0===a?"A"+this.radiusX.toString()+" "+this.radiusY.toString()+" "+this.Gw.toString()+" "+(this.aw?1:0)+" "+(this.Zv?1:0)+" "+this.D.toString()+" "+this.F.toString():"A"+this.radiusX.toFixed(a)+" "+this.radiusY.toFixed(a)+" "+this.Gw.toFixed(a)+" "+(this.aw?1:0)+" "+(this.Zv?1:0)+" "+this.D.toFixed(a)+" "+this.F.toFixed(a);break;default:a=this.type.toString()}return a+(this.dh?"z":"")};var $c;O.Move=$c=t.w(O,"Move",0);var Nc;O.Line=Nc=t.w(O,"Line",1);var ad; +O.Bezier=ad=t.w(O,"Bezier",2);var bd;O.QuadraticBezier=bd=t.w(O,"QuadraticBezier",3);var cd;O.Arc=cd=t.w(O,"Arc",4);var dd;O.SvgArc=dd=t.w(O,"SvgArc",4);O.prototype.freeze=function(){this.cb=!0;return this};O.prototype.Pa=function(){this.cb=!1;return this};O.prototype.close=O.prototype.close=function(){this.dh=!0;return this}; +function ed(a,b){if(null!==a.Pi&&!1===b.Ta)return a.Pi;var c=a.radiusX,d=a.radiusY;void 0===d&&(d=c);var e=a.Zm,g=a.$m,h=D.aD(0,0,c=g(p,r)&&(q=Math.PI);1<=g(p,r)&&(q=0);0===m&&0q&&(q+=2*Math.PI);m=b>h?1:b/h; +r=b>h?h/b:1;b=D.aD(0,0,b>h?b:h,k,k+q,!0);h=t.Og();h.reset();h.translate(c,d);h.rotate(a.bo,0,0);h.scale(m,r);Yc(b,h);t.Ne(h);a.Pi=b;return a.Pi}t.g(O,"isClosed",O.prototype.Ds);t.defineProperty(O,{Ds:"isClosed"},function(){return this.dh},function(a){this.dh!==a&&(this.dh=a,this.Ta=!0)});t.g(O,"type",O.prototype.type);t.defineProperty(O,{type:"type"},function(){return this.Z},function(a){f&&t.nb(a,O,O,"type");t.L(this,a);this.Z=a;this.Ta=!0});t.g(O,"endX",O.prototype.D); +t.defineProperty(O,{D:"endX"},function(){return this.qe},function(a){f&&t.o(a,O,"endX");t.L(this,a);this.qe=a;this.Ta=!0});t.g(O,"endY",O.prototype.F);t.defineProperty(O,{F:"endY"},function(){return this.re},function(a){f&&t.o(a,O,"endY");t.L(this,a);this.re=a;this.Ta=!0});t.defineProperty(O,{pb:"point1X"},function(){return this.Ag},function(a){f&&t.o(a,O,"point1X");t.L(this,a);this.Ag=a;this.Ta=!0}); +t.defineProperty(O,{Fb:"point1Y"},function(){return this.Bg},function(a){f&&t.o(a,O,"point1Y");t.L(this,a);this.Bg=a;this.Ta=!0});t.defineProperty(O,{je:"point2X"},function(){return this.Fk},function(a){f&&t.o(a,O,"point2X");t.L(this,a);this.Fk=a;this.Ta=!0});t.defineProperty(O,{ke:"point2Y"},function(){return this.Gk},function(a){f&&t.o(a,O,"point2Y");t.L(this,a);this.Gk=a;this.Ta=!0}); +t.defineProperty(O,{Aa:"centerX"},function(){return this.Zm},function(a){f&&t.o(a,O,"centerX");t.L(this,a);this.Zm=a;this.Ta=!0});t.defineProperty(O,{Ma:"centerY"},function(){return this.$m},function(a){f&&t.o(a,O,"centerY");t.L(this,a);this.$m=a;this.Ta=!0});t.defineProperty(O,{radiusX:"radiusX"},function(){return this.rj},function(a){f&&t.o(a,O,"radiusX");0>a&&t.ia(a,">= zero",O,"radiusX");t.L(this,a);this.rj=a;this.Ta=!0}); +t.defineProperty(O,{radiusY:"radiusY"},function(){return this.sj},function(a){f&&t.o(a,O,"radiusY");0>a&&t.ia(a,">= zero",O,"radiusY");t.L(this,a);this.sj=a;this.Ta=!0});t.defineProperty(O,{kg:"startAngle"},function(){return this.se},function(a){this.se!==a&&(t.L(this,a),f&&t.o(a,O,"startAngle"),a%=360,0>a&&(a+=360),this.se=a,this.Ta=!0)}); +t.defineProperty(O,{Fh:"sweepAngle"},function(){return this.te},function(a){f&&t.o(a,O,"sweepAngle");t.L(this,a);360a&&(a=-360);this.te=a;this.Ta=!0});t.defineProperty(O,{Zv:"isClockwiseArc"},function(){return!!this.te},function(a){t.L(this,a);this.te=a?1:0;this.Ta=!0});t.defineProperty(O,{aw:"isLargeArc"},function(){return!!this.se},function(a){t.L(this,a);this.se=a?1:0;this.Ta=!0}); +t.defineProperty(O,{Gw:"xAxisRotation"},function(){return this.bo},function(a){f&&t.o(a,O,"xAxisRotation");a%=360;0>a&&(a+=360);t.L(this,a);this.bo=a;this.Ta=!0});function od(){this.ba=null;this.cz=(new v(0,0)).freeze();this.Ix=(new v(0,0)).freeze();this.Gt=this.vu=0;this.ju="";this.gv=this.Ut=!1;this.Rt=this.It=0;this.Qi=this.au=!1;this.lq=null;this.ev=0;this.Sf=this.cv=null}t.ea("InputEvent",od); +od.prototype.copy=function(){var a=new od;a.ba=this.ba;a.cz=this.$c.copy().freeze();a.Ix=this.V.copy().freeze();a.vu=this.vu;a.Gt=this.Gt;a.ju=this.ju;a.Ut=this.Ut;a.gv=this.gv;a.It=this.It;a.Rt=this.Rt;a.au=this.au;a.Qi=this.Qi;a.lq=this.lq;a.ev=this.ev;a.cv=this.cv;a.Sf=this.Sf;return a}; +od.prototype.toString=function(){var a="^";this.Lc&&(a+="M:"+this.Lc);this.button&&(a+="B:"+this.button);this.key&&(a+="K:"+this.key);this.we&&(a+="C:"+this.we);this.Lj&&(a+="D:"+this.Lj);this.Ae&&(a+="h");this.bubbles&&(a+="b");null!==this.V&&(a+="@"+this.V.toString());return a};t.g(od,"diagram",od.prototype.h);t.defineProperty(od,{h:"diagram"},function(){return this.ba},function(a){this.ba=a});t.g(od,"viewPoint",od.prototype.$c); +t.defineProperty(od,{$c:"viewPoint"},function(){return this.cz},function(a){t.k(a,v,od,"viewPoint");this.cz.assign(a)});t.g(od,"documentPoint",od.prototype.V);t.defineProperty(od,{V:"documentPoint"},function(){return this.Ix},function(a){t.k(a,v,od,"documentPoint");this.Ix.assign(a)});t.g(od,"modifiers",od.prototype.Lc);t.defineProperty(od,{Lc:"modifiers"},function(){return this.vu},function(a){this.vu=a});t.g(od,"button",od.prototype.button); +t.defineProperty(od,{button:"button"},function(){return this.Gt},function(a){this.Gt=a});t.g(od,"key",od.prototype.key);t.defineProperty(od,{key:"key"},function(){return this.ju},function(a){this.ju=a});t.g(od,"down",od.prototype.Nj);t.defineProperty(od,{Nj:"down"},function(){return this.Ut},function(a){this.Ut=a});t.g(od,"up",od.prototype.Ni);t.defineProperty(od,{Ni:"up"},function(){return this.gv},function(a){this.gv=a});t.g(od,"clickCount",od.prototype.we); +t.defineProperty(od,{we:"clickCount"},function(){return this.It},function(a){this.It=a});t.g(od,"delta",od.prototype.Lj);t.defineProperty(od,{Lj:"delta"},function(){return this.Rt},function(a){this.Rt=a});t.g(od,"handled",od.prototype.Ae);t.defineProperty(od,{Ae:"handled"},function(){return this.au},function(a){this.au=a});t.g(od,"bubbles",od.prototype.bubbles);t.defineProperty(od,{bubbles:"bubbles"},function(){return this.Qi},function(a){this.Qi=a});t.g(od,"event",od.prototype.event); +t.defineProperty(od,{event:"event"},function(){return this.lq},function(a){this.lq=a});t.A(od,{cw:"isTouchEvent"},function(){var a=window.TouchEvent;return a&&this.event instanceof a});t.g(od,"timestamp",od.prototype.timestamp);t.defineProperty(od,{timestamp:"timestamp"},function(){return this.ev},function(a){this.ev=a});t.g(od,"targetDiagram",od.prototype.lg);t.defineProperty(od,{lg:"targetDiagram"},function(){return this.cv},function(a){this.cv=a});t.g(od,"targetObject",od.prototype.Nd); +t.defineProperty(od,{Nd:"targetObject"},function(){return this.Sf},function(a){this.Sf=a});t.g(od,"control",od.prototype.control);t.defineProperty(od,{control:"control"},function(){return 0!==(this.Lc&1)},function(a){this.Lc=a?this.Lc|1:this.Lc&-2});t.g(od,"shift",od.prototype.shift);t.defineProperty(od,{shift:"shift"},function(){return 0!==(this.Lc&4)},function(a){this.Lc=a?this.Lc|4:this.Lc&-5});t.g(od,"alt",od.prototype.alt); +t.defineProperty(od,{alt:"alt"},function(){return 0!==(this.Lc&2)},function(a){this.Lc=a?this.Lc|2:this.Lc&-3});t.g(od,"meta",od.prototype.Fm);t.defineProperty(od,{Fm:"meta"},function(){return 0!==(this.Lc&8)},function(a){this.Lc=a?this.Lc|8:this.Lc&-9});t.g(od,"left",od.prototype.left);t.defineProperty(od,{left:"left"},function(){return 0===this.button},function(a){this.button=a?0:2});t.g(od,"middle",od.prototype.cI); +t.defineProperty(od,{cI:"middle"},function(){return 1===this.button},function(a){this.button=a?1:0});t.g(od,"right",od.prototype.right);t.defineProperty(od,{right:"right"},function(){return 2===this.button},function(a){this.button=a?2:0});function pd(){this.ba=null;this.Mb="";this.Iu=this.Zu=null;this.Ht=!1}t.ea("DiagramEvent",pd);pd.prototype.copy=function(){var a=new pd;a.ba=this.ba;a.Mb=this.Mb;a.Zu=this.Zu;a.Iu=this.Iu;a.Ht=this.Ht;return a}; +pd.prototype.toString=function(){var a="*"+this.name;this.cancel&&(a+="x");null!==this.Cw&&(a+=":"+this.Cw.toString());null!==this.ow&&(a+="("+this.ow.toString()+")");return a};t.g(pd,"diagram",pd.prototype.h);t.defineProperty(pd,{h:"diagram"},function(){return this.ba},function(a){this.ba=a});t.g(pd,"name",pd.prototype.name);t.defineProperty(pd,{name:"name"},function(){return this.Mb},function(a){this.Mb=a});t.g(pd,"subject",pd.prototype.Cw); +t.defineProperty(pd,{Cw:"subject"},function(){return this.Zu},function(a){this.Zu=a});t.g(pd,"parameter",pd.prototype.ow);t.defineProperty(pd,{ow:"parameter"},function(){return this.Iu},function(a){this.Iu=a});t.g(pd,"cancel",pd.prototype.cancel);t.defineProperty(pd,{cancel:"cancel"},function(){return this.Ht},function(a){this.Ht=a});function qd(){this.clear()}t.ea("ChangedEvent",qd);var rd;qd.Transaction=rd=t.w(qd,"Transaction",-1);var sd;qd.Property=sd=t.w(qd,"Property",0);var td; +qd.Insert=td=t.w(qd,"Insert",1);var ud;qd.Remove=ud=t.w(qd,"Remove",2);qd.prototype.clear=qd.prototype.clear=function(){this.Sp=sd;this.Tl=this.uu="";this.yu=this.zu=this.Fu=this.Ln=this.Eu=this.ba=this.Cd=null}; +qd.prototype.copy=function(){var a=new qd;a.Cd=this.Cd;a.ba=this.ba;a.Sp=this.Sp;a.uu=this.uu;a.Tl=this.Tl;a.Eu=this.Eu;var b=this.Ln;a.Ln=t.jb(b)&&"function"===typeof b.W?b.W():b;b=this.Fu;a.Fu=t.jb(b)&&"function"===typeof b.W?b.W():b;b=this.zu;a.zu=t.jb(b)&&"function"===typeof b.W?b.W():b;b=this.yu;a.yu=t.jb(b)&&"function"===typeof b.W?b.W():b;return a}; +qd.prototype.toString=function(){var a="",a=this.fd===rd?a+"* ":this.fd===sd?a+(null!==this.da?"!m":"!d"):a+((null!==this.da?"!m":"!d")+this.fd);this.propertyName&&"string"===typeof this.propertyName&&(a+=" "+this.propertyName);this.kf&&this.kf!==this.propertyName&&(a+=" "+this.kf);a+=": ";this.fd===rd?null!==this.oldValue&&(a+=" "+this.oldValue):(null!==this.object&&(a+=vd(this.object)),null!==this.oldValue&&(a+=" old: "+vd(this.oldValue)),null!==this.Ff&&(a+=" "+this.Ff),null!==this.newValue&& +(a+=" new: "+vd(this.newValue)),null!==this.Df&&(a+=" "+this.Df));return a};qd.prototype.getValue=qd.prototype.wa=function(a){return a?this.oldValue:this.newValue};qd.prototype.getParam=function(a){return a?this.Ff:this.Df};qd.prototype.canUndo=qd.prototype.canUndo=function(){return null!==this.da||null!==this.h?!0:!1};qd.prototype.undo=qd.prototype.undo=function(){this.canUndo()&&(null!==this.da?this.da.changeState(this,!0):null!==this.h&&this.h.changeState(this,!0))}; +qd.prototype.canRedo=qd.prototype.canRedo=function(){return null!==this.da||null!==this.h?!0:!1};qd.prototype.redo=qd.prototype.redo=function(){this.canRedo()&&(null!==this.da?this.da.changeState(this,!1):null!==this.h&&this.h.changeState(this,!1))};t.g(qd,"model",qd.prototype.da);t.defineProperty(qd,{da:"model"},function(){return this.Cd},function(a){this.Cd=a});t.g(qd,"diagram",qd.prototype.h);t.defineProperty(qd,{h:"diagram"},function(){return this.ba},function(a){this.ba=a});t.g(qd,"change",qd.prototype.fd); +t.defineProperty(qd,{fd:"change"},function(){return this.Sp},function(a){f&&t.nb(a,qd,qd,"change");this.Sp=a});t.g(qd,"modelChange",qd.prototype.kf);t.defineProperty(qd,{kf:"modelChange"},function(){return this.uu},function(a){f&&t.j(a,"string",qd,"modelChange");this.uu=a});t.g(qd,"propertyName",qd.prototype.propertyName);t.defineProperty(qd,{propertyName:"propertyName"},function(){return this.Tl},function(a){f&&"string"!==typeof a&&t.k(a,Function,qd,"propertyName");this.Tl=a}); +t.g(qd,"isTransactionFinished",qd.prototype.QH);t.A(qd,{QH:"isTransactionFinished"},function(){return this.Sp===rd&&("CommittedTransaction"===this.Tl||"FinishedUndo"===this.Tl||"FinishedRedo"===this.Tl)});t.g(qd,"object",qd.prototype.object);t.defineProperty(qd,{object:"object"},function(){return this.Eu},function(a){this.Eu=a});t.g(qd,"oldValue",qd.prototype.oldValue);t.defineProperty(qd,{oldValue:"oldValue"},function(){return this.Ln},function(a){this.Ln=a});t.g(qd,"oldParam",qd.prototype.Ff); +t.defineProperty(qd,{Ff:"oldParam"},function(){return this.Fu},function(a){this.Fu=a});t.g(qd,"newValue",qd.prototype.newValue);t.defineProperty(qd,{newValue:"newValue"},function(){return this.zu},function(a){this.zu=a});t.g(qd,"newParam",qd.prototype.Df);t.defineProperty(qd,{Df:"newParam"},function(){return this.yu},function(a){this.yu=a}); +function C(a){1b||(t.ri(this.Fe,b),me(this,"nodeDataArray",ud,"nodeDataArray",this,a,null,b,null),this.nt(a)))}};C.prototype.removeNodeDataCollection=function(a){if(t.isArray(a))for(var b=t.wb(a),c=0;cb&&(b=t.wb(a));t.qi(a,b,c);me(this,"",td,"",a,null,c,null,b)}; +C.prototype.removeArrayItem=function(a,b){void 0===b&&(b=-1);f&&(t.js(a,C,"removeArrayItem:arr"),t.o(b,C,"removeArrayItem:idx"));a===this.Fe&&t.l("Model.removeArrayItem should not be called on the Model.nodeDataArray");-1===b&&(b=t.wb(a)-1);var c=t.mb(a,b);t.ri(a,b);me(this,"",ud,"",a,c,null,b,null)};t.g(C,"nodeCategoryProperty",C.prototype.dl); +t.defineProperty(C,{dl:"nodeCategoryProperty"},function(){return this.fr},function(a){var b=this.fr;b!==a&&(ne(a,C,"nodeCategoryProperty"),this.fr=a,this.i("nodeCategoryProperty",b,a))});C.prototype.getCategoryForNodeData=C.prototype.getCategoryForNodeData=function(a){if(null===a)return"";var b=this.fr;if(""===b)return"";b=t.ab(a,b);if(void 0===b)return"";if("string"===typeof b)return b;t.l("getCategoryForNodeData found a non-string category for "+a+": "+b);return""}; +C.prototype.setCategoryForNodeData=C.prototype.ww=function(a,b){t.j(b,"string",C,"setCategoryForNodeData:cat");if(null!==a){var c=this.fr;if(""!==c)if(this.ae(a)){var d=t.ab(a,c);void 0===d&&(d="");d!==b&&(t.Oa(a,c,b),me(this,"nodeCategory",sd,c,a,d,b))}else t.Oa(a,c,b)}}; +function P(a,b){2e||(t.ri(d,e),this.ui(a)&&(xe(this,b,a),me(this,"linkLabelKeys",ud,c,a,b,null)))}else void 0!==d&&t.l(c+" property is not an Array; cannot removeLabelKeyforLinkData: "+a)}}};t.g(P,"linkDataArray",P.prototype.Hi); +t.defineProperty(P,{Hi:"linkDataArray"},function(){return this.xg},function(a){var b=this.xg;if(b!==a){t.js(a,P,"linkDataArray");this.Ld&&t.lc&&(null!==b&&t.Cm(b,"linkDataArray",this,!0),a=t.Cm(a,"linkDataArray",this,!1));for(var c=t.wb(a),d=0;db)){t.ri(this.xg,b);me(this,"linkDataArray",ud,"linkDataArray",this,a,null,b,null);b=this.xm(a);xe(this,b,a);b=this.ym(a);xe(this,b,a);var c=this.Yk(a);if(t.isArray(c))for(var d=t.wb(c),e=0;ea.ol&&t.trace("Ending transaction without having started a transaction: "+c);var d=1===a.ol;d&&b&&a.isEnabled&&a.Ec("CommittingTransaction",c,a.Uk);var e=0;if(0a.Tj;e--)g=d.ta(e),null!==g&&g.clear(), +d.Zc(e);e=a.$z;0===e&&(e=1);0=e&&(g=d.ta(0),null!==g&&g.clear(),d.Zc(0),a.vk--);d.add(b);a.vk++;d.freeze();g=b}a.Ec("CommittedTransaction",c,g)}else{a.Wh=!0;try{a.isEnabled&&null!==g&&(g.Ko=!0,g.undo())}finally{a.Ec("RolledBackTransaction",c,g),a.Wh=!1}null!==g&&g.clear()}a.Qt=null;return!0}if(a.isEnabled&&!b&&null!==g){a=e;c=g.sh;for(b=c.count-1;b>=a;b--)d=c.ta(b),null!==d&&d.undo(),c.Pa(),c.Zc(b);c.freeze()}return!1} +wd.prototype.canUndo=wd.prototype.canUndo=function(){if(!this.isEnabled||0=this.ol&&!this.Px&&(a=a.h,null!==a&&!1===a.Mf||t.trace("Change not within a transaction: "+c.toString()))}}; +wd.prototype.skipsEvent=function(a){if(null===a||0>a.fd.value)return!0;a=a.object;if(a instanceof Q){if(a=a.layer,null!==a&&a.kc)return!0}else if(a instanceof Zd&&a.kc)return!0;return!1};t.A(wd,{dI:"models"},function(){return this.sy.m});t.g(wd,"isEnabled",wd.prototype.isEnabled);t.defineProperty(wd,{isEnabled:"isEnabled"},function(){return this.Vh},function(a){this.Vh=a});t.A(wd,{xF:"transactionToUndo"},function(){return 0<=this.Tj&&this.Tj<=this.history.count-1?this.history.ta(this.Tj):null}); +t.A(wd,{wF:"transactionToRedo"},function(){return this.Tjb.bg||(b.scale=a))};oa.prototype.canDecreaseZoom=function(a){void 0===a&&(a=1/this.qt);t.o(a,oa,"canDecreaseZoom:factor");var b=this.h;if(null===b||b.jm!==Je)return!1;a*=b.scale;return ab.bg?!1:b.fs}; +oa.prototype.increaseZoom=function(a){void 0===a&&(a=this.qt);t.o(a,oa,"increaseZoom:factor");var b=this.h;null!==b&&b.jm===Je&&(a*=b.scale,ab.bg||(b.scale=a))};oa.prototype.canIncreaseZoom=function(a){void 0===a&&(a=this.qt);t.o(a,oa,"canIncreaseZoom:factor");var b=this.h;if(null===b||b.jm!==Je)return!1;a*=b.scale;return ab.bg?!1:b.fs};oa.prototype.resetZoom=function(a){void 0===a&&(a=this.gD);t.o(a,oa,"resetZoom:newscale");var b=this.h;null===b||ab.bg||(b.scale=a)}; +oa.prototype.canResetZoom=function(a){void 0===a&&(a=1);t.o(a,oa,"canResetZoom:newscale");var b=this.h;return null===b||ab.bg?!1:b.fs};oa.prototype.zoomToFit=function(){var a=this.h;if(null!==a){var b=a.scale,c=a.position;b!==this.AC||isNaN(this.my)?(this.my=b,this.PB=c.copy(),a.zoomToFit(),a.zh(),this.AC=a.scale):(a.scale=this.my,a.position=this.PB)}};oa.prototype.canZoomToFit=function(){var a=this.h;return null===a?!1:a.fs}; +oa.prototype.collapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b)return!1;b.mc("Collapse Tree");var c=new A(S);if(a instanceof S&&a.Ac)a.collapseTree(),c.add(a);else for(a=b.selection.m;a.next();){var d=a.value;d instanceof S&&d.Ac&&(d.collapseTree(),c.add(d))}b.Ea("TreeCollapsed",c);b.ye("Collapse Tree")}; +oa.prototype.canCollapseTree=function(a){void 0===a&&(a=null);var b=this.h;if(null===b||b.Wa)return!1;if(a instanceof S){if(!a.Ac)return!1;if(0c||Math.abs(b.y-a.y)>d};t.A($d,{h:"diagram"},function(){return this.ba}); +t.g($d,"name",$d.prototype.name);t.defineProperty($d,{name:"name"},function(){return this.Mb},function(a){this.Mb=a});t.g($d,"isEnabled",$d.prototype.isEnabled);t.defineProperty($d,{isEnabled:"isEnabled"},function(){return this.Vh},function(a){this.Vh=a});t.g($d,"isActive",$d.prototype.oa);t.defineProperty($d,{oa:"isActive"},function(){return this.FB},function(a){this.FB=a});t.g($d,"transactionResult",$d.prototype.We); +t.defineProperty($d,{We:"transactionResult"},function(){return this.wC},function(a){this.wC=a}); +function $e(){0e&&(e=k),l>g&&(g=l))}}Infinity===c?b.q(0,0,0,0):b.q(c,d,e-c,g-d)} +function zf(a,b){if(null===a.gd){var c=a.h;if(null!==c&&!c.Wa&&!c.Pe&&null!==a.rc){wf(a);c.xb=!b;a.Kp=!b;a.Li=c.yc.V;for(var c=a.XC?c.copyParts(a.rc.nl(),c,!0):c.copyParts(c.selection,c,!0),d=c.m;d.next();)d.value.location=d.key.location;d=t.qf();yf(c,d);t.Ic(d);for(var d=new ia(B,Object),e=a.rc.m;e.next();){var g=e.key;g.Kd()&&g.canCopy()&&(g=c.wa(g),null!==g&&(a.Kp&&(g.he="Tool"),g.yf(),d.add(g,gf(g.location))))}for(c=c.m;c.next();)e=c.value,e instanceof X&&e.canCopy()&&d.add(e,gf());a.gd=d;af(a, +d.nl());null!==a.Vc&&(c=a.Vc,d=c.bj(),c.cl(a.Li.x-(d.x+d.width/2),a.Li.y-(d.y+d.height/2)))}}}function vf(a){var b=a.h;null!==b&&(null!==a.gd&&(b.wA(a.gd.nl(),!1),a.gd=null),b.xb=!1,a.Kp=!1,a.Li=b.yc.V)}function uf(a){if(null!==a.Vc){if(a.yi&&null!==a.hi){var b=a.hi;b.h.remove(b.Od);b.h.remove(b.Pd)}a.Vc=null;a.hi=null}}function Af(a,b,c){var d=a.h;if(null!==d){var e=a.Li,g=t.M();g.assign(d.S.V);a.moveParts(b,g.it(e),c);t.B(g)}} +$e.prototype.moveParts=function(a,b,c){if(null!==a&&(t.k(a,ia,$e,"moveParts:parts"),0!==a.count)){var d=t.M(),e=t.M();e.assign(b);isNaN(e.x)&&(e.x=0);isNaN(e.y)&&(e.y=0);var g=this.$u;g||bf(this,a);for(var h=new A,k=new A(Da),l=a.m;l.next();){var m=l.key;if(m.Kd()){var n=Bf(this,m,a);if(null!==n)h.add({Bc:m,info:l.value,BH:n});else if(!c||m.canMove()){n=l.value.point;d.assign(n);var p=this.computeMove(m,d.add(e),a);m.location=p;l.value.Jy=p.it(n)}}else l.key instanceof X&&k.add(l.Vd)}for(c=h.m;c.next();)h= +c.value,n=h.info.point,d.assign(n),h.Bc.location=d.add(h.BH.Jy);n=t.M();c=t.M();for(k=k.m;k.next();)if(p=k.value,h=p.key,h instanceof X)if(h.up)if(l=h.ca,m=h.ga,null!==this.Vc&&this.yi)p=p.value.point,a.add(h,gf(e)),l=b.x-p.x,m=b.y-p.y,h.cl(l,m);else{if(null!==l){n.assign(l.location);var q=a.wa(l);null!==q&&n.it(q.point)}null!==m&&(c.assign(m.location),q=a.wa(m),null!==q&&c.it(q.point));null!==l&&null!==m?n.zi(c)?(p=p.value.point,l=d,l.assign(n),l.it(p),a.add(h,gf(n)),h.cl(l.x,l.y)):(h.up=!1,h.Tb()): +(p=p.value.point,a.add(h,gf(null!==l?n:null!==m?c:b)),l=e.x-p.x,m=e.y-p.y,h.cl(l,m))}else if(null===h.ca||null===h.ga)p=p.value.point,a.add(h,gf(b)),l=e.x-p.x,m=e.y-p.y,h.cl(l,m);t.B(d);t.B(e);t.B(n);t.B(c);g||sf(this,a)}};function Bf(a,b,c){b=b.ib;if(null!==b){a=Bf(a,b,c);if(null!==a)return a;a=c.wa(b);if(null!==a)return a}return null} +function wf(a){if(null!==a.rc){for(var b=a.h,c=a.rc.m;c.next();){var d=c.key;d.Kd()&&(d.location=c.value.point)}for(c=a.rc.m;c.next();)if(d=c.key,d instanceof X&&d.up){var e=c.value.point;a.rc.add(d,gf());d.cl(-e.x,-e.y)}b.zh()}} +$e.prototype.computeMove=function(a,b,c,d){void 0===d&&(d=new v);d.assign(b);if(null===a)return d;void 0===c&&(c=null);var e=b;if(this.Mo&&(this.XD||null===c||this.h.S.Ni)&&(e=t.M(),c=e,c.assign(b),null!==a)){var g=this.h;if(null!==g){var h=g.Io,k=this.Lz,g=k.width,k=k.height,l=this.GD,m=l.x,l=l.y,n=this.FD;if(null!==h){var p=h.xs;isNaN(g)&&(g=p.width);isNaN(k)&&(k=p.height);h=h.Kz;isNaN(m)&&(m=h.x);isNaN(l)&&(l=h.y)}h=t.cc(0,0);h.ft(0,0,g,k,n);D.ss(b.x,b.y,m+h.x,l+h.y,g,k,c);t.B(h)}}c=null!==a.Bz? +a.Bz(a,b,e):e;k=a.rE;g=k.x;isNaN(g)&&(g=a.location.x);k=k.y;isNaN(k)&&(k=a.location.y);h=a.lE;m=h.x;isNaN(m)&&(m=a.location.x);h=h.y;isNaN(h)&&(h=a.location.y);d.q(Math.max(g,Math.min(c.x,m)),Math.max(k,Math.min(c.y,h)));e!==b&&t.B(e);return d};function Cf(a,b){if(null===b)return!0;var c=b.Q;return null===c||c instanceof Fe||c.layer.kc||a.rc&&a.rc.contains(c)||a.gd&&a.gd.contains(c)?!0:!1} +function Df(a,b,c,d){var e=a.h;if(null!==e){a.yi&&(null!==a.Vc&&(a.Vc.ca=null,a.Vc.ga=null),Ef(a,!1));var g=!1;!1===a.Vu&&(g=e.xb,e.xb=!0);var h=!1,k=Ff(e,b,null,function(b){return!Cf(a,b)}),l=e.S;l.Nd=k;var m=e.xb;e.xb=!0;if(k!==a.wl){var n=a.wl;a.Ku=n;for(a.wl=k;null!==n;){var p=n.cA;if(null!==p){if(k===n)break;if(null!==k&&k.Ei(n))break;p(l,n,k);h=!0;if(l.Ae)break}n=n.fa}for(n=a.Ku;null!==k;){p=k.sE;if(null!==p){if(n===k)break;if(null!==n&&n.Ei(k))break;p(l,k,n);h=!0;if(l.Ae)break}k=k.fa}k=a.wl}null=== +k&&(p=e.tE,null!==p&&(p(l),h=!0));a.doDragOver(b,k);e.xb=m;h&&e.zh();!1===a.Vu&&(e.xb=g);(e.bf||e.cf)&&(c||d)&&Gf(e,b)}}function Qf(a,b,c){var d=a.hi;if(null===d)return null;var e=a.h.vm(b,d.lA,function(a){return d.findValidLinkablePort(a,c)});a=t.M();for(var g=Infinity,h=null,e=e.m;e.next();){var k=e.value;if(null!==k.Q){var l=k.$a(Fb,a),l=b.Mj(l);lc.ka)){var d=a.h;if(null!==d&&!d.Wa&&(d=a.hi,null!==d)){var e=null,g=null;null===c.ca&&(e=Qf(a,c.n(0),!1),null!==e&&(g=e.Q));var h=null,k=null;null===c.ga&&(h=Qf(a,c.n(c.ka-1),!0),null!==h&&(k=h.Q));if((null===g||g instanceof S)&&(null===k||k instanceof S)){var l=d.isValidLink(g,e,k,h);b?(c.dn=c.n(0).copy(),c.hn=c.n(c.ka-1).copy(),c.up=!1,c.ca=g,null!==e&&(c.Af=e.md),c.ga=k,null!==h&&(c.ng=h.md)):l?Rf(d,g,e,k,h):Rf(d,null,null,null,null)}}}} +$e.prototype.doDragOver=function(){};function Sf(a,b){var c=a.h;if(null!==c&&null!==c.da){a.yi&&Ef(a,!0);rf(a);var d=Ff(c,b,null,function(b){return!Cf(a,b)}),e=c.S;e.Nd=d;if(null!==d)for(var g=d;null!==g;){var h=g.Ls;if(null!==h&&(h(e,g),e.Ae))break;g=g.fa}else h=c.Ls,null!==h&&h(e);a.doDropOnto(b,d);for(d=c.selection.m;d.next();)e=d.value,e instanceof S&&Tf(c,e.ua)}}$e.prototype.doDropOnto=function(){}; +$e.prototype.doMouseMove=function(){if(this.oa){var a=this.h;if(null!==a&&null!==this.to&&null!==this.rc){var b=!1,c=!1;this.mayCopy()?(b=!0,zf(this,!1),Af(this,this.gd,!0)):this.mayMove()?(c=!0,vf(this),Af(this,this.rc,!0)):vf(this);Df(this,a.S.V,c,b)}}}; +$e.prototype.doMouseUp=function(){if(this.oa){this.hq=!0;var a=this.h;if(null!==a){var b=!1,c=this.mayCopy();c&&null!==this.gd?(wf(this),vf(this),zf(this,!0),Af(this,this.gd,!0),null!==this.gd&&a.XE(this.gd.nl())):(b=!0,vf(this),this.mayMove()&&(Af(this,this.rc,!0),this.Vu=!1,Df(this,a.S.V,!0,!1),this.Vu=!0));Sf(this,a.S.V);if(this.oa){this.gd=null;if(b&&null!==this.rc)for(b=this.rc.m;b.next();){var d=b.key;d instanceof S&&(d=d.ib,null===d||null===d.placeholder||this.rc.contains(d)||d.vz&&d.Y())}a.Jc(); +sf(this,this.rc);this.We=c?"Copy":"Move";a.Ea(c?"SelectionCopied":"SelectionMoved",a.selection)}this.stopTool()}}};$e.prototype.mayCopy=function(){var a=this.h;if(null===a||a.Wa||a.Pe||!a.fm||!a.Ej||(a.El?!a.S.Fm:!a.S.control))return!1;for(a=a.selection.m;a.next();){var b=a.value;if(b.Kd()&&b.canCopy())return!0}return null!==this.Vc&&this.yi&&this.Vc.canCopy()?!0:!1}; +$e.prototype.mayMove=function(){var a=this.h;if(null===a||a.Wa||!a.Nk)return!1;for(a=a.selection.m;a.next();){var b=a.value;if(b.Kd()&&b.canMove())return!0}return null!==this.Vc&&this.yi&&this.Vc.canMove()?!0:!1};var tf=new A($e),cf=null,df=null;$e.prototype.mayCopyExternal=function(){var a=this.h;return null===a||!a.lz||a.Wa||a.Pe||!a.fm||null===a.da?!1:!0}; +$e.prototype.doSimulatedDragEnter=function(){if(this.mayCopyExternal()){var a=cf;if(null!==a){vf(a);wf(a);var b=a.h;null!==b&&a.Un.P()&&(b.position=a.Un);null!==b&&qf(b)}tf.contains(this)||tf.add(this)}};$e.prototype.doSimulatedDragLeave=function(){cf.$v=!1;this.doCancel()};$e.prototype.doSimulatedDragOver=function(){if(this.mayCopyExternal()){var a=this.h;if(null!==a){var b=cf;null!==b&&null!==b.rc&&(Uf(this,b.rc.nl(),!1),Af(this,this.gd,!1),Df(this,a.S.V,!1,!0))}}}; +$e.prototype.doSimulatedDrop=function(){var a=cf;if(null!==a&&(a.hq=!0,vf(this),this.mayCopyExternal())){var b=this.h;null!==b&&(this.mc("Drop"),Uf(this,a.rc.nl(),!0),Af(this,this.gd,!0),null!==this.gd&&b.XE(this.gd.nl()),this.We="ExternalCopy",Sf(this,b.S.V),this.gd=null,b.Ea("ExternalObjectsDropped",b.selection),this.Xj(),b.Jc())}}; +function Uf(a,b,c){if(null===a.gd){var d=a.h;if(null!==d&&!d.Wa&&!d.Pe&&null!==d.da){d.xb=!c;a.Kp=!c;a.Li=d.S.V;d=d.copyParts(b,d,!0);c=t.qf();yf(b,c);var e=c.x+c.width/2,g=c.y+c.height/2;t.Ic(c);var h=a.Xu;c=new ia(B,Object);var k=t.M();for(b=b.m;b.next();){var l=b.value;if(l.Kd()&&l.canCopy()){var m=l.location,l=d.wa(l);k.q(h.x-(e-m.x),h.y-(g-m.y));l.location=k;a.Kp&&(l.he="Tool");l.yf();c.add(l,gf(k))}}t.B(k);for(d=d.m;d.next();)e=d.value,e instanceof X&&e.canCopy()&&c.add(e,gf());a.gd=c;af(a, +c.nl());null!==a.Vc&&(c=a.Vc,d=c.bj(),c.cl(a.Li.x-(d.x+d.width/2),a.Li.y-(d.y+d.height/2)))}}} +function Vf(){0=d&&(d=0.1);for(var e=this,g=b.vm(c,d,function(b){return e.findValidLinkablePort(b,a)},null,!0),d=Infinity,b=null,g=g.m;g.next();){var h=g.value,k=h.Q;if(k instanceof S){var l=h.$a(Fb,t.M()),m=c.x-l.x,n=c.y-l.y;t.B(l);l=m*m+n*n;lc){if(null!==this.$b&&a===this.fg&&b===this.gg)return!0;var d=b.md;null===d&&(d="");if(a.Ov(d).count>=c)return!1}return!0}; +Vf.prototype.isValidTo=function(a,b){if(null===a||null===b)return this.Am;if(this.h.Va===this&&(null!==a.layer&&!a.layer.gm||!0!==b.NA))return!1;var c=b.sF;if(Infinity>c){if(null!==this.$b&&a===this.hg&&b===this.ig)return!0;var d=b.md;null===d&&(d="");if(a.Zf(d).count>=c)return!1}return!0};Vf.prototype.isInSameNode=function(a,b){if(null===a||null===b)return!1;if(a===b)return!0;var c=a.Q,d=b.Q;return null!==c&&c===d}; +Vf.prototype.isLinked=function(a,b){if(null===a||null===b)return!1;var c=a.Q;if(!(c instanceof S))return!1;var d=a.md;null===d&&(d="");var e=b.Q;if(!(e instanceof S))return!1;var g=b.md;null===g&&(g="");for(e=e.Zf(g);e.next();)if(g=e.value,g.ca===c&&g.Af===d)return!0;return!1}; +Vf.prototype.isValidLink=function(a,b,c,d){if(!this.isValidFrom(a,b)||!this.isValidTo(c,d)||!(null===b||null===d||(b.zD&&d.rF||!this.isInSameNode(b,d))&&(b.yD&&d.qF||!this.isLinked(b,d)))||null!==this.$b&&(null!==a&&Wf(this,a,this.$b)||null!==c&&Wf(this,c,this.$b))||null!==a&&null!==c&&(null===a.data&&null!==c.data||null!==a.data&&null===c.data)||!Xf(this,a,c,this.$b))return!1;if(null!==a){var e=a.Yo;if(null!==e&&!e(a,b,c,d,this.$b))return!1}if(null!==c&&(e=c.Yo,null!==e&&!e(a,b,c,d,this.$b)))return!1; +e=this.Yo;return null!==e?e(a,b,c,d,this.$b):!0};function Wf(a,b,c){if(null===b)return!1;var d=b.ld;if(null===d)return!1;if(d===c)return!0;var e=new la(S);e.add(b);return Yf(a,d,c,e)}function Yf(a,b,c,d){if(b===c)return!0;var e=b.ca;if(null!==e&&e.wh&&(d.add(e),Yf(a,e.ld,c,d)))return!0;b=b.ga;return null!==b&&b.wh&&(d.add(b),Yf(a,b.ld,c,d))?!0:!1} +function Xf(a,b,c,d){if(null===b||null===c)return a.Am;var e=a.h.GF;if(e!==Zf){if(e===$f){if(null!==d&&!d.sc)return!0;for(e=c.ie;e.next();){var g=e.value;if(g!==d&&g.sc&&g.ga===c)return!1}return!ag(a,b,c,d,!0)}if(e===gg){if(null!==d&&!d.sc)return!0;for(e=b.ie;e.next();)if(g=e.value,g!==d&&g.sc&&g.ca===b)return!1;return!ag(a,b,c,d,!0)}if(e===hg)return b===c?a=!0:(e=new la(S),e.add(c),a=ig(a,e,b,c,d)),!a;if(e===jg)return!ag(a,b,c,d,!1);if(e===kg)return b===c?a=!0:(e=new la(S),e.add(c),a=lg(a,e,b,c, +d)),!a}return!0}function ag(a,b,c,d,e){if(b===c)return!0;if(null===b||null===c)return!1;for(var g=b.ie;g.next();){var h=g.value;if(h!==d&&(!e||h.sc)&&h.ga===b&&(h=h.ca,h!==b&&ag(a,h,c,d,e)))return!0}return!1}function ig(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.ie;g.next();){var h=g.value;if(h!==e&&h.ga===c&&(h=h.ca,h!==c&&ig(a,b,h,d,e)))return!0}return!1} +function lg(a,b,c,d,e){if(c===d)return!0;if(null===c||null===d||b.contains(c))return!1;b.add(c);for(var g=c.ie;g.next();){var h=g.value;if(h!==e){var k=h.ca,h=h.ga,k=k===c?h:k;if(k!==c&&lg(a,b,k,d,e))return!0}}return!1}t.g(Vf,"linkValidation",Vf.prototype.Yo);t.defineProperty(Vf,{Yo:"linkValidation"},function(){return this.zk},function(a){null!==a&&t.j(a,"function",Vf,"linkValidation");this.zk=a});t.g(Vf,"portTargeted",Vf.prototype.Ws); +t.defineProperty(Vf,{Ws:"portTargeted"},function(){return this.fC},function(a){null!==a&&t.j(a,"function",Vf,"portTargeted");this.fC=a});function pa(){0b.ws+1&&ch.Mj(e)&&(k=b.points.copy(),k.Zc(c), +b.points=k,b.ve(),b.updateAdornments()),t.B(h)}a.Jc();this.We=this.name;a.Ea("LinkReshaped",this.es)}this.stopTool()};function Lg(a,b,c,d,e,g){return g?Math.abs(b.y-c.y)=a.x)c=0>=a.y?c+225:1<=a.y?c+135:c+180;else if(1<=a.x)0>=a.y?c+=315:1<=a.y&&(c+=45);else if(0>=a.y)c+=270;else if(1<=a.y)c+=90;else break a;0>c?c+=360:360<=c&&(c-=360);b.cursor=22.5>c?"e-resize":67.5>c?"se-resize":112.5>c?"s-resize":157.5>c?"sw-resize":202.5>c?"w-resize":247.5>c?"nw-resize":292.5>c?"n-resize":337.5>c?"ne-resize":"e-resize"}else if(b instanceof y)for(b=b.elements;b.next();)Ng(a, +b.value,c)}t.defineProperty(Mg,{ys:"handleArchetype"},function(){return this.tk},function(a){a&&t.k(a,Q,Mg,"handleArchetype");this.tk=a});t.A(Mg,{handle:"handle"},function(){return this.Qb});t.defineProperty(Mg,{Gc:"adornedObject"},function(){return this.Ga},function(a){a&&t.k(a,Q,Mg,"adornedObject");this.Ga=a});Mg.prototype.canStart=function(){if(!this.isEnabled)return!1;var a=this.h;return null!==a&&!a.Wa&&a.jo&&a.S.left?null!==this.findToolHandleAt(a.yc.V,this.name)?!0:!1:!1}; +Mg.prototype.doActivate=function(){var a=this.h;null!==a&&(this.Qb=this.findToolHandleAt(a.yc.V,this.name),null!==this.Qb&&(this.Ga=this.Qb.Q.Gc,this.Mn=this.Ga.angle,this.hG.set(this.Ga.Na),this.yy.set(this.Ga.Q.location),this.Gu.set(this.Ga.ya),this.Mx=this.computeCellSize(),this.Ox=this.computeMinSize(),this.Nx=this.computeMaxSize(),a.ud=!0,this.mc(this.name),this.oa=!0))};Mg.prototype.doDeactivate=function(){var a=this.h;null!==a&&(this.Xj(),this.Ga=this.Qb=null,this.oa=a.ud=!1)}; +Mg.prototype.doCancel=function(){this.Ga.ya=this.Gu;this.Ga.Q.location=this.yy;this.stopTool()};Mg.prototype.doMouseMove=function(){var a=this.h;if(this.oa&&null!==a){var b=this.Ox,c=this.Nx,d=this.Mx,e=this.Ga.DD(a.S.V,t.M()),g=Qg;this.Ga instanceof Y&&(g=this.Ga.Tv,g===Rg&&(g=this.Ga.La.fc));b=this.computeResize(e,this.Qb.alignment,b,c,d,!(g===Sg||g===Tg||a.S.shift));this.resize(b);a.zh();t.B(e)}}; +Mg.prototype.doMouseUp=function(){var a=this.h;if(this.oa&&null!==a){var b=this.Ox,c=this.Nx,d=this.Mx,e=this.Ga.DD(a.S.V,t.M()),g=Qg;this.Ga instanceof Y&&(g=this.Ga.Tv,g===Rg&&(g=this.Ga.La.fc));b=this.computeResize(e,this.Qb.alignment,b,c,d,!(g===Sg||g===Tg||a.S.shift));this.resize(b);t.B(e);a.Jc();this.We=this.name;a.Ea("PartResized",this.Ga,this.Gu)}this.stopTool()}; +Mg.prototype.resize=function(a){if(null!==this.h){var b=this.Ga.Q,c=b.position.copy(),d=this.Ga.Na.copy(),e=this.Ga.Wk(),g=this.Ga.Sj();360<=e?e-=360:0>e&&(e+=360);var h=Math.PI*e/180,k=Math.cos(h),h=Math.sin(h),l=a.width-d.width,d=a.height-d.height,m=90e?1:0;c.x+=g*((a.x+l*m)*k-(a.y+d*(0e?1:0))*h);c.y+=g*((a.x+l*(180e?1:0))*h+(a.y+d*m)*k);this.Ga.ya=a.size;b.yf();b.move(c)}}; +Mg.prototype.computeResize=function(a,b,c,d,e,g){b.jd()&&(b=Fb);var h=this.Ga.Na,k=h.x,l=h.y,m=h.x+h.width,n=h.y+h.height,p=1;if(!g){var p=h.width,q=h.height;0>=p&&(p=1);0>=q&&(q=1);p=q/p}q=t.M();D.ss(a.x,a.y,k,l,e.width,e.height,q);a=h.copy();0>=b.x?0>=b.y?(a.x=Math.max(q.x,m-d.width),a.x=Math.min(a.x,m-c.width),a.width=Math.max(m-a.x,c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.width=Math.max(Math.min(q.x-k,d.width),c.width),a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y, +n-c.height),a.height=Math.max(n-a.y,c.height),g||(b=a.height/a.width,p=b.y?(a.y=Math.max(q.y,n-d.height),a.y=Math.min(a.y,n-c.height),a.height=n-a.y,g||(a.width= +a.height/p,a.x=k+0.5*(m-k-a.width))):1<=b.y&&(a.height=Math.max(Math.min(q.y-l,d.height),c.height),g||(a.width=a.height/p,a.x=k+0.5*(m-k-a.width)));t.B(q);return a};Mg.prototype.computeMinSize=function(){var a=this.Ga.Te.copy(),b=this.Te;!isNaN(b.width)&&b.width>a.width&&(a.width=b.width);!isNaN(b.height)&&b.height>a.height&&(a.height=b.height);return a}; +Mg.prototype.computeMaxSize=function(){var a=this.Ga.Ce.copy(),b=this.Ce;!isNaN(b.width)&&b.widtha&&(a+=360));var b=Math.min(Math.abs(this.jF),180),c=Math.min(Math.abs(this.iF),b/2);!this.h.S.shift&&0b-c&&(a=(Math.floor(a/b)+1)*b));360<=a?a-=360:0>a&&(a+=360);return a};t.g(Ug,"snapAngleMultiple",Ug.prototype.jF); +t.defineProperty(Ug,{jF:"snapAngleMultiple"},function(){return this.My},function(a){this.My!==a&&(f&&t.j(a,"number",Ug,"snapAngleMultiple"),this.My=a)});t.g(Ug,"snapAngleEpsilon",Ug.prototype.iF);t.defineProperty(Ug,{iF:"snapAngleEpsilon"},function(){return this.Ly},function(a){this.Ly!==a&&(f&&t.j(a,"number",Ug,"snapAngleEpsilon"),this.Ly=a)});t.g(Ug,"originalAngle",Ug.prototype.iI);t.A(Ug,{iI:"originalAngle"},function(){return this.Mn}); +function Wg(){0e.right&&(c.x-=d.width+5);c.xe.bottom&&(c.y-=d.height+5);c.ye.right&&(c.x-=d.width+5);c.xe.bottom?c.y-(d.height+5):c.y+20;c.y=a)return b;for(var c=0,d=0,e=0,g=0,h=0,k=this.qb.m;k.next();){var l=k.value;l instanceof V?e++:l instanceof S?d++:l instanceof X?g++:l instanceof Fe?h++:c++}k="";0=d.count)a=d.count;else if(d.ta(a)===b)return-1;d.td(a,b);b.As();d=this.h;null!==d&&(c?d.na():d.zm(b));b instanceof V&&this.zw(b);return a};aa.Oe=function(a,b,c){var d=this.qb;if(0>a||a>=d.length){if(a=d.indexOf(b),0>a)return-1}else if(d.ta(a)!==b&&(a=d.indexOf(b),0>a))return-1;b.Bs();d.Zc(a);d=this.h;null!==d&&(c?d.na():d.Oe(b));b.Cn=null;return a}; +aa.zw=function(a){for(;null!==a;){if(a.layer===this){var b=a;if(b.Kc.next()){for(var c=-1,d=-1,e=this.qb.p,g=e.length,h=0;hd&&k.ib===b&&(d=h,0<=c))break}!(0>d)&&da||1=a)return b;for(var c=this.Lb.m;c.next();)b+="\n "+c.value.toString(a-1);return b};z.prototype.checkProperties=function(){return t.SG(this)};z.fromDiv=function(a){var b=a;"string"===typeof a&&(b=document.getElementById(a));return b instanceof HTMLDivElement&&b.ba instanceof z?b.ba:null};t.g(z,"div",z.prototype.xi); +t.defineProperty(z,{xi:"div"},function(){return this.vb},function(a){null!==a&&t.k(a,HTMLDivElement,z,"div");if(this.vb!==a){var b=this.vb;if(null!==b){delete b.ba;b.innerHTML="";null!==this.Sa&&(this.Sa.ba=null,this.Sa.removeEventListener("touchstart",this.vF,!1),this.Sa.removeEventListener("touchmove",this.uF,!1),this.Sa.removeEventListener("touchend",this.tF,!1));b=this.fv;if(null!==b){for(var c=b.WB.p,d=c.length,e=0;e=d&&t.Ka(t.ov)!==t.Ka("7da71ca0ad381e90")&&(d=a[t.Ka("73a612b6fb191d")](t.Ka("76a715b2ef3e149757")));if(this.Xi=!(0a.scale&&h.canIncreaseZoom()||gc)b.preventDefault();else{a.Ql=null;return}if(null!==a.Ql){var d=a.Sa,e=d.getBoundingClientRect();b=new v(b.pageX-window.scrollX-d.width/e.width*e.left,b.pageY-window.scrollY-d.height/e.height*e.top);d=a.Ih;c*=a.Ql;e=a.Yf;if(c>a.scale&&e.canIncreaseZoom()||cl&&(a.position= +new v(-(a.uj.scrollWidth-a.oc)+this.scrollLeft-a.oc/r+a.hd.right,a.position.y))),this.kC&&a.cf&&(bn&&(a.position=new v(a.position.x,-(a.vj.scrollHeight-a.nc)+this.scrollTop-a.nc/r+a.hd.bottom))),t.B(s),Wh(a),a.Pu=!1,a.ej=!1,b=a.hd,c=a.lb,k=b.right,l=c.right,m=b.bottom,n=c.bottom,p=b.x,q=c.x,b=b.y,c=c.y,e>=d&&p>=q&&k<=l&&(a.Hy.style.width="1px"),h>=g&&b>=c&&m<=n&&(a.Iy.style.height="1px")}}else Xh(this.ba)}; +z.prototype.bC=function(){this.ba.isEnabled?this.ba.Gy=!0:Xh(this.ba)};z.prototype.computeBounds=z.prototype.df=function(){0a.bg&&(l=a.bg),l):b===ei?(l=k>h?(g-a.af)/c:(e-a.af)/d,1a.bg&&(l=a.bg),l):a.scale}}z.prototype.zoomToFit=z.prototype.zoomToFit=function(){this.scale=ai(this,di)}; +z.prototype.zoomToRect=function(a,b){void 0===b&&(b=di);var c=a.width,d=a.height;if(!(0===c||0===d||isNaN(c)&&isNaN(d))){var e=1;if(b===di||b===ei)if(isNaN(c))e=this.lb.height*this.scale/d;else if(isNaN(d))e=this.lb.width*this.scale/c;else var e=this.oc,g=this.nc,e=b===ei?g/d>e/c?(g-(this.Al?this.af:0))/d:(e-(this.Bl?this.af:0))/c:Math.min(g/d,e/c);this.scale=e;this.position=new v(a.x,a.y)}}; +z.prototype.alignDocument=function(a,b){this.dj&&ci(this,this.df());var c=this.hd,d=this.lb,e=this.gc;this.gc=!0;this.position=new v(c.x+(a.x*c.width+a.offsetX)-(b.x*d.width-b.offsetX),c.y+(a.y*c.height+a.offsetY)-(b.y*d.height-b.offsetY));this.gc=e;this.na()}; +function bi(a,b,c,d,e,g){g.kd()&&(d>c.width&&(b.x=c.x+(g.x*c.width+g.offsetX)-(g.x*d-g.offsetX)),e>c.height&&(b.y=c.y+(g.y*c.height+g.offsetY)-(g.y*e-g.offsetY)));dc.left?b.x=c.left:b.xc.top?b.y=c.top:b.yc.touches.length)&&c.preventDefault();c.cancelBubble=!0;return!1} +z.prototype.VH=function(a){if(this.ba.isEnabled){var b=this.ba.hc;Ph(this.ba,this.ba,a,b,!1);b.key=String.fromCharCode(a.which);b.Nj=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del";break;case 48:b.key="0";break;case 187:b.key="Add";break;case 189:b.key="Subtract"; +break;case 107:b.key="Add";break;case 109:b.key="Subtract";break;case 27:b.key="Esc"}this.ba.doKeyDown();return 187!==a.which&&189!==a.which&&48!==a.which&&107!==a.which&&109!==a.which||!0!==a.ctrlKey?Rh(this.ba,b,a):(a.cancelBubble=!0,void 0!==a.preventDefault?a.preventDefault():a.returnValue=!1,Event.stop&&(t.l("Event.stop can fire for this browser"),Event.stop(a)),void 0!==a.stopPropagation&&a.stopPropagation(),!1)}}; +z.prototype.WH=function(a){if(this.ba.isEnabled){var b=this.ba.hc;Ph(this.ba,this.ba,a,b,!1);b.key=String.fromCharCode(a.which);b.Ni=!0;switch(a.which){case 33:b.key="PageUp";break;case 34:b.key="PageDown";break;case 35:b.key="End";break;case 36:b.key="Home";break;case 37:b.key="Left";break;case 38:b.key="Up";break;case 39:b.key="Right";break;case 40:b.key="Down";break;case 45:b.key="Insert";break;case 46:b.key="Del"}this.ba.doKeyUp();return Rh(this.ba,b,a)}}; +z.prototype.ah=function(a){var b=this.Sa;if(null===b)return new v(0,0);var c=b.getBoundingClientRect(),d=a.clientX-b.width/c.width*c.left;a=a.clientY-b.height/c.height*c.top;return null!==this.rd?(d=new v(d,a),Oa(d,this.rd),d):new v(d,a)};t.g(z,"renderingHints",z.prototype.HE);t.defineProperty(z,{HE:"renderingHints"},function(){return this.gC},function(a){this.gC=a;this.sA()});z.prototype.invalidateDocumentBounds=z.prototype.Jc=function(){this.dj=!0;this.Gf()}; +function fi(a){a.zd||Yh(a);a.dj&&ci(a,a.df());$h(a);for(a=a.On.m;a.next();)fi(a.value)}z.prototype.redraw=z.prototype.sA=function(){this.gc||this.zd||(this.na(),gi(this),Wh(this),this.Jc(),this.zh())};z.prototype.isUpdateRequested=function(){return this.Uf};z.prototype.delayInitialization=function(a){hi(this);this.Mf=!1;a&&setTimeout(a,1)}; +z.prototype.requestUpdate=z.prototype.Gf=function(a){void 0===a&&(a=!1);if(!0!==this.Uf&&!(this.gc||!1===a&&this.zd)){this.Uf=!0;var b=this;requestAnimationFrame(function(){b.Uf&&b.zh()})}};z.prototype.maybeUpdate=z.prototype.zh=function(){if(!this.mq||this.Uf)this.mq&&(this.mq=!1),hi(this)}; +function hi(a){if(!a.zd&&(a.Uf=!1,null!==a.vb)){a.zd=!0;a.aA();!a.gc&&a.ej&&(Xh(a)||Xh(a));null!==a.Pc&&(a.Pc.visible&&!a.Zt&&(ni(a),a.Zt=!0),!a.Pc.visible&&a.Zt&&(a.Zt=!1));Yh(a);var b=!1;if(!a.Mf||a.Bt)a.Mf?oi(a,!a.St):(a.mc("Initial Layout"),oi(a,!1)),b=!0;a.St=!1;Yh(a);a.Ky||fi(a);b&&(a.Mf||(pi(a),ni(a)),a.Ea("LayoutCompleted"));qi(a);Yh(a);a.gc||!a.ej||Xh(a)||(Xh(a),Yh(a));b&&!a.Mf&&(a.Mf=!0,a.ye("Initial Layout"),a.va.clear(),setTimeout(function(){a.Uj=!1},1));a.Me();a.zd=!1}} +function pi(a){if(a.wk!==Je)a.scale=ai(a,a.wk);else if(a.rl!==Je)a.scale=ai(a,a.rl);else{var b=a.SD;isFinite(b)&&0b;b++){var c=a.Nf.m;if(null===c||0===a.Nf.count)break;a.Nf=new la(Q);var d=a,e=a.Nf;for(c.reset();c.next();){var g=c.value;!g.Kd()||g instanceof V||(g.$k()?(mh(g,Infinity,Infinity),g.xc()):e.add(g))}for(c.reset();c.next();)g=c.value,g instanceof V&&ri(d,g);for(c.reset();c.next();)d=c.value,d instanceof X&&(d.$k()?(mh(d,Infinity,Infinity),d.xc(),d.iw()):e.add(d));for(c.reset();c.next();)d=c.value,d instanceof Fe&&(d.$k()?(mh(d,Infinity,Infinity),d.xc()): +e.add(d))}}function ri(a,b){for(var c=b.Kc,d=t.yb();c.next();){var e=c.value;e instanceof V?(si(e)||ti(e)||ui(e))&&ri(a,e):e instanceof X?d.push(e):(mh(e,Infinity,Infinity),e.xc())}c=d.length;for(e=0;e=l[0]&&c>=l[1]&&b+d<=l[0]+l[2]&&c+e<=l[1]+l[3])return!1;b<=l[0]&&c<=l[1]&&b+d>=l[0]+l[2]&&c+e>=l[1]+l[3]?(g[k][2]=0,g[k][3]=0):b>=l[0]&&b=l[1]&&c+e<=l[1]+l[3]?(d=b+d-(l[0]+l[2]),b=l[0]+l[2],k=-1):b+d>l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c+e<=l[1]+l[3]?(d=l[0]-b,k=-1):b>=l[0]&&b+d<=l[0]+l[2]&&c>=l[1]&&c= +l[0]&&b+d<=l[0]+l[2]&&c+e>l[1]&&c+e<=l[1]+l[3]?(e=l[1]-c,k=-1):g[k][0]>=b&&g[k][0]=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]-=b+d-g[k][0],g[k][0]=b+d,k=-1):g[k][0]+g[k][2]>b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]+g[k][3]<=c+e?(g[k][2]=b-g[k][0],k=-1):g[k][0]>=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]>=c&&g[k][1]=b&&g[k][0]+g[k][2]<=b+d&&g[k][1]+g[k][3]>c&&g[k][1]+g[k][3]<=c+e&&(g[k][3]=c-g[k][1],k=-1)}for(k=0;kk&&c/W>l||(a.MD&&a.bf&&(q+1E+1&&(n=(x-E)*W+a.oc+"px",a.uj.scrollLeft=a.position.x*W)),a.ND&&a.cf&&(r+1M+1&&(p=(L-M)*W+a.nc+"px",a.vj.scrollTop=a.position.y*W)));m="1px"!==n;c="1px"!==p;m!==a.Al&&(a.nc="1px"===n?a.nc+a.af:Math.max(a.nc-a.af,1),b.height=a.nc,h=!0);a.Al=m;a.Hy.style.width=n;c!==a.Bl&&(a.oc= +"1px"===p?a.oc+a.af:Math.max(a.oc-a.af,1),b.width=a.oc,h=!0);a.Bl=c;a.Iy.style.height=p;h&&Th(a);m=a.oc;c=a.nc;a.vj.style.height=c+"px";a.vj.style.width=m+(a.Bl?a.af:0)+"px";a.uj.style.width=m+"px";a.uj.style.height=c+(a.Al?a.af:0)+"px";a.Gy=!1;return d!==m||e!==c?(n=a.lb,a.Us(g,n,h?!0:void 0),!1):!0}}} +z.prototype.add=z.prototype.add=function(a){t.k(a,B,z,"add:part");var b=a.h;if(b!==this){null!==b&&t.l("Cannot add part "+a.toString()+" to "+this.toString()+". It is already a part of "+b.toString());var c=a.he,b=this.rs(c);null===b&&(b=this.rs(""));null===b&&t.l('Cannot add a Part when unable find a Layer named "'+c+'" and there is no default Layer');a.layer!==b&&(c=a.h===this?b.zm(99999999,a,!0):b.zm(99999999,a),0<=c&&this.Mc(td,"parts",b,null,a,null,c),b.kc||this.Jc(),a.J(Di),c=a.Po,null!==c&& +c(a,null,b))}};z.prototype.zm=function(a){if(a instanceof S){if(this.Du.add(a),a instanceof V){var b=a.ib;null===b?this.Hk.add(a):b.Jn.add(a);b=a.Vb;null!==b&&(b.h=this)}}else a instanceof X?this.mu.add(a):a instanceof Fe||this.qb.add(a);a.rb&&a.Y();if(b=a.data){a instanceof Fe||(a instanceof X?this.pk.add(b,a):this.Qh.add(b,a));var c=this;Ei(a,function(a){Fi(c,a)})}!0!==ti(a)&&!0!==ui(a)||this.Nf.add(a);Gi(a,!0,this);a.ub()&&(a.ua.P()&&this.na(Ch(a,a.ua)),this.Jc())}; +z.prototype.Oe=function(a){a.ve();if(a instanceof S){if(this.Du.remove(a),a instanceof V){var b=a.ib;null===b?this.Hk.remove(a):b.Jn.remove(a);b=a.Vb;null!==b&&(b.h=null)}}else a instanceof X?this.mu.remove(a):a instanceof Fe||this.qb.remove(a);if(b=a.data){a instanceof Fe||(a instanceof X?this.pk.remove(b):this.Qh.remove(b));var c=this;Ei(a,function(a){Hi(c,a)})}this.Nf.remove(a);a.ub()&&(a.ua.P()&&this.na(Ch(a,a.ua)),this.Jc())}; +z.prototype.remove=z.prototype.remove=function(a){t.k(a,B,z,"remove:part");a.Za=!1;var b=a.layer;if(null!==b&&b.h===this){a.J(Ii);a.sm();var c=b.Oe(-1,a);0<=c&&this.Mc(ud,"parts",b,a,null,c,null);c=a.Po;null!==c&&c(a,b,null);b.kc||this.Jc()}};z.prototype.removeParts=z.prototype.wA=function(a,b){if(a===this.selection){var c=new la;c.He(a);a=c}for(c=a.m;c.next();){var d=c.value;d.h===this&&(b&&!d.canDelete()||this.remove(d))}}; +z.prototype.copyParts=z.prototype.copyParts=function(a,b,c){return this.Yf.copyParts(a,b,c)};z.prototype.moveParts=z.prototype.moveParts=function(a,b,c){t.k(b,v,z,"moveParts:offset");var d=this.zb;if(null!==d){d=d.ce;null===d&&(d=new $e,d.h=this);var e=new ia(B,Object);if(a)a=a.m;else{for(a=this.gp;a.next();)ff(d,e,a.value,c);for(a=this.Ki;a.next();)ff(d,e,a.value,c);a=this.links}for(;a.next();)ff(d,e,a.value,c);d.moveParts(e,b,c)}}; +function Ji(a,b,c){t.k(b,Zd,z,"addLayer:layer");null!==b.h&&b.h!==a&&t.l("Cannot share a Layer with another Diagram: "+b+" of "+b.h);null===c?null!==b.h&&t.l("Cannot add an existing Layer to this Diagram again: "+b):(t.k(c,Zd,z,"addLayer:existingLayer"),c.h!==a&&t.l("Existing Layer must be in this Diagram: "+c+" not in "+c.h),b===c&&t.l("Cannot move a Layer before or after itself: "+b));if(b.h!==a){b=b.name;a=a.Lb;c=a.count;for(var d=0;dd&&this.Jc()}; +z.prototype.addLayerAfter=function(a,b){Ji(this,a,b);a.le(this);var c=this.Lb,d=c.indexOf(a);0<=d&&(c.remove(a),null!==this.Cd&&this.Mc(ud,"layers",this,a,null,d,null));for(var e=c.count,g=0;gd&&this.Jc()}; +z.prototype.removeLayer=function(a){t.k(a,Zd,z,"removeLayer:layer");a.h!==this&&t.l("Cannot remove a Layer from another Diagram: "+a+" of "+a.h);if(""!==a.name){var b=this.Lb,c=b.indexOf(a);if(b.remove(a)){for(b=a.qb.copy().m;b.next();){var d=b.value,e=d.he;d.he=e!==a.name?e:""}null!==this.Cd&&this.Mc(ud,"layers",this,a,null,c,null);this.na();this.Jc()}}};z.prototype.findLayer=z.prototype.rs=function(a){for(var b=this.ew;b.next();){var c=b.value;if(c.name===a)return c}return null}; +z.prototype.addChangedListener=z.prototype.jz=function(a){t.j(a,"function",z,"addChangedListener:listener");null===this.Si&&(this.Si=new A("function"));this.Si.add(a)};z.prototype.removeChangedListener=z.prototype.uA=function(a){t.j(a,"function",z,"removeChangedListener:listener");null!==this.Si&&(this.Si.remove(a),0===this.Si.count&&(this.Si=null))}; +z.prototype.vv=function(a){this.xb||this.va.KD(a);a.fd!==rd&&(this.Uj=!0);if(null!==this.Si){var b=this.Si,c=b.length;if(1===c)b=b.ta(0),b(a);else if(0!==c)for(var d=b.Ve(),e=0;em||("LineV"===l.Db?g=g*m/D.BD(g,m):e=e*m/D.BD(e,m))}h=c.xs;d.q(g*h.width,e*h.height);if(b)k=b.width,l=b.height,g=b.x,h=b.y;else{e=t.qf();g=a.lb;e.q(g.x,g.y,g.width,g.height);for(h=a.On.m;h.next();)g=h.value.lb,cb(e,g.x,g.y,g.width,g.height);k=e.width;l=e.height;g=e.x;h=e.y;if(!e.P())return}c.width=k+2*d.width;c.height=l+2*d.height;e=t.M();D.ss(g,h,0,0,d.width,d.height, +e);e.offset(-d.width,-d.height);t.Qj(d);c.Q.location=e;t.B(e)}}z.prototype.clearSelection=z.prototype.xv=function(){var a=0a&&t.ia(a,">= zero",z,"linkSpacing"),this.hj=a,this.i("linkSpacing",b,a))});t.A(z,{ew:"layers"},function(){return this.Lb.m});t.g(z,"isModelReadOnly",z.prototype.Pe);t.defineProperty(z,{Pe:"isModelReadOnly"},function(){var a=this.Cd;return null===a?!1:a.Wa},function(a){var b=this.Cd;null!==b&&(b.Wa=a)});t.g(z,"isReadOnly",z.prototype.Wa); +t.defineProperty(z,{Wa:"isReadOnly"},function(){return this.yk},function(a){var b=this.yk;b!==a&&(t.j(a,"boolean",z,"isReadOnly"),this.yk=a,this.i("isReadOnly",b,a))});t.g(z,"isEnabled",z.prototype.isEnabled);t.defineProperty(z,{isEnabled:"isEnabled"},function(){return this.Vh},function(a){var b=this.Vh;b!==a&&(t.j(a,"boolean",z,"isEnabled"),this.Vh=a,this.i("isEnabled",b,a))});t.g(z,"allowClipboard",z.prototype.pv); +t.defineProperty(z,{pv:"allowClipboard"},function(){return this.tt},function(a){var b=this.tt;b!==a&&(t.j(a,"boolean",z,"allowClipboard"),this.tt=a,this.i("allowClipboard",b,a))});t.g(z,"allowCopy",z.prototype.Ej);t.defineProperty(z,{Ej:"allowCopy"},function(){return this.bk},function(a){var b=this.bk;b!==a&&(t.j(a,"boolean",z,"allowCopy"),this.bk=a,this.i("allowCopy",b,a))});t.g(z,"allowDelete",z.prototype.Mk); +t.defineProperty(z,{Mk:"allowDelete"},function(){return this.ck},function(a){var b=this.ck;b!==a&&(t.j(a,"boolean",z,"allowDelete"),this.ck=a,this.i("allowDelete",b,a))});t.g(z,"allowDragOut",z.prototype.qv);t.defineProperty(z,{qv:"allowDragOut"},function(){return this.ut},function(a){var b=this.ut;b!==a&&(t.j(a,"boolean",z,"allowDragOut"),this.ut=a,this.i("allowDragOut",b,a))});t.g(z,"allowDrop",z.prototype.lz); +t.defineProperty(z,{lz:"allowDrop"},function(){return this.vt},function(a){var b=this.vt;b!==a&&(t.j(a,"boolean",z,"allowDrop"),this.vt=a,this.i("allowDrop",b,a))});t.g(z,"allowTextEdit",z.prototype.mo);t.defineProperty(z,{mo:"allowTextEdit"},function(){return this.lk},function(a){var b=this.lk;b!==a&&(t.j(a,"boolean",z,"allowTextEdit"),this.lk=a,this.i("allowTextEdit",b,a))});t.g(z,"allowGroup",z.prototype.ho); +t.defineProperty(z,{ho:"allowGroup"},function(){return this.dk},function(a){var b=this.dk;b!==a&&(t.j(a,"boolean",z,"allowGroup"),this.dk=a,this.i("allowGroup",b,a))});t.g(z,"allowUngroup",z.prototype.no);t.defineProperty(z,{no:"allowUngroup"},function(){return this.mk},function(a){var b=this.mk;b!==a&&(t.j(a,"boolean",z,"allowUngroup"),this.mk=a,this.i("allowUngroup",b,a))});t.g(z,"allowInsert",z.prototype.fm); +t.defineProperty(z,{fm:"allowInsert"},function(){return this.xt},function(a){var b=this.xt;b!==a&&(t.j(a,"boolean",z,"allowInsert"),this.xt=a,this.i("allowInsert",b,a))});t.g(z,"allowLink",z.prototype.gm);t.defineProperty(z,{gm:"allowLink"},function(){return this.ek},function(a){var b=this.ek;b!==a&&(t.j(a,"boolean",z,"allowLink"),this.ek=a,this.i("allowLink",b,a))});t.g(z,"allowRelink",z.prototype.Fj); +t.defineProperty(z,{Fj:"allowRelink"},function(){return this.gk},function(a){var b=this.gk;b!==a&&(t.j(a,"boolean",z,"allowRelink"),this.gk=a,this.i("allowRelink",b,a))});t.g(z,"allowMove",z.prototype.Nk);t.defineProperty(z,{Nk:"allowMove"},function(){return this.fk},function(a){var b=this.fk;b!==a&&(t.j(a,"boolean",z,"allowMove"),this.fk=a,this.i("allowMove",b,a))});t.g(z,"allowReshape",z.prototype.io); +t.defineProperty(z,{io:"allowReshape"},function(){return this.hk},function(a){var b=this.hk;b!==a&&(t.j(a,"boolean",z,"allowReshape"),this.hk=a,this.i("allowReshape",b,a))});t.g(z,"allowResize",z.prototype.jo);t.defineProperty(z,{jo:"allowResize"},function(){return this.ik},function(a){var b=this.ik;b!==a&&(t.j(a,"boolean",z,"allowResize"),this.ik=a,this.i("allowResize",b,a))});t.g(z,"allowRotate",z.prototype.lo); +t.defineProperty(z,{lo:"allowRotate"},function(){return this.jk},function(a){var b=this.jk;b!==a&&(t.j(a,"boolean",z,"allowRotate"),this.jk=a,this.i("allowRotate",b,a))});t.g(z,"allowSelect",z.prototype.Ie);t.defineProperty(z,{Ie:"allowSelect"},function(){return this.kk},function(a){var b=this.kk;b!==a&&(t.j(a,"boolean",z,"allowSelect"),this.kk=a,this.i("allowSelect",b,a))});t.g(z,"allowUndo",z.prototype.mz); +t.defineProperty(z,{mz:"allowUndo"},function(){return this.yt},function(a){var b=this.yt;b!==a&&(t.j(a,"boolean",z,"allowUndo"),this.yt=a,this.i("allowUndo",b,a))});t.g(z,"allowZoom",z.prototype.fs);t.defineProperty(z,{fs:"allowZoom"},function(){return this.At},function(a){var b=this.At;b!==a&&(t.j(a,"boolean",z,"allowZoom"),this.At=a,this.i("allowZoom",b,a))});t.g(z,"hasVerticalScrollbar",z.prototype.ND); +t.defineProperty(z,{ND:"hasVerticalScrollbar"},function(){return this.cu},function(a){var b=this.cu;b!==a&&(t.j(a,"boolean",z,"hasVerticalScrollbar"),this.cu=a,gi(this),this.na(),this.i("hasVerticalScrollbar",b,a),$h(this))});t.g(z,"hasHorizontalScrollbar",z.prototype.MD);t.defineProperty(z,{MD:"hasHorizontalScrollbar"},function(){return this.bu},function(a){var b=this.bu;b!==a&&(t.j(a,"boolean",z,"hasHorizontalScrollbar"),this.bu=a,gi(this),this.na(),this.i("hasHorizontalScrollbar",b,a),$h(this))}); +t.g(z,"allowHorizontalScroll",z.prototype.bf);t.defineProperty(z,{bf:"allowHorizontalScroll"},function(){return this.wt},function(a){var b=this.wt;b!==a&&(t.j(a,"boolean",z,"allowHorizontalScroll"),this.wt=a,this.i("allowHorizontalScroll",b,a),$h(this))});t.g(z,"allowVerticalScroll",z.prototype.cf);t.defineProperty(z,{cf:"allowVerticalScroll"},function(){return this.zt},function(a){var b=this.zt;b!==a&&(t.j(a,"boolean",z,"allowVerticalScroll"),this.zt=a,this.i("allowVerticalScroll",b,a),$h(this))}); +t.g(z,"scrollHorizontalLineChange",z.prototype.np);t.defineProperty(z,{np:"scrollHorizontalLineChange"},function(){return this.Qu},function(a){var b=this.Qu;b!==a&&(t.j(a,"number",z,"scrollHorizontalLineChange"),0>a&&t.ia(a,">= 0",z,"scrollHorizontalLineChange"),this.Qu=a,this.i("scrollHorizontalLineChange",b,a))});t.g(z,"scrollVerticalLineChange",z.prototype.op); +t.defineProperty(z,{op:"scrollVerticalLineChange"},function(){return this.Ru},function(a){var b=this.Ru;b!==a&&(t.j(a,"number",z,"scrollVerticalLineChange"),0>a&&t.ia(a,">= 0",z,"scrollVerticalLineChange"),this.Ru=a,this.i("scrollVerticalLineChange",b,a))});t.g(z,"lastInput",z.prototype.S);t.defineProperty(z,{S:"lastInput"},function(){return this.hc},function(a){f&&t.k(a,od,z,"lastInput");this.hc=a});t.g(z,"firstInput",z.prototype.yc); +t.defineProperty(z,{yc:"firstInput"},function(){return this.tg},function(a){f&&t.k(a,od,z,"firstInput");this.tg=a});t.g(z,"currentCursor",z.prototype.Uc);t.defineProperty(z,{Uc:"currentCursor"},function(){return this.Ot},function(a){t.j(a,"string",z,"currentCursor");null===this.Sa||this.Ot===a||""===a&&this.Ot===this.fq||(this.Ot=a,""!==a?(this.Sa.style.cursor=a,this.vb.style.cursor=a):(this.Sa.style.cursor=this.zz,this.vb.style.cursor=this.zz))});t.g(z,"defaultCursor",z.prototype.zz); +t.defineProperty(z,{zz:"defaultCursor"},function(){return this.fq},function(a){t.j(a,"string",z,"defaultCursor");var b=this.fq;b!==a&&(this.fq=a,this.i("defaultCursor",b,a))});t.g(z,"hasGestureZoom",z.prototype.DH);t.defineProperty(z,{DH:"hasGestureZoom"},function(){return this.Uh},function(a){var b=this.Uh;b!==a&&(t.j(a,"boolean",z,"hasGestureZoom"),this.Uh=a,this.i("hasGestureZoom",b,a))});t.g(z,"click",z.prototype.click); +t.defineProperty(z,{click:"click"},function(){return this.Mh},function(a){var b=this.Mh;b!==a&&(null!==a&&t.j(a,"function",z,"click"),this.Mh=a,this.i("click",b,a))});t.g(z,"doubleClick",z.prototype.tm);t.defineProperty(z,{tm:"doubleClick"},function(){return this.Sh},function(a){var b=this.Sh;b!==a&&(null!==a&&t.j(a,"function",z,"doubleClick"),this.Sh=a,this.i("doubleClick",b,a))});t.g(z,"contextClick",z.prototype.ns); +t.defineProperty(z,{ns:"contextClick"},function(){return this.Oh},function(a){var b=this.Oh;b!==a&&(null!==a&&t.j(a,"function",z,"contextClick"),this.Oh=a,this.i("contextClick",b,a))});t.g(z,"mouseOver",z.prototype.Os);t.defineProperty(z,{Os:"mouseOver"},function(){return this.bi},function(a){var b=this.bi;b!==a&&(null!==a&&t.j(a,"function",z,"mouseOver"),this.bi=a,this.i("mouseOver",b,a))});t.g(z,"mouseHover",z.prototype.Ns); +t.defineProperty(z,{Ns:"mouseHover"},function(){return this.ai},function(a){var b=this.ai;b!==a&&(null!==a&&t.j(a,"function",z,"mouseHover"),this.ai=a,this.i("mouseHover",b,a))});t.g(z,"mouseHold",z.prototype.Ms);t.defineProperty(z,{Ms:"mouseHold"},function(){return this.$h},function(a){var b=this.$h;b!==a&&(null!==a&&t.j(a,"function",z,"mouseHold"),this.$h=a,this.i("mouseHold",b,a))});t.g(z,"mouseDragOver",z.prototype.tE); +t.defineProperty(z,{tE:"mouseDragOver"},function(){return this.wu},function(a){var b=this.wu;b!==a&&(null!==a&&t.j(a,"function",z,"mouseDragOver"),this.wu=a,this.i("mouseDragOver",b,a))});t.g(z,"mouseDrop",z.prototype.Ls);t.defineProperty(z,{Ls:"mouseDrop"},function(){return this.Zh},function(a){var b=this.Zh;b!==a&&(null!==a&&t.j(a,"function",z,"mouseDrop"),this.Zh=a,this.i("mouseDrop",b,a))});t.g(z,"toolTip",z.prototype.mt); +t.defineProperty(z,{mt:"toolTip"},function(){return this.li},function(a){var b=this.li;b!==a&&(null!==a&&t.k(a,Fe,z,"toolTip"),this.li=a,this.i("toolTip",b,a))});t.g(z,"contextMenu",z.prototype.contextMenu);t.defineProperty(z,{contextMenu:"contextMenu"},function(){return this.Ph},function(a){var b=this.Ph;b!==a&&(null!==a&&t.k(a,Fe,z,"contextMenu"),this.Ph=a,this.i("contextMenu",b,a))});t.g(z,"commandHandler",z.prototype.Yf); +t.defineProperty(z,{Yf:"commandHandler"},function(){return this.qx},function(a){var b=this.qx;b!==a&&(t.k(a,oa,z,"commandHandler"),null!==a.h&&t.l("Cannot share CommandHandlers between Diagrams: "+a.toString()),null!==b&&b.le(null),this.qx=a,a.le(this))});t.g(z,"toolManager",z.prototype.zb); +t.defineProperty(z,{zb:"toolManager"},function(){return this.fv},function(a){var b=this.fv;b!==a&&(t.k(a,De,z,"toolManager"),null!==a.h&&t.l("Cannot share ToolManagers between Diagrams: "+a.toString()),null!==b&&b.le(null),this.fv=a,a.le(this))});t.g(z,"defaultTool",z.prototype.Gv);t.defineProperty(z,{Gv:"defaultTool"},function(){return this.Fx},function(a){var b=this.Fx;b!==a&&(t.k(a,$d,z,"defaultTool"),this.Fx=a,this.Va===b&&(this.Va=a))});t.g(z,"currentTool",z.prototype.Va); +t.defineProperty(z,{Va:"currentTool"},function(){return this.Ax},function(a){var b=this.Ax;null!==b&&(b.oa&&b.doDeactivate(),b.cancelWaitAfter(),b.doStop());null===a&&(a=this.Gv);null!==a&&(t.k(a,$d,z,"currentTool"),this.Ax=a,a.le(this),a.doStart())});t.A(z,{selection:"selection"},function(){return this.Uu});t.g(z,"maxSelectionCount",z.prototype.mE); +t.defineProperty(z,{mE:"maxSelectionCount"},function(){return this.ru},function(a){var b=this.ru;if(b!==a)if(t.j(a,"number",z,"maxSelectionCount"),0<=a&&!isNaN(a)){if(this.ru=a,this.i("maxSelectionCount",b,a),!this.va.kb&&(a=this.selection.count-a,0= 0",z,"maxSelectionCount")});t.g(z,"nodeSelectionAdornmentTemplate",z.prototype.yE); +t.defineProperty(z,{yE:"nodeSelectionAdornmentTemplate"},function(){return this.Cu},function(a){var b=this.Cu;b!==a&&(t.k(a,Fe,z,"nodeSelectionAdornmentTemplate"),this.Cu=a,this.i("nodeSelectionAdornmentTemplate",b,a))});t.g(z,"groupSelectionAdornmentTemplate",z.prototype.HD);t.defineProperty(z,{HD:"groupSelectionAdornmentTemplate"},function(){return this.$t},function(a){var b=this.$t;b!==a&&(t.k(a,Fe,z,"groupSelectionAdornmentTemplate"),this.$t=a,this.i("groupSelectionAdornmentTemplate",b,a))}); +t.g(z,"linkSelectionAdornmentTemplate",z.prototype.jE);t.defineProperty(z,{jE:"linkSelectionAdornmentTemplate"},function(){return this.lu},function(a){var b=this.lu;b!==a&&(t.k(a,Fe,z,"linkSelectionAdornmentTemplate"),this.lu=a,this.i("linkSelectionAdornmentTemplate",b,a))});t.g(z,"isModified",z.prototype.Uj); +t.defineProperty(z,{Uj:"isModified"},function(){var a=this.va;return null===a?this.ey:null!==a.Uk?!0:this.ey&&this.vk!==a.Tj},function(a){if(this.ey!==a){t.j(a,"boolean",z,"isModified");this.ey=a;var b=this.va;!a&&b&&(this.vk=b.Tj);a||Ki(this)}});function Ki(a){var b=a.Uj;a.yC!==b&&(a.yC=b,a.Ea("Modified"))}t.g(z,"model",z.prototype.da); +t.defineProperty(z,{da:"model"},function(){return this.Cd},function(a){var b=this.Cd;if(b!==a){t.k(a,C,z,"model");null!==b&&b.va!==a.va&&b.va.LH&&t.l("Do not replace a Diagram.model while a transaction is in progress.");this.xv();this.Mf=!1;this.mq=!0;this.Uf=!1;var c=this.zd;this.zd=!0;null!==b&&(b.uA(this.UB),b instanceof P&&Li(this,b.Hi),Li(this,b.eg));this.Cd=a;a.jz(this.TB);Mi(this,a.eg);a instanceof P&&Ni(this,a.Hi);a.uA(this.TB);a.jz(this.UB);this.zd=c;this.gc||this.na();null!==b&&(a.va.isEnabled= +b.va.isEnabled)}});t.defineProperty(z,{Ra:null},function(){return this.NB},function(a){this.NB=a}); +function Ih(a,b){if(b.da===a.da&&a.Ra){a.Ra=!1;try{var c=b.fd,d=b.kf;if(""!==d)if(c===sd){if("linkFromKey"===d){var e=b.object,g=a.zf(e);if(null!==g){var h=b.newValue,k=a.$f(h);g.ca=k}}else if("linkToKey"===d)e=b.object,g=a.zf(e),null!==g&&(h=b.newValue,k=a.$f(h),g.ga=k);else if("linkFromPortId"===d){if(e=b.object,g=a.zf(e),null!==g){var l=b.newValue;"string"===typeof l&&(g.Af=l)}}else if("linkToPortId"===d)e=b.object,g=a.zf(e),null!==g&&(l=b.newValue,"string"===typeof l&&(g.ng=l));else if("nodeGroupKey"=== +d){var e=b.object,m=a.Ai(e);if(null!==m){var n=b.newValue;if(void 0!==n){var p=a.$f(n);m.ib=p instanceof V?p:null}else m.ib=null}}else if("linkLabelKeys"===d){if(e=b.object,g=a.zf(e),null!==g){var q=b.oldValue,r=b.newValue;if(t.isArray(q))for(var s=t.wb(q),u=0;uthis.bg&&(a=this.bg);if(b!==a){var c=this.Xb=a;if(!this.gc&&!this.zd&&(this.gc=!0,null!==this.Sa)){a=this.lb.copy();var d=this.oc/c,e=this.nc/c;a.width=this.oc/b;a.height=this.nc/b;var g=this.Ih.copy();if(isNaN(g.x))switch(this.Cv){case $b:g.x=0;break;case ac:g.x=d-1;break;case Fb:g.x=d/2;break;case vb:case cc:g.x=d/2}if(isNaN(g.y))switch(this.Cv){case Yb:g.y=0;break;case bc:g.y= +e-1;break;case Fb:g.y=e/2;break;case vb:case cc:g.y=e/2}var h=this.position,b=new v(h.x+g.x/b-g.x/c,h.y+g.y/b-g.y/c);bi(this,b,this.hd,d,e,this.ul);this.position=b;this.gc=!1;this.Us(a,this.lb)}this.na();gi(this)}});t.g(z,"autoScale",z.prototype.jm);t.defineProperty(z,{jm:"autoScale"},function(){return this.rl},function(a){var b=this.rl;b!==a&&(t.nb(a,z,z,"autoScale"),this.rl=a,this.i("autoScale",b,a),a!==Je&&$h(this))});t.g(z,"initialAutoScale",z.prototype.HH); +t.defineProperty(z,{HH:"initialAutoScale"},function(){return this.wk},function(a){var b=this.wk;b!==a&&(t.nb(a,z,z,"initialAutoScale"),this.wk=a,this.i("initialAutoScale",b,a))});t.g(z,"initialViewportSpot",z.prototype.TD);t.defineProperty(z,{TD:"initialViewportSpot"},function(){return this.eu},function(a){var b=this.eu;b!==a&&(t.k(a,H,z,"initialViewportSpot"),a.kd()||t.l("initialViewportSpot must be a real Spot: "+a),this.eu=a,this.i("initialViewportSpot",b,a))});t.g(z,"initialDocumentSpot",z.prototype.QD); +t.defineProperty(z,{QD:"initialDocumentSpot"},function(){return this.du},function(a){var b=this.du;b!==a&&(t.k(a,H,z,"initialDocumentSpot"),a.kd()||t.l("initialViewportSpot must be a real Spot: "+a),this.du=a,this.i("initialDocumentSpot",b,a))});t.g(z,"minScale",z.prototype.cg);t.defineProperty(z,{cg:"minScale"},function(){return this.tu},function(a){t.o(a,z,"minScale");var b=this.tu;b!==a&&0this.scale&&(this.scale=a)):t.ia(a,"> 0",z,"minScale")}); +t.g(z,"maxScale",z.prototype.bg);t.defineProperty(z,{bg:"maxScale"},function(){return this.qu},function(a){t.o(a,z,"maxScale");var b=this.qu;b!==a&&0 0",z,"maxScale")});t.g(z,"zoomPoint",z.prototype.Ih);t.defineProperty(z,{Ih:"zoomPoint"},function(){return this.kv},function(a){this.kv.K(a)||(t.k(a,v,z,"zoomPoint"),this.kv=a=a.W())});t.g(z,"contentAlignment",z.prototype.Cv); +t.defineProperty(z,{Cv:"contentAlignment"},function(){return this.ul},function(a){var b=this.ul;b.K(a)||(t.k(a,H,z,"contentAlignment"),this.ul=a=a.W(),this.i("contentAlignment",b,a),$h(this))});t.g(z,"initialContentAlignment",z.prototype.IH);t.defineProperty(z,{IH:"initialContentAlignment"},function(){return this.un},function(a){var b=this.un;b.K(a)||(t.k(a,H,z,"initialContentAlignment"),this.un=a=a.W(),this.i("initialContentAlignment",b,a))});t.g(z,"padding",z.prototype.padding); +t.defineProperty(z,{padding:"padding"},function(){return this.Ge},function(a){"number"===typeof a?a=new Va(a):t.k(a,Va,z,"padding");var b=this.Ge;b.K(a)||(this.Ge=a=a.W(),this.Jc(),this.i("padding",b,a))});t.A(z,{Ki:"nodes"},function(){return this.Du.m});t.A(z,{links:"links"},function(){return this.mu.m});t.A(z,{gp:"parts"},function(){return this.qb.m});z.prototype.findTopLevelGroups=function(){return this.Hk.m};t.g(z,"layout",z.prototype.Vb); +t.defineProperty(z,{Vb:"layout"},function(){return this.Bd},function(a){var b=this.Bd;b!==a&&(t.k(a,ke,z,"layout"),null!==b&&(b.h=null,b.group=null),this.Bd=a,a.h=this,a.group=null,this.Bt=!0,this.i("layout",b,a),this.Gf())});z.prototype.layoutDiagram=function(a){Yh(this);a&&Xi(this,!0);oi(this,!1)};function Xi(a,b){for(var c=a.Hk.m;c.next();)Yi(a,c.value,b);null!==a.Vb&&(b?a.Vb.gf=!1:a.Vb.J())} +function Yi(a,b,c){if(null!==b){for(var d=b.Jn.m;d.next();)Yi(a,d.value,c);null!==b.Vb&&(c?b.Vb.gf=!1:b.Vb.J())}}function oi(a,b){for(var c=a.Hk.m;c.next();)Zi(a,c.value,b);c=a.Vb;if(null!==c&&!c.gf){if(b&&!c.Wz)return;c.doLayout(a);Yh(a);c.gf=!0}a.Bt=!1}function Zi(a,b,c){if(null!==b){for(var d=b.Jn.m;d.next();)Zi(a,d.value,c);d=b.Vb;null===d||d.gf||c&&!d.Wz||(b.$B=!b.location.P(),d.doLayout(b),b.J($i),d.gf=!0,ri(a,b))}}t.g(z,"isTreePathToChildren",z.prototype.Yc); +t.defineProperty(z,{Yc:"isTreePathToChildren"},function(){return this.iu},function(a){var b=this.iu;if(b!==a&&(t.j(a,"boolean",z,"isTreePathToChildren"),this.iu=a,this.i("isTreePathToChildren",b,a),!this.va.kb))for(a=this.Ki;a.next();)aj(a.value)});z.prototype.findTreeRoots=function(){for(var a=new A(S),b=this.Ki.m;b.next();){var c=b.value;c.Oo&&null===c.vs()&&a.add(c)}return a.m};t.g(z,"isCollapsingExpanding",z.prototype.Hd); +t.defineProperty(z,{Hd:null},function(){return this.GB},function(a){this.GB=a}); +function Gh(a){function b(a){var b=a.toLowerCase(),h=new A("function");c.add(a,h);c.add(b,h);d.add(a,a);d.add(b,a)}var c=new ia("string",A),d=new ia("string","string");b("BackgroundSingleClicked");b("BackgroundDoubleClicked");b("BackgroundContextClicked");b("ClipboardChanged");b("ClipboardPasted");b("DocumentBoundsChanged");b("ExternalObjectsDropped");b("InitialLayoutCompleted");b("LayoutCompleted");b("LinkDrawn");b("LinkRelinked");b("LinkReshaped");b("Modified");b("ObjectSingleClicked");b("ObjectDoubleClicked"); +b("ObjectContextClicked");b("PartCreated");b("PartResized");b("PartRotated");b("SelectionMoved");b("SelectionCopied");b("SelectionDeleting");b("SelectionDeleted");b("SelectionGrouped");b("SelectionUngrouped");b("ChangingSelection");b("ChangedSelection");b("SubGraphCollapsed");b("SubGraphExpanded");b("TextEdited");b("TreeCollapsed");b("TreeExpanded");b("ViewportBoundsChanged");a.Hx=c;a.Gx=d}function ka(a,b){var c=a.Gx.wa(b);return null!==c?c:a.Gx.wa(b.toLowerCase())} +function bj(a,b){var c=a.Hx.wa(b);if(null!==c)return c;c=a.Hx.wa(b.toLowerCase());if(null!==c)return c;t.l("Unknown DiagramEvent name: "+b);return null}z.prototype.addDiagramListener=z.prototype.kz=function(a,b){t.j(a,"string",z,"addDiagramListener:name");t.j(b,"function",z,"addDiagramListener:listener");var c=bj(this,a);null!==c&&c.add(b)}; +z.prototype.removeDiagramListener=z.prototype.FE=function(a,b){t.j(a,"string",z,"removeDiagramListener:name");t.j(b,"function",z,"addDiagramListener:listener");var c=bj(this,a);null!==c&&c.remove(b)};z.prototype.raiseDiagramEvent=z.prototype.Ea=function(a,b,c){f&&t.j(a,"string",z,"raiseDiagramEvent:name");var d=bj(this,a),e=new pd;e.h=this;e.name=ka(this,a);void 0!==b&&(e.Cw=b);void 0!==c&&(e.ow=c);a=d.length;if(1===a)d=d.ta(0),d(e);else if(0!==a)for(b=d.Ve(),c=0;c=d.top&&0>=d.left&&0>=d.right&&0>=d.bottom)return c;var e=a.lb,g=a.scale,e=t.Yj(0,0,e.width*g,e.height*g),h=t.cc(0,0);if(b.x>=e.x&&b.xe.x+e.width-d.right&&(k=Math.max(a.np,1),k|=0,h.x+=k,b.x>e.x+e.width-d.right/2&&(h.x+=k),b.x>e.x+e.width-d.right/4&&(h.x+=4*k));b.y>=e.y&&b.ye.y+e.height-d.bottom&&(k=Math.max(a.op,1),k|=0,h.y+=k,b.y>e.y+e.height-d.bottom/2&&(h.y+=k),b.y>e.y+e.height-d.bottom/4&&(h.y+=4*k));h.zi(D.ak)||(c=new v(c.x+h.x/g,c.y+h.y/g));t.Ic(e);t.B(h);return c}z.prototype.makeSVG=function(a){void 0===a&&(a={});a.context="svg";a=yj(this,a);return null!==a?a.jt:null}; +z.prototype.makeImage=function(a){var b=document.createElement("img");b.src=this.$H(a);return b instanceof HTMLImageElement?b:null};z.prototype.makeImageData=z.prototype.$H=function(a){void 0===a&&(a={});var b=yj(this,a);return null!==b?b.toDataURL(a.type,a.details):""}; +function yj(a,b){a.zh();if(null===a.Sa)return null;"object"!==typeof b&&t.l("properties argument must be an Object.");var c=!1,d=b.size||null,e=b.scale||null;void 0!==b.scale&&isNaN(b.scale)&&(e="NaN");var g=b.maxSize||new ea(2E3,2E3);void 0===b.maxSize&&(c=!0);var h=b.position||null,k=b.parts||null,l=void 0===b.padding?1:b.padding,m=b.background||null,n=b.omitTemporary;void 0===n&&(n=!0);var p=b.showTemporary;void 0===p&&(p=!n);n=b.showGrid;void 0===n&&(n=p);null!==d&&isNaN(d.width)&&isNaN(d.height)&& +(d=null);l&&"number"===typeof l&&(l=new Va(l));l||(l=new Va(0));l.left=Math.max(l.left,0);l.right=Math.max(l.right,0);l.top=Math.max(l.top,0);l.bottom=Math.max(l.bottom,0);a.mn=!1;Th(a);var q=document.createElement("canvas"),r=q.getContext("2d"),s=q;if(!(d||e||k||h))return q.width=a.Sa.width+Math.ceil(l.left+l.right),q.height=a.Sa.height+Math.ceil(l.top+l.bottom),"svg"===b.context&&(r=s=new nc(q),r instanceof nc&&(a.mn=!0)),yi(a,r,l,new ea(q.width,q.height),a.Xb,a.sb,k,m,p,n),a.mn=!0,s;var u,x=new v(0, +0);u=a.hd.copy();u.EI(a.padding);null!==h&&h.P()?(x=h,e||(e=1)):(x.x=u.x,x.y=u.y);if(k){var E,h=!0,k=k.m;for(k.reset();k.next();){var F=k.value;if(F instanceof B){var G=F.layer;G&&!G.visible||G&&G.kc||!F.ub()||(F=F.ua,F.P()&&(h?(h=!1,E=F.copy()):E.$j(F)))}}h&&(E=new w(0,0,0,0));u.width=E.width;u.height=E.height;x.x=E.x;x.y=E.y}h=E=0;l&&(E=l.left+l.right,h=l.top+l.bottom);F=G=0;d&&(G=d.width,F=d.height,isFinite(G)&&(G=Math.max(0,G-E)),isFinite(F)&&(F=Math.max(0,F-h)));d&&e?("NaN"===e&&(e=1),d.P()? +(d=G,u=F):isNaN(F)?(d=G,u=u.height*e):(d=u.width*e,u=F)):d?d.P()?(e=Math.min(G/u.width,F/u.height),d=G,u=F):isNaN(F)?(e=G/u.width,d=G,u=u.height*e):(e=F/u.height,d=u.width*e,u=F):e?"NaN"===e&&g.P()?(e=Math.min((g.width-E)/u.width,(g.height-h)/u.height),1E||u>g)&&(t.trace("Diagram.makeImage(data): Diagram width or height is larger than the default max size. ("+ +Math.ceil(d)+"x"+Math.ceil(u)+" vs 2000x2000) Consider increasing the max size."),t.IF=!0),isNaN(E)&&(E=2E3),isNaN(g)&&(g=2E3),isFinite(E)&&(d=Math.min(d,E)),isFinite(g)&&(u=Math.min(u,g)));q.width=Math.ceil(d);q.height=Math.ceil(u);"svg"===b.context&&(r=s=new nc(q),r instanceof nc&&(a.mn=!0));yi(a,r,l,new ea(Math.ceil(d),Math.ceil(u)),e,x,k,m,p,n);a.mn=!0;return s} +z.inherit=function(a,b){t.j(a,"function",z,"inherit");t.j(b,"function",z,"inherit");b.jG&&t.l("Cannot inherit from "+t.Gg(b));t.Ja(a,b)};function zj(a){1a)&&t.ia(a,"0 <= loc <= 1",Ud,"addColorStop:loc");t.j(b,"string",Ud,"addColorStop:color");null===this.qg&&(this.qg=new ia("number","string"));this.qg.add(a,b);this.Z===Wd&&(this.type=Xd);this.rg=null};t.g(Ud,"type",Ud.prototype.type); +t.defineProperty(Ud,{type:"type"},function(){return this.Z},function(a){t.L(this,a);t.nb(a,Ud,Ud,"type");this.Z=a;this.start.jd()&&(a===Xd?this.start=Db:a===Yd&&(this.start=Fb));this.end.jd()&&(a===Xd?this.end=Nb:a===Yd&&(this.end=Fb));this.rg=null});t.g(Ud,"color",Ud.prototype.color);t.defineProperty(Ud,{color:"color"},function(){return this.an},function(a){t.L(this,a);t.j(a,"string",Ud,"color");this.an=a;this.rg=null});t.g(Ud,"start",Ud.prototype.start); +t.defineProperty(Ud,{start:"start"},function(){return this.Tn},function(a){t.L(this,a);a instanceof H||t.Nb(a,"Spot",Ud,"start");this.Tn=a.W();this.rg=null});t.g(Ud,"end",Ud.prototype.end);t.defineProperty(Ud,{end:"end"},function(){return this.on},function(a){t.L(this,a);a instanceof H||t.Nb(a,"Spot",Ud,"end");this.on=a.W();this.rg=null});t.g(Ud,"startRadius",Ud.prototype.tp); +t.defineProperty(Ud,{tp:"startRadius"},function(){return this.Yu},function(a){t.L(this,a);t.o(a,Ud,"startRadius");0>a&&t.ia(a,">= zero",Ud,"startRadius");this.Yu=a;this.rg=null});t.g(Ud,"endRadius",Ud.prototype.wo);t.defineProperty(Ud,{wo:"endRadius"},function(){return this.Wt},function(a){t.L(this,a);t.o(a,Ud,"endRadius");0>a&&t.ia(a,">= zero",Ud,"endRadius");this.Wt=a;this.rg=null});t.g(Ud,"colorStops",Ud.prototype.qo); +t.defineProperty(Ud,{qo:"colorStops"},function(){return this.qg},function(a){t.L(this,a);f&&t.k(a,ia,Ud,"colorStops");this.qg=a;this.rg=null});t.g(Ud,"pattern",Ud.prototype.pattern);t.defineProperty(Ud,{pattern:"pattern"},function(){return this.Ju},function(a){t.L(this,a);this.Ju=a;this.rg=null}); +Ud.randomColor=function(a,b){void 0===a&&(a=128);f&&(t.o(a,Ud,"randomColor:min"),(0>a||255d.length&&(d="0"+d);2>e.length&&(e="0"+e);2>c.length&&(c="0"+c);return"#"+ +d+e+c}; +function Q(){t.uc(this);this.ha=30723;this.fi=null;this.Mb="";this.dc=this.Bb=null;this.sb=(new v(NaN,NaN)).freeze();this.Ye=(new ea(NaN,NaN)).freeze();this.Wd=D.Rm;this.mj=D.WF;this.rd=new fa;this.ql=new fa;this.Ak=new fa;this.Xb=1;this.Wm=0;this.nh=Rg;this.Rq=D.Fp;this.Dc=(new w(NaN,NaN,NaN,NaN)).freeze();this.Ob=(new w(NaN,NaN,NaN,NaN)).freeze();this.Qc=(new w(0,0,NaN,NaN)).freeze();this.Sr=this.nq=this.T=this.lr=this.Xd=null;this.Tr=this.oq=Infinity;this.Mp=this.me=vb;this.wr=0;this.tj=1;this.Tp= +0;this.Ti=1;this.zr=-Infinity;this.yr=0;this.Ar=D.ak;this.Br=sg;this.$p="";this.Sl=this.Nh=this.vl=this.vc=this.O=null}t.ea("GraphObject",Q);t.th(Q); +Q.prototype.cloneProtected=function(a){a.ha=this.ha|6144;a.Mb=this.Mb;a.Bb=this.Bb;a.dc=this.dc;a.sb.assign(this.sb);a.Ye.assign(this.Ye);a.Wd=this.Wd.W();a.mj=this.mj.W();a.Ak=this.Ak.copy();a.Xb=this.Xb;a.Wm=this.Wm;a.nh=this.nh;a.Rq=this.Rq.W();a.Dc.assign(this.Dc);a.Ob.assign(this.Ob);a.Qc.assign(this.Qc);a.lr=this.lr;a.me=this.me.W();a.Mp=this.Mp.W();a.wr=this.wr;a.tj=this.tj;a.Tp=this.Tp;a.Ti=this.Ti;a.zr=this.zr;a.yr=this.yr;a.Ar=this.Ar.W();a.Br=this.Br;a.$p=this.$p;if(null!==this.O){var b= +this.O;a.O={Mh:b.Mh,Sh:b.Sh,Oh:b.Oh,br:b.br,cr:b.cr,bi:b.bi,ai:b.ai,$h:b.$h,$q:b.$q,ar:b.ar,Zh:b.Zh,Hp:b.Hp,Ip:b.Ip,Jp:b.Jp,Gp:b.Gp,li:b.li,Ph:b.Ph}}null!==this.T&&(b=this.T,a.T={aj:b.aj.W(),Cj:b.Cj.W(),Zi:b.Zi,Aj:b.Aj,Yi:b.Yi,zj:b.zj,$i:b.$i,Bj:b.Bj});a.nq=this.nq;a.oq=this.oq;a.Sr=this.Sr;a.Tr=this.Tr;a.vc=this.vc;if(Array.isArray(this.vl))for(a.vl=this.vl.slice(0),b=0;bk;)k+=g[n++%l],p=!p;q=!1}else k=g[n++%l];k>m&&(k=m);var r=Math.sqrt(k*k/(1+e*e));0>d&&(r=-r);b+=r;c+=e*r;p?a.lineTo(b,c):a.moveTo(b,c);m-=k;p=!p}}aa.Mc=function(a,b,c,d,e,g,h){var k=this.Q;null!==k&&(k.Im(a,b,c,d,e,g,h),0!==(this.ha&1024)&&c===this&&a===sd&&Jj(this,k,b))}; +function Jj(a,b,c){var d=a.Bo();if(null!==d)for(var e=a.vc.m;e.next();){var g=e.value,h=d.data,k=g.ht;null!==k&&(h=d.de(k));if(null!==h&&(g.EF(a,h,c,null!==k?null:b.h),null!==k&&(h=d,""!==k&&(h=d.de(k)),null!==h))){var k=g.Nm,l=d;""!==k&&(l=d.de(k));null!==l&&g.FF(l,h,c)}}}aa.i=function(a,b,c){this.Mc(sd,a,this,b,c)};function Kj(a,b,c,d,e){var g=a.Dc,h=a.Ak;h.reset();Lj(a,h,b,c,d,e);a.Ak=h;g.x=b;g.y=c;g.width=d;g.height=e;h.Es()||h.yF(g)} +function Mj(a,b,c,d){if(!1===a.mf)return!1;d.multiply(a.transform);return c?a.Bf(b,d):a.om(b,d)}aa.tD=function(a,b,c){if(!1===this.mf)return!1;var d=this.Na;b=a.Mj(b);var e=!1;c&&(e=Pa(a.x,a.y,0,0,0,d.height)d.width*e&&10>d.height*e)return a=eb(c.x-5*g,c.y-5*g,c.width+10*g,c.height+10*g,b.x,b.y),t.B(b),a}if(void 0!==this.Gc||this instanceof Y?eb(c.x-5,c.y-5,c.width+10,c.height+10,b.x,b.y):c.Da(b)){if(this.Nh&&!this.Nh.Da(b))return!1;if(null!==this.dc&&c.Da(b)||null!== +this.Bb&&this.Qc.Da(a))return!0;t.B(b);return this.Hj(a)}t.B(b);return!1};Q.prototype.Hj=function(a){var b=this.Na;return eb(0,0,b.width,b.height,a.x,a.y)}; +Q.prototype.containsRect=Q.prototype.Ij=function(a){f&&t.k(a,w,Q,"containsRect:r");if(0===this.angle)return this.ua.Ij(a);var b=this.Na,b=t.Yj(0,0,b.width,b.height),c=this.transform,d=!1,e=t.cc(a.x,a.y);b.Da(c.Ci(e))&&(e.q(a.x,a.bottom),b.Da(c.Ci(e))&&(e.q(a.right,a.bottom),b.Da(c.Ci(e))&&(e.q(a.right,a.y),b.Da(c.Ci(e))&&(d=!0))));t.B(e);t.Ic(b);return d}; +Q.prototype.containedInRect=Q.prototype.om=function(a,b){f&&t.k(a,w,Q,"containedInRect:r");if(void 0===b)return a.Ij(this.ua);var c=this.Na,d=!1,e=t.cc(0,0);a.Da(b.Qa(e))&&(e.q(0,c.height),a.Da(b.Qa(e))&&(e.q(c.width,c.height),a.Da(b.Qa(e))&&(e.q(c.width,0),a.Da(b.Qa(e))&&(d=!0))));return d}; +Q.prototype.intersectsRect=Q.prototype.Bf=function(a,b){f&&t.k(a,w,Q,"intersectsRect:r");if(void 0===b&&(b=this.transform,0===this.angle))return a.Bf(this.ua);var c=this.Na,d=b,e=t.cc(0,0),g=t.cc(0,c.height),h=t.cc(c.width,c.height),k=t.cc(c.width,0),l=!1;if(a.Da(d.Qa(e))||a.Da(d.Qa(g))||a.Da(d.Qa(h))||a.Da(d.Qa(k)))l=!0;else{var c=t.Yj(0,0,c.width,c.height),m=t.cc(a.x,a.y);c.Da(d.Ci(m))?l=!0:(m.q(a.x,a.bottom),c.Da(d.Ci(m))?l=!0:(m.q(a.right,a.bottom),c.Da(d.Ci(m))?l=!0:(m.q(a.right,a.y),c.Da(d.Ci(m))&& +(l=!0))));t.B(m);t.Ic(c);!l&&(D.Xv(a,e,g)||D.Xv(a,g,h)||D.Xv(a,h,k)||D.Xv(a,k,e))&&(l=!0)}t.B(e);t.B(g);t.B(h);t.B(k);return l};Q.prototype.getDocumentPoint=Q.prototype.$a=function(a,b){void 0===b&&(b=new v);a.jd()&&t.l("Spot must be real");var c=this.Na;b.q(a.x*c.width+a.offsetX,a.y*c.height+a.offsetY);this.$d.Qa(b);return b};Q.prototype.getDocumentAngle=Q.prototype.Wk=function(){var a=this.$d,a=180/Math.PI*Math.atan2(a.m12,a.m11);0>a&&(a+=360);return a}; +Q.prototype.getDocumentScale=Q.prototype.Sj=function(){var a=this.Xb;return null!==this.fa?a*this.fa.Sj():a};Q.prototype.getLocalPoint=Q.prototype.DD=function(a,b){void 0===b&&(b=new v);b.assign(a);this.$d.Ci(b);return b};Q.prototype.getNearestIntersectionPoint=Q.prototype.Zk=function(a,b,c){return this.Go(a.x,a.y,b.x,b.y,c)};aa=Q.prototype; +aa.Go=function(a,b,c,d,e){var g=this.transform,h=1/(g.m11*g.m22-g.m12*g.m21),k=g.m22*h,l=-g.m12*h,m=-g.m21*h,n=g.m11*h,p=h*(g.m21*g.dy-g.m22*g.dx),q=h*(g.m12*g.dx-g.m11*g.dy);if(null!==this.Ok)return g=this.ua,D.Zk(g.left,g.top,g.right,g.bottom,a,b,c,d,e);h=a*k+b*m+p;a=a*l+b*n+q;b=c*k+d*m+p;c=c*l+d*n+q;e.q(0,0);d=this.Na;c=D.Zk(0,0,d.width,d.height,h,a,b,c,e);e.transform(g);return c}; +function mh(a,b,c,d,e){if(!1!==si(a)){var g=a.margin,h=g.top+g.bottom;b=Math.max(b-(g.right+g.left),0);c=Math.max(c-h,0);g=a.angle;if(90===g||270===g)g=b,b=c,c=g,g=d,d=e,e=g;g=a.ya;h=0;a.bb&&(h=a.bb);b=isFinite(g.width)?g.width+h:b;c=isFinite(g.height)?g.height+h:c;var g=d||0,h=e||0,k=a instanceof y;switch(Nj(a)){case Qg:h=g=0;k&&(c=b=Infinity);break;case Ic:isFinite(b)&&b>d&&(g=b);isFinite(c)&&c>e&&(h=c);break;case Fj:isFinite(b)&&b>d&&(g=b);h=0;k&&(c=Infinity);break;case Ej:isFinite(c)&&c>e&&(h= +c),g=0,k&&(b=Infinity)}var k=a.Ce,l=a.Te;g>k.width&&l.widthk.height&&l.heighta.height||this.Gn.Ii>a.width))&&(c=!0);this.ha=c?this.ha|256:this.ha&-257;this.Ob.P()||t.l("Non-real actualBounds has been set. Object "+ +this+", actualBounds: "+this.Ob.toString());Qj(this,g,this.Ob);t.Ic(g)};aa.Gj=function(){};function Rj(a,b,c,d,e){var g=a.ua;g.x=b;g.y=c;g.width=d;g.height=e;if(!a.ya.P()){g=a.Dc;c=a.margin;b=c.right+c.left;var h=c.top+c.bottom;c=g.width+b;g=g.height+h;d+=b;e+=h;b=Nj(a);c===d&&g===e&&(b=Qg);switch(b){case Qg:if(c>d||g>e)Oj(a,!0),mh(a,c>d?d:c,g>e?e:g);break;case Ic:Oj(a,!0);mh(a,d,e,0,0);break;case Fj:Oj(a,!0);mh(a,d,g,0,0);break;case Ej:Oj(a,!0),mh(a,c,e,0,0)}}} +function Qj(a,b,c){Sj(a,!1);var d=a.Q;if(null!==d){var e=d.h;if(null!==e)if(Tj(d),a instanceof B){var g=!1,d=b.P();if(!1===e.dj){var h=e.hd,k=e.padding,l=h.x+k.left,m=h.y+k.top,n=h.width-2*k.right,h=h.height-2*k.bottom;d&&b.x>l&&b.y>m&&b.rightl&&c.y>m&&c.rightc.width+c.x||c.x>h.width+h.x||m>c.height+c.y||c.y>h.height+h.y)break a;h=!0;xc(a,1,0,0,1,0,0);a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}l=!1;if(this instanceof B&&(l=!0,!this.ub()))break a;m=!1;this.Q&&(m=this.Q.Gi);a.vi.Se=[1,0,0,1,0,0];null!==this.dc&&(ak(this,a,this.dc,!0,!0),this.dc instanceof Ud&&this.dc.type===Yd?(a.beginPath(),a.rect(c.x,c.y,c.width,c.height),bk(a,this.dc,!0)):a.fillRect(c.x, +c.y,c.width,c.height));l&&this.Gi&&(xc(a,1,0,0,1,0,0),c=this.am,a.shadowOffsetX=c.x,a.shadowOffsetY=c.y,a.shadowColor=this.$l,a.shadowBlur=this.Zl/b.scale,a.Xa());this instanceof y?xc(a,d.m11,d.m12,d.m21,d.m22,d.dx,d.dy):a.vi.Se=[d.m11,d.m12,d.m21,d.m22,d.dx,d.dy];if(null!==this.Bb){var k=this.Na,c=d=0,n=k.width,k=k.height,p=0;this instanceof Y&&(k=this.La.Gb,d=k.x,c=k.y,n=k.width,k=k.height,p=this.Dg);ak(this,a,this.Bb,!0);this.Bb instanceof Ud&&this.Bb.type===Yd?(a.beginPath(),a.rect(d-p/2,c-p/ +2,n+p,k+p),bk(a,this.Bb,!0)):a.fillRect(d-p/2,c-p/2,n+p,k+p)}if(m&&(null!==this.Bb||null!==this.dc||null!==e&&0!==(e.ha&512)||null!==e&&e.type===Oh&&e.Pv()!==this)){ck(this,!0);var q=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}else ck(this,!1);this.Vk(a,b);m&&0!==(this.ha&512)===!0&&(a.shadowOffsetX=q[0],a.shadowOffsetY=q[1],a.shadowBlur=q[2]);l&&m&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);g?(a.restore(),h&&a.ag.pop(),Th(b,a)):this instanceof +y&&a.ag.pop();l&&m&&a.ag.pop()}}}else if(this instanceof y&&(this.type===Wj||this.type===Xj))Yj(this,a,b);else if(d=this.Ob,0!==d.width&&0!==d.height&&!isNaN(d.x)&&!isNaN(d.y)){q=this.transform;g=this.fa;h=this.ql;h.reset();null!==g&&(g.og()?h.multiply(g.$d):null!==g.fa&&h.multiply(g.fa.$d));h.multiply(this.rd);h=0!==(this.ha&256);this instanceof ma&&Zj(this,a);if(h){f&&f.pH&&t.trace("clip"+this.toString());c=g.og()?g.Na:g.ua;this.Nh?(k=this.Nh,l=k.x,m=k.y,n=k.width,k=k.height):(l=Math.max(d.x,c.x), +m=Math.max(d.y,c.y),n=Math.min(d.right,c.right)-l,k=Math.min(d.bottom,c.bottom)-m);if(l>d.width+d.x||d.x>c.width+c.x||m>d.height+d.y||d.y>c.height+c.y)return;a.save();a.beginPath();a.rect(l,m,n,k);a.clip()}c=!1;if(this instanceof B){c=!0;if(!this.ub())return;this.Gi&&(l=this.am,a.shadowOffsetX=l.x*b.scale,a.shadowOffsetY=l.y*b.scale,a.shadowColor=this.$l,a.shadowBlur=this.Zl)}l=!1;this.Q&&(l=this.Q.Gi);null!==this.dc&&(ak(this,a,this.dc,!0,!0),this.dc instanceof Ud&&this.dc.type===Yd?(a.beginPath(), +a.rect(d.x,d.y,d.width,d.height),bk(a,this.dc,!0)):a.fillRect(d.x,d.y,d.width,d.height));q.Es()||a.transform(q.m11,q.m12,q.m21,q.m22,q.dx,q.dy);null!==this.Bb&&(k=this.Na,m=d=0,n=k.width,k=k.height,p=0,this instanceof Y&&(k=this.La.Gb,d=k.x,m=k.y,n=k.width,k=k.height,p=this.Dg),ak(this,a,this.Bb,!0),this.Bb instanceof Ud&&this.Bb.type===Yd?(a.beginPath(),a.rect(d-p/2,m-p/2,n+p,k+p),bk(a,this.Bb,!0)):a.fillRect(d-p/2,m-p/2,n+p,k+p));l&&(null!==this.Bb||null!==this.dc||null!==g&&0!==(g.ha&512)||null!== +g&&g.type===Oh&&g.Pv()!==this)?(ck(this,!0),e=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0):ck(this,!1);this.Vk(a,b);l&&0!==(this.ha&512)===!0&&(a.shadowOffsetX=e[0],a.shadowOffsetY=e[1],a.shadowBlur=e[2]);c&&l&&(a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0);h?(a.restore(),this instanceof y?Th(b,a,!0):Th(b,a,!1)):q.Es()||(e=1/(q.m11*q.m22-q.m12*q.m21),a.transform(q.m22*e,-q.m12*e,-q.m21*e,q.m11*e,e*(q.m21*q.dy-q.m22*q.dx),e*(q.m12*q.dx-q.m11* +q.dy)))}};function Yj(a,b,c){var d=a.Ob;0===d.width||0===d.height||isNaN(d.x)||isNaN(d.y)||(null!==a.dc&&(ak(a,b,a.dc,!0,!0),a.dc instanceof Ud&&a.dc.type===Yd?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),bk(b,a.dc,!0)):b.fillRect(d.x,d.y,d.width,d.height)),null!==a.Bb&&(ak(a,b,a.Bb,!0),a.Bb instanceof Ud&&a.Bb.type===Yd?(b.beginPath(),b.rect(d.x,d.y,d.width,d.height),bk(b,a.Bb,!0)):b.fillRect(d.x,d.y,d.width,d.height)),a.Vk(b,c))}aa.Vk=function(){}; +function bk(a,b,c){if(c)if(a instanceof CanvasRenderingContext2D&&b instanceof Ud&&b.type===Yd){var d=b.ux;b=b.tx;b>d?(a.scale(d/b,1),a.translate((b-d)/2,0),c?a.fill():a.stroke(),a.translate(-(b-d)/2,0),a.scale(1/(d/b),1)):d>b?(a.scale(1,b/d),a.translate(0,(d-b)/2),c?a.fill():a.stroke(),a.translate(0,-(d-b)/2),a.scale(1,1/(b/d))):c?a.fill():a.stroke()}else c?a.fill():a.stroke();else a.stroke()} +function ak(a,b,c,d,e){if(null!==c){var g=1,h=1;if("string"===typeof c)d?b.Sm!==c&&(b.fillStyle=c,b.Sm=c):b.Tm!==c&&(b.strokeStyle=c,b.Tm=c);else if(c.type===Wd)c=c.color,d?b.Sm!==c&&(b.fillStyle=c,b.Sm=c):b.Tm!==c&&(b.strokeStyle=c,b.Tm=c);else{var k,h=a.Na,g=h.width,h=h.height;if(e)var l=a.ua,g=l.width,h=l.height;var m=b instanceof CanvasRenderingContext2D;if(m&&(c.rg&&c.type===Dj||c.ux===g&&c.tx===h))k=c.rg;else{var n,p,q=p=0;e&&(l=a.ua,g=l.width,h=l.height,p=l.x,q=l.y);c.start instanceof v?(a= +c.start.x,e=c.start.y):c.start instanceof H?(a=c.start.x*g,e=c.start.y*h):(a=Fb.x*g,e=Fb.y*h);c.end instanceof v?(l=c.end.x,n=c.end.y):c.end instanceof H?(l=c.end.x*g,n=c.end.y*h):c.type===Xd?(l=Nb.x*g,n=Nb.y*h):(l=Fb.x*g,n=Fb.y*h);a+=p;l+=p;e+=q;n+=q;c.type===Xd?k=b.createLinearGradient(a,e,l,n):c.type===Yd?(p=isNaN(c.wo)?Math.max(g,h)/2:c.wo,isNaN(c.tp)?(k=0,p=Math.max(g,h)/2):k=c.tp,k=b.createRadialGradient(a,e,k,l,n,p)):c.type===Dj?k=b.createPattern(c.pattern,"repeat"):t.Nb(c.type,"Brush type"); +if(c.type!==Dj&&(p=c.qo))for(p=p.m;p.next();)k.addColorStop(p.key,p.value);m&&(c.rg=k,c.ux=g,c.tx=h)}d?b.Sm!==k&&(b.fillStyle=k,b.Sm=k):b.Tm!==k&&(b.strokeStyle=k,b.Tm=k)}}}Q.prototype.isContainedBy=Q.prototype.Ei=function(a){if(a instanceof y)a:{if(this!==a&&null!==a)for(var b=this.fa;null!==b;){if(b===a){a=!0;break a}b=b.fa}a=!1}else a=!1;return a};Q.prototype.isVisibleObject=Q.prototype.bl=function(){if(!this.visible)return!1;var a=this.fa;return null!==a?a.bl():!0}; +function dk(a){if(0!==(a.ha&2048)===!0){var b=a.rd;b.reset();if(!a.Ob.P()||!a.Dc.P()){ek(a,!1);return}b.translate(a.Ob.x,a.Ob.y);b.translate(-a.Ba.x,-a.Ba.y);var c=a.Na;Lj(a,b,c.x,c.y,c.width,c.height);ek(a,!1);fk(a,!0)}0!==(a.ha&4096)===!0&&(null===a.fa?(a.ql.set(a.rd),fk(a,!1)):null!==a.fa.$d&&(b=a.ql,b.reset(),b.multiply(a.fa.ql),b.multiply(a.rd),fk(a,!1)))} +function Lj(a,b,c,d,e,g){1!==a.scale&&b.scale(a.scale);if(0!==a.angle){var h=Fb;a.Re&&a.Re.kd()&&(h=a.Re);var k=t.M();if(a instanceof B&&a.Zb!==a)for(c=a.Zb,d=c.Na,k.ft(d.x,d.y,d.width,d.height,h),c.Ak.Qa(k),k.offset(-c.Ba.x,-c.Ba.y),h=c.fa;null!==h&&h!==a;)h.Ak.Qa(k),k.offset(-h.Ba.x,-h.Ba.y),h=h.fa;else k.ft(c,d,e,g,h);b.rotate(a.angle,k.x,k.y);t.B(k)}} +Q.prototype.Y=function(a){if(!0!==si(this)){Oj(this,!0);Sj(this,!0);var b=this.fa;null!==b?a||b.Y():(a=this.h,null!==a&&(a.Nf.add(this),this instanceof S&&(a.va.kb||this.Ig(),null!==this.ld&&gk(this.ld)),a.Gf()));if(this instanceof y){var c=null;a=this.za;b=a.length;this.Z===Oh&&(c=hk(this,a,b))&&c.Y(!0);a=a.p;for(c=0;ca?a=0:1=a&&t.l("GraphObject.scale must be greater than zero"),this.Xb=a,Pj(this),this.Y(),this.i("scale",b,a))});t.g(Q,"angle",Q.prototype.angle);t.defineProperty(Q,{angle:"angle"},function(){return this.Wm},function(a){var b=this.Wm;b!==a&&(f&&t.o(a,Q,"angle"),a%=360,0>a&&(a+=360),b!==a&&(this.Wm=a,this.Y(),Pj(this),this.i("angle",b,a)))}); +t.g(Q,"desiredSize",Q.prototype.ya);t.defineProperty(Q,{ya:"desiredSize"},function(){return this.Ye},function(a){var b=this.Ye;b.K(a)||(f&&t.k(a,ea,Q,"desiredSize"),this.Ye=a=a.W(),this.Y(),this instanceof Y&&this.Cf(),this.i("desiredSize",b,a),a=this.Q,null!==a&&0!==(this.ha&1024)&&(Jj(this,a,"width"),Jj(this,a,"height")))});t.g(Q,"width",Q.prototype.width); +t.defineProperty(Q,{width:"width"},function(){return this.Ye.width},function(a){if(this.Ye.width!==a){f&&t.j(a,"number",Q,"width");var b=this.Ye;this.Ye=a=(new ea(a,this.Ye.height)).freeze();this.Y();this instanceof Y&&this.Cf();this.i("desiredSize",b,a);b=this.Q;null!==b&&0!==(this.ha&1024)&&Jj(this,b,"width")}});t.g(Q,"height",Q.prototype.height); +t.defineProperty(Q,{height:"height"},function(){return this.Ye.height},function(a){if(this.Ye.height!==a){f&&t.j(a,"number",Q,"height");var b=this.Ye;this.Ye=a=(new ea(this.Ye.width,a)).freeze();this.Y();this instanceof Y&&this.Cf();this.i("desiredSize",b,a);b=this.Q;null!==b&&0!==(this.ha&1024)&&Jj(this,b,"height")}});t.g(Q,"minSize",Q.prototype.Te); +t.defineProperty(Q,{Te:"minSize"},function(){return this.Wd},function(a){var b=this.Wd;b.K(a)||(f&&t.k(a,ea,Q,"minSize"),a=a.copy(),isNaN(a.width)&&(a.width=0),isNaN(a.height)&&(a.height=0),a.freeze(),this.Wd=a,this.Y(),this.i("minSize",b,a))});t.g(Q,"maxSize",Q.prototype.Ce); +t.defineProperty(Q,{Ce:"maxSize"},function(){return this.mj},function(a){var b=this.mj;b.K(a)||(f&&t.k(a,ea,Q,"maxSize"),a=a.copy(),isNaN(a.width)&&(a.width=Infinity),isNaN(a.height)&&(a.height=Infinity),a.freeze(),this.mj=a,this.Y(),this.i("maxSize",b,a))});t.A(Q,{Ba:"measuredBounds"},function(){return this.Dc});t.A(Q,{Na:"naturalBounds"},function(){return this.Qc},{configurable:!0});t.g(Q,"margin",Q.prototype.margin); +t.defineProperty(Q,{margin:"margin"},function(){return this.Rq},function(a){"number"===typeof a?a=new Va(a):f&&t.k(a,Va,Q,"margin");var b=this.Rq;b.K(a)||(this.Rq=a=a.W(),this.Y(),this.i("margin",b,a))});t.A(Q,{transform:null},function(){0!==(this.ha&2048)===!0&&dk(this);return this.rd});t.A(Q,{$d:null},function(){0!==(this.ha&4096)===!0&&dk(this);return this.ql});t.g(Q,"alignment",Q.prototype.alignment); +t.defineProperty(Q,{alignment:"alignment"},function(){return this.me},function(a){var b=this.me;b.K(a)||(f?t.k(a,H,Q,"alignment"):a.jd()&&!a.zc()&&t.l("alignment must be a real Spot or Spot.Default"),this.me=a=a.W(),gk(this),this.i("alignment",b,a))});t.g(Q,"column",Q.prototype.column);t.defineProperty(Q,{column:"column"},function(){return this.Tp},function(a){f&&t.o(a,Q,"column");a=Math.round(a);var b=this.Tp;b!==a&&(0>a&&t.ia(a,">= 0",Q,"column"),this.Tp=a,this.Y(),this.i("column",b,a))}); +t.g(Q,"columnSpan",Q.prototype.TC);t.defineProperty(Q,{TC:"columnSpan"},function(){return this.Ti},function(a){f&&t.o(a,Q,"columnSpan");a=Math.round(a);var b=this.Ti;b!==a&&(1>a&&t.ia(a,">= 1",Q,"columnSpan"),this.Ti=a,this.Y(),this.i("columnSpan",b,a))});t.g(Q,"row",Q.prototype.ac);t.defineProperty(Q,{ac:"row"},function(){return this.wr},function(a){f&&t.o(a,Q,"row");a=Math.round(a);var b=this.wr;b!==a&&(0>a&&t.ia(a,">= 0",Q,"row"),this.wr=a,this.Y(),this.i("row",b,a))});t.g(Q,"rowSpan",Q.prototype.rowSpan); +t.defineProperty(Q,{rowSpan:"rowSpan"},function(){return this.tj},function(a){f&&t.o(a,Q,"rowSpan");a=Math.round(a);var b=this.tj;b!==a&&(1>a&&t.ia(a,">= 1",Q,"rowSpan"),this.tj=a,this.Y(),this.i("rowSpan",b,a))});t.g(Q,"alignmentFocus",Q.prototype.Dj); +t.defineProperty(Q,{Dj:"alignmentFocus"},function(){return this.Mp},function(a){var b=this.Mp;b.K(a)||(f?t.k(a,H,Q,"alignmentFocus"):a.jd()&&!a.zc()&&t.l("alignmentFocus must be a real Spot or Spot.Default"),this.Mp=a=a.W(),this.Y(),this.i("alignmentFocus",b,a))});t.g(Q,"portId",Q.prototype.md); +t.defineProperty(Q,{md:"portId"},function(){return this.lr},function(a){var b=this.lr;if(b!==a){f&&null!==a&&t.j(a,"string",Q,"portId");var c=this.Q;null===c||c instanceof S||(t.l("portID being set on a Link: "+a),c=null);null!==b&&c&&qk(c,this);this.lr=a;if(null!==a&&c){c.cj=!0;null===c.Yd&&rk(c);var d=this.md;null!==d&&c.Yd.add(d,this)}this.i("portId",b,a)}});function sk(a){var b={value:null};tk(a,b);return b.value} +function tk(a,b){var c=a.fa;return null===c||!tk(c,b)&&a.visible?(b.value=a,!1):!0}function mk(a){var b=a.Q;b instanceof S&&(a=a.h)&&!a.va.kb&&b.Ig()}t.g(Q,"toSpot",Q.prototype.gb);t.defineProperty(Q,{gb:"toSpot"},function(){return null!==this.T?this.T.Cj:ub},function(a){null===this.T&&this.Be();var b=this.T.Cj;b.K(a)||(f&&t.k(a,H,Q,"toSpot"),a=a.W(),this.T.Cj=a,this.i("toSpot",b,a),mk(this))});t.g(Q,"toEndSegmentLength",Q.prototype.Zj); +t.defineProperty(Q,{Zj:"toEndSegmentLength"},function(){return null!==this.T?this.T.Aj:10},function(a){null===this.T&&this.Be();var b=this.T.Aj;b!==a&&(f&&t.j(a,"number",Q,"toEndSegmentLength"),0>a&&t.ia(a,">= 0",Q,"toEndSegmentLength"),this.T.Aj=a,this.i("toEndSegmentLength",b,a),mk(this))});t.g(Q,"toEndSegmentDirection",Q.prototype.vp); +t.defineProperty(Q,{vp:"toEndSegmentDirection"},function(){return null!==this.T?this.T.zj:Hj},function(a){null===this.T&&this.Be();var b=this.T.zj;b!==a&&(f&&t.nb(a,S,Q,"toEndSegmentDirection"),this.T.zj=a,this.i("toEndSegmentDirection",b,a),mk(this))});t.g(Q,"toShortLength",Q.prototype.wp); +t.defineProperty(Q,{wp:"toShortLength"},function(){return null!==this.T?this.T.Bj:0},function(a){null===this.T&&this.Be();var b=this.T.Bj;b!==a&&(f&&t.j(a,"number",Q,"toShortLength"),this.T.Bj=a,this.i("toShortLength",b,a),mk(this))});t.g(Q,"toLinkable",Q.prototype.NA);t.defineProperty(Q,{NA:"toLinkable"},function(){return this.Sr},function(a){var b=this.Sr;b!==a&&(f&&null!==a&&t.j(a,"boolean",Q,"toLinkable"),this.Sr=a,this.i("toLinkable",b,a))});t.g(Q,"toMaxLinks",Q.prototype.sF); +t.defineProperty(Q,{sF:"toMaxLinks"},function(){return this.Tr},function(a){var b=this.Tr;b!==a&&(f&&t.o(a,Q,"toMaxLinks"),0>a&&t.ia(a,">= 0",Q,"toMaxLinks"),this.Tr=a,this.i("toMaxLinks",b,a))});t.g(Q,"fromSpot",Q.prototype.fb);t.defineProperty(Q,{fb:"fromSpot"},function(){return null!==this.T?this.T.aj:ub},function(a){null===this.T&&this.Be();var b=this.T.aj;b.K(a)||(f&&t.k(a,H,Q,"fromSpot"),a=a.W(),this.T.aj=a,this.i("fromSpot",b,a),mk(this))});t.g(Q,"fromEndSegmentLength",Q.prototype.Rj); +t.defineProperty(Q,{Rj:"fromEndSegmentLength"},function(){return null!==this.T?this.T.Zi:10},function(a){null===this.T&&this.Be();var b=this.T.Zi;b!==a&&(f&&t.j(a,"number",Q,"fromEndSegmentLength"),0>a&&t.ia(a,">= 0",Q,"fromEndSegmentLength"),this.T.Zi=a,this.i("fromEndSegmentLength",b,a),mk(this))});t.g(Q,"fromEndSegmentDirection",Q.prototype.Co); +t.defineProperty(Q,{Co:"fromEndSegmentDirection"},function(){return null!==this.T?this.T.Yi:Hj},function(a){null===this.T&&this.Be();var b=this.T.Yi;b!==a&&(f&&t.nb(a,S,Q,"fromEndSegmentDirection"),this.T.Yi=a,this.i("fromEndSegmentDirection",b,a),mk(this))});t.g(Q,"fromShortLength",Q.prototype.Do); +t.defineProperty(Q,{Do:"fromShortLength"},function(){return null!==this.T?this.T.$i:0},function(a){null===this.T&&this.Be();var b=this.T.$i;b!==a&&(f&&t.j(a,"number",Q,"fromShortLength"),this.T.$i=a,this.i("fromShortLength",b,a),mk(this))});t.g(Q,"fromLinkable",Q.prototype.Hz);t.defineProperty(Q,{Hz:"fromLinkable"},function(){return this.nq},function(a){var b=this.nq;b!==a&&(f&&null!==a&&t.j(a,"boolean",Q,"fromLinkable"),this.nq=a,this.i("fromLinkable",b,a))});t.g(Q,"fromMaxLinks",Q.prototype.AD); +t.defineProperty(Q,{AD:"fromMaxLinks"},function(){return this.oq},function(a){var b=this.oq;b!==a&&(f&&t.o(a,Q,"fromMaxLinks"),0>a&&t.ia(a,">= 0",Q,"fromMaxLinks"),this.oq=a,this.i("fromMaxLinks",b,a))});t.g(Q,"cursor",Q.prototype.cursor);t.defineProperty(Q,{cursor:"cursor"},function(){return this.$p},function(a){var b=this.$p;b!==a&&(t.j(a,"string",Q,"cursor"),this.$p=a,this.i("cursor",b,a))});t.g(Q,"click",Q.prototype.click); +t.defineProperty(Q,{click:"click"},function(){return null!==this.O?this.O.Mh:null},function(a){null===this.O&&Gj(this);var b=this.O.Mh;b!==a&&(null!==a&&t.j(a,"function",Q,"click"),this.O.Mh=a,this.i("click",b,a))});t.g(Q,"doubleClick",Q.prototype.tm);t.defineProperty(Q,{tm:"doubleClick"},function(){return null!==this.O?this.O.Sh:null},function(a){null===this.O&&Gj(this);var b=this.O.Sh;b!==a&&(null!==a&&t.j(a,"function",Q,"doubleClick"),this.O.Sh=a,this.i("doubleClick",b,a))}); +t.g(Q,"contextClick",Q.prototype.ns);t.defineProperty(Q,{ns:"contextClick"},function(){return null!==this.O?this.O.Oh:null},function(a){null===this.O&&Gj(this);var b=this.O.Oh;b!==a&&(null!==a&&t.j(a,"function",Q,"contextClick"),this.O.Oh=a,this.i("contextClick",b,a))});t.g(Q,"mouseEnter",Q.prototype.dA); +t.defineProperty(Q,{dA:"mouseEnter"},function(){return null!==this.O?this.O.br:null},function(a){null===this.O&&Gj(this);var b=this.O.br;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseEnter"),this.O.br=a,this.i("mouseEnter",b,a))});t.g(Q,"mouseLeave",Q.prototype.eA);t.defineProperty(Q,{eA:"mouseLeave"},function(){return null!==this.O?this.O.cr:null},function(a){null===this.O&&Gj(this);var b=this.O.cr;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseLeave"),this.O.cr=a,this.i("mouseLeave",b,a))}); +t.g(Q,"mouseOver",Q.prototype.Os);t.defineProperty(Q,{Os:"mouseOver"},function(){return null!==this.O?this.O.bi:null},function(a){null===this.O&&Gj(this);var b=this.O.bi;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseOver"),this.O.bi=a,this.i("mouseOver",b,a))});t.g(Q,"mouseHover",Q.prototype.Ns); +t.defineProperty(Q,{Ns:"mouseHover"},function(){return null!==this.O?this.O.ai:null},function(a){null===this.O&&Gj(this);var b=this.O.ai;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseHover"),this.O.ai=a,this.i("mouseHover",b,a))});t.g(Q,"mouseHold",Q.prototype.Ms);t.defineProperty(Q,{Ms:"mouseHold"},function(){return null!==this.O?this.O.$h:null},function(a){null===this.O&&Gj(this);var b=this.O.$h;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseHold"),this.O.$h=a,this.i("mouseHold",b,a))}); +t.g(Q,"mouseDragEnter",Q.prototype.sE);t.defineProperty(Q,{sE:"mouseDragEnter"},function(){return null!==this.O?this.O.$q:null},function(a){null===this.O&&Gj(this);var b=this.O.$q;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseDragEnter"),this.O.$q=a,this.i("mouseDragEnter",b,a))});t.g(Q,"mouseDragLeave",Q.prototype.cA); +t.defineProperty(Q,{cA:"mouseDragLeave"},function(){return null!==this.O?this.O.ar:null},function(a){null===this.O&&Gj(this);var b=this.O.ar;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseDragLeave"),this.O.ar=a,this.i("mouseDragLeave",b,a))});t.g(Q,"mouseDrop",Q.prototype.Ls);t.defineProperty(Q,{Ls:"mouseDrop"},function(){return null!==this.O?this.O.Zh:null},function(a){null===this.O&&Gj(this);var b=this.O.Zh;b!==a&&(null!==a&&t.j(a,"function",Q,"mouseDrop"),this.O.Zh=a,this.i("mouseDrop",b,a))}); +t.g(Q,"actionDown",Q.prototype.gz);t.defineProperty(Q,{gz:"actionDown"},function(){return null!==this.O?this.O.Hp:null},function(a){null===this.O&&Gj(this);var b=this.O.Hp;b!==a&&(null!==a&&t.j(a,"function",Q,"actionDown"),this.O.Hp=a,this.i("actionDown",b,a))});t.g(Q,"actionUp",Q.prototype.iz); +t.defineProperty(Q,{iz:"actionUp"},function(){return null!==this.O?this.O.Jp:null},function(a){null===this.O&&Gj(this);var b=this.O.Jp;b!==a&&(null!==a&&t.j(a,"function",Q,"actionUp"),this.O.Jp=a,this.i("actionUp",b,a))});t.g(Q,"actionMove",Q.prototype.hz);t.defineProperty(Q,{hz:"actionMove"},function(){return null!==this.O?this.O.Ip:null},function(a){null===this.O&&Gj(this);var b=this.O.Ip;b!==a&&(null!==a&&t.j(a,"function",Q,"actionMove"),this.O.Ip=a,this.i("actionMove",b,a))}); +t.g(Q,"actionCancel",Q.prototype.fz);t.defineProperty(Q,{fz:"actionCancel"},function(){return null!==this.O?this.O.Gp:null},function(a){null===this.O&&Gj(this);var b=this.O.Gp;b!==a&&(null!==a&&t.j(a,"function",Q,"actionCancel"),this.O.Gp=a,this.i("actionCancel",b,a))});t.g(Q,"toolTip",Q.prototype.mt); +t.defineProperty(Q,{mt:"toolTip"},function(){return null!==this.O?this.O.li:null},function(a){null===this.O&&Gj(this);var b=this.O.li;b!==a&&(null!==a&&t.k(a,Fe,Q,"toolTip"),this.O.li=a,this.i("toolTip",b,a))});t.g(Q,"contextMenu",Q.prototype.contextMenu);t.defineProperty(Q,{contextMenu:"contextMenu"},function(){return null!==this.O?this.O.Ph:null},function(a){null===this.O&&Gj(this);var b=this.O.Ph;b!==a&&(null!==a&&t.k(a,Fe,Q,"contextMenu"),this.O.Ph=a,this.i("contextMenu",b,a))}); +Q.prototype.bind=Q.prototype.bind=function(a){a.Sf=this;var b=this.Bo();null!==b&&uk(b)&&t.l("Cannot add a Binding to a template that has already been copied: "+a);null===this.vc&&(this.vc=new A(ze));this.vc.add(a)};Q.prototype.findTemplateBinder=Q.prototype.Bo=function(){for(var a=this instanceof y?this:this.fa;null!==a;){if(null!==a.sl&&a instanceof y)return a;a=a.fa}return null};Q.fromSvg=function(a){return vk(a)};Q.prototype.setProperties=function(a){t.xw(this,a)};var wk; +Q.make=wk=function(a,b){var c=arguments,d=null,e=null;if("function"===typeof a)e=a;else if("string"===typeof a){var g=xk.wa(a);"function"===typeof g?(c=Array.prototype.slice.call(arguments),d=g(c)):e=ba[a]}null===d&&(void 0===e&&(d=window.$,void 0!==d&&void 0!==d.noop&&t.l("GraphObject.make failed to complete. Is it conflicting with another $ var? (such as jQuery)"),t.l("GraphObject.make failed to complete, it may be conflicting with another var.")),null!==e&&e.constructor||t.l("GraphObject.make requires a class function or class name, not: "+ +a),d=new e);g=1;d instanceof z&&1d)&&t.l("Must specify non-negative integer row for RowColumnDefinition "+b),c.Fl=!0,c.oe=d):void 0!==b.column?(d=b.column,(void 0===d||null===d||Infinity===d||isNaN(d)||0>d)&&t.l("Must specify non-negative integer column for RowColumnDefinition "+b),c.Fl=!1,c.oe=d):t.l("Must specify row or column value in a RowColumnDefinition "+b),d=t.XG(b,"row","column"),t.xw(c,d)):t.xw(c,b);else t.l('Unknown initializer "'+b+'" for object being constructed by GraphObject.make: '+ +a)}var xk;Q.Builders=xk=new ia("string","function"); +xk.add("Button",function(){var a=new Ud(Xd);a.addColorStop(0,"white");a.addColorStop(1,"lightgray");var b=new Ud(Xd);b.addColorStop(0,"white");b.addColorStop(1,"dodgerblue");var c=wk(y,Oh,{Yv:!0},wk(Y,{name:"ButtonBorder",Db:"RoundedRectangle",fill:a,stroke:"gray"}));c.dA=function(a,c){var g=c.ta(0),h=c._buttonFillOver;void 0===h&&(h=b);c._buttonFillNormal=g.fill;g.fill=h;h=c._buttonStrokeOver;void 0===h&&(h="blue");c._buttonStrokeNormal=g.stroke;g.stroke=h};c.eA=function(b,c){var g=c.ta(0),h=c._buttonFillNormal; +void 0===h&&(h=a);g.fill=h;h=c._buttonStrokeNormal;void 0===h&&(h="gray");g.stroke=h};return c}); +xk.add("TreeExpanderButton",function(){var a=wk("Button",wk(Y,{name:"ButtonIcon",Db:"MinusLine",ya:D.Dp},(new ze("figure","isTreeExpanded",function(a,c){var d=null,e=c.fa;e&&(d=a?e._treeExpandedFigure:e._treeCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).jA("")),{visible:!1},(new ze("visible","isTreeLeaf",function(a){return!a})).jA(""));a.click=function(a,c){var d=c.Q;d instanceof Fe&&(d=d.rh);if(d instanceof S){var e=d.h;if(null!==e){e=e.Yf;if(d.Ac){if(!e.canCollapseTree(d))return}else if(!e.canExpandTree(d))return; +a.Ae=!0;d.Ac?e.collapseTree(d):e.expandTree(d)}}};return a}); +xk.add("SubGraphExpanderButton",function(){var a=wk("Button",wk(Y,{name:"ButtonIcon",Db:"MinusLine",ya:D.Dp},(new ze("figure","isSubGraphExpanded",function(a,c){var d=null,e=c.fa;e&&(d=a?e._subGraphExpandedFigure:e._subGraphCollapsedFigure);d||(d=a?"MinusLine":"PlusLine");return d})).jA("")));a.click=function(a,c){var d=c.Q;d instanceof Fe&&(d=d.rh);if(d instanceof V){var e=d.h;if(null!==e){e=e.Yf;if(d.Qe){if(!e.canCollapseSubGraph(d))return}else if(!e.canExpandSubGraph(d))return;a.Ae=!0;d.Qe?e.collapseSubGraph(d): +e.expandSubGraph(d)}}};return a});xk.add("ContextMenuButton",function(){var a=wk("Button");a.Eh=Fj;var b=a.de("ButtonBorder");b instanceof Y&&(b.Db="Rectangle",b.G=new H(0,0,2,2),b.H=new H(1,1,-2,-2));return a}); +function y(a){Q.call(this);void 0===a?0===arguments.length?this.Z=Vg:t.l("invalid argument to Panel constructor: undefined"):(t.nb(a,y,y,"type"),this.Z=a);this.za=new A(Q);this.Ge=D.Fp;this.ug=!1;this.Z===Vh&&(this.ug=!0);this.vf=1;this.cq=vb;this.fc=Rg;this.Z===kk&&dl(this);this.ao=Sg;this.sq=(new ea(10,10)).freeze();this.tq=D.ak;this.sl=this.xl=null;this.ky="";this.vg=this.fj=null;this.An="category";this.Of=null;this.ni=new w(NaN,NaN,NaN,NaN);this.Xn=null;this.cj=!1}t.ea("Panel",y);t.th(y); +t.Ja(y,Q);function dl(a){a.Vi=D.Fp;a.Xg=1;a.Rh=null;a.zl=null;a.Wg=1;a.Vg=null;a.yl=null;a.Sc=[];a.Nc=[];a.Xl=el;a.tl=el;a.mi=0;a.Xh=0} +y.prototype.cloneProtected=function(a){Q.prototype.cloneProtected.call(this,a);a.Z=this.Z;a.Ge=this.Ge.W();a.ug=this.ug;a.vf=this.vf;a.cq=this.cq.W();a.fc=this.fc;if(a.Z===kk){a.Vi=this.Vi.W();a.Xg=this.Xg;a.Rh=this.Rh;a.zl=this.zl;a.Wg=this.Wg;a.Vg=this.Vg;a.yl=this.yl;var b=[];if(0a&&t.ia(a,">= 0",y,"padding"),a=new Va(a)):(t.k(a,Va,y,"padding"),0>a.left&&t.ia(a.left,">= 0",y,"padding:val.left"),0>a.right&&t.ia(a.right,">= 0",y,"padding:val.right"),0>a.top&&t.ia(a.top,">= 0",y,"padding:val.top"),0>a.bottom&&t.ia(a.bottom,">= 0",y,"padding:val.bottom"));var b=this.Ge;b.K(a)||(this.Ge=a=a.W(),this.Y(),this.i("padding",b,a))});t.g(y,"defaultAlignment",y.prototype.Kj); +t.defineProperty(y,{Kj:"defaultAlignment"},function(){return this.cq},function(a){var b=this.cq;b.K(a)||(f&&t.k(a,H,y,"defaultAlignment"),this.cq=a=a.W(),this.Y(),this.i("defaultAlignment",b,a))});t.g(y,"defaultStretch",y.prototype.Az);t.defineProperty(y,{Az:"defaultStretch"},function(){return this.fc},function(a){var b=this.fc;b!==a&&(t.nb(a,Q,y,"defaultStretch"),this.fc=a,this.Y(),this.i("defaultStretch",b,a))});t.g(y,"defaultSeparatorPadding",y.prototype.iH); +t.defineProperty(y,{iH:"defaultSeparatorPadding"},function(){return void 0===this.Vi?D.Fp:this.Vi},function(a){if(void 0!==this.Vi){"number"===typeof a?a=new Va(a):f&&t.k(a,Va,y,"defaultSeparatorPadding");var b=this.Vi;b.K(a)||(this.Vi=a=a.W(),this.i("defaultSeparatorPadding",b,a))}});t.g(y,"defaultRowSeparatorStroke",y.prototype.gH); +t.defineProperty(y,{gH:"defaultRowSeparatorStroke"},function(){return void 0===this.Rh?null:this.Rh},function(a){var b=this.Rh;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Rh=a,this.i("defaultRowSeparatorStroke",b,a))});t.g(y,"defaultRowSeparatorStrokeWidth",y.prototype.hH); +t.defineProperty(y,{hH:"defaultRowSeparatorStrokeWidth"},function(){return void 0===this.Xg?1:this.Xg},function(a){if(void 0!==this.Xg){var b=this.Xg;b!==a&&(this.Xg=a,this.i("defaultRowSeparatorStrokeWidth",b,a))}});t.g(y,"defaultRowSeparatorDashArray",y.prototype.fH); +t.defineProperty(y,{fH:"defaultRowSeparatorDashArray"},function(){return void 0===this.zl?null:this.zl},function(a){if(void 0!==this.zl){var b=this.zl;b!==a&&(Array.isArray(a)||t.Nb(a,"Array",y,"defaultRowSeparatorDashArray:val"),this.zl=a,this.i("defaultRowSeparatorDashArray",b,a))}});t.g(y,"defaultColumnSeparatorStroke",y.prototype.bH); +t.defineProperty(y,{bH:"defaultColumnSeparatorStroke"},function(){return void 0===this.Vg?null:this.Vg},function(a){if(void 0!==this.Vg){var b=this.Vg;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Vg=a,this.i("defaultColumnSeparatorStroke",b,a))}});t.g(y,"defaultColumnSeparatorStrokeWidth",y.prototype.cH); +t.defineProperty(y,{cH:"defaultColumnSeparatorStrokeWidth"},function(){return void 0===this.Wg?1:this.Wg},function(a){if(void 0!==this.Wg){var b=this.Wg;b!==a&&(this.Wg=a,this.i("defaultColumnSeparatorStrokeWidth",b,a))}});t.g(y,"defaultColumnSeparatorDashArray",y.prototype.aH); +t.defineProperty(y,{aH:"defaultColumnSeparatorDashArray"},function(){return void 0===this.yl?null:this.yl},function(a){if(void 0!==this.yl){var b=this.yl;b!==a&&(Array.isArray(a)||t.Nb(a,"Array",y,"defaultColumnSeparatorDashArray:val"),this.yl=a,this.i("defaultColumnSeparatorDashArray",b,a))}});t.g(y,"viewboxStretch",y.prototype.KI); +t.defineProperty(y,{KI:"viewboxStretch"},function(){return this.ao},function(a){var b=this.ao;b!==a&&(t.nb(a,Q,y,"viewboxStretch"),this.ao=a,this.i("viewboxStretch",b,a))});t.g(y,"gridCellSize",y.prototype.xs); +t.defineProperty(y,{xs:"gridCellSize"},function(){return this.sq},function(a){var b=this.sq;b.K(a)||(t.k(a,ea,y,"gridCellSize"),a.P()&&0!==a.width&&0!==a.height||t.l("Invalid Panel.gridCellSize: "+a),this.sq=a.W(),null!==this.h&&this===this.h.Io&&ni(this.h),this.na(),this.i("gridCellSize",b,a))});t.g(y,"gridOrigin",y.prototype.Kz); +t.defineProperty(y,{Kz:"gridOrigin"},function(){return this.tq},function(a){var b=this.tq;b.K(a)||(t.k(a,v,y,"gridOrigin"),a.P()||t.l("Invalid Panel.gridOrigin: "+a),this.tq=a.W(),this.h&&ni(this.h),this.na(),this.i("gridOrigin",b,a))}); +y.prototype.Vk=function(a,b){var c=this.opacity,d=1;1!==c&&(d=a.globalAlpha,a.globalAlpha=d*c);if(this.Z===Vh){c=this.Sj()*b.scale;0>=c&&(c=1);var e=this.xs,d=e.width,e=e.height,g=this.Na,h=g.width,g=g.height,k=Math.ceil(h/d),l=Math.ceil(g/e),m=this.Kz;a.save();a.beginPath();a.rect(0,0,h,g);a.clip();for(var n=[],p=this.za.p,q=this.za.length,r=0;rd*u*c))break}else for(L=G=Math.floor(-m.y/e);L<=G+l&&!(M=L*e+m.y,0<=M&&M<=g&&jl(L,u,s)&&(x&&!F?Ij(a,0,M,h,M,E,r.Tc):(a.moveTo(0,M),a.lineTo(h,M)),2>e*u*c));L++);a.stroke();x&&(void 0!==a.setLineDash?(a.setLineDash(t.Jh),a.lineDashOffset=0):void 0!==a.webkitLineDash?(a.webkitLineDash=t.Jh,a.webkitLineDashOffset=0):void 0!==a.mozDash&&(a.mozDash=null,a.mozDashOffset=0))}a.restore();Th(b,a,!1)}else{this.Z===kk&&(a.lineCap="butt",kl(this,a,!0,this.Sc,!0),kl(this, +a,!1,this.Nc,!0),ll(this,a,!0,this.Sc),ll(this,a,!1,this.Nc),kl(this,a,!0,this.Sc,!1),kl(this,a,!1,this.Nc,!1));F=this.za.length;for(e=0;e +h.height&&(m-=r-h.height):r>h.width&&(m-=r-h.width);g=g.position+m/2;b.lineWidth=m;r=a.padding;c?(g+=r.top,m=r.left,r=h.width-r.right,n&&!q?Ij(b,m,g,r,g,p,0):(b.moveTo(m,g),b.lineTo(r,g))):(g+=r.left,m=r.top,r=h.height-r.bottom,n&&!q?Ij(b,g,m,g,r,p,0):(b.moveTo(g,m),b.lineTo(g,r)));b.stroke();n&&(void 0!==b.setLineDash?(b.setLineDash(t.Jh),b.lineDashOffset=0):void 0!==b.webkitLineDash?(b.webkitLineDash=t.Jh,b.webkitLineDashOffset=0):void 0!==b.mozDash&&(b.mozDash=null,b.mozDashOffset=0))}}} +function kl(a,b,c,d,e){for(var g=d.length,h,k=a.ua,l=0;lm)){var n=ml(h),p=h.Lm;isNaN(p)&&(p=c?a.Xg:a.Wg);var q=h.Km;null===q&&(q=c?a.Rh:a.Vg);null===q&&(p=0);n-=p;p=h.position+p;n+=h.Rb;p+n>m&&(n=m-p);0>=n||(m=a.padding,ak(a,b,h.background,!0),c?b.fillRect(m.left,p+m.top,k.width-(m.left+m.right),n):b.fillRect(p+m.left,m.top,n,k.height-(m.top+m.bottom)))}}} +function jl(a,b,c){if(0!==a%b)return!1;b=c.length;for(var d=0;dGc&&(mc=Gc),ql(ga,ga.Rb+mc),Gc=Math.max(Gc-mc,0));1!==na.Ti||!qh&&Od!==Qg&&Od!==Ej||(ga=this.fe(rc),mc=Math.max(Qe-ga.Rb,0),mc>wc&&(mc=wc),ql(ga,ga.Rb+mc),wc=Math.max(wc-mc,0));dg&&ik(na)}}}t.xa(ph);for(var ee=0,fe=0,tb=this.Av,ja=0;ja=this.tw);hc++)ga=this.ge(na.ac+hc),Qd.height+=Math.max(ga.Ah,isNaN(ga.wf)?ga.jf:Math.min(ga.wf,ga.jf));for(hc=1;hc=this.Av);hc++)ga=this.fe(na.column+hc),Qd.width+=Math.max(ga.Ah,isNaN(ga.wf)?ga.jf:Math.min(ga.wf,ga.jf));yb.width+=Qd.width;yb.height+=Qd.height;Rb=na.margin;Lf=Rb.right+Rb.left;Mf=Rb.top+Rb.bottom;mh(na,yb.width,yb.height,lf,bb);for(var te=na.Ba,Qe=Math.max(te.width+Lf,0),Re=Math.max(te.height+Mf,0),Dg=0,hc=0;hcsc&&(ql(ga,Math.min(ga.jf,sc+Rd)),ga.Ab!==sc&&(Rd-=ga.Ab-sc));if(-1===ga.index-1)break;ga=this.ge(ga.index-1)}for(var Se=0,hc=0;hcsc&&(ql(ga,Math.min(ga.jf,sc+Rd)),ga.Ab!==sc&&(Rd-=ga.Ab-sc));if(-1===ga.index-1)break;ga=this.fe(ga.index-1)}}t.xa(zg);t.Qj(Qd);t.Qj(yb);for(var of=0,he=0,Od=Nj(this),Eg= +this.ya,eg=this.Ce,Hc=fe=ee=0,ie=0,tb=this.Av,ja=0;jash)mh(Sb, +Infinity,Infinity),Sd=Sb.Ba,ue.$j(Sd),this.Lh.add(Sd);else{var Pf=Sb.nf,so=Sb.bt,hl=Sb.Dj;hl.jd()&&(hl=Fb);var rj=Sb.ct,oq=Sb.zA,ki,li,sj=0;if(Pf<-sh||Pf>=sh){var to=oj.qE,tj=oj.pE;rj!==sg&&(sj=oj.computeAngle(Sb,rj,tj),Sb.angle=sj);ki=to.x-Ue.x;li=to.y-Ue.y}else{var pf,uh;if(0<=Pf)pf=ji.p[Pf],uh=Pfc||q>d)this.Y(),mh(this,p>c?c:p,q>d?d:q);break;case Ic:Oj(this,!0);mh(this,c+s,d+u,0,0);break;case Fj:Oj(this,!0);mh(this,c+s,q+u,0,0);break;case Ej:Oj(this,!0),mh(this,p+s,d+u,0,0)}}l=this.ua;l.x=a;l.y= +b;l.width=c;l.height=d;var x=this.Z.Mb;switch(x){case "Position":for(var E=e.x-this.padding.left,F=e.y-this.padding.top,G=0;G=this.tw);ja++){var na=this.ge(Bb+ja);Cb.height+=na.total}for(ja=1;ja=this.Av);ja++){var hj=this.fe(Dd+ja);Cb.width+=hj.total}var yg=fc.Ab+Cb.width,rc=Cd.Ab+Cb.height;k.x=be;k.y=Bc;k.width=yg;k.height=rc;Bc+rc>e.height&&(rc=Math.max(e.height- +Bc,0));be+yg>e.width&&(yg=Math.max(e.width-be,0));var oh=be,gc=Bc,ph=yg,zg=rc,Dc=bb.alignment,Ec,Fc,wc,Gc;if(Dc.zc()){Dc=this.Kj;Dc.kd()||(Dc=Fb);Ec=Dc.x;Fc=Dc.y;wc=Dc.offsetX;Gc=Dc.offsetY;var Kf=fc.alignment,ga=Cd.alignment;Kf.kd()&&(Ec=Kf.x,wc=Kf.offsetX);ga.kd()&&(Fc=ga.y,Gc=ga.offsetY)}else Ec=Dc.x,Fc=Dc.y,wc=Dc.offsetX,Gc=Dc.offsetY;if(isNaN(Ec)||isNaN(Fc))Fc=Ec=0.5,Gc=wc=0;var Nd=ce.width,Ed=ce.height,ij=bb.Ce,jj=bb.Te,Nd=Math.min(ij.width,Nd),Ed=Math.min(ij.height,Ed),Nd=Math.max(jj.width, +Nd),Ed=Math.max(jj.height,Ed),mc=bb.margin,lb=mc.left+mc.right,mb=mc.top+mc.bottom,Ag=lk(bb,Cd,fc);if(isNaN(bb.ya.width)&&isNaN(fc.width)&&Ag===Ic||Ag===Fj)Nd=Math.max(yg-lb,0);if(isNaN(bb.ya.height)&&isNaN(Cd.height)&&Ag===Ic||Ag===Ej)Ed=Math.max(rc-mb,0);var fl=Ed+mb;k.x+=k.width*Ec-(Nd+lb)*Ec+wc+mc.left;k.y+=k.height*Fc-fl*Fc+Gc+mc.top;bb.visible&&(eb(oh,gc,ph,zg,k.x,k.y,Nd,Ed)?bb.xc(k.x,k.y,Nd,Ed):bb.xc(k.x,k.y,Nd,Ed,new w(oh,gc,ph,zg)))}}}}t.Qj(Cb);for(Bb=0;Bb=rh){var Dg=this.qE,Rd=this.pE;ge!==sg&&(hc= +this.computeAngle(ld,ge,Rd),ld.angle=hc);nf=Dg.x;Qd=Dg.y}else{var sc=void 0,Se=void 0;if(0<=Pd)sc=Bg.p[Pd],Se=Pdn.width||m.y>n.height||0>m.x+m.width||0>m.y+m.height)){m=t.Og();m.set(h);if(l instanceof y?l.Pj(a,b,c,d,e,m):Mj(l,a,d,m))null!==b&&(l=b(l)),l&& +(null===c||c(l))&&e.add(l);t.Ne(m)}}}void 0===g&&t.Ne(h);return d}void 0===g&&t.Ne(h);return!1};function Bl(a,b,c,d){for(var e=a.za.length;e--;){var g=a.za.p[e];if(g.visible){var h=g.ua,k=a.Na;h.x>k.width||h.y>k.height||0>h.x+h.width||0>h.y+h.height||(g instanceof y&&Bl(g,b,c,d),null!==b&&(g=b(g)),g&&(null===c||c(g))&&d.add(g))}}} +aa.vm=function(a,b,c,d,e,g){if(!1===this.mf)return!1;void 0===c&&(c=null);void 0===d&&(d=null);var h=this.Na,k=this.og(),l=k?a:Oa(t.cc(a.x,a.y),this.transform),m=k?b:Oa(t.cc(b.x,b.y),this.transform),n=l.Mj(m),p=0r.width||q.y>r.height||0>q.x+q.width||0>q.y+q.height||(n.og()?(q=n.transform,Oa(k.set(a),q),Oa(l.set(b),q)):(k.set(a),l.set(b)),n instanceof y?!n.vm(k,l,c,d,e,g):!n.tD(k,l,e))||(null!==c&&(n=c(n)),n&&(null===d||d(n))&&g.add(n))}t.B(k);t.B(l)}return e?p:h}return!1}; +function nl(a){var b=a.G;if(void 0===b||b===vb)b=null;null===b&&a instanceof Y&&(a=a.La,null!==a&&(b=a.G));null===b&&(b=wb);return b}function ol(a){var b=a.H;if(void 0===b||b===vb)b=null;null===b&&a instanceof Y&&(a=a.La,null!==a&&(b=a.H));null===b&&(b=Ob);return b}y.prototype.add=y.prototype.add=function(a){t.k(a,Q,y,"add:element");this.td(this.za.count,a)};y.prototype.elt=y.prototype.ta=function(a){return this.za.ta(a)}; +y.prototype.insertAt=y.prototype.td=function(a,b){b instanceof B&&t.l("Cannot add a Part to a Panel: "+b);if(this===b||this.Ei(b))this===b&&t.l("Cannot make a Panel contain itself: "+this.toString()),t.l("Cannot make a Panel indirectly contain itself: "+this.toString()+" already contains "+b.toString());var c=b.fa;null!==c&&c!==this&&t.l("Cannot add a GraphObject that already belongs to another Panel to this Panel: "+b.toString()+", already contained by "+c.toString()+", cannot be shared by this Panel: "+ +this.toString());this.Z!==Vh||b instanceof Y||t.l("Can only add Shapes to a Grid Panel, not: "+b);b.hl(this);b.Sl=null;if(null!==this.Xz){var d=b.data;null!==d&&"object"===typeof d&&(null===this.Of&&(this.Of=new ia(Object,y)),this.Of.add(d,b))}var e=this.za,d=-1;if(c===this){for(var g=-1,h=e.count,k=0;k=e.count&&a>=e.count)return;e.Zc(g);d=g}else t.l("element "+b.toString()+" has panel "+c.toString()+" but is not contained by it.")}if(0>a|| +a>e.count)a=e.count;e.td(a,b);this.Y();b.Y();null!==b.md&&(this.cj=!0);b instanceof y&&!0===b.cj&&(this.cj=!0);c=this.Q;null!==c&&(c.nj=null,c.lj=NaN,null!==b.md&&c instanceof S&&(c.cj=!0),e=this.h,null!==e&&e.va.kb||(-1!==d&&c.Mc(ud,"elements",this,b,null,d,null),c.Mc(td,"elements",this,null,b,null,a)))};y.prototype.remove=y.prototype.remove=function(a){t.k(a,Q,y,"remove:element");for(var b=this.za,c=b.count,d=-1,e=0;ea&&t.ia(a,">= 0",y,"getRowDefinition:idx");a=Math.round(a);var b=this.Sc;if(void 0===b[a]){var c=new Ak;c.hl(this);c.Fl=!0;c.oe=a;b[a]=c}return b[a]};y.prototype.removeRowDefinition=function(a){if(void 0!==this.Sc){f&&t.o(a,y,"removeRowDefinition:idx");0>a&&t.ia(a,">= 0",y,"removeRowDefinition:idx");a=Math.round(a);var b=this.Sc;b[a]&&(b[a]=void 0)}}; +t.A(y,{Av:"columnCount"},function(){return void 0===this.Nc?0:this.Nc.length});y.prototype.getColumnDefinition=y.prototype.fe=function(a){if(void 0===this.Nc)return null;f&&t.o(a,y,"getColumnDefinition:idx");0>a&&t.ia(a,">= 0",y,"getColumnDefinition:idx");a=Math.round(a);var b=this.Nc;if(void 0===b[a]){var c=new Ak;c.hl(this);c.Fl=!1;c.oe=a;b[a]=c}return b[a]}; +y.prototype.removeColumnDefinition=function(a){if(void 0!==this.Nc){f&&t.o(a,y,"removeColumnDefinition:idx");0>a&&t.ia(a,">= 0",y,"removeColumnDefinition:idx");a=Math.round(a);var b=this.Nc;b[a]&&(b[a]=void 0)}};t.g(y,"rowSizing",y.prototype.UE); +t.defineProperty(y,{UE:"rowSizing"},function(){return void 0===this.Xl?el:this.Xl},function(a){if(void 0!==this.Xl){var b=this.Xl;b!==a&&(a!==el&&a!==sl&&t.l("rowSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.Xl=a,this.Y(),this.i("rowSizing",b,a))}});t.g(y,"columnSizing",y.prototype.SC); +t.defineProperty(y,{SC:"columnSizing"},function(){return void 0===this.tl?el:this.tl},function(a){if(void 0!==this.tl){var b=this.tl;b!==a&&(a!==el&&a!==sl&&t.l("columnSizing must be RowColumnDefinition.ProportionalExtra or RowColumnDefinition.None"),this.tl=a,this.Y(),this.i("columnSizing",b,a))}});t.g(y,"topIndex",y.prototype.JI); +t.defineProperty(y,{JI:"topIndex"},function(){return void 0===this.mi?0:this.mi},function(a){if(void 0!==this.mi){var b=this.mi;b!==a&&((!isFinite(a)||0>a)&&t.l("topIndex must be greater than zero and a real number. Was "+a),this.mi=a,this.Y(),this.i("topIndex",b,a))}});t.g(y,"leftIndex",y.prototype.YH); +t.defineProperty(y,{YH:"leftIndex"},function(){return void 0===this.Xh?0:this.Xh},function(a){if(void 0!==this.Xh){var b=this.Xh;b!==a&&((!isFinite(a)||0>a)&&t.l("leftIndex must be greater than zero and a real number. Was "+a),this.Xh=a,this.Y(),this.i("leftIndex",b,a))}});y.prototype.findRowForLocalY=function(a){if(0>a)return-1;if(this.type!==kk)return NaN;for(var b=0,c=this.Sc,d=c.length,e=this.mi;ea)return-1;if(this.type!==kk)return NaN;for(var b=0,c=this.Nc,d=c.length,e=this.Xh;ea;)this.Oe(a);a=this.Xz;if(null!==a)for(var b=t.wb(a),c=0;ca||1a&&t.ia(a,">= 0",Ak,"height"),this.wf=a,ql(this,this.Ab),this.Ec("size",b,a))});t.g(Ak,"width",Ak.prototype.width);t.defineProperty(Ak,{width:"width"},function(){return this.wf},function(a){var b=this.wf;b!==a&&(f&&t.j(a,"number",Ak,"width"),0>a&&t.ia(a,">= 0",Ak,"width"),this.wf=a,ql(this,this.Ab),this.Ec("size",b,a))});t.g(Ak,"minimum",Ak.prototype.Ah); +t.defineProperty(Ak,{Ah:"minimum"},function(){return this.Nl},function(a){var b=this.Nl;b!==a&&(f&&t.j(a,"number",Ak,"minimum"),(0>a||!isFinite(a))&&t.ia(a,">= 0",Ak,"minimum"),this.Nl=a,ql(this,this.Ab),this.Ec("minimum",b,a))});t.g(Ak,"maximum",Ak.prototype.jf);t.defineProperty(Ak,{jf:"maximum"},function(){return this.Ml},function(a){var b=this.Ml;b!==a&&(f&&t.j(a,"number",Ak,"maximum"),0>a&&t.ia(a,">= 0",Ak,"maximum"),this.Ml=a,ql(this,this.Ab),this.Ec("maximum",b,a))});t.g(Ak,"alignment",Ak.prototype.alignment); +t.defineProperty(Ak,{alignment:"alignment"},function(){return this.me},function(a){var b=this.me;b.K(a)||(f&&t.k(a,H,Ak,"alignment"),this.me=a.W(),this.Ec("alignment",b,a))});t.g(Ak,"stretch",Ak.prototype.Eh);t.defineProperty(Ak,{Eh:"stretch"},function(){return this.nh},function(a){var b=this.nh;b!==a&&(f&&t.nb(a,Q,Ak,"stretch"),this.nh=a,this.Ec("stretch",b,a))});t.g(Ak,"separatorPadding",Ak.prototype.AA); +t.defineProperty(Ak,{AA:"separatorPadding"},function(){return this.wj},function(a){"number"===typeof a?a=new Va(a):null!==a&&f&&t.k(a,Va,Ak,"separatorPadding");var b=this.wj;null!==a&&null!==b&&b.K(a)||(null!==a&&(a=a.W()),this.wj=a,this.Ec("separatorPadding",b,a))});t.g(Ak,"separatorStroke",Ak.prototype.Km); +t.defineProperty(Ak,{Km:"separatorStroke"},function(){return this.Gr},function(a){var b=this.Gr;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Gr=a,this.fa&&this.fa.na(),this.Ec("separatorStroke",b,a))});t.g(Ak,"separatorStrokeWidth",Ak.prototype.Lm);t.defineProperty(Ak,{Lm:"separatorStrokeWidth"},function(){return this.Hr},function(a){var b=this.Hr;b!==a&&(this.Hr=a,this.fa&&this.fa.na(),this.Ec("separatorStrokeWidth",b,a))}); +t.g(Ak,"separatorDashArray",Ak.prototype.aF);t.defineProperty(Ak,{aF:"separatorDashArray"},function(){return this.jh},function(a){var b=this.jh;b!==a&&(Array.isArray(a)||t.Nb(a,"Array",Ak,"separatorDashArray:val"),this.jh=a,this.fa&&this.fa.na(),this.Ec("separatorDashArray",b,a))});t.g(Ak,"background",Ak.prototype.background); +t.defineProperty(Ak,{background:"background"},function(){return this.Bb},function(a){var b=this.Bb;b!==a&&(null===a||"string"===typeof a||a instanceof Ud)&&(a instanceof Ud&&a.freeze(),this.Bb=a,this.fa&&this.fa.na(),this.Ec("background",b,a))});t.g(Ak,"coversSeparators",Ak.prototype.Fv);t.defineProperty(Ak,{Fv:"coversSeparators"},function(){return this.Zp},function(a){var b=this.Zp;b!==a&&(t.j(a,"boolean",Ak,"coversSeparators"),this.Zp=a,this.Ec("coversSeparators",b,a))});t.g(Ak,"sizing",Ak.prototype.gt); +t.defineProperty(Ak,{gt:"sizing"},function(){return this.Jr},function(a){var b=this.Jr;b!==a&&(f&&t.nb(a,Ak,Ak,"sizing"),this.Jr=a,this.Ec("sizing",b,a))});function rl(a){if(a.gt===Dl){var b=a.fi;return a.xh?b.UE:b.SC}return a.gt}t.A(Ak,{Rb:"actual"},function(){return this.Ab});t.A(Ak,{total:"total"},function(){return this.Ab+ml(this)});t.A(Ak,{position:"position"},function(){return this.sb}); +Ak.prototype.bind=Ak.prototype.bind=function(a){a.Sf=this;var b=this.fa;null!==b&&(b=b.Bo(),null!==b&&uk(b)&&t.l("Cannot add a Binding to a RowColumnDefinition that is already frozen: "+a));null===this.vc&&(this.vc=new A(ze));this.vc.add(a)}; +function Y(){Q.call(this);this.La=null;this.pn="None";this.Cg=!1;this.qq=Rg;this.nk=null;this.tb=this.Cc="black";this.Dg=1;this.Vn="butt";this.Wn="miter";this.cm=10;this.bm=null;this.Tc=0;this.ki=this.ji=vb;this.ir=this.hr=0;this.vq=!1;this.Aq=!0;this.kr=null;this.rn=this.Yn="None";this.uq=1}t.ea("Shape",Y);t.Ja(Y,Q); +Y.prototype.cloneProtected=function(a){Q.prototype.cloneProtected.call(this,a);a.La=this.La;a.pn=this.pn;a.Cg=this.Cg;a.qq=this.qq;a.nk=this.nk;a.Cc=this.Cc;a.tb=this.tb;a.Dg=this.Dg;a.Vn=this.Vn;a.Wn=this.Wn;a.cm=this.cm;a.bm=null;this.bm&&(a.bm=this.bm.slice(0));a.Tc=this.Tc;a.ji=this.ji.W();a.ki=this.ki.W();a.hr=this.hr;a.ir=this.ir;a.vq=this.vq;a.Aq=this.Aq;a.kr=this.kr;a.Yn=this.Yn;a.rn=this.rn;a.uq=this.uq}; +Y.prototype.toString=function(){return"Shape("+("None"!==this.Db?this.Db:"None"!==this.Om?this.Om:this.Sv)+")#"+t.jc(this)}; +function El(a,b,c,d){var e=0.001,g=d.Ba,h=g.width,g=g.height,k,l,m,n=c.length;if(!(2>n)){k=c[0][0];l=c[0][1];for(var p,q,r,s,u=0,x=t.yb(),E=1;Eu){t.xa(x);return}e>r?(F=e-r,e=r):F=0;var G=Math.sqrt(e* +e/(1+q*q));0>p&&(G=-G);k+=G;l+=q*G;a.translate(k,l);a.rotate(s);a.translate(-(h/2),-(g/2));0===F&&d.Vk(a,b);a.translate(h/2,g/2);a.rotate(-s);a.translate(-k,-l);u-=e;r-=e;if(0!==F){m++;if(m===x.length){t.xa(x);return}r=x[m];p=r[0];s=r[1];q=r[2];r=r[3];e=F}}t.xa(x)}} +Y.prototype.Vk=function(a,b){if(null!==this.tb||null!==this.Cc){null!==this.Cc&&ak(this,a,this.Cc,!0);null!==this.tb&&ak(this,a,this.tb,!1);var c=this.Dg;if(0===c){var d=this.Q;d instanceof Fe&&d.type===pg&&d.Gc instanceof Y&&(c=d.Gc.bb)}a.lineWidth=c;a.lineJoin=this.Wn;a.lineCap=this.Vn;a.miterLimit=this.cm;var e=!1;this.Q&&(e=this.Q.Gi);var g=!0;null!==this.tb&&null===this.Cc&&(g=!1);var d=!1,h=this.Bw;if(null!==h){var k=d=!0;void 0!==a.setLineDash?(a.setLineDash(h),a.lineDashOffset=this.Tc):void 0!== +a.webkitLineDash?(a.webkitLineDash=h,a.webkitLineDashOffset=this.Tc):void 0!==a.mozDash?(a.mozDash=h,a.mozDashOffset=this.Tc):k=!1}var l=this.La;if(null!==l){if(l.Z===Jc)a.beginPath(),d&&!k?Ij(a,l.Yb,l.ic,l.dd,l.qd,h,this.Tc):(a.moveTo(l.Yb,l.ic),a.lineTo(l.dd,l.qd)),null!==this.Cc&&bk(a,this.Cc,!0),0!==c&&null!==this.tb&&bk(a,this.tb,!1);else if(l.Z===Kc){var m=l.Yb,n=l.ic,p=l.dd,l=l.qd,q=Math.min(m,p),r=Math.min(n,l),m=Math.abs(p-m),n=Math.abs(l-n);null!==this.Cc&&(this.Cc instanceof Ud&&this.Cc.type=== +Yd?(a.beginPath(),a.rect(q,r,m,n),bk(a,this.Cc,!0)):a.fillRect(q,r,m,n));if(null!==this.tb){if(g&&e){var s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur];a.shadowOffsetX=0;a.shadowOffsetY=0;a.shadowBlur=0}d&&!k?(k=[[q,r],[q+m,r],[q+m,r+n],[q,r+n],[q,r]],a.beginPath(),Fl(a,k,h,this.Tc),bk(a,this.tb,!1)):0!==c&&(this.tb instanceof Ud&&this.tb.type===Yd?(a.beginPath(),a.rect(q,r,m,n),bk(a,this.tb,!1)):a.strokeRect(q,r,m,n));g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2])}}else if(l.Z=== +Lc)m=l.Yb,n=l.ic,p=l.dd,l=l.qd,q=Math.abs(p-m)/2,r=Math.abs(l-n)/2,m=Math.min(m,p)+q,n=Math.min(n,l)+r,a.beginPath(),a.moveTo(m,n-r),a.bezierCurveTo(m+D.sa*q,n-r,m+q,n-D.sa*r,m+q,n),a.bezierCurveTo(m+q,n+D.sa*r,m+D.sa*q,n+r,m,n+r),a.bezierCurveTo(m-D.sa*q,n+r,m-q,n+D.sa*r,m-q,n),a.bezierCurveTo(m-q,n-D.sa*r,m-D.sa*q,n-r,m,n-r),a.closePath(),null!==this.Cc&&bk(a,this.Cc,!0),d&&!k&&(k=t.yb(),D.ue(m,n-r,m+D.sa*q,n-r,m+q,n-D.sa*r,m+q,n,0.5,k),D.ue(m+q,n,m+q,n+D.sa*r,m+D.sa*q,n+r,m,n+r,0.5,k),D.ue(m,n+ +r,m-D.sa*q,n+r,m-q,n+D.sa*r,m-q,n,0.5,k),D.ue(m-q,n,m-q,n-D.sa*r,m-D.sa*q,n-r,m,n-r,0.5,k),a.beginPath(),Fl(a,k,h,this.Tc),t.xa(k)),0!==c&&null!==this.tb&&(g&&e&&(s=[a.shadowOffsetX,a.shadowOffsetY,a.shadowBlur],a.shadowOffsetX=0,a.shadowOffsetY=0,a.shadowBlur=0),bk(a,this.tb,!1),g&&e&&(a.shadowOffsetX=s[0],a.shadowOffsetY=s[1],a.shadowBlur=s[2]));else if(l.Z===zc){for(var q=l.rk,r=q.length,u=0;uM.Fh);else for(var G=ed(M,x),W=G.length,T=0;Tm))if(h=b[0][0],k=b[0][1],2===m)Ij(a,h,k,b[1][0],b[1][1],c,d);else{a.moveTo(h,k);for(var n,p,q,r=0,s=t.yb(),u=1;ur&&(e=r);e>q?(x=e-q,e=q):x=0;var E=Math.sqrt(e*e/(1+p*p));0>n&&(E= +-E);h+=E;k+=p*E;m?a.lineTo(h,k):a.moveTo(h,k);r-=e;q-=e;if(0!==x){l++;if(l===s.length){t.xa(s);return}q=s[l];n=q[0];p=q[1];q=q[2];e=x}else m=!m}t.xa(s)}}Y.prototype.getDocumentPoint=Y.prototype.$a=function(a,b){void 0===b&&(b=new v);a.jd()&&t.l("Spot must be real");var c=this.Na,d=this.bb;b.q(a.x*(c.width+d)-d/2+c.x+a.offsetX,a.y*(c.height+d)-d/2+c.y+a.offsetY);this.$d.Qa(b);return b}; +Y.prototype.Hj=function(a,b){var c=this.La;if(null===c||null===this.fill&&null===this.stroke)return!1;var d=c.Gb,e=this.bb/2;c.type!==Jc||b||(e+=2);var g=t.qf();g.assign(d);g.Hg(e+2,e+2);if(!g.Da(a))return t.Ic(g),!1;d=e+1E-4;if(c.type===Jc){if(null===this.stroke)return!1;g=(c.D-c.la)*(a.x-c.la)+(c.F-c.ma)*(a.y-c.ma);return 0>(c.la-c.D)*(a.x-c.D)+(c.ma-c.F)*(a.y-c.F)||0>g?!1:D.vd(c.la,c.ma,c.D,c.F,e,a.x,a.y)}if(c.type===Kc){var h=c.la,k=c.ma,l=c.D,m=c.F,c=Math.min(h,l),n=Math.min(k,m),h=Math.abs(l- +h),k=Math.abs(m-k);g.x=c;g.y=n;g.width=h;g.height=k;if(null===this.fill){g.Hg(-d,-d);if(g.Da(a))return!1;g.Hg(d,d)}null!==this.stroke&&g.Hg(e,e);e=g.Da(a);t.Ic(g);return e}if(c.type===Lc){h=c.la;k=c.ma;l=c.D;m=c.F;c=Math.min(h,l);n=Math.min(k,m);h=Math.abs(l-h);k=Math.abs(m-k);g=h/2;k/=2;c=a.x-(c+g);n=a.y-(n+k);if(null===this.fill){g-=d;k-=d;if(0>=g||0>=k||1>=c*c/(g*g)+n*n/(k*k))return!1;g+=d;k+=d}null!==this.stroke&&(g+=e,k+=e);return 0>=g||0>=k?!1:1>=c*c/(g*g)+n*n/(k*k)}if(c.type===zc)return null=== +this.fill?nd(c,a.x,a.y,e):c.Da(a,e,1=this.bb)n=D.Mg(p.Yb,p.ic,p.dd,p.qd,g,h,k,l,e);else{var r,s;p.Yb===p.dd?(r=m,s=0):(b=(p.qd-p.ic)/(p.dd-p.Yb),s=m/Math.sqrt(1+b*b),r=s*b);d=t.yb();b=new v;D.Mg(p.Yb+ +r,p.ic+s,p.dd+r,p.qd+s,g,h,k,l,b)&&d.push(b);b=new v;D.Mg(p.Yb-r,p.ic-s,p.dd-r,p.qd-s,g,h,k,l,b)&&d.push(b);b=new v;D.Mg(p.Yb+r,p.ic+s,p.Yb-r,p.ic-s,g,h,k,l,b)&&d.push(b);b=new v;D.Mg(p.dd+r,p.qd+s,p.dd-r,p.qd-s,g,h,k,l,b)&&d.push(b);b=d.length;if(0===b)return t.xa(d),!1;n=!0;s=Infinity;for(r=0;rMath.abs(c)){n=h-b-c*(g-d);if(0>a*a*c*c+x*x-n*n){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(a*a*c*c+x*x-n*n);k=(-(a*a*c*n)+a*x*m)/(x*x+a*a*c*c)+d;a=(-(a*a*c*n)-a*x*m)/(x*x+a*a*c*c)+d;l=c*(k-d)+n+b;b=c*(a-d)+n+b;d=Math.abs((g-k)*(g-k))+Math.abs((h-l)*(h-l));h=Math.abs((g-a)*(g-a))+Math.abs((h-b)* +(h-b));dk){e.x=NaN;e.y=NaN;n=!1;break a}m=Math.sqrt(k);l=b+m;b-=m;d=Math.abs(l-h);h=Math.abs(b-h);dc?a-c:c-a)<(b>d?b-d:d-b)?(e=be||D.Fa(l.y,e))&&(l.ye||D.Fa(l.x,e))&&(l.x=h&&d<=a}a=h&&c<=a} +Y.prototype.tD=function(a,b,c){function d(a,b){for(var c=a.length,d=0;de)return!0}return!1}if(c&&null!==this.fill&&this.Hj(a,!0))return!0;var e=a.Mj(b);b=e;1.5=e||Qa(b,g,0,-p)>=e||Qa(b,g,0,p)>=e||Qa(b,g,n,0)>=e?!1: +!0}else if(g.type===zc){h=g.Gb;k=h.x;l=h.y;m=h.x+h.width;h=h.y+h.height;if(a.x>m&&a.xh&&a.ye&&Pa(a.x,a.y,k,l,m,l)>e&&Pa(a.x,a.y,m,h,k,h)>e&&Pa(a.x,a.y,m,h,m,l)>e)return!1;b=Math.sqrt(e);if(c){if(null===this.fill?nd(g,a.x,a.y,b):g.Da(a,b,!0))return!0}else{c=g.ob;for(b=0;be)return!1;l=k.Ca.p;m=l.length;for(h=0;he)return!1;break;case ad:g=t.yb(); +D.ue(n,p,q.pb,q.Fb,q.je,q.ke,q.D,q.F,0.8,g);n=d(g,a);t.xa(g);if(n)return!1;n=q.D;p=q.F;if(a.ps(n,p)>e)return!1;break;case bd:g=t.yb();D.hp(n,p,q.pb,q.Fb,q.D,q.F,0.8,g);n=d(g,a);t.xa(g);if(n)return!1;n=q.D;p=q.F;if(a.ps(n,p)>e)return!1;break;case cd:case dd:var q=q.type===cd?ed(q,k):kd(q,k,n,p),r=q.length,s=null,g=t.yb();for(b=0;b= 0",Y,"strokeWidth:val")});t.g(Y,"strokeCap",Y.prototype.lF); +t.defineProperty(Y,{lF:"strokeCap"},function(){return this.Vn},function(a){var b=this.Vn;b!==a&&("string"!==typeof a||"butt"!==a&&"round"!==a&&"square"!==a?t.ia(a,'"butt", "round", or "square"',Y,"strokeCap"):(this.Vn=a,this.na(),this.i("strokeCap",b,a)))});t.g(Y,"strokeJoin",Y.prototype.CI); +t.defineProperty(Y,{CI:"strokeJoin"},function(){return this.Wn},function(a){var b=this.Wn;b!==a&&("string"!==typeof a||"miter"!==a&&"bevel"!==a&&"round"!==a?t.ia(a,'"miter", "bevel", or "round"',Y,"strokeJoin"):(this.Wn=a,this.na(),this.i("strokeJoin",b,a)))});t.g(Y,"strokeMiterLimit",Y.prototype.DI); +t.defineProperty(Y,{DI:"strokeMiterLimit"},function(){return this.cm},function(a){var b=this.cm;if(b!==a)if(f&&t.o(a,Y,"strokeMiterLimit"),0 0",Y,"strokeWidth:val")});t.g(Y,"strokeDashArray",Y.prototype.Bw); +t.defineProperty(Y,{Bw:"strokeDashArray"},function(){return this.bm},function(a){var b=this.bm;if(b!==a){null===a||Array.isArray(a)||t.Nb(a,"Array",Y,"strokeDashArray:val");if(null!==a)for(var c=a.length,d=0;de||!isFinite(e))&&t.l("strokeDashArray:val "+e+" is a negative number or not a real number.")}this.bm=a;this.na();this.i("strokeDashArray",b,a)}});t.g(Y,"strokeDashOffset",Y.prototype.mF); +t.defineProperty(Y,{mF:"strokeDashOffset"},function(){return this.Tc},function(a){var b=this.Tc;b!==a&&(f&&t.o(a,Y,"strokeDashOffset"),0<=a&&(this.Tc=a,this.na(),this.i("strokeDashOffset",b,a)))});t.g(Y,"figure",Y.prototype.Db); +t.defineProperty(Y,{Db:"figure"},function(){return this.pn},function(a){var b=this.pn;if(b!==a){f&&t.j(a,"string",Y,"figure");var c=D.Bi[a];"function"===typeof c?c=a:(c=D.Bi[a.toLowerCase()])||t.l("Unknown Shape.figure: "+a);if(b!==c){if(a=this.Q)a.lj=NaN;this.pn=c;this.Cg=!1;this.Cf();this.i("figure",b,c)}}});t.g(Y,"toArrow",Y.prototype.Om); +t.defineProperty(Y,{Om:"toArrow"},function(){return this.Yn},function(a){var b=this.Yn;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"toArrow");var c=D.yo(a);c instanceof I?c=a:(c=D.yo(a.toLowerCase()))||t.l("Unknown Shape.toArrow: "+a);b!==c&&(this.Yn=c,this.Cg=!1,this.Cf(),Jl(this,c),this.i("toArrow",b,c))}});t.g(Y,"fromArrow",Y.prototype.Sv); +t.defineProperty(Y,{Sv:"fromArrow"},function(){return this.rn},function(a){var b=this.rn;!0===a?a="Standard":!1===a&&(a="None");if(b!==a){f&&t.j(a,"string",Y,"fromArrow");var c=D.yo(a);c instanceof I?c=a:(c=D.yo(a.toLowerCase()))||t.l("Unknown Shape.fromArrow: "+a);b!==c&&(this.rn=c,this.Cg=!1,this.Cf(),Jl(this,c),this.i("fromArrow",b,c))}}); +function Jl(a,b){var c=a.h;if(null===c||!c.va.kb){a.ct=Kl;c=Ub;switch(b){case "halfarrowtop":c=Ob;break;case "halftriangletop":c=Ob;break;case "openrighttriangletop":c=Ob;break;case "opentriangletop":c=Ob}"None"!==a.Yn?(a.nf=-1,a.Dj=c):"None"!==a.rn&&(a.nf=0,a.Dj=new H(1-c.x,c.y))}}t.defineProperty(Y,{G:"spot1"},function(){return this.ji},function(a){t.k(a,H,Y,"spot1");var b=this.ji;b.K(a)||(this.ji=a=a.W(),this.Y(),this.i("spot1",b,a))}); +t.defineProperty(Y,{H:"spot2"},function(){return this.ki},function(a){t.k(a,H,Y,"spot2");var b=this.ki;b.K(a)||(this.ki=a=a.W(),this.Y(),this.i("spot2",b,a))});t.defineProperty(Y,{tc:"parameter1"},function(){return this.hr},function(a){var b=this.hr;b!==a&&(this.hr=a,this.Y(),this.i("parameter1",b,a))});t.defineProperty(Y,{Vs:"parameter2"},function(){return this.ir},function(a){var b=this.ir;b!==a&&(this.ir=a,this.Y(),this.i("parameter2",b,a))}); +t.A(Y,{Na:"naturalBounds"},function(){if(null!==this.La)return this.Qc.assign(this.La.Gb),this.Qc;var a=this.ya;return new w(0,0,a.width,a.height)});t.g(Y,"isRectangular",Y.prototype.OH);t.defineProperty(Y,{OH:"isRectangular"},function(){return this.Aq},function(a){var b=this.Aq;b!==a&&(f&&t.j(a,"boolean",Y,"isRectangular"),this.Aq=a,this.Y(),this.i("isRectangular",b,a))});t.g(Y,"pathObject",Y.prototype.kA); +t.defineProperty(Y,{kA:"pathObject"},function(){return this.kr},function(a){var b=this.kr;b!==a&&(f&&t.k(a,Q,Y,"pathObject"),this.kr=a,this.na(),this.i("pathObject",b,a))});t.g(Y,"geometryStretch",Y.prototype.Tv);t.defineProperty(Y,{Tv:"geometryStretch"},function(){return this.qq},function(a){var b=this.qq;b!==a&&(t.nb(a,Q,Y,"geometryStretch"),this.qq=a,this.i("geometryStretch",b,a))});t.g(Y,"interval",Y.prototype.interval); +t.defineProperty(Y,{interval:"interval"},function(){return this.uq},function(a){var b=this.uq;f&&t.o(a,Y,"interval");a=Math.floor(a);b!==a&&0<=a&&(this.uq=a,this.h&&ni(this.h),this.Y(),this.i("interval",b,a))});function ma(){Q.call(this);this.Zd="";this.tb="black";this.Zg="13px sans-serif";this.Fd="start";this.xq=!0;this.Gl=this.Hl=!1;this.Nn=Ll;this.dm=Ml;this.pu=this.Jq=0;this.qn=this.ny=this.oy=null;this.Gn={};this.jq=!1;this.Ze=this.yj=this.Rr=null}t.ea("TextBlock",ma);t.Ja(ma,Q); +ma.prototype.cloneProtected=function(a){Q.prototype.cloneProtected.call(this,a);a.Zd=this.Zd;a.tb=this.tb;a.Zg=this.Zg;a.Fd=this.Fd;a.xq=this.xq;a.Hl=this.Hl;a.Gl=this.Gl;a.dm=this.dm;a.Nn=this.Nn;a.Jq=this.Jq;a.pu=this.pu;a.oy=this.oy;a.ny=this.ny;a.qn=this.qn;a.Gn=this.Gn;a.jq=this.jq;a.Rr=this.Rr;a.yj=this.yj;a.Ze=this.Ze};ma.prototype.toString=function(){return 22m*k*k&&(h=!0);m=e.pi.length;for(k=0;kc&&(n=c);var p=l,l=a,q=g,r=c,s=d,u=0;h?("start"===this.Fd||"left"===this.Fd?u=0:"end"===this.Fd||"right"===this.Fd? +u=r-n:"center"===this.Fd?u=(r-n)/2:t.l("textAlign must be start, end, left, right, or center"),l.fillRect(0+u,q+0.25*s,n,1)):("start"===this.Fd||"left"===this.Fd?u=0:"end"===this.Fd||"right"===this.Fd?u=r:"center"===this.Fd?u=r/2:t.l("textAlign must be start, end, left, right, or center"),l.fillText(p,0+u,q+s-0.25*s),p=s/20|0,this.Hl&&("end"===this.Fd||"right"===this.Fd?u-=n:"center"===this.Fd&&(u-=n/2),l.beginPath(),l.lineWidth=p,l.moveTo(0+u,q+s-0.2*s),l.lineTo(0+u+n,q+s-0.2*s),l.stroke()),this.Gl&& +(l.beginPath(),l.lineWidth=p,q=q+s-s/2.2|0,0!==p%2&&(q+=0.5),l.moveTo(0,q),l.lineTo(0+n,q),l.stroke()));g+=d}}}; +ma.prototype.Js=function(a,b,c,d){var e={},g=0,h=0;if(isNaN(this.ya.width)){g=this.Zd;if(0===g.length)g=0;else if(this.bw){for(var k=h=0,l=!1,m={Hh:0};!l;){var n=Sl(g,k,m);-1===n&&(n=g.length,l=!0);k=Tl(g.substr(k,n-k).replace(/^\s+|\s+$/g,""),this.Zg);k>h&&(h=k);k=m.Hh}g=h}else h=Sl(g,0,{}),0<=h&&(g=g.substr(0,h)),g=k=Tl(g,this.Zg);g=Math.min(g,a/this.scale);g=Math.max(8,g)}else g=this.ya.width;this.fa&&(g=Math.min(g,this.fa.Ce.width),g=Math.max(g,this.fa.Te.width));h=Rl(this,g,e);h=isNaN(this.ya.height)? +Math.min(h,b/this.scale):this.ya.height;if(this.SA===Ol||isNaN(this.ya.width))g=e.Ii,isNaN(this.ya.width)&&(g=Math.max(8,g));g=Math.max(c,g);h=Math.max(d,h);Sa(this.Qc,g,h);Kj(this,0,0,g,h);this.Gn=e};ma.prototype.Gj=function(a,b,c,d){Rj(this,a,b,c,d)}; +function Ql(a,b,c,d){b=b.replace(/^\s+|\s+$/g,"");void 0===c.Ii&&(c.Ii=0);void 0===c.pi&&(c.pi=[]);void 0===c.hm&&(c.hm=[]);var e=0,g,h,k=a.Zg;a.Nn===Pl?(t.rp!==k&&(t.qp.font=k,t.rp=k),g=0,void 0!==t.Fz[k]&&5E3>t.wD?g=t.Fz[k]:(g=t.qp.measureText(t.rD).width,t.Fz[k]=g,t.wD++)):g=0;var l=g;if(a.dm===Nl){c.Hh=1;g=Tl(b,k);if(0===l||g<=d)return c.Ii=g,c.pi.push(c.Ii),c.hm.push(b),new ea(g,nh(a));var m=Ul(b);b=b.substr(m.length);h=Ul(b);for(g=Tl(m+h,k);0d&&1d;){var n=1;g=Tl(m.substr(0,n),k);for(h=0;g<=d;)n++,h=g,g=Tl(m.substr(0,n),k);1===n?(c.pi[l]=g,e=Math.max(e,g)):(c.pi[l]=h,e=Math.max(e,h));n--;1>n&&(n=1);c.hm[l]=m.substr(0,n);l++; +m=m.substr(n)}h=Ul(b);for(g=Tl(m+h,k);0=b?a:a.substr(0,c)} +function Tl(a,b){t.rp!==b&&(t.qp.font=b,t.rp=b);return t.qp.measureText(a).width}function nh(a){if(null!==a.qn)return a.qn;var b=a.Zg;t.rp!==b&&(t.qp.font=b,t.rp=b);var c=0;void 0!==t.Gz[b]&&5E3>t.xD?c=t.Gz[b]:(c=1.3*t.qp.measureText("M").width,t.Gz[b]=c,t.xD++);return a.qn=c}function Sl(a,b,c){void 0===c.Hh&&(c.Hh=0);var d=a.indexOf("\r",b);-1===d&&(d=a.indexOf("\n",b));0<=d&&(c.Hh="\r"===a[d]&&d+1e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.2,0.22);b.H=new H(0.8,0.9);t.v(a);return b},DataTransmission:"Hexagon", +Hexagon:function(a,b,c){var d=D.Sk(6);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;6>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.07,0.25);b.H=new H(0.93,0.75);t.v(a);return b},Heptagon:function(a,b,c){var d=D.Sk(7);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;7>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.2,0.15);b.H=new H(0.8,0.85);t.v(a);return b},Octagon:function(a,b,c){var d=D.Sk(8);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;8>e;e++)a.lineTo(d[e].x* +b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.15,0.15);b.H=new H(0.85,0.85);t.v(a);return b},Nonagon:function(a,b,c){var d=D.Sk(9);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;9>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.17,0.13);b.H=new H(0.82,0.82);t.v(a);return b},Decagon:function(a,b,c){var d=D.Sk(10);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.16,0.16);b.H=new H(0.84,0.84);t.v(a);return b},Dodecagon:function(a, +b,c){var d=D.Sk(12);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.16,0.16);b.H=new H(0.84,0.84);t.v(a);return b},FivePointedStar:function(a,b,c){var d=D.qm(5);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;10>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.312,0.383);b.H=new H(0.693,0.765);t.v(a);return b},SixPointedStar:function(a,b,c){var d=D.qm(6);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;12>e;e++)a.lineTo(d[e].x* +b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.17,0.251);b.H=new H(0.833,0.755);t.v(a);return b},SevenPointedStar:function(a,b,c){var d=D.qm(7);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;14>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.363,0.361);b.H=new H(0.641,0.709);t.v(a);return b},EightPointedStar:function(a,b,c){var d=D.qm(8);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;16>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.252,0.255);b.H=new H(0.75,0.75);t.v(a); +return b},NinePointedStar:function(a,b,c){var d=D.qm(9);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;18>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.355,0.361);b.H=new H(0.645,0.651);t.v(a);return b},TenPointedStar:function(a,b,c){var d=D.qm(10);a=t.u();J(a,d[0].x*b,d[0].y*c,!0);for(var e=1;20>e;e++)a.lineTo(d[e].x*b,d[e].y*c);t.xa(d);N(a);b=a.s;b.G=new H(0.281,0.261);b.H=new H(0.723,0.748);t.v(a);return b},FivePointedBurst:function(a,b,c){var d=D.ro(5);a=t.u();J(a,d[0].x*b,d[0].y* +c,!0);for(var e=1;e=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=d*D.sa;var e=t.u();J(e,d,0,!0); +e.lineTo(b-d,0);K(e,b-a,0,b,a,b,d);e.lineTo(b,c-d);K(e,b,c-a,b-a,c,b-d,c);e.lineTo(d,c);K(e,a,c,0,c-a,0,c-d);e.lineTo(0,d);K(e,0,a,a,0,d,0);N(e);b=e.s;1=d&&(d=5);d=Math.min(d,b/3);d=Math.min(d,c/3);a=t.u();J(a,d,0,!0);a.lineTo(b-d,0);K(a,b-0,0,b,0,b,d);a.lineTo(b,c-d);K(a,b,c-0,b-0,c,b-d,c);a.lineTo(d,c);K(a,0,c,0,c-0,0,c-d);a.lineTo(0,d);K(a,0,0,0,0,d,0);N(a);b=a.s;b.G=wb;b.H=Ob; +t.v(a);return b},SquareIBeam:function(a,b,c){var d=a?a.tc:0;0===d&&(d=0.2);a=t.u();J(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,d*c);a.lineTo((0.5+d/2)*b,d*c);a.lineTo((0.5+d/2)*b,(1-d)*c);a.lineTo(1*b,(1-d)*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,(1-d)*c);a.lineTo((0.5-d/2)*b,(1-d)*c);a.lineTo((0.5-d/2)*b,d*c);a.lineTo(0,d*c);N(a);b=a.s;t.v(a);return b},Trapezoid:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.2);var d=t.u();J(d,a*b,0,!0);d.lineTo((1-a)*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);b=d.s; +b.G=new H(a,0);b.H=new H(1-a,1);t.v(d);return b},ManualLoop:"ManualOperation",ManualOperation:function(a,b,c){var d=a?a.tc:0;a=t.u();J(a,d,0,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);N(a);b=a.s;b.G=new H(0.1,0);b.H=new H(0.9,1);t.v(a);return b},GenderMale:function(a,b,c){a=t.u();var d=D.sa,e=0.4*d,g=0.4,h=t.M(),k=t.M(),l=t.M(),m=t.M();J(a,(0.5-g)*b,0.5*c,!0);K(a,(0.5-g)*b,(0.5-e)*c,(0.5-e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5, +0.44,l,m,k,h,h);K(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);var n=t.cc(k.x,k.y);D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.56,h,h,k,l,m);var p=t.cc(k.x,k.y);a.lineTo((0.1*n.x+0.855)*b,0.1*n.y*c);a.lineTo(0.85*b,0.1*n.y*c);a.lineTo(0.85*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,0.15*c);a.lineTo((0.1*p.x+0.9)*b,(0.1*p.y+0.05*0.9)*c);a.lineTo(p.x*b,p.y*c);K(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);K(a,(0.5+g)*b,(0.5+e)*c,(0.5+e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5-e)* +b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);g=0.35;e=0.35*d;J(a,0.5*b,(0.5-g)*c,!0,!0);K(a,(0.5-e)*b,(0.5-g)*c,(0.5-g)*b,(0.5-e)*c,(0.5-g)*b,0.5*c);K(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);K(a,(0.5+g)*b,(0.5-e)*c,(0.5+e)*b,(0.5-g)*c,0.5*b,(0.5-g)*c);J(a,(0.5-g)*b,0.5*c,!0);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);t.B(p);b=a.s;b.G=new H(0.202,0.257);b.H=new H(0.692,0.839);b.fc=Sg;t.v(a);return b},GenderFemale:function(a, +b,c){a=t.u();var d=0.375,e=0,g=-0.125,h=4*(Math.SQRT2-1)/3*d;J(a,(0.525+e)*b,(0.5+d+g)*c,!0);K(a,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+d+e)*b,(0.5+g)*c);K(a,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);K(a,(0.5-h+e)*b,(0.5-d+g)*c,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-d+e)*b,(0.5+g)*c);K(a,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-h+e)*b,(0.5+d+g)*c,(0.475+e)*b,(0.5+d+g)*c);a.lineTo(0.475*b,0.85*c);a.lineTo(0.425*b,0.85*c);a.lineTo(0.425*b,0.9*c);a.lineTo(0.475*b,0.9*c);a.lineTo(0.475* +b,1*c);a.lineTo(0.525*b,1*c);a.lineTo(0.525*b,0.9*c);a.lineTo(0.575*b,0.9*c);a.lineTo(0.575*b,0.85*c);a.lineTo(0.525*b,0.85*c);N(a);d=0.325;e=0;g=-0.125;h=4*(Math.SQRT2-1)/3*d;J(a,(0.5+d+e)*b,(0.5+g)*c,!0,!0);K(a,(0.5+d+e)*b,(0.5+h+g)*c,(0.5+h+e)*b,(0.5+d+g)*c,(0.5+e)*b,(0.5+d+g)*c);K(a,(0.5-h+e)*b,(0.5+d+g)*c,(0.5-d+e)*b,(0.5+h+g)*c,(0.5-d+e)*b,(0.5+g)*c);K(a,(0.5-d+e)*b,(0.5-h+g)*c,(0.5-h+e)*b,(0.5-d+g)*c,(0.5+e)*b,(0.5-d+g)*c);K(a,(0.5+h+e)*b,(0.5-d+g)*c,(0.5+d+e)*b,(0.5-h+g)*c,(0.5+d+e)*b,(0.5+ +g)*c);J(a,(0.525+e)*b,(0.5+d+g)*c,!0);b=a.s;b.G=new H(0.232,0.136);b.H=new H(0.782,0.611);b.fc=Sg;t.v(a);return b},PlusLine:function(a,b,c){a=t.u();J(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},XLine:function(a,b,c){a=t.u();J(a,0,1*c,!1);a.lineTo(1*b,0);a.moveTo(0,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},AsteriskLine:function(a,b,c){a=t.u();var d=0.2/Math.SQRT2;J(a,d*b,(1-d)*c,!1);a.lineTo((1-d)*b,d*c);a.moveTo(d*b,d*c);a.lineTo((1-d)*b,(1-d)* +c);a.moveTo(0*b,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0*c);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b},CircleLine:function(a,b,c){var d=0.5*D.sa;a=t.u();J(a,1*b,0.5*c,!1);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new H(0.146,0.146);b.H=new H(0.853,0.853);b.fc=Sg;t.v(a);return b},Pie:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;J(a,(0.5*Math.SQRT2/2+0.5)*b,(0.5- +0.5*Math.SQRT2/2)*c,!0);K(a,0.7*b,0*c,0.5*b,0*c,0.5*b,0*c);K(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);K(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.5*b,1*c);K(a,(0.5+d+0)*b,1*c,1*b,(0.5+d+0)*c,1*b,0.5*c);a.lineTo(0.5*b,0.5*c);N(a);b=a.s;t.v(a);return b},PiePiece:function(a,b,c){var d=D.sa/Math.SQRT2*0.5,e=Math.SQRT2/2,g=1-Math.SQRT2/2;a=t.u();J(a,b,c,!0);K(a,b,(1-d)*c,(e+d)*b,(g+d)*c,e*b,g*c);a.lineTo(0,c);N(a);b=a.s;t.v(a);return b},StopSign:function(a,b,c){a=1/(Math.SQRT2+2);var d=t.u();J(d,a*b,0,!0); +d.lineTo((1-a)*b,0);d.lineTo(1*b,a*c);d.lineTo(1*b,(1-a)*c);d.lineTo((1-a)*b,1*c);d.lineTo(a*b,1*c);d.lineTo(0,(1-a)*c);d.lineTo(0,a*c);N(d);b=d.s;b.G=new H(a/2,a/2);b.H=new H(1-a/2,1-a/2);t.v(d);return b},LogicImplies:function(a,b,c){var d=a?a.tc:0;0===d&&(d=0.2);a=t.u();J(a,(1-d)*b,0*c,!1);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);b=a.s;b.G=wb;b.H=new H(0.8,0.5);t.v(a);return b},LogicIff:function(a,b,c){var d=a?a.tc:0;0===d&&(d=0.2);a=t.u();J(a,(1-d)*b,0*c,!1); +a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,c);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(d*b,0);a.lineTo(0,0.5*c);a.lineTo(d*b,c);b=a.s;b.G=new H(0.2,0);b.H=new H(0.8,0.5);t.v(a);return b},LogicNot:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},LogicAnd:function(a,b,c){a=t.u();J(a,0,1*c,!1);a.lineTo(0.5*b,0);a.lineTo(1*b,1*c);b=a.s;b.G=new H(0.25,0.5);b.H=new H(0.75,1);t.v(a);return b},LogicOr:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1* +b,0);b=a.s;b.G=new H(0.219,0);b.H=new H(0.78,0.409);t.v(a);return b},LogicXor:function(a,b,c){a=t.u();J(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);var d=0.5*D.sa;K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.fc=Sg;t.v(a);return b},LogicTruth:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0.5*b,0);a.lineTo(0.5*b,1*c);b=a.s;t.v(a);return b}, +LogicFalsity:function(a,b,c){a=t.u();J(a,0,1*c,!1);a.lineTo(1*b,1*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);b=a.s;t.v(a);return b},LogicThereExists:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);b=a.s;t.v(a);return b},LogicForAll:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0.5*b,1*c);a.lineTo(1*b,0);a.moveTo(0.25*b,0.5*c);a.lineTo(0.75*b,0.5*c);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,0.5);t.v(a);return b}, +LogicIsDefinedAs:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(b,0);a.moveTo(0,0.5*c);a.lineTo(b,0.5*c);a.moveTo(0,c);a.lineTo(b,c);b=a.s;b.G=new H(0.01,0.01);b.H=new H(0.99,0.49);t.v(a);return b},LogicIntersect:function(a,b,c){var d=0.5*D.sa;a=t.u();J(a,0,1*c,!1);a.lineTo(0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new H(0,0.5);b.H=Ob;t.v(a);return b},LogicUnion:function(a,b,c){var d=0.5*D.sa;a=t.u();J(a,1*b,0,!1);a.lineTo(1*b, +0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);a.lineTo(0,0);b=a.s;b.G=wb;b.H=new H(1,0.5);t.v(a);return b},Arrow:function(a,b,c){var d=a?a.tc:0,e=a?a.Vs:0;0===d&&(d=0.3);0===e&&(e=0.3);a=t.u();J(a,0,(0.5-e/2)*c,!0);a.lineTo((1-d)*b,(0.5-e/2)*c);a.lineTo((1-d)*b,0);a.lineTo(1*b,0.5*c);a.lineTo((1-d)*b,1*c);a.lineTo((1-d)*b,(0.5+e/2)*c);a.lineTo(0,(0.5+e/2)*c);N(a);b=a.s;b.G=new H(0,0.5-e/2);d=D.Xk(0,0.5+e/2,1,0.5+e/2,1-d,1,1,0.5,t.M());b.H=new H(d.x,d.y); +t.B(d);t.v(a);return b},ISOProcess:"Chevron",Chevron:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.5*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);N(a);b=a.s;t.v(a);return b},DoubleArrow:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.3*b,0.214*c);a.lineTo(0.3*b,0);a.lineTo(1*b,0.5*c);a.lineTo(0.3*b,1*c);a.lineTo(0.3*b,0.786*c);a.lineTo(0,1*c);N(a);J(a,0.3*b,0.214*c,!1);a.lineTo(0.3*b,0.786*c);a.Xa(!1);b=a.s;t.v(a);return b},DoubleEndArrow:function(a,b,c){a=t.u(); +J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.3*b,0.7*c);a.lineTo(0.3*b,1*c);a.lineTo(0,0.5*c);a.lineTo(0.3*b,0);a.lineTo(0.3*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);N(a);b=a.s;c=D.Xk(0,0.5,0.3,0,0,0.3,0.3,0.3,t.M());b.G=new H(c.x,c.y);c=D.Xk(0.7,1,1,0.5,0.7,0.7,1,0.7,c);b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},IBeamArrow:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0.2*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0,1*c); +a.lineTo(0,0);a.lineTo(0.2*b,0);a.lineTo(0.2*b,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);N(a);b=a.s;b.G=new H(0,0.3);c=D.Xk(0.7,1,1,0.5,0.7,0.7,1,0.7,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},Pointer:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0);N(a);b=a.s;b.G=new H(0.2,0.35);c=D.Xk(0.2,0.65,1,0.65,0,1,1,0.5,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},RoundedPointer:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0,1*c);K(a,0.5* +b,0.75*c,0.5*b,0.25*c,0,0);N(a);b=a.s;b.G=new H(0.4,0.35);c=D.Xk(0.2,0.65,1,0.65,0,1,1,0.5,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},SplitEndArrow:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0.7*b,0.7*c);a.lineTo(0,0.7*c);a.lineTo(0.2*b,0.5*c);a.lineTo(0,0.3*c);a.lineTo(0.7*b,0.3*c);a.lineTo(0.7*b,0);N(a);b=a.s;b.G=new H(0.2,0.3);c=D.Xk(0.7,1,1,0.5,0.7,0.7,1,0.7,t.M());b.H=new H(c.x,c.y);t.B(c);t.v(a);return b},MessageToUser:"SquareArrow",SquareArrow:function(a, +b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0.7*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.7*b,0);N(a);b=a.s;b.G=wb;b.H=new H(0.7,1);t.v(a);return b},Cone1:function(a,b,c){var d=D.sa;a=0.5*d;var e=0.1*d,d=t.u();J(d,0,0.9*c,!0);d.lineTo(0.5*b,0);d.lineTo(1*b,0.9*c);K(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);K(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);N(d);b=d.s;b.G=new H(0.25,0.5);b.H=new H(0.75,0.97);t.v(d);return b},Cone2:function(a,b,c){a=t.u();J(a,0,0.9*c,!0);K(a,(1-0.85/0.9)*b,1*c,0.85/0.9*b,1*c, +1*b,0.9*c);a.lineTo(0.5*b,0);a.lineTo(0,0.9*c);N(a);J(a,0,0.9*c,!1);K(a,(1-0.85/0.9)*b,0.8*c,0.85/0.9*b,0.8*c,1*b,0.9*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.5);b.H=new H(0.75,0.82);t.v(a);return b},Cube1:function(a,b,c){a=t.u();J(a,0.5*b,1*c,!0);a.lineTo(1*b,0.85*c);a.lineTo(1*b,0.15*c);a.lineTo(0.5*b,0*c);a.lineTo(0*b,0.15*c);a.lineTo(0*b,0.85*c);N(a);J(a,0.5*b,1*c,!1);a.lineTo(0.5*b,0.3*c);a.lineTo(0,0.15*c);a.moveTo(0.5*b,0.3*c);a.lineTo(1*b,0.15*c);a.Xa(!1);b=a.s;b.G=new H(0,0.3);b.H=new H(0.5,0.85); +t.v(a);return b},Cube2:function(a,b,c){a=t.u();J(a,0,0.3*c,!0);a.lineTo(0*b,1*c);a.lineTo(0.7*b,c);a.lineTo(1*b,0.7*c);a.lineTo(1*b,0*c);a.lineTo(0.3*b,0*c);N(a);J(a,0,0.3*c,!1);a.lineTo(0.7*b,0.3*c);a.lineTo(1*b,0*c);a.moveTo(0.7*b,0.3*c);a.lineTo(0.7*b,1*c);a.Xa(!1);b=a.s;b.G=new H(0,0.3);b.H=new H(0.7,1);t.v(a);return b},MagneticData:"Cylinder1",Cylinder1:function(a,b,c){var d=D.sa;a=0.5*d;var e=0.1*d,d=t.u();J(d,0,0.1*c,!0);K(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);K(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1* +b,0.1*c);d.lineTo(b,0.9*c);K(d,1*b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);K(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);d.lineTo(0,0.1*c);J(d,0,0.1*c,!1);K(d,0,(0.1+e)*c,(0.5-a)*b,0.2*c,0.5*b,0.2*c);K(d,(0.5+a)*b,0.2*c,1*b,(0.1+e)*c,1*b,0.1*c);d.Xa(!1);b=d.s;b.G=new H(0,0.2);b.H=new H(1,0.9);t.v(d);return b},Cylinder2:function(a,b,c){var d=D.sa;a=0.5*d;var e=0.1*d,d=t.u();J(d,0,0.9*c,!0);d.lineTo(0,0.1*c);K(d,0,(0.1-e)*c,(0.5-a)*b,0,0.5*b,0);K(d,(0.5+a)*b,0,1*b,(0.1-e)*c,1*b,0.1*c);d.lineTo(1*b,0.9*c);K(d,1* +b,(0.9+e)*c,(0.5+a)*b,1*c,0.5*b,1*c);K(d,(0.5-a)*b,1*c,0,(0.9+e)*c,0,0.9*c);J(d,0,0.9*c,!1);K(d,0,(0.9-e)*c,(0.5-a)*b,0.8*c,0.5*b,0.8*c);K(d,(0.5+a)*b,0.8*c,1*b,(0.9-e)*c,1*b,0.9*c);d.Xa(!1);b=d.s;b.G=new H(0,0.1);b.H=new H(1,0.8);t.v(d);return b},Cylinder3:function(a,b,c){var d=D.sa;a=0.1*d;var e=0.5*d,d=t.u();J(d,0.1*b,0,!0);d.lineTo(0.9*b,0);K(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);K(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);K(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);K(d,0,(0.5- +e)*c,(0.1-a)*b,0,0.1*b,0);J(d,0.1*b,0,!1);K(d,(0.1+a)*b,0,0.2*b,(0.5-e)*c,0.2*b,0.5*c);K(d,0.2*b,(0.5+e)*c,(0.1+a)*b,1*c,0.1*b,1*c);d.Xa(!1);b=d.s;b.G=new H(0.2,0);b.H=new H(0.9,1);t.v(d);return b},DirectData:"Cylinder4",Cylinder4:function(a,b,c){var d=D.sa;a=0.1*d;var e=0.5*d,d=t.u();J(d,0.9*b,0,!0);K(d,(0.9+a)*b,0,1*b,(0.5-e)*c,1*b,0.5*c);K(d,1*b,(0.5+e)*c,(0.9+a)*b,1*c,0.9*b,1*c);d.lineTo(0.1*b,1*c);K(d,(0.1-a)*b,1*c,0,(0.5+e)*c,0,0.5*c);K(d,0,(0.5-e)*c,(0.1-a)*b,0,0.1*b,0);d.lineTo(0.9*b,0);J(d, +0.9*b,0,!1);K(d,(0.9-a)*b,0,0.8*b,(0.5-e)*c,0.8*b,0.5*c);K(d,0.8*b,(0.5+e)*c,(0.9-a)*b,1*c,0.9*b,1*c);d.Xa(!1);b=d.s;b.G=new H(0.1,0);b.H=new H(0.8,1);t.v(d);return b},Prism1:function(a,b,c){a=t.u();J(a,0.25*b,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(b,0.5*c);a.lineTo(0.5*b,c);a.lineTo(0,c);N(a);J(a,0.25*b,0.25*c,!1);a.lineTo(0.5*b,c);a.Xa(!1);b=a.s;b.G=new H(0.408,0.172);b.H=new H(0.833,0.662);t.v(a);return b},Prism2:function(a,b,c){a=t.u();J(a,0,0.25*c,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c); +a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);N(a);J(a,0,c,!1);a.lineTo(0.25*b,0.5*c);a.lineTo(b,0.25*c);a.moveTo(0,0.25*c);a.lineTo(0.25*b,0.5*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.5);b.H=new H(0.75,0.75);t.v(a);return b},Pyramid1:function(a,b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(b,0.75*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.75*c);N(a);J(a,0.5*b,0,!1);a.lineTo(0.5*b,1*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.367);b.H=new H(0.75,0.875);t.v(a);return b},Pyramid2:function(a,b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(b,0.85* +c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.85*c);N(a);J(a,0.5*b,0,!1);a.lineTo(0.5*b,0.7*c);a.lineTo(0,0.85*c);a.moveTo(0.5*b,0.7*c);a.lineTo(1*b,0.85*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.367);b.H=new H(0.75,0.875);t.v(a);return b},Actor:function(a,b,c){var d=D.sa,e=0.2*d,g=0.1*d,h=0.5,k=0.1;a=t.u();J(a,h*b,(k+0.1)*c,!0);K(a,(h-e)*b,(k+0.1)*c,(h-0.2)*b,(k+g)*c,(h-0.2)*b,k*c);K(a,(h-0.2)*b,(k-g)*c,(h-e)*b,(k-0.1)*c,h*b,(k-0.1)*c);K(a,(h+e)*b,(k-0.1)*c,(h+0.2)*b,(k-g)*c,(h+0.2)*b,k*c);K(a,(h+0.2)*b,(k+g)*c, +(h+e)*b,(k+0.1)*c,h*b,(k+0.1)*c);e=0.05;g=d*e;J(a,0.5*b,0.2*c,!0);a.lineTo(0.95*b,0.2*c);h=0.95;k=0.25;K(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);a.lineTo(1*b,0.6*c);a.lineTo(0.85*b,0.6*c);a.lineTo(0.85*b,0.35*c);e=0.025;g=d*e;h=0.825;k=0.35;K(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.8*b,1*c);a.lineTo(0.55*b,1*c);a.lineTo(0.55*b,0.7*c);e=0.05;g=d*e;h=0.5;k=0.7;K(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h-g)*b,(k-e)* +c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.45*b,1*c);a.lineTo(0.2*b,1*c);a.lineTo(0.2*b,0.35*c);e=0.025;g=d*e;h=0.175;k=0.35;K(a,(h+e)*b,(k-g)*c,(h+g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h-g)*b,(k-e)*c,(h-e)*b,(k-g)*c,(h-e)*b,k*c);a.lineTo(0.15*b,0.6*c);a.lineTo(0*b,0.6*c);a.lineTo(0*b,0.25*c);e=0.05;g=d*e;h=0.05;k=0.25;K(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);a.lineTo(0.5*b,0.2*c);b=a.s;b.G=new H(0.2,0.2);b.H=new H(0.8,0.65);t.v(a);return b},Card:function(a,b,c){a=t.u();J(a,1*b,0*c,!0);a.lineTo(1* +b,1*c);a.lineTo(0*b,1*c);a.lineTo(0*b,0.2*c);a.lineTo(0.2*b,0*c);N(a);b=a.s;b.G=new H(0,0.2);b.H=Ob;t.v(a);return b},Collate:function(a,b,c){a=t.u();J(a,0.5*b,0.5*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);J(a,0.5*b,0.5*c,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0.5*b,0.5*c);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,0.25);t.v(a);return b},CreateRequest:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,0,a* +c,!1);d.lineTo(1*b,a*c);d.moveTo(0,(1-a)*c);d.lineTo(1*b,(1-a)*c);d.Xa(!1);b=d.s;b.G=new H(0,a);b.H=new H(1,1-a);t.v(d);return b},Database:function(a,b,c){a=t.u();var d=D.sa,e=0.5*d,d=0.1*d;J(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);K(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);K(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);K(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);K(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);J(a,1*b,0.1*c,!1);K(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);K(a,(0.5-e)*b,0.2*c,0,(0.1+d)* +c,0,0.1*c);a.moveTo(1*b,0.2*c);K(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);K(a,(0.5-e)*b,0.3*c,0,(0.2+d)*c,0,0.2*c);a.moveTo(1*b,0.3*c);K(a,1*b,(0.3+d)*c,(0.5+e)*b,0.4*c,0.5*b,0.4*c);K(a,(0.5-e)*b,0.4*c,0,(0.3+d)*c,0,0.3*c);a.Xa(!1);b=a.s;b.G=new H(0,0.4);b.H=new H(1,0.9);t.v(a);return b},StoredData:"DataStorage",DataStorage:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0);K(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0,1*c);K(a,0.25*b,0.9*c,0.25*b,0.1*c,0,0);N(a);b=a.s;b.G=new H(0.226,0);b.H=new H(0.81, +1);t.v(a);return b},DiskStorage:function(a,b,c){a=t.u();var d=D.sa,e=0.5*d,d=0.1*d;J(a,1*b,0.1*c,!0);a.lineTo(1*b,0.9*c);K(a,1*b,(0.9+d)*c,(0.5+e)*b,1*c,0.5*b,1*c);K(a,(0.5-e)*b,1*c,0,(0.9+d)*c,0,0.9*c);a.lineTo(0,0.1*c);K(a,0,(0.1-d)*c,(0.5-e)*b,0,0.5*b,0);K(a,(0.5+e)*b,0,1*b,(0.1-d)*c,1*b,0.1*c);J(a,1*b,0.1*c,!1);K(a,1*b,(0.1+d)*c,(0.5+e)*b,0.2*c,0.5*b,0.2*c);K(a,(0.5-e)*b,0.2*c,0,(0.1+d)*c,0,0.1*c);a.moveTo(1*b,0.2*c);K(a,1*b,(0.2+d)*c,(0.5+e)*b,0.3*c,0.5*b,0.3*c);K(a,(0.5-e)*b,0.3*c,0,(0.2+d)* +c,0,0.2*c);a.Xa(!1);b=a.s;b.G=new H(0,0.3);b.H=new H(1,0.9);t.v(a);return b},Display:function(a,b,c){a=t.u();J(a,0.25*b,0,!0);a.lineTo(0.75*b,0);K(a,1*b,0,1*b,1*c,0.75*b,1*c);a.lineTo(0.25*b,1*c);a.lineTo(0,0.5*c);N(a);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,1);t.v(a);return b},DividedEvent:function(a,b,c){a=a?a.tc:0;0===a?a=0.2:0.15>a&&(a=0.15);var d=t.u(),e=0.2*D.sa;J(d,0,0.2*c,!0);K(d,0,(0.2-e)*c,(0.2-e)*b,0,0.2*b,0);d.lineTo(0.8*b,0);K(d,(0.8+e)*b,0,1*b,(0.2-e)*c,1*b,0.2*c);d.lineTo(1*b,0.8*c); +K(d,1*b,(0.8+e)*c,(0.8+e)*b,1*c,0.8*b,1*c);d.lineTo(0.2*b,1*c);K(d,(0.2-e)*b,1*c,0,(0.8+e)*c,0,0.8*c);d.lineTo(0,0.2*c);J(d,0,a*c,!1);d.lineTo(1*b,a*c);d.Xa(!1);b=d.s;b.G=new H(0,a);b.H=new H(1,1-a);t.v(d);return b},DividedProcess:function(a,b,c){a=a?a.tc:0;0.1>a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,0,a*c,!1);d.lineTo(1*b,a*c);d.Xa(!1);b=d.s;b.G=new H(0,a);b.H=Ob;t.v(d);return b},Document:function(a,b,c){c/=0.8;a=t.u();J(a,0,0.7*c,!0);a.lineTo(0, +0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);K(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);N(a);b=a.s;b.G=wb;b.H=new H(1,0.6);t.v(a);return b},ExternalOrganization:function(a,b,c){a=a?a.tc:0;0.2>a&&(a=0.2);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,a*b,0,!1);d.lineTo(0,a*c);d.moveTo(1*b,a*c);d.lineTo((1-a)*b,0);d.moveTo(0,(1-a)*c);d.lineTo(a*b,1*c);d.moveTo((1-a)*b,1*c);d.lineTo(1*b,(1-a)*c);d.Xa(!1);b=d.s;b.G=new H(a/2,a/2);b.H=new H(1-a/2,1-a/2);t.v(d);return b},ExternalProcess:function(a, +b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);N(a);J(a,0.1*b,0.4*c,!1);a.lineTo(0.1*b,0.6*c);a.moveTo(0.9*b,0.6*c);a.lineTo(0.9*b,0.4*c);a.moveTo(0.6*b,0.1*c);a.lineTo(0.4*b,0.1*c);a.moveTo(0.4*b,0.9*c);a.lineTo(0.6*b,0.9*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.25);b.H=new H(0.75,0.75);t.v(a);return b},File:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);N(a);J(a,0.75*b,0,!1);a.lineTo(0.75*b,0.25*c); +a.lineTo(1*b,0.25*c);a.Xa(!1);b=a.s;b.G=new H(0,0.25);b.H=Ob;t.v(a);return b},Interrupt:function(a,b,c){a=t.u();J(a,1*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);J(a,1*b,0.5*c,!1);a.lineTo(1*b,1*c);J(a,1*b,0.5*c,!1);a.lineTo(1*b,0);b=a.s;b.G=new H(0,0.25);b.H=new H(0.5,0.75);t.v(a);return b},InternalStorage:function(a,b,c){var d=a?a.tc:0;a=a?a.Vs:0;0===d&&(d=0.1);0===a&&(a=0.1);var e=t.u();J(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(1*b,1*c);e.lineTo(0,1*c);N(e);J(e,d*b,0,!1);e.lineTo(d* +b,1*c);e.moveTo(0,a*c);e.lineTo(1*b,a*c);e.Xa(!1);b=e.s;b.G=new H(d,a);b.H=Ob;t.v(e);return b},Junction:function(a,b,c){a=t.u();var d=1/Math.SQRT2,e=(1-1/Math.SQRT2)/2,g=0.5*D.sa;J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+g)*c,(0.5+g)*b,1*c,0.5*b,1*c);K(a,(0.5-g)*b,1*c,0,(0.5+g)*c,0,0.5*c);K(a,0,(0.5-g)*c,(0.5-g)*b,0,0.5*b,0);K(a,(0.5+g)*b,0,1*b,(0.5-g)*c,1*b,0.5*c);J(a,(e+d)*b,(e+d)*c,!1);a.lineTo(e*b,e*c);a.moveTo(e*b,(e+d)*c);a.lineTo((e+d)*b,e*c);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b},LinedDocument:function(a, +b,c){c/=0.8;a=t.u();J(a,0,0.7*c,!0);a.lineTo(0,0);a.lineTo(1*b,0);a.lineTo(1*b,0.7*c);K(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);N(a);J(a,0.1*b,0,!1);a.lineTo(0.1*b,0.75*c);a.Xa(!1);b=a.s;b.G=new H(0.1,0);b.H=new H(1,0.6);t.v(a);return b},LoopLimit:function(a,b,c){a=t.u();J(a,0,1*c,!0);a.lineTo(0,0.25*c);a.lineTo(0.25*b,0);a.lineTo(0.75*b,0);a.lineTo(1*b,0.25*c);a.lineTo(1*b,1*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=Ob;t.v(a);return b},SequentialData:"MagneticTape",MagneticTape:function(a,b,c){a=t.u();var d= +0.5*D.sa;J(a,0.5*b,1*c,!0);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,0.9*c,0.6*b,0.9*c);a.lineTo(1*b,0.9*c);a.lineTo(1*b,1*c);a.lineTo(0.5*b,1*c);b=a.s;b.G=new H(0.15,0.15);b.H=new H(0.85,0.8);t.v(a);return b},ManualInput:function(a,b,c){a=t.u();J(a,1*b,0,!0);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.25*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=Ob;t.v(a);return b},MessageFromUser:function(a,b,c){a= +a?a.tc:0;0===a&&(a=0.7);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(a*b,0.5*c);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);b=d.s;b.G=wb;b.H=new H(a,1);t.v(d);return b},MicroformProcessing:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.25);var d=t.u();J(d,0,0,!0);d.lineTo(0.5*b,a*c);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.5*b,(1-a)*c);d.lineTo(0,1*c);N(d);b=d.s;b.G=new H(0,a);b.H=new H(1,1-a);t.v(d);return b},MicroformRecording:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0.25*c);a.lineTo(1*b, +0.15*c);a.lineTo(1*b,0.85*c);a.lineTo(0.75*b,0.75*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=new H(1,0.75);t.v(a);return b},MultiDocument:function(a,b,c){c/=0.8;a=t.u();J(a,b,0,!0);a.lineTo(b,0.5*c);K(a,0.96*b,0.47*c,0.93*b,0.45*c,0.9*b,0.44*c);a.lineTo(0.9*b,0.6*c);K(a,0.86*b,0.57*c,0.83*b,0.55*c,0.8*b,0.54*c);a.lineTo(0.8*b,0.7*c);K(a,0.4*b,0.4*c,0.4*b,1*c,0,0.7*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);a.lineTo(0.1*b,0.1*c);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);N(a);J(a,0.1*b,0.2*c, +!1);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.54*c);a.moveTo(0.2*b,0.1*c);a.lineTo(0.9*b,0.1*c);a.lineTo(0.9*b,0.44*c);a.Xa(!1);b=a.s;b.G=new H(0,0.25);b.H=new H(0.8,0.77);t.v(a);return b},MultiProcess:function(a,b,c){a=t.u();J(a,0.1*b,0.1*c,!0);a.lineTo(0.2*b,0.1*c);a.lineTo(0.2*b,0);a.lineTo(1*b,0);a.lineTo(1*b,0.8*c);a.lineTo(0.9*b,0.8*c);a.lineTo(0.9*b,0.9*c);a.lineTo(0.8*b,0.9*c);a.lineTo(0.8*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.2*c);a.lineTo(0.1*b,0.2*c);N(a);J(a,0.2*b,0.1*c,!1);a.lineTo(0.9*b, +0.1*c);a.lineTo(0.9*b,0.8*c);a.moveTo(0.1*b,0.2*c);a.lineTo(0.8*b,0.2*c);a.lineTo(0.8*b,0.9*c);a.Xa(!1);b=a.s;b.G=new H(0,0.2);b.H=new H(0.8,1);t.v(a);return b},OfflineStorage:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=1-a,e=t.u();J(e,0,0,!0);e.lineTo(1*b,0);e.lineTo(0.5*b,1*c);N(e);J(e,0.5*a*b,a*c,!1);e.lineTo((1-0.5*a)*b,a*c);e.Xa(!1);b=e.s;b.G=new H(d/4+0.5*a,a);b.H=new H(3*d/4+0.5*a,a+0.5*d);t.v(e);return b},OffPageConnector:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(0.75*b,0);a.lineTo(1* +b,0.5*c);a.lineTo(0.75*b,1*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=wb;b.H=new H(0.75,1);t.v(a);return b},Or:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);J(a,1*b,0.5*c,!1);a.lineTo(0,0.5*c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b},PaperTape:function(a,b,c){c/=0.8;a=t.u();J(a,0,0.7*c,!0);a.lineTo(0, +0.3*c);K(a,0.5*b,0.6*c,0.5*b,0,1*b,0.3);a.lineTo(1*b,0.7*c);K(a,0.5*b,0.4*c,0.5*b,1*c,0,0.7*c);N(a);b=a.s;b.G=new H(0,0.49);b.H=new H(1,0.75);t.v(a);return b},PrimitiveFromCall:function(a,b,c){var d=a?a.tc:0;a=a?a.Vs:0;0===d&&(d=0.1);0===a&&(a=0.3);var e=t.u();J(e,0,0,!0);e.lineTo(1*b,0);e.lineTo((1-a)*b,0.5*c);e.lineTo(1*b,1*c);e.lineTo(0,1*c);N(e);b=e.s;b.G=new H(d,0);b.H=new H(1-a,1);t.v(e);return b},PrimitiveToCall:function(a,b,c){var d=a?a.tc:0;a=a?a.Vs:0;0===d&&(d=0.1);0===a&&(a=0.3);var e= +t.u();J(e,0,0,!0);e.lineTo((1-a)*b,0);e.lineTo(1*b,0.5*c);e.lineTo((1-a)*b,1*c);e.lineTo(0,1*c);N(e);b=e.s;b.G=new H(d,0);b.H=new H(1-a,1);t.v(e);return b},Subroutine:"Procedure",Procedure:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,(1-a)*b,0,!1);d.lineTo((1-a)*b,1*c);d.moveTo(a*b,0);d.lineTo(a*b,1*c);d.Xa(!1);b=d.s;b.G=new H(a,0);b.H=new H(1-a,1);t.v(d);return b},Process:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d= +t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0,1*c);N(d);J(d,a*b,0,!1);d.lineTo(a*b,1*c);d.Xa(!1);b=d.s;b.G=new H(a,0);b.H=Ob;t.v(d);return b},Sort:function(a,b,c){a=t.u();J(a,0.5*b,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0.5*b,1*c);a.lineTo(0,0.5*c);N(a);J(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0.25);b.H=new H(0.75,0.5);t.v(a);return b},Start:function(a,b,c){a=t.u();J(a,0.25*b,0,!0);J(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25* +b,0.5*c,0.25*b,0.5*c);J(a,0.25*b,0,!1);a.lineTo(0.25*b,1*c);a.moveTo(0.75*b,0);a.lineTo(0.75*b,1*c);a.Xa(!1);b=a.s;b.G=new H(0.25,0);b.H=new H(0.75,1);t.v(a);return b},Terminator:function(a,b,c){a=t.u();J(a,0.25*b,0,!0);a.arcTo(270,180,0.75*b,0.5*c,0.25*b,0.5*c);a.arcTo(90,180,0.25*b,0.5*c,0.25*b,0.5*c);b=a.s;b.G=new H(0.23,0);b.H=new H(0.77,1);t.v(a);return b},TransmittalTape:function(a,b,c){a=a?a.tc:0;0===a&&(a=0.1);var d=t.u();J(d,0,0,!0);d.lineTo(1*b,0);d.lineTo(1*b,1*c);d.lineTo(0.75*b,(1-a)* +c);d.lineTo(0,(1-a)*c);N(d);b=d.s;b.G=wb;b.H=new H(1,1-a);t.v(d);return b},AndGate:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0,0,!0);a.lineTo(0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=wb;b.H=new H(0.55,1);t.v(a);return b},Buffer:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);N(a);b=a.s;b.G=new H(0,0.25);b.H=new H(0.5,0.75);t.v(a);return b},Clock:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,1* +b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);J(a,1*b,0.5*c,!1);a.lineTo(1*b,0.5*c);J(a,0.8*b,0.75*c,!1);a.lineTo(0.8*b,0.25*c);a.lineTo(0.6*b,0.25*c);a.lineTo(0.6*b,0.75*c);a.lineTo(0.4*b,0.75*c);a.lineTo(0.4*b,0.25*c);a.lineTo(0.2*b,0.25*c);a.lineTo(0.2*b,0.75*c);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b},Ground:function(a,b,c){a=t.u();J(a,0.5*b,0,!1);a.lineTo(0.5*b,0.4*c); +a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.3*b,0.8*c);a.lineTo(0.7*b,0.8*c);a.moveTo(0.4*b,1*c);a.lineTo(0.6*b,1*c);b=a.s;t.v(a);return b},Inverter:function(a,b,c){a=t.u();var d=0.1*D.sa;J(a,0.8*b,0.5*c,!0);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.8*b,0.5*c);J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);K(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);K(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);K(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new H(0,0.25); +b.H=new H(0.4,0.75);t.v(a);return b},NandGate:function(a,b,c){a=t.u();var d=D.sa,e=0.5*d,g=0.4*d,d=0.1*d;J(a,0.8*b,0.5*c,!0);K(a,0.8*b,(0.5+g)*c,(0.4+e)*b,1*c,0.4*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(0.4*b,0);K(a,(0.4+e)*b,0,0.8*b,(0.5-g)*c,0.8*b,0.5*c);J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.9+d)*b,0.6*c,0.9*b,0.6*c);K(a,(0.9-d)*b,0.6*c,0.8*b,(0.5+d)*c,0.8*b,0.5*c);K(a,0.8*b,(0.5-d)*c,(0.9-d)*b,0.4*c,0.9*b,0.4*c);K(a,(0.9+d)*b,0.4*c,1*b,(0.5-d)*c,1*b,0.5*c);b=a.s;b.G=new H(0,0.05);b.H=new H(0.55, +0.95);t.v(a);return b},NorGate:function(a,b,c){a=t.u();var d=D.sa,e=0.5,g=d*e,h=0,k=0.5;J(a,0.8*b,0.5*c,!0);K(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0,1*c);K(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);K(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;J(a,(h-e)*b,k*c,!0);K(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);K(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);K(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new H(0.2,0.25); +b.H=new H(0.6,0.75);t.v(a);return b},OrGate:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0,0,!0);K(a,(0+d+d)*b,0*c,0.8*b,(0.5-d)*c,1*b,0.5*c);K(a,0.8*b,(0.5+d)*c,(0+d+d)*b,1*c,0,1*c);K(a,0.25*b,0.75*c,0.25*b,0.25*c,0,0);N(a);b=a.s;b.G=new H(0.2,0.25);b.H=new H(0.75,0.75);t.v(a);return b},XnorGate:function(a,b,c){a=t.u();var d=D.sa,e=0.5,g=d*e,h=0.2,k=0.5;J(a,0.1*b,0,!1);K(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);J(a,0.8*b,0.5*c,!0);K(a,0.7*b,(k+g)*c,(h+g)*b,(k+e)*c,0.2*b,1*c);K(a,0.45*b,0.75*c,0.45* +b,0.25*c,0.2*b,0);K(a,(h+g)*b,(k-e)*c,0.7*b,(k-g)*c,0.8*b,0.5*c);e=0.1;g=0.1*d;h=0.9;k=0.5;J(a,(h-e)*b,k*c,!0);K(a,(h-e)*b,(k-g)*c,(h-g)*b,(k-e)*c,h*b,(k-e)*c);K(a,(h+g)*b,(k-e)*c,(h+e)*b,(k-g)*c,(h+e)*b,k*c);K(a,(h+e)*b,(k+g)*c,(h+g)*b,(k+e)*c,h*b,(k+e)*c);K(a,(h-g)*b,(k+e)*c,(h-e)*b,(k+g)*c,(h-e)*b,k*c);b=a.s;b.G=new H(0.4,0.25);b.H=new H(0.65,0.75);t.v(a);return b},XorGate:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0.1*b,0,!1);K(a,0.35*b,0.25*c,0.35*b,0.75*c,0.1*b,1*c);J(a,0.2*b,0,!0);K(a,(0.2+ +d)*b,0*c,0.9*b,(0.5-d)*c,1*b,0.5*c);K(a,0.9*b,(0.5+d)*c,(0.2+d)*b,1*c,0.2*b,1*c);K(a,0.45*b,0.75*c,0.45*b,0.25*c,0.2*b,0);N(a);b=a.s;b.G=new H(0.4,0.25);b.H=new H(0.8,0.75);t.v(a);return b},Capacitor:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Resistor:function(a,b,c){a=t.u();J(a,0,0.5*c,!1);a.lineTo(0.1*b,0);a.lineTo(0.2*b,1*c);a.lineTo(0.3*b,0);a.lineTo(0.4*b,1*c);a.lineTo(0.5*b,0);a.lineTo(0.6*b,1*c);a.lineTo(0.7*b,0.5*c);b=a.s;t.v(a); +return b},Inductor:function(a,b,c){a=t.u();var d=0.1*D.sa,e=0.1,g=0.5;J(a,(e-0.5*d)*b,(g+0.1)*c,!1);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.3;g=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);g=e=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)*b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.7;g=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,e*b,(g+0.1)*c);K(a,(e-d)*b,(g+0.1)*c,(e-0.1)* +b,(g+d)*c,(e+0.1)*b,(g+d)*c);e=0.9;g=0.5;K(a,(e+0.1)*b,(g+d)*c,(e+d)*b,(g+0.1)*c,(e+0.5*d)*b,(g+0.1)*c);b=a.s;t.v(a);return b},ACvoltageSource:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0*b,0.5*c,!1);K(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);K(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);a.moveTo(0.1*b,0.5*c);K(a,0.5*b,0*c,0.5*b,1*c,0.9*b,0.5*c);b=a.s;b.fc=Sg;t.v(a);return b},DCvoltageSource:function(a,b,c){a=t.u(); +J(a,0,0.75*c,!1);a.lineTo(0,0.25*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},Diode:function(a,b,c){a=t.u();J(a,1*b,0,!1);a.lineTo(1*b,0.5*c);a.lineTo(0,1*c);a.lineTo(0,0);a.lineTo(1*b,0.5*c);a.lineTo(1*b,1*c);b=a.s;b.G=new H(0,0.25);b.H=new H(0.5,0.75);t.v(a);return b},Wifi:function(a,b,c){var d=b,e=c;b*=0.38;c*=0.6;a=t.u();var g=D.sa,h=0.8*g,k=0.8,l=0,m=0.5,d=(d-b)/2,e=(e-c)/2;J(a,l*b+d,(m+k)*c+e,!0);K(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);K(a,(l-k)*b+d,(m-h)* +c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);K(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);K(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);N(a);h=0.4*g;k=0.4;l=0.2;m=0.5;J(a,l*b+d,(m+k)*c+e,!0);K(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);K(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);K(a,l*b+d,(m-k)*c+e,(l-k+0.5*h)*b+d,(m-h)*c+e,(l-k+0.5*h)*b+d,m*c+e);K(a,(l-k+0.5*h)*b+d,(m+h)*c+e,l*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);N(a);h=0.2*g;k=0.2; +m=l=0.5;J(a,(l-k)*b+d,m*c+e,!0);K(a,(l-k)*b+d,(m-h)*c+e,(l-h)*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);K(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);K(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);K(a,(l-h)*b+d,(m+k)*c+e,(l-k)*b+d,(m+h)*c+e,(l-k)*b+d,m*c+e);h=0.4*g;k=0.4;l=0.8;m=0.5;J(a,l*b+d,(m-k)*c+e,!0);K(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);K(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);K(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5* +h)*b+d,m*c+e);K(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);N(a);h=0.8*g;k=0.8;l=1;m=0.5;J(a,l*b+d,(m-k)*c+e,!0);K(a,(l+h)*b+d,(m-k)*c+e,(l+k)*b+d,(m-h)*c+e,(l+k)*b+d,m*c+e);K(a,(l+k)*b+d,(m+h)*c+e,(l+h)*b+d,(m+k)*c+e,l*b+d,(m+k)*c+e);K(a,l*b+d,(m+k)*c+e,(l+k-0.5*h)*b+d,(m+h)*c+e,(l+k-0.5*h)*b+d,m*c+e);K(a,(l+k-0.5*h)*b+d,(m-h)*c+e,l*b+d,(m-k)*c+e,l*b+d,(m-k)*c+e);N(a);b=a.s;t.v(a);return b},Email:function(a,b,c){a=t.u();J(a,0,0,!0);a.lineTo(1*b,0);a.lineTo(1*b,1*c);a.lineTo(0,1* +c);a.lineTo(0,0);N(a);J(a,0,0,!1);a.lineTo(0.5*b,0.6*c);a.lineTo(1*b,0);a.moveTo(0,1*c);a.lineTo(0.45*b,0.54*c);a.moveTo(1*b,1*c);a.lineTo(0.55*b,0.54*c);a.Xa(!1);b=a.s;t.v(a);return b},Ethernet:function(a,b,c){a=t.u();J(a,0.35*b,0,!0);a.lineTo(0.65*b,0);a.lineTo(0.65*b,0.4*c);a.lineTo(0.35*b,0.4*c);a.lineTo(0.35*b,0);N(a);J(a,0.1*b,1*c,!0,!0);a.lineTo(0.4*b,1*c);a.lineTo(0.4*b,0.6*c);a.lineTo(0.1*b,0.6*c);a.lineTo(0.1*b,1*c);N(a);J(a,0.6*b,1*c,!0,!0);a.lineTo(0.9*b,1*c);a.lineTo(0.9*b,0.6*c);a.lineTo(0.6* +b,0.6*c);a.lineTo(0.6*b,1*c);N(a);J(a,0,0.5*c,!1);a.lineTo(1*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.5*b,0.4*c);a.moveTo(0.75*b,0.5*c);a.lineTo(0.75*b,0.6*c);a.moveTo(0.25*b,0.5*c);a.lineTo(0.25*b,0.6*c);a.Xa(!1);b=a.s;t.v(a);return b},Power:function(a,b,c){a=t.u();var d=D.sa,e=0.4*d,g=0.4,h=t.M(),k=t.M(),l=t.M(),m=t.M();D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5-e,0.5+g,0.5,0.5,h,h,k,l,m);var n=t.cc(k.x,k.y);J(a,k.x*b,k.y*c,!0);K(a,l.x*b,l.y*c,m.x*b,m.y*c,(0.5+g)*b,0.5*c);K(a,(0.5+g)*b,(0.5+e)*c,(0.5+ +e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5-e)*b,(0.5+g)*c,(0.5-g)*b,(0.5+e)*c,(0.5-g)*b,0.5*c);D.si(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);K(a,l.x*b,l.y*c,m.x*b,m.y*c,k.x*b,k.y*c);e=0.3*d;g=0.3;D.si(0.5-g,0.5,0.5-g,0.5-e,0.5-e,0.5-g,0.5,0.5-g,0.5,l,m,k,h,h);a.lineTo(k.x*b,k.y*c);K(a,m.x*b,m.y*c,l.x*b,l.y*c,(0.5-g)*b,0.5*c);K(a,(0.5-g)*b,(0.5+e)*c,(0.5-e)*b,(0.5+g)*c,0.5*b,(0.5+g)*c);K(a,(0.5+e)*b,(0.5+g)*c,(0.5+g)*b,(0.5+e)*c,(0.5+g)*b,0.5*c);D.si(0.5,0.5-g,0.5+e,0.5-g,0.5+g,0.5- +e,0.5+g,0.5,0.5,h,h,k,l,m);K(a,m.x*b,m.y*c,l.x*b,l.y*c,k.x*b,k.y*c);N(a);J(a,0.45*b,0,!0);a.lineTo(0.45*b,0.5*c);a.lineTo(0.55*b,0.5*c);a.lineTo(0.55*b,0);N(a);t.B(h);t.B(k);t.B(l);t.B(m);t.B(n);b=a.s;b.G=new H(0.25,0.55);b.H=new H(0.75,0.8);t.v(a);return b},Fallout:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,0*b,0.5*c,!0);K(a,0*b,(0.5-d)*c,(0.5-d)*b,0*c,0.5*b,0*c);K(a,(0.5+d)*b,0*c,1*b,(0.5-d)*c,1*b,0.5*c);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0*b,(0.5+d)*c,0*b,0.5*c);var e= +d=0;J(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.4;e=0;N(a);J(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);d=0.2;e=-0.3;N(a);J(a,(0.3+d)*b,(0.8+e)*c,!0,!0);a.lineTo((0.5+d)*b,(0.5+e)*c);a.lineTo((0.1+d)*b,(0.5+e)*c);a.lineTo((0.3+d)*b,(0.8+e)*c);N(a);b=a.s;b.fc=Sg;t.v(a);return b},IrritationHazard:function(a,b,c){a=t.u();J(a,0.2*b,0*c,!0);a.lineTo(0.5* +b,0.3*c);a.lineTo(0.8*b,0*c);a.lineTo(1*b,0.2*c);a.lineTo(0.7*b,0.5*c);a.lineTo(1*b,0.8*c);a.lineTo(0.8*b,1*c);a.lineTo(0.5*b,0.7*c);a.lineTo(0.2*b,1*c);a.lineTo(0*b,0.8*c);a.lineTo(0.3*b,0.5*c);a.lineTo(0*b,0.2*c);N(a);b=a.s;b.G=new H(0.3,0.3);b.H=new H(0.7,0.7);t.v(a);return b},ElectricalHazard:function(a,b,c){a=t.u();J(a,0.37,0*c,!0);a.lineTo(0.5*b,0.11*c);a.lineTo(0.77*b,0.04*c);a.lineTo(0.33*b,0.49*c);a.lineTo(1*b,0.37*c);a.lineTo(0.63*b,0.86*c);a.lineTo(0.77*b,0.91*c);a.lineTo(0.34*b,1*c);a.lineTo(0.34* +b,0.78*c);a.lineTo(0.44*b,0.8*c);a.lineTo(0.65*b,0.56*c);a.lineTo(0*b,0.68*c);N(a);b=a.s;t.v(a);return b},FireHazard:function(a,b,c){a=t.u();J(a,0.1*b,1*c,!0);K(a,-0.25*b,0.63*c,0.45*b,0.44*c,0.29*b,0*c);K(a,0.48*b,0.17*c,0.54*b,0.35*c,0.51*b,0.42*c);K(a,0.59*b,0.29*c,0.58*b,0.28*c,0.59*b,0.18*c);K(a,0.8*b,0.34*c,0.88*b,0.43*c,0.75*b,0.6*c);K(a,0.87*b,0.48*c,0.88*b,0.43*c,0.88*b,0.31*c);K(a,1.17*b,0.76*c,0.82*b,0.8*c,0.9*b,1*c);N(a);b=a.s;b.G=new H(0.05,0.645);b.H=new H(0.884,0.908);t.v(a);return b}, +BpmnActivityLoop:function(a,b,c){a=t.u();var d=4*(Math.SQRT2-1)/3*0.5;J(a,(0.5*Math.SQRT2/2+0.5)*b,(1-(0.5-0.5*Math.SQRT2/2))*c,!1);K(a,1*b,0.7*c,1*b,0.5*c,1*b,0.5*c);K(a,1*b,(0.5-d+0)*c,(0.5+d+0)*b,0*c,0.5*b,0*c);K(a,(0.5-d+0)*b,0*c,0*b,(0.5-d+0)*c,0*b,0.5*c);K(a,0*b,(0.5+d+0)*c,(0.5-d+0)*b,1*c,0.35*b,0.98*c);a.moveTo(0.35*b,0.8*c);a.lineTo(0.35*b,1*c);a.lineTo(0.15*b,1*c);b=a.s;t.v(a);return b},BpmnActivityParallel:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(0,1*c);a.moveTo(0.5*b,0);a.lineTo(0.5* +b,1*c);a.moveTo(1*b,0);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivitySequential:function(a,b,c){a=t.u();J(a,0,0,!1);a.lineTo(1*b,0);a.moveTo(0,0.5*c);a.lineTo(1*b,0.5*c);a.moveTo(0,1*c);a.lineTo(1*b,1*c);b=a.s;t.v(a);return b},BpmnActivityAdHoc:function(a,b,c){a=t.u();J(a,0,0,!1);J(a,1*b,1*c,!1);J(a,0,0.5*c,!1);K(a,0.2*b,0.35*c,0.3*b,0.35*c,0.5*b,0.5*c);K(a,0.7*b,0.65*c,0.8*b,0.65*c,1*b,0.5*c);b=a.s;t.v(a);return b},BpmnActivityCompensation:function(a,b,c){a=t.u();J(a,0,0.5*c,!0);a.lineTo(0.5* +b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,1*c);a.lineTo(1*b,0);a.lineTo(0.5*b,0.5*c);a.lineTo(0.5*b,1*c);N(a);b=a.s;t.v(a);return b},BpmnTaskMessage:function(a,b,c){a=t.u();J(a,0,0.2*c,!0);a.lineTo(1*b,0.2*c);a.lineTo(1*b,0.8*c);a.lineTo(0,0.8*c);a.lineTo(0,0.8*c);N(a);J(a,0,0.2*c,!1);a.lineTo(0.5*b,0.5*c);a.lineTo(1*b,0.2*c);a.Xa(!1);b=a.s;t.v(a);return b},BpmnTaskScript:function(a,b,c){a=t.u();J(a,0.7*b,1*c,!0);a.lineTo(0.3*b,1*c);K(a,0.6*b,0.5*c,0,0.5*c,0.3*b,0);a.lineTo(0.7*b,0);K(a,0.4*b,0.5*c, +1*b,0.5*c,0.7*b,1*c);N(a);J(a,0.45*b,0.73*c,!1);a.lineTo(0.7*b,0.73*c);a.moveTo(0.38*b,0.5*c);a.lineTo(0.63*b,0.5*c);a.moveTo(0.31*b,0.27*c);a.lineTo(0.56*b,0.27*c);a.Xa(!1);b=a.s;t.v(a);return b},BpmnTaskUser:function(a,b,c){a=t.u();J(a,0,0,!1);J(a,0.335*b,(1-0.555)*c,!0);a.lineTo(0.335*b,0.595*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.665*b,(1-0.555)*c);K(a,0.88*b,0.46*c,0.98*b,0.54*c,1*b,0.68*c);a.lineTo(1*b,1*c);a.lineTo(0,1*c);a.lineTo(0,0.68*c);K(a,0.02*b,0.54*c,0.12*b,0.46*c,0.335*b,(1-0.555)* +c);a.lineTo(0.365*b,0.405*c);var d=0.5-0.285,e=Math.PI/4,g=4*(1-Math.cos(e))/(3*Math.sin(e)),e=g*d,g=g*d;K(a,(0.5-(e+d)/2)*b,(d+(d+g)/2)*c,(0.5-d)*b,(d+g)*c,(0.5-d)*b,d*c);K(a,(0.5-d)*b,(d-g)*c,(0.5-e)*b,(d-d)*c,0.5*b,(d-d)*c);K(a,(0.5+e)*b,(d-d)*c,(0.5+d)*b,(d-g)*c,(0.5+d)*b,d*c);K(a,(0.5+d)*b,(d+g)*c,(0.5+(e+d)/2)*b,(d+(d+g)/2)*c,0.635*b,0.405*c);a.lineTo(0.635*b,0.405*c);a.lineTo(0.665*b,(1-0.555)*c);a.lineTo(0.665*b,0.595*c);a.lineTo(0.335*b,0.595*c);J(a,0.2*b,1*c,!1);a.lineTo(0.2*b,0.8*c);J(a, +0.8*b,1*c,!1);a.lineTo(0.8*b,0.8*c);b=a.s;t.v(a);return b},BpmnEventConditional:function(a,b,c){a=t.u();J(a,0.1*b,0,!0);a.lineTo(0.9*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.1*b,1*c);N(a);J(a,0.2*b,0.2*c,!1);a.lineTo(0.8*b,0.2*c);a.moveTo(0.2*b,0.4*c);a.lineTo(0.8*b,0.4*c);a.moveTo(0.2*b,0.6*c);a.lineTo(0.8*b,0.6*c);a.moveTo(0.2*b,0.8*c);a.lineTo(0.8*b,0.8*c);a.Xa(!1);b=a.s;t.v(a);return b},BpmnEventError:function(a,b,c){a=t.u();J(a,0,1*c,!0);a.lineTo(0.33*b,0);a.lineTo(0.66*b,0.5*c);a.lineTo(1*b,0);a.lineTo(0.66* +b,1*c);a.lineTo(0.33*b,0.5*c);N(a);b=a.s;t.v(a);return b},BpmnEventEscalation:function(a,b,c){a=t.u();J(a,0,0,!1);J(a,1*b,1*c,!1);J(a,0.1*b,1*c,!0);a.lineTo(0.5*b,0);a.lineTo(0.9*b,1*c);a.lineTo(0.5*b,0.5*c);N(a);b=a.s;t.v(a);return b},BpmnEventTimer:function(a,b,c){a=t.u();var d=0.5*D.sa;J(a,1*b,0.5*c,!0);K(a,1*b,(0.5+d)*c,(0.5+d)*b,1*c,0.5*b,1*c);K(a,(0.5-d)*b,1*c,0,(0.5+d)*c,0,0.5*c);K(a,0,(0.5-d)*c,(0.5-d)*b,0,0.5*b,0);K(a,(0.5+d)*b,0,1*b,(0.5-d)*c,1*b,0.5*c);J(a,0.5*b,0,!1);a.lineTo(0.5*b,0.15* +c);a.moveTo(0.5*b,1*c);a.lineTo(0.5*b,0.85*c);a.moveTo(0,0.5*c);a.lineTo(0.15*b,0.5*c);a.moveTo(1*b,0.5*c);a.lineTo(0.85*b,0.5*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.58*b,0.1*c);a.moveTo(0.5*b,0.5*c);a.lineTo(0.78*b,0.54*c);a.Xa(!1);b=a.s;b.fc=Sg;t.v(a);return b}};for(var Vl in D.Bi)D.Bi[Vl.toLowerCase()]=Vl; +D.sv={"":"",Standard:"F1 m 0,0 l 8,4 -8,4 2,-4 z",Backward:"F1 m 8,0 l -2,4 2,4 -8,-4 z",Triangle:"F1 m 0,0 l 8,4.62 -8,4.62 z",BackwardTriangle:"F1 m 8,4 l 0,4 -8,-4 8,-4 0,4 z",Boomerang:"F1 m 0,0 l 8,4 -8,4 4,-4 -4,-4 z",BackwardBoomerang:"F1 m 8,0 l -8,4 8,4 -4,-4 4,-4 z",SidewaysV:"m 0,0 l 8,4 -8,4 0,-1 6,-3 -6,-3 0,-1 z",BackwardV:"m 8,0 l -8,4 8,4 0,-1 -6,-3 6,-3 0,-1 z",OpenTriangle:"m 0,0 l 8,4 -8,4",BackwardOpenTriangle:"m 8,0 l -8,4 8,4",OpenTriangleLine:"m 0,0 l 8,4 -8,4 m 8.5,0 l 0,-8", +BackwardOpenTriangleLine:"m 8,0 l -8,4 8,4 m -8.5,0 l 0,-8",OpenTriangleTop:"m 0,0 l 8,4 m 0,4",BackwardOpenTriangleTop:"m 8,0 l -8,4 m 0,4",OpenTriangleBottom:"m 0,8 l 8,-4",BackwardOpenTriangleBottom:"m 0,4 l 8,4",HalfTriangleTop:"F1 m 0,0 l 0,4 8,0 z m 0,8",BackwardHalfTriangleTop:"F1 m 8,0 l 0,4 -8,0 z m 0,8",HalfTriangleBottom:"F1 m 0,4 l 0,4 8,-4 z",BackwardHalfTriangleBottom:"F1 m 8,4 l 0,4 -8,-4 z",ForwardSemiCircle:"m 4,0 b 270 180 0 4 4",BackwardSemiCircle:"m 4,8 b 90 180 0 -4 4",Feather:"m 0,0 l 3,4 -3,4", +BackwardFeather:"m 3,0 l -3,4 3,4",DoubleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardDoubleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4",TripleFeathers:"m 0,0 l 3,4 -3,4 m 3,-8 l 3,4 -3,4 m 3,-8 l 3,4 -3,4",BackwardTripleFeathers:"m 3,0 l -3,4 3,4 m 3,-8 l -3,4 3,4 m 3,-8 l -3,4 3,4",ForwardSlash:"m 0,8 l 5,-8",BackSlash:"m 0,0 l 5,8",DoubleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8",DoubleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8",TripleForwardSlash:"m 0,8 l 4,-8 m -2,8 l 4,-8 m -2,8 l 4,-8", +TripleBackSlash:"m 0,0 l 4,8 m -2,-8 l 4,8 m -2,-8 l 4,8",Fork:"m 0,4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4",LineFork:"m 0,0 l 0,8 m 0,-4 l 8,0 m -8,0 l 8,-4 m -8,4 l 8,4",BackwardLineFork:"m 8,4 l -8,0 m 8,0 l -8,-4 m 8,4 l -8,4 m 8,-8 l 0,8",CircleFork:"F1 m 6,4 b 0 360 -3 0 3 z m 0,0 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4",BackwardCircleFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 6,0 b 0 360 -3 0 3",CircleLineFork:"F1 m 6,4 b 0 360 -3 0 3 z m 1,-4 l 0,8 m 0,-4 l 6,0 m -6,0 l 6,-4 m -6,4 l 6,4", +BackwardCircleLineFork:"F1 m 0,4 l 6,0 m -6,-4 l 6,4 m -6,4 l 6,-4 m 0,-4 l 0,8 m 7,-4 b 0 360 -3 0 3",Circle:"F1 m 8,4 b 0 360 -4 0 4 z",Block:"F1 m 0,0 l 0,8 8,0 0,-8 z",StretchedDiamond:"F1 m 0,3 l 5,-3 5,3 -5,3 -5,-3 z",Diamond:"F1 m 0,4 l 4,-4 4,4 -4,4 -4,-4 z",Chevron:"F1 m 0,0 l 5,0 3,4 -3,4 -5,0 3,-4 -3,-4 z",StretchedChevron:"F1 m 0,0 l 8,0 3,4 -3,4 -8,0 3,-4 -3,-4 z",NormalArrow:"F1 m 0,2 l 4,0 0,-2 4,4 -4,4 0,-2 -4,0 z",X:"m 0,0 l 8,8 m 0,-8 l -8,8",TailedNormalArrow:"F1 m 0,0 l 2,0 1,2 3,0 0,-2 2,4 -2,4 0,-2 -3,0 -1,2 -2,0 1,-4 -1,-4 z", +DoubleTriangle:"F1 m 0,0 l 4,4 -4,4 0,-8 z m 4,0 l 4,4 -4,4 0,-8 z",BigEndArrow:"F1 m 0,0 l 5,2 0,-2 3,4 -3,4 0,-2 -5,2 0,-8 z",ConcaveTailArrow:"F1 m 0,2 h 4 v -2 l 4,4 -4,4 v -2 h -4 l 2,-2 -2,-2 z",RoundedTriangle:"F1 m 0,1 a 1,1 0 0 1 1,-1 l 7,3 a 0.5,1 0 0 1 0,2 l -7,3 a 1,1 0 0 1 -1,-1 l 0,-6 z",SimpleArrow:"F1 m 1,2 l -1,-2 2,0 1,2 -1,2 -2,0 1,-2 5,0 0,-2 2,2 -2,2 0,-2 z",AccelerationArrow:"F1 m 0,0 l 0,8 0.2,0 0,-8 -0.2,0 z m 2,0 l 0,8 1,0 0,-8 -1,0 z m 3,0 l 2,0 2,4 -2,4 -2,0 0,-8 z",BoxArrow:"F1 m 0,0 l 4,0 0,2 2,0 0,-2 2,4 -2,4 0,-2 -2,0 0,2 -4,0 0,-8 z", +TriangleLine:"F1 m 8,4 l -8,-4 0,8 8,-4 z m 0.5,4 l 0,-8",CircleEndedArrow:"F1 m 10,4 l -2,-3 0,2 -2,0 0,2 2,0 0,2 2,-3 z m -4,0 b 0 360 -3 0 3 z",DynamicWidthArrow:"F1 m 0,3 l 2,0 2,-1 2,-2 2,4 -2,4 -2,-2 -2,-1 -2,0 0,-2 z",EquilibriumArrow:"m 0,3 l 8,0 -3,-3 m 3,5 l -8,0 3,3",FastForward:"F1 m 0,0 l 3.5,4 0,-4 3.5,4 0,-4 1,0 0,8 -1,0 0,-4 -3.5,4 0,-4 -3.5,4 0,-8 z",Kite:"F1 m 0,4 l 2,-4 6,4 -6,4 -2,-4 z",HalfArrowTop:"F1 m 0,0 l 4,4 4,0 -8,-4 z m 0,8",HalfArrowBottom:"F1 m 0,8 l 4,-4 4,0 -8,4 z", +OpposingDirectionDoubleArrow:"F1 m 0,4 l 2,-4 0,2 4,0 0,-2 2,4 -2,4 0,-2 -4,0 0,2 -2,-4 z",PartialDoubleTriangle:"F1 m 0,0 4,3 0,-3 4,4 -4,4 0,-3 -4,3 0,-8 z",LineCircle:"F1 m 0,0 l 0,8 m 7 -4 b 0 360 -3 0 3 z",DoubleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",TripleLineCircle:"F1 m 0,0 l 0,8 m 2,-8 l 0,8 m 2,-8 l 0,8 m 7 -4 b 0 360 -3 0 3 z",CircleLine:"F1 m 6 4 b 0 360 -3 0 3 z m 1,-4 l 0,8",DiamondCircle:"F1 m 8,4 l -4,4 -4,-4 4,-4 4,4 m 8,0 b 0 360 -4 0 4 z",PlusCircle:"F1 m 8,4 b 0 360 -4 0 4 l -8 0 z m -4 -4 l 0 8", +OpenRightTriangleTop:"m 8,0 l 0,4 -8,0 m 0,4",OpenRightTriangleBottom:"m 8,8 l 0,-4 -8,0",Line:"m 0,0 l 0,8",DoubleLine:"m 0,0 l 0,8 m 2,0 l 0,-8",TripleLine:"m 0,0 l 0,8 m 2,0 l 0,-8 m 2,0 l 0,8",PentagonArrow:"F1 m 8,4 l -4,-4 -4,0 0,8 4,0 4,-4 z",None:""};D.mA={};D.tv={};D.yo=function(a){if(D.sv){for(var b in D.sv){var c=Qc(D.sv[b],!1);D.tv[b]=c;b.toLowerCase()!==b&&(D.tv[b.toLowerCase()]=b)}D.sv=void 0}return D.tv[a]};Y.FigureGenerators=D.Bi;Y.ArrowheadGeometries=D.tv; +function B(a){0===arguments.length?y.call(this):y.call(this,a);this.aa=49663;this.Dn=this.Sg="";this.ur=this.rr=this.Dr=this.Hq=null;this.Fr="";this.Kh=this.Er=this.Yl=null;this.tr="";this.Rn=null;this.sr=(new ea(NaN,NaN)).freeze();this.vr="";this.Sn=null;this.Zd="";this.Cn=this.Xp=this.ok=null;this.Yh=(new v(NaN,NaN)).freeze();this.Pq="";this.Bk=null;this.Qq=wb;this.Zq=D.TF;this.Sq=D.SF;this.gq=null;this.Iq=Wl;this.am=(new v(6,6)).freeze();this.$l="gray";this.Zl=4;this.fG=-1;this.cG=new w;this.nj= +null;this.lj=NaN}t.ea("Part",B);t.Ja(B,y);B.prototype.cloneProtected=function(a){y.prototype.cloneProtected.call(this,a);a.aa=this.aa&-4097|49152;a.Sg=this.Sg;a.Dn=this.Dn;a.Hq=this.Hq;a.Dr=this.Dr;a.rr=this.rr;a.ur=this.ur;a.Fr=this.Fr;a.Er=this.Er;a.Kh=null;a.tr=this.tr;a.sr.assign(this.sr);a.vr=this.vr;a.Zd=this.Zd;a.Xp=this.Xp;a.Yh.assign(this.Yh);a.Pq=this.Pq;a.Qq=this.Qq.W();a.Zq=this.Zq.W();a.Sq=this.Sq.W();a.gq=this.gq;a.Iq=this.Iq;a.am.assign(this.am);a.$l=this.$l;a.Zl=this.Zl}; +B.prototype.uh=function(a){y.prototype.uh.call(this,a);Tj(a);a.Yl=null;a.Rn=null;a.Sn=null;a.Bk=null;a.nj=null};B.prototype.toString=function(){var a=t.Gg(Object.getPrototypeOf(this))+"#"+t.jc(this);this.data&&(a+="("+vd(this.data)+")");return a};B.LayoutNone=0;var Di;B.LayoutAdded=Di=1;var Ii;B.LayoutRemoved=Ii=2;var Dh;B.LayoutShown=Dh=4;var Eh;B.LayoutHidden=Eh=8;B.LayoutNodeSized=16;var $i;B.LayoutGroupLayout=$i=32;B.LayoutNodeReplaced=64;var Wl;B.LayoutStandard=Wl=Di|Ii|Dh|Eh|16|$i|64; +B.prototype.Im=function(a,b,c,d,e,g,h){var k=this.h;null!==k&&(a===td&&"elements"===b?e instanceof y&&Ei(e,function(a){Fi(k,a)}):a===ud&&"elements"===b&&e instanceof y&&Ei(e,function(a){Hi(k,a)}),k.Mc(a,b,c,d,e,g,h))};B.prototype.updateTargetBindings=B.prototype.Eb=function(a){y.prototype.Eb.call(this,a);if(null!==this.data)for(a=this.elements;a.next();){var b=a.value;b instanceof y&&Ei(b,function(a){null!==a.data&&a.Eb()})}};t.A(B,{nv:"adornments"},function(){return null===this.Kh?t.Pg:this.Kh.m}); +B.prototype.findAdornment=B.prototype.xo=function(a){f&&t.j(a,"string",B,"findAdornment:category");var b=this.Kh;return null===b?null:b.wa(a)};B.prototype.addAdornment=B.prototype.Jk=function(a,b){if(null!==b){f&&(t.j(a,"string",B,"addAdornment:category"),t.k(b,Fe,B,"addAdornment:ad"));var c=null,d=this.Kh;null!==d&&(c=d.wa(a));if(c!==b){if(null!==c){var e=c.h;null!==e&&e.remove(c)}null===d&&(this.Kh=d=new ia("string",Fe));b.Sg!==a&&(b.Hc=a);d.add(a,b);c=this.h;null!==c&&(c.add(b),b.data=this.data)}}}; +B.prototype.removeAdornment=B.prototype.fl=function(a){f&&t.j(a,"string",B,"removeAdornment:category");var b=this.Kh;if(null!==b){var c=b.wa(a);if(null!==c){var d=c.h;null!==d&&d.remove(c)}b.remove(a);0===b.count&&(this.Kh=null)}};B.prototype.clearAdornments=B.prototype.ve=function(){var a=this.Kh;if(null!==a){for(var b=t.yb(),a=a.m;a.next();)b.push(a.key);for(var a=b.length,c=0;c=c.mE)){this.aa^=4096;var d=!1;if(null!==c){d=c.xb;c.xb=!0;var e=c.selection;e.Pa();a?e.add(this):e.remove(this);e.freeze()}this.i("isSelected",b,a);Yl(this);a=this.$E;null!==a&&a(this);null!==c&&(c.Gf(),c.xb=d)}}});t.g(B,"isShadowed",B.prototype.Gi); +t.defineProperty(B,{Gi:"isShadowed"},function(){return 0!==(this.aa&8192)},function(a){var b=0!==(this.aa&8192);b!==a&&(f&&t.j(a,"boolean",B,"isShadowed"),this.aa^=8192,this.i("isShadowed",b,a),this.na())});function ui(a){return 0!==(a.aa&32768)}function Zl(a,b){a.aa=b?a.aa|32768:a.aa&-32769}function Vj(a,b){a.aa=b?a.aa|65536:a.aa&-65537}function yh(a){return 0!==(a.aa&131072)}B.prototype.Hf=function(a){this.aa=a?this.aa|131072:this.aa&-131073};t.g(B,"selectionObjectName",B.prototype.vw); +t.defineProperty(B,{vw:"selectionObjectName"},function(){return this.Fr},function(a){var b=this.Fr;b!==a&&(f&&t.j(a,"string",B,"selectionObjectName"),this.Fr=a,this.Yl=null,this.i("selectionObjectName",b,a))});t.g(B,"selectionAdornmentTemplate",B.prototype.ZE);t.defineProperty(B,{ZE:"selectionAdornmentTemplate"},function(){return this.Dr},function(a){var b=this.Dr;b!==a&&(f&&t.k(a,Fe,B,"selectionAdornmentTemplate"),this instanceof X&&(a.type=pg),this.Dr=a,this.i("selectionAdornmentTemplate",b,a))}); +t.A(B,{dt:"selectionObject"},function(){if(null===this.Yl){var a=this.vw;null!==a&&""!==a?(a=this.de(a),this.Yl=null!==a?a:this):this instanceof X?(a=this.path,this.Yl=null!==a?a:this):this.Yl=this}return this.Yl});t.g(B,"selectionChanged",B.prototype.$E);t.defineProperty(B,{$E:"selectionChanged"},function(){return this.Er},function(a){var b=this.Er;b!==a&&(null!==a&&t.j(a,"function",B,"selectionChanged"),this.Er=a,this.i("selectionChanged",b,a))});t.g(B,"resizeAdornmentTemplate",B.prototype.KE); +t.defineProperty(B,{KE:"resizeAdornmentTemplate"},function(){return this.rr},function(a){var b=this.rr;b!==a&&(f&&t.k(a,Fe,B,"resizeAdornmentTemplate"),this.rr=a,this.i("resizeAdornmentTemplate",b,a))});t.g(B,"resizeObjectName",B.prototype.NE);t.defineProperty(B,{NE:"resizeObjectName"},function(){return this.tr},function(a){var b=this.tr;b!==a&&(f&&t.j(a,"string",B,"resizeObjectName"),this.tr=a,this.Rn=null,this.i("resizeObjectName",b,a))}); +t.A(B,{ME:"resizeObject"},function(){if(null===this.Rn){var a=this.NE;null!==a&&""!==a?(a=this.de(a),this.Rn=null!==a?a:this):this.Rn=this}return this.Rn});t.g(B,"resizeCellSize",B.prototype.LE);t.defineProperty(B,{LE:"resizeCellSize"},function(){return this.sr},function(a){var b=this.sr;b.K(a)||(f&&t.k(a,ea,B,"resizeCellSize"),this.sr=a=a.W(),this.i("resizeCellSize",b,a))});t.g(B,"rotateAdornmentTemplate",B.prototype.QE); +t.defineProperty(B,{QE:"rotateAdornmentTemplate"},function(){return this.ur},function(a){var b=this.ur;b!==a&&(f&&t.k(a,Fe,B,"rotateAdornmentTemplate"),this.ur=a,this.i("rotateAdornmentTemplate",b,a))});t.g(B,"rotateObjectName",B.prototype.SE);t.defineProperty(B,{SE:"rotateObjectName"},function(){return this.vr},function(a){var b=this.vr;b!==a&&(f&&t.j(a,"string",B,"rotateObjectName"),this.vr=a,this.Sn=null,this.i("rotateObjectName",b,a))}); +t.A(B,{RE:"rotateObject"},function(){if(null===this.Sn){var a=this.SE;null!==a&&""!==a?(a=this.de(a),this.Sn=null!==a?a:this):this.Sn=this}return this.Sn});t.g(B,"text",B.prototype.text);t.defineProperty(B,{text:"text"},function(){return this.Zd},function(a){var b=this.Zd;b!==a&&(f&&t.j(a,"string",B,"text"),this.Zd=a,this.i("text",b,a))});t.g(B,"containingGroup",B.prototype.ib); +t.defineProperty(B,{ib:"containingGroup"},function(){return this.ok},function(a){if(this.Kd()){var b=this.ok;if(b!==a){f&&null!==a&&t.k(a,V,B,"containingGroup");null===a||this!==a&&!a.Fs(this)||(this===a&&t.l("Cannot make a Group a member of itself: "+this.toString()),t.l("Cannot make a Group indirectly contain itself: "+this.toString()+" already contains "+a.toString()));this.J(Ii);var c=this.h;null!==b?em(b,this):this instanceof V&&null!==c&&c.Hk.remove(this);this.ok=a;null!==a?fm(a,this):this instanceof +V&&null!==c&&c.Hk.add(this);this.J(Di);if(null!==c){var d=this.data,e=c.da;null!==d&&e instanceof P&&e.DA(d,e.Hb(null!==a?a.data:null))}d=this.wz;null!==d&&(e=!0,null!==c&&(e=c.Ra,c.Ra=!0),d(this,b,a),null!==c&&(c.Ra=e));if(this instanceof V)for(c=new la(B),Ee(c,this,!0,0),c=c.m;c.next();)if(d=c.value,d instanceof S)for(d=d.ie;d.next();)e=d.value,Wi(e);if(this instanceof S)for(d=this.ie;d.next();)e=d.value,Wi(e);this.i("containingGroup",b,a);null!==a&&a.zw()}}else t.l("cannot set the Part.containingGroup of a Link or Adornment")}); +function Tj(a){a=a.ib;null!==a&&(a.Y(),null!==a.rb&&a.rb.Y(),a.Ig())}B.prototype.As=function(){var a=this.ok;null!==a&&fm(a,this)};B.prototype.Bs=function(){var a=this.ok;null!==a&&em(a,this)};B.prototype.sm=function(){var a=this.data;if(null!==a){var b=this.h;null!==b&&(b=b.da,null!==b&&b.rw(a))}};t.g(B,"containingGroupChanged",B.prototype.wz); +t.defineProperty(B,{wz:"containingGroupChanged"},function(){return this.Xp},function(a){var b=this.Xp;b!==a&&(null!==a&&t.j(a,"function",B,"containingGroupChanged"),this.Xp=a,this.i("containingGroupChanged",b,a))});B.prototype.findTopLevelPart=function(){return gm(this,this)};function gm(a,b){var c=b.ib;return null!==c?gm(a,c):b instanceof S&&(c=b.ld,null!==c)?gm(a,c):b}t.A(B,{Oo:"isTopLevel"},function(){return null!==this.ib||this instanceof S&&this.wh?!1:!0}); +B.prototype.isMemberOf=B.prototype.Fs=function(a){return a instanceof V?hm(this,this,a):!1};function hm(a,b,c){if(b===c||null===c)return!1;var d=b.ib;return null===d||d!==c&&!hm(a,d,c)?b instanceof S&&(b=b.ld,null!==b)?hm(a,b,c):!1:!0}B.prototype.findCommonContainingGroup=B.prototype.sH=function(a){return im(this,this,a)}; +function im(a,b,c){if(null===b||null===c)return null;var d=b.ib;if(null===d)return null;if(b===c)return d;var e=c.ib;return null===e?null:d===e?e:hm(a,c,d)?d:hm(a,b,e)?e:im(a,d,e)}t.g(B,"layoutConditions",B.prototype.eE);t.defineProperty(B,{eE:"layoutConditions"},function(){return this.Iq},function(a){var b=this.Iq;b!==a&&(f&&t.j(a,"number",B,"layoutConditions"),this.Iq=a,this.i("layoutConditions",b,a))}); +B.prototype.canLayout=function(){if(!this.Vz||!this.ub())return!1;var a=this.layer;return null!==a&&a.kc||this instanceof S&&this.wh?!1:!0};B.prototype.invalidateLayout=B.prototype.J=function(a){void 0===a&&(a=16777215);var b;this.Vz&&0!==(a&this.eE)?(b=this.layer,null!==b&&b.kc||this instanceof S&&this.wh?b=!1:(b=this.h,b=null!==b&&b.va.kb?!1:!0)):b=!1;if(b)if(b=this.ok,null!==b){var c=b.Vb;null!==c?c.J():b.J(a)}else a=this.h,null!==a&&(c=a.Vb,null!==c&&c.J())};t.g(B,"dragComputation",B.prototype.Bz); +t.defineProperty(B,{Bz:"dragComputation"},function(){return this.gq},function(a){var b=this.gq;b!==a&&(null!==a&&t.j(a,"function",B,"dragComputation"),this.gq=a,this.i("dragComputation",b,a))});t.g(B,"shadowOffset",B.prototype.dF);t.defineProperty(B,{dF:"shadowOffset"},function(){return this.am},function(a){var b=this.am;b.K(a)||(f&&t.k(a,v,B,"shadowOffset"),this.am=a=a.W(),this.na(),this.i("shadowOffset",b,a))});t.g(B,"shadowColor",B.prototype.shadowColor); +t.defineProperty(B,{shadowColor:"shadowColor"},function(){return this.$l},function(a){var b=this.$l;b!==a&&(f&&t.j(a,"string",B,"shadowColor"),this.$l=a,this.na(),this.i("shadowColor",b,a))});t.g(B,"shadowBlur",B.prototype.shadowBlur);t.defineProperty(B,{shadowBlur:"shadowBlur"},function(){return this.Zl},function(a){var b=this.Zl;b!==a&&(f&&t.j(a,"number",B,"shadowBlur"),this.Zl=a,this.na(),this.i("shadowBlur",b,a))}); +function Fe(a){0===arguments.length?B.call(this,Vg):B.call(this,a);this.he="Adornment";this.Ga=null;this.aa&=-257;this.Yh=new v(NaN,NaN);this.Lh=new A(w);this.rb=null;this.hy=!1}t.ea("Adornment",Fe);t.Ja(Fe,B);aa=Fe.prototype;aa.toString=function(){var a=this.rh;return"Adornment("+this.Hc+")"+(null!==a?a.toString():"")};aa.bj=function(){return this.Ga&&this.Ga.Q instanceof X?this.Ga.Q.bj():null};aa.rq=function(){return null}; +aa.iw=function(){var a=this.Gc.Q,b=this.Gc;if(a instanceof X&&b instanceof Y){var c=a.path,b=c.La;a.iw();for(var b=c.La,a=this.za,c=a.length,d=0;da&&(a=1);var b=this.h;if(null!==b&&!b.Hd){b.Hd=!0;var c=b.Yc,d=new la(S);d.add(this);qm(this,d,c,a,this.Ac);b.Hd=!1;b.na()}}; +function qm(a,b,c,d,e){if(1a&&(a=2);var b=this.h;if(null!==b&&!b.Hd){b.Hd=!0;var c=b.Yc,d=new la(S);d.add(this);sm(this,d,c,a,this.Ac);b.Hd=!1}};function sm(a,b,c,d,e){a.Ac=!0;for(var g=c?a.Ov():a.Zf();g.next();){var h=g.value;h.sc&&(e||(h.Eg||h.Tb(),h.updateAdornments()),h=h.Jz(a),null!==h&&h!==a&&!b.contains(h)&&(b.add(h),e||(h.na(),h.updateAdornments(),Tj(h),h.J(Dh)),2a&&(a=2),null===c||c.Hd||(c.Hd=!0,b=c.Yc,d=new la(S),d.add(this),sm(this,d,b,a,!1),c.Hd=!1)):(a=1,1>a&&(a=1),null===c||c.Hd||(c.Hd=!0,b=c.Yc,d=new la(S),d.add(this),qm(this,d,b,a,!0),c.Hd=!1)))}}); +t.g(S,"wasTreeExpanded",S.prototype.Pm);t.defineProperty(S,{Pm:"wasTreeExpanded"},function(){return this.$r},function(a){var b=this.$r;b!==a&&(f&&t.j(a,"boolean",S,"wasTreeExpanded"),this.$r=a,this.i("wasTreeExpanded",b,a))});t.g(S,"treeExpandedChanged",S.prototype.AF);t.defineProperty(S,{AF:"treeExpandedChanged"},function(){return this.Vr},function(a){var b=this.Vr;b!==a&&(null!==a&&t.j(a,"function",S,"treeExpandedChanged"),this.Vr=a,this.i("treeExpandedChanged",b,a))});t.g(S,"isTreeLeaf",S.prototype.yh); +t.defineProperty(S,{yh:"isTreeLeaf"},function(){return this.Dq},function(a){var b=this.Dq;b!==a&&(f&&t.j(a,"boolean",S,"isTreeLeaf"),this.Dq=a,this.i("isTreeLeaf",b,a))}); +function X(){B.call(this,pg);this.Lf=null;this.$g="";this.Tf=this.pq=null;this.oh="";this.Ur=null;this.qr=this.pr=this.or=!1;this.Eq=!0;this.Lp=sg;this.Yp=0;this.aq=sg;this.bq=NaN;this.Ul=Ek;this.Kr=0.5;this.gi=this.$e=null;this.qc=(new A(v)).freeze();this.pe=null;this.Eg=!1;this.Ey=null;this.Qy=!1;this.Ym=this.Th=this.La=null;this.Xe=0;this.hn=this.dn=null;this.Lh=new A(w);this.Vy=new v;this.rC=this.pC=null;this.sx=!1;this.T=null}t.ea("Link",X);t.Ja(X,B); +X.prototype.cloneProtected=function(a){B.prototype.cloneProtected.call(this,a);a.$g=this.$g;a.pq=this.pq;a.oh=this.oh;a.Ur=this.Ur;a.or=this.or;a.pr=this.pr;a.qr=this.qr;a.Eq=this.Eq;a.Lp=this.Lp;a.Yp=this.Yp;a.aq=this.aq;a.bq=this.bq;a.Ul=this.Ul;a.Kr=this.Kr};X.prototype.uh=function(a){B.prototype.uh.call(this,a);this.$g=a.$g;this.oh=a.oh;a.gi=null;a.pe=null;a.Tb();a.Ym=this.Ym;a.Xe=this.Xe};var Ek;X.Normal=Ek=t.w(X,"Normal",1);X.Orthogonal=t.w(X,"Orthogonal",2); +X.AvoidsNodes=t.w(X,"AvoidsNodes",6);var tm;X.AvoidsNodesStraight=tm=t.w(X,"AvoidsNodesStraight",7);var sg;X.None=sg=t.w(X,"None",0);var Kg;X.Bezier=Kg=t.w(X,"Bezier",9);var rg;X.JumpGap=rg=t.w(X,"JumpGap",10);var qg;X.JumpOver=qg=t.w(X,"JumpOver",11);var Bk;X.End=Bk=t.w(X,"End",17);var Ck;X.Scale=Ck=t.w(X,"Scale",18);var Dk;X.Stretch=Dk=t.w(X,"Stretch",19);var Kl;X.OrientAlong=Kl=t.w(X,"OrientAlong",21);var um;X.OrientPlus90=um=t.w(X,"OrientPlus90",22);var vm; +X.OrientMinus90=vm=t.w(X,"OrientMinus90",23);var wm;X.OrientOpposite=wm=t.w(X,"OrientOpposite",24);var xm;X.OrientUpright=xm=t.w(X,"OrientUpright",25);var ym;X.OrientPlus90Upright=ym=t.w(X,"OrientPlus90Upright",26);var zm;X.OrientMinus90Upright=zm=t.w(X,"OrientMinus90Upright",27);var Am;X.OrientUpright45=Am=t.w(X,"OrientUpright45",28);X.prototype.Be=function(){this.T={aj:vb,Cj:vb,Zi:NaN,Aj:NaN,Yi:jm,zj:jm,$i:NaN,Bj:NaN}}; +X.prototype.$k=function(){var a=this.ca;if(null!==a&&(ti(a)||ui(a)))return!1;a=this.ga;return null!==a&&(ti(a)||ui(a))?!1:!0};X.prototype.Kd=function(){return!1}; +X.prototype.computeAngle=function(a,b,c){switch(b){default:case sg:a=0;break;case Kl:a=c;break;case um:a=c+90;break;case vm:a=c-90;break;case wm:a=c+180;break;case xm:a=D.Ts(c);90a&&(a-=180);break;case ym:a=D.Ts(c+90);90a&&(a-=180);break;case zm:a=D.Ts(c-90);90a&&(a-=180);break;case Am:a=D.Ts(c);if(45a||225a)return 0;90a&&(a-=180)}return D.Ts(a)};t.g(X,"fromNode",X.prototype.ca); +t.defineProperty(X,{ca:"fromNode"},function(){return this.Lf},function(a){var b=this.Lf;if(b!==a){f&&null!==a&&t.k(a,S,X,"fromNode");var c=this.Wc;null!==b&&(this.Tf!==b&&om(b,this,c),null!==c&&(c.Xd=null),Bm(this),b.J(Ii));this.Lf=a;this.Th=null;this.Tb();var d=this.h;if(null!==d){var e=this.data,g=d.da;if(null!==e)if(g instanceof P){var h=null!==a?a.data:null;g.BA(e,g.Hb(h))}else g instanceof Jd&&(h=null!==a?a.data:null,d.Yc?g.Ch(e,g.Hb(h)):(null!==b&&g.Ch(b.data,void 0),g.Ch(h,g.Hb(null!==this.Tf? +this.Tf.data:null))))}e=this.Wc;g=this.Iz;null!==g&&(h=!0,null!==d&&(h=d.Ra,d.Ra=!0),g(this,c,e),null!==d&&(d.Ra=h));null!==a&&(this.Tf!==a&&nm(a,this,e),null!==e&&(e.Xd=null),Cm(this),a.J(Di));this.i("fromNode",b,a);Wi(this)}});t.g(X,"fromPortId",X.prototype.Af); +t.defineProperty(X,{Af:"fromPortId"},function(){return this.$g},function(a){var b=this.$g;if(b!==a){f&&t.j(a,"string",X,"fromPortId");var c=this.Wc;null!==c&&(c.Xd=null);Bm(this);this.$g=a;var d=this.Wc;null!==d&&(d.Xd=null);var e=this.h;if(null!==e){var g=this.data,h=e.da;null!==g&&h instanceof P&&h.CA(g,a)}c!==d&&(this.Th=null,this.Tb(),g=this.Iz,null!==g&&(h=!0,null!==e&&(h=e.Ra,e.Ra=!0),g(this,c,d),null!==e&&(e.Ra=h)));Cm(this);this.i("fromPortId",b,a)}}); +t.A(X,{Wc:"fromPort"},function(){var a=this.Lf;return null===a?null:a.us(this.$g)});t.g(X,"fromPortChanged",X.prototype.Iz);t.defineProperty(X,{Iz:"fromPortChanged"},function(){return this.pq},function(a){var b=this.pq;b!==a&&(null!==a&&t.j(a,"function",X,"fromPortChanged"),this.pq=a,this.i("fromPortChanged",b,a))});t.g(X,"toNode",X.prototype.ga); +t.defineProperty(X,{ga:"toNode"},function(){return this.Tf},function(a){var b=this.Tf;if(b!==a){f&&null!==a&&t.k(a,S,X,"toNode");var c=this.Qd;null!==b&&(this.Lf!==b&&om(b,this,c),null!==c&&(c.Xd=null),Bm(this),b.J(Ii));this.Tf=a;this.Th=null;this.Tb();var d=this.h;if(null!==d){var e=this.data,g=d.da;if(null!==e)if(g instanceof P){var h=null!==a?a.data:null;g.GA(e,g.Hb(h))}else g instanceof Jd&&(h=null!==a?a.data:null,d.Yc?(null!==b&&g.Ch(b.data,void 0),g.Ch(h,g.Hb(null!==this.Lf?this.Lf.data:null))): +g.Ch(e,g.Hb(h)))}e=this.Qd;g=this.OA;null!==g&&(h=!0,null!==d&&(h=d.Ra,d.Ra=!0),g(this,c,e),null!==d&&(d.Ra=h));null!==a&&(this.Lf!==a&&nm(a,this,e),null!==e&&(e.Xd=null),Cm(this),a.J(Di));this.i("toNode",b,a);Wi(this)}});t.g(X,"toPortId",X.prototype.ng); +t.defineProperty(X,{ng:"toPortId"},function(){return this.oh},function(a){var b=this.oh;if(b!==a){f&&t.j(a,"string",X,"toPortId");var c=this.Qd;null!==c&&(c.Xd=null);Bm(this);this.oh=a;var d=this.Qd;null!==d&&(d.Xd=null);var e=this.h;if(null!==e){var g=this.data,h=e.da;null!==g&&h instanceof P&&h.HA(g,a)}c!==d&&(this.Th=null,this.Tb(),g=this.OA,null!==g&&(h=!0,null!==e&&(h=e.Ra,e.Ra=!0),g(this,c,d),null!==e&&(e.Ra=h)));Cm(this);this.i("toPortId",b,a)}}); +t.A(X,{Qd:"toPort"},function(){var a=this.Tf;return null===a?null:a.us(this.oh)});t.g(X,"toPortChanged",X.prototype.OA);t.defineProperty(X,{OA:"toPortChanged"},function(){return this.Ur},function(a){var b=this.Ur;b!==a&&(null!==a&&t.j(a,"function",X,"toPortChanged"),this.Ur=a,this.i("toPortChanged",b,a))}); +t.defineProperty(X,{fb:"fromSpot"},function(){return null!==this.T?this.T.aj:vb},function(a){null===this.T&&this.Be();var b=this.T.aj;b.K(a)||(f&&t.k(a,H,X,"fromSpot"),a=a.W(),this.T.aj=a,this.i("fromSpot",b,a),this.Tb())}); +t.defineProperty(X,{Rj:"fromEndSegmentLength"},function(){return null!==this.T?this.T.Zi:NaN},function(a){null===this.T&&this.Be();var b=this.T.Zi;b!==a&&(f&&t.j(a,"number",X,"fromEndSegmentLength"),0>a&&t.ia(a,">= 0",X,"fromEndSegmentLength"),this.T.Zi=a,this.i("fromEndSegmentLength",b,a),this.Tb())}); +t.defineProperty(X,{Co:"fromEndSegmentDirection"},function(){return null!==this.T?this.T.Yi:jm},function(a){null===this.T&&this.Be();var b=this.T.Yi;b!==a&&(f&&t.nb(a,S,X,"fromEndSegmentDirection"),this.T.Yi=a,this.i("fromEndSegmentDirection",b,a),this.Tb())});t.defineProperty(X,{Do:"fromShortLength"},function(){return null!==this.T?this.T.$i:NaN},function(a){null===this.T&&this.Be();var b=this.T.$i;b!==a&&(f&&t.j(a,"number",X,"fromShortLength"),this.T.$i=a,this.i("fromShortLength",b,a),this.Tb())}); +t.defineProperty(X,{gb:"toSpot"},function(){return null!==this.T?this.T.Cj:vb},function(a){null===this.T&&this.Be();var b=this.T.Cj;b.K(a)||(f&&t.k(a,H,X,"toSpot"),a=a.W(),this.T.Cj=a,this.i("toSpot",b,a),this.Tb())}); +t.defineProperty(X,{Zj:"toEndSegmentLength"},function(){return null!==this.T?this.T.Aj:NaN},function(a){null===this.T&&this.Be();var b=this.T.Aj;b!==a&&(f&&t.j(a,"number",X,"toEndSegmentLength"),0>a&&t.ia(a,">= 0",X,"toEndSegmentLength"),this.T.Aj=a,this.i("toEndSegmentLength",b,a),this.Tb())}); +t.defineProperty(X,{vp:"toEndSegmentDirection"},function(){return null!==this.T?this.T.zj:jm},function(a){null===this.T&&this.Be();var b=this.T.zj;b!==a&&(f&&t.nb(a,S,X,"toEndSegmentDirection"),this.T.zj=a,this.i("toEndSegmentDirection",b,a),this.Tb())});t.defineProperty(X,{wp:"toShortLength"},function(){return null!==this.T?this.T.Bj:NaN},function(a){null===this.T&&this.Be();var b=this.T.Bj;b!==a&&(f&&t.j(a,"number",X,"toShortLength"),this.T.Bj=a,this.i("toShortLength",b,a),this.Tb())}); +function Wi(a){var b=a.ca,c=a.ga;null!==b&&null!==c?Dm(a,b.sH(c)):Dm(a,null)}function Dm(a,b){var c=a.ok;if(c!==b){null!==c&&em(c,a);a.ok=b;null!==b&&fm(b,a);var d=a.wz;if(null!==d){var e=!0,g=a.h;null!==g&&(e=g.Ra,g.Ra=!0);d(a,c,b);null!==g&&(g.Ra=e)}!a.Eg||a.pC!==c&&a.rC!==c||a.Tb()}}X.prototype.getOtherNode=X.prototype.Jz=function(a){f&&t.k(a,S,X,"getOtherNode:node");var b=this.ca;return a===b?this.ga:b}; +X.prototype.getOtherPort=function(a){f&&t.k(a,Q,X,"getOtherPort:port");var b=this.Wc;return a===b?this.Qd:b};t.A(X,{fJ:"isLabeledLink"},function(){return null===this.$e?!1:0=d&&(l=d-1),k=this.n(l-1),g=this.n(l),D.oo(e.x,e.y,h.x,h.y,k.x,k.y,g.x,g.y,0.5,a),b=Math.min(g.x,b),c=Math.min(g.y,c),e=g;else for(e=this.n(0),g=this.n(1),b=Math.min(e.x,g.x),c=Math.min(e.y,g.y),a.q(e.x,e.y,0,0),a.Mi(g),l=2;lc&&(c=-c)):D.Fa(c.y,d.y)?(c=d.x-c.x,0>c&&(c=-c)):c=Math.sqrt(c.Mj(d)),g.push(c),e+=c;for(d=h=c=0;ce/2)break;c+=d;h++}t.xa(g);b=this.n(h);g=this.n(h+1);b.x===g.x?b.y>g.y?a.q(b.x,b.y-(e/2-c)):a.q(b.x,b.y+(e/2-c)):b.y===g.y?b.x>g.x?a.q(b.x-(e/2-c),b.y):a.q(b.x+(e/2-c),b.y):(e=(e/2-c)/d,a.q(b.x+e*(g.x-b.x),b.y+e*(g.y-b.y)));return a};t.A(X,{pE:"midAngle"},function(){this.updateRoute();return this.computeMidAngle()}); +X.prototype.computeMidAngle=function(){var a=this.ka;if(2>a)return NaN;if(this.computeCurve()===Kg&&4<=a&&!this.Ub){var b=(a-1)/3|0,c=3*(b/2|0);if(1===b%2){var c=Math.floor(c),a=this.n(c),b=this.n(c+1),d=this.n(c+2),c=this.n(c+3);return D.QG(a.x,a.y,b.x,b.y,d.x,d.y,c.x,c.y)}if(0e?a.wi(b):b.wi(d)};t.g(X,"points",X.prototype.points); +t.defineProperty(X,{points:"points"},function(){return this.qc},function(a){f&&(Array.isArray(a)||a instanceof A||t.l("Link.points value is not an instance of List or Array"));var b=this.qc;if(b!==a){if(Array.isArray(a)){for(var c=0===a.length%2,d=0;dp&&(u-=180));0>u?u+=360:360<=u&&(u-=360);k&&(x+=Math.abs(p));0===u?r=x:90===u?s=x:180===u?r=-x:270===u?s=-x:(r=x*Math.cos(u*Math.PI/180),s=x*Math.sin(u*Math.PI/180));if(g.jd()&&k){var E=c.$a(Fb,t.M()),F=t.cc(E.x+1E3*r,E.y+1E3*s);this.getLinkPointFromPoint(b,c,E,F,!0,q);t.B(E);t.B(F)}}var x=this.getLinkPoint(d,e,h,!1,l,b,c),G=0,L=0,M=0;if(l||h!==ub||k)E=this.computeEndSegmentLength(d,e,h, +!1),M=this.getLinkDirection(d,e,x,h,!1,l,b,c),k&&(M+=l?0:30,0>p&&(M+=180)),0>M?M+=360:360<=M&&(M-=360),k&&(E+=Math.abs(p)),0===M?G=E:90===M?L=E:180===M?G=-E:270===M?L=-E:(G=E*Math.cos(M*Math.PI/180),L=E*Math.sin(M*Math.PI/180)),h.jd()&&k&&(E=e.$a(Fb,t.M()),F=t.cc(E.x+1E3*G,E.y+1E3*L),this.getLinkPointFromPoint(d,e,E,F,!1,x),t.B(E),t.B(F));e=q;if(l||g!==ub||k)e=new v(q.x+r,q.y+s);c=x;if(l||h!==ub||k)c=new v(x.x+G,x.y+L);!n&&!l&&g.jd()&&3k&&(m=-m),r=(0>h?-1:1)*m+q,s=l*(r-q)+u),q=a.x+2*g/3,u=a.y+2*h/3,x=q,G=u,D.I(h,0)?G=0h?-1:1)*m+q,G=l*(x-q)+u),this.po(),this.qh(a),this.Kk(r,s),this.Kk(x,G),this.qh(n),this.of(0,this.getLinkPoint(b,c,ub,!0,!1,d,e)),this.of(3,this.getLinkPoint(d,e,ub,!1,!1,b,c))):(a=d,d=this.getLinkPoint(b,c,ub,!0,!1,a,e),e=this.getLinkPoint(a, +e,ub,!1,!1,b,c),this.hasCurviness()?(h=e.x-d.x,b=e.y-d.y,c=this.computeCurviness(),a=d.x+h/2,n=d.y+b/2,g=a,k=n,D.I(b,0)?k=0c&&(g=-g),g=(0>b?-1:1)*g+a,k=h*(g-a)+n),this.qh(d),this.Kk(g,k)):this.qh(d),this.qh(e)));return!0};function Jm(a,b){Math.abs(b.x-a.x)>Math.abs(b.y-a.y)?(b.x=b.x>=a.x?a.x+9E9:a.x-9E9,b.y=a.y):(b.y=b.y>=a.y?a.y+9E9:a.y-9E9,b.x=a.x);return b} +X.prototype.getLinkPointFromPoint=function(a,b,c,d,e,g){void 0===g&&(g=new v);if(null===a||null===b)return g.assign(c),g;a.ub()||(e=bm(a),null!==e&&e!==a&&(b=e.port));var h;a=null;if(null===b.fa)e=d.x,d=d.y,h=c.x,c=c.y;else{a=b.fa.$d;e=1/(a.m11*a.m22-a.m12*a.m21);h=a.m22*e;var k=-a.m12*e,l=-a.m21*e,m=a.m11*e,n=e*(a.m21*a.dy-a.m22*a.dx),p=e*(a.m12*a.dx-a.m11*a.dy);e=d.x*h+d.y*l+n;d=d.x*k+d.y*m+p;h=c.x*h+c.y*l+n;c=c.x*k+c.y*m+p}b.Go(e,d,h,c,g);a&&g.transform(a);return g}; +function Km(a,b){var c=b.Xd;null===c&&(c=new Lm,c.port=b,c.Bc=b.Q,b.Xd=c);return Mm(c,a)} +X.prototype.getLinkPoint=function(a,b,c,d,e,g,h,k){void 0===k&&(k=new v);if(c.kd())return b.$a(c,k),k;if(c.No()&&(c=Km(this,b),null!==c)){k.assign(c.Uo);if(e&&this.at===tm){var l=Km(this,h);if(c.pm=m.x&&a.x<=m.x+m.width?k.x=a.x:a.y>=m.y&&a.y<=m.y+m.height&&(k.y=a.y);t.B(c);t.B(l)}}return k}g=b.$a(Fb,t.M());c=null;this.ka>(e?6:2)?(h=d?this.n(1):this.n(this.ka-2),e&&(h=Jm(g,h.copy()))): +(c=t.M(),h=h.$a(Fb,c),e&&(h=Jm(g,h)));this.getLinkPointFromPoint(a,b,g,h,d,k);t.B(g);null!==c&&t.B(c);return k}; +X.prototype.getLinkDirection=function(a,b,c,d,e,g,h,k){a:if(d.kd())c=d.x>d.y?d.x>1-d.y?0:d.x<1-d.y?270:315:d.x1-d.y?90:d.x<1-d.y?180:135:0.5>d.x?225:0.5(g?6:2)?(k=e?this.n(1):this.n(this.ka-2),k=g?Jm(a,k.copy()):c):(d=t.M(),k=k.$a(Fb,d));c=Math.abs(k.x-a.x)>Math.abs(k.y-a.y)?k.x>=a.x?0:180:k.y>= +a.y?90:270;t.B(a);null!==d&&t.B(d)}g=jm;g=e?this.Co:this.vp;g===jm&&(g=e?b.Co:b.vp);switch(g){case km:b=b.Wk();c+=b;360<=c&&(c-=360);break;case jm:case Hj:b=b.Wk();if(0===b)break;45<=b&&135>b?c+=90:135<=b&&225>b?c+=180:225<=b&&315>b&&(c+=270);360<=c&&(c-=360)}return c};X.prototype.computeEndSegmentLength=function(a,b,c,d){if(c.No()&&(a=Km(this,b),null!==a))return a.Lv;a=NaN;a=d?this.Rj:this.Zj;isNaN(a)&&(a=d?b.Rj:b.Zj);isNaN(a)&&(a=10);return a}; +X.prototype.computeSpot=function(a){return a?Hm(this,this.Wc):Im(this,this.Qd)};function Hm(a,b){var c=a.fb;c.zc()&&(void 0===b&&(b=a.Wc),null!==b&&(c=b.fb));return c===vb?ub:c}function Im(a,b){var c=a.gb;c.zc()&&(void 0===b&&(b=a.Qd),null!==b&&(c=b.gb));return c===vb?ub:c}X.prototype.computeOtherPoint=function(a,b){var c=b.$a(Fb),d;d=b.Xd;d=null!==d?Mm(d,this):null;null!==d&&(c=d.Uo);return c};X.prototype.computeShortLength=function(a){return a?Nm(this):Om(this)}; +function Nm(a){var b=a.Do;isNaN(b)&&(a=a.Wc,null!==a&&(b=a.Do));return isNaN(b)?0:b}function Om(a){var b=a.wp;isNaN(b)&&(a=a.Qd,null!==a&&(b=a.wp));return isNaN(b)?0:b} +X.prototype.Pj=function(a,b,c,d,e,g){if(!1===this.mf)return!1;void 0===b&&(b=null);void 0===c&&(c=null);var h=g;void 0===g&&(h=t.Og(),h.reset());h.multiply(this.transform);if(this.om(a,h))return Bl(this,b,c,e),void 0===g&&t.Ne(h),!0;if(this.Bf(a,h)){var k=!1;if(!this.ug)for(var l=this.za.length;l--;){var m=this.za.p[l];if(m.visible||m===this.Zb){var n=m.ua,p=this.Na;if(!(n.x>p.width||n.y>p.height||0>n.x+n.width||0>n.y+n.height)){n=t.Og();n.set(h);if(m instanceof y)k=m.Pj(a,b,c,d,e,n);else if(this.path=== +m){var k=m,q=a,r=d,p=n;if(!1===k.mf)k=!1;else if(p.multiply(k.transform),r)b:{var s=q,u=p;if(k.om(s,u))k=!0;else{if(void 0===u&&(u=k.transform,s.Ij(k.ua))){k=!0;break b}var p=s.left,q=s.right,r=s.top,s=s.bottom,x=t.M(),E=t.M(),F=t.M(),G=t.Og();G.set(u);G.vE(k.transform);G.Qz();E.x=q;E.y=r;E.transform(G);x.x=p;x.y=r;x.transform(G);u=!1;Il(k,x,E,F)?u=!0:(x.x=q,x.y=s,x.transform(G),Il(k,x,E,F)?u=!0:(E.x=p,E.y=s,E.transform(G),Il(k,x,E,F)?u=!0:(x.x=p,x.y=r,x.transform(G),Il(k,x,E,F)&&(u=!0))));t.Ne(G); +t.B(x);t.B(E);t.B(F);k=u}}else k=k.om(q,p)}else k=Mj(m,a,d,n);k&&(null!==b&&(m=b(m)),m&&(null===c||c(m))&&e.add(m));t.Ne(n)}}}void 0===g&&t.Ne(h);return k||null!==this.background||null!==this.Ok}void 0===g&&t.Ne(h);return!1};t.A(X,{Ub:"isOrthogonal"},function(){return 2===(this.Ul.value&2)});t.A(X,{Di:"isAvoiding"},function(){return 4===(this.Ul.value&4)});X.prototype.computeCurve=function(){if(null===this.Th){var a=this.Ub;this.Th=this.Wc===this.Qd&&!a}return this.Th?Kg:this.ze}; +X.prototype.computeCorner=function(){if(this.ze===Kg)return 0;var a=this.Ev;if(isNaN(a)||0>a)a=10;return a};X.prototype.computeCurviness=function(){var a=this.os;if(isNaN(a)){var b=this.Xe;if(0!==b){var a=10,c=this.h;null!==c&&(a=c.Vo);c=Math.abs(b);a=a/2+((c-1)/2|0)*a;0===c%2&&(a=-a);0>b&&(a=-a)}else a=10}return a};X.prototype.hasCurviness=function(){return!isNaN(this.os)||0!==this.Xe&&!this.Ub}; +X.prototype.adjustPoints=function(a,b,c,d){var e=this.fo;if(this.Ub){if(e===Ck)return!1;e===Dk&&(e=Bk)}switch(e){case Ck:var g=this.n(a),h=this.n(c);if(!g.K(b)||!h.K(d)){var e=g.x,g=g.y,k=h.x-e,l=h.y-g,m=Math.sqrt(k*k+l*l);if(!D.I(m,0)){var n;D.I(k,0)?n=0>l?-Math.PI/2:Math.PI/2:(n=Math.atan(l/Math.abs(k)),0>k&&(n=Math.PI-n));var h=b.x,p=b.y,k=d.x-h,q=d.y-p,l=Math.sqrt(k*k+q*q);D.I(k,0)?q=0>q?-Math.PI/2:Math.PI/2:(q=Math.atan(q/Math.abs(k)),0>k&&(q=Math.PI-q));m=l/m;n=q-n;this.of(a,b);for(a+=1;al?-Math.PI/2:Math.PI/2:(l=Math.atan(l/Math.abs(k)),0>k&&(l=Math.PI-l)),k=l+n,b*=m,this.U(a,h+b*Math.cos(k),p+b*Math.sin(k)));this.of(c,d)}}return!0;case Dk:g=this.n(a);p=this.n(c);if(!g.K(b)||!p.K(d)){e=g.x;g=g.y;h=p.x;p=p.y;m=(h-e)*(h-e)+(p-g)*(p-g);k=b.x;n=b.y;var l=d.x,q=d.y,r=0,s=1,r=0!==l-k?(q-n)/(l-k):9E9;0!==r&&(s=Math.sqrt(1+1/(r*r)));this.of(a,b);for(a+=1;ab?0:45<=b&&135>b?90:135<=b&&225>b?180:270;d=-45<=d&&45>d?0:45<=d&&135>d?90:135<=d&&225>d?180:270;var h=e.ua.copy(),k=g.ua.copy();if(h.P()&&k.P()){h.Hg(8,8);k.Hg(8,8);h.Mi(a);k.Mi(c);var l,m;if(0===b)if(c.x>a.x||270===d&&c.ya.x||90===d&&c.y>a.y&&k.right>a.x)l=new v(c.x,a.y),m=new v(c.x,(a.y+c.y)/2),180===d?(l.x=this.computeMidOrthoPosition(a.x,c.x,!1),m.x=l.x,m.y=c.y):270===d&&c.ya.y?(l.x=a.xk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.right,m.x=l.x,m.y=c.y):0===d&&a.xk.top&&a.yh.bottom)180===d&&(k.Da(a)||h.Da(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(180===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=h.left&&c.x<=a.x||a.x<=k.right&&a.x>=c.x){if(90===d||270===d)l=new v(Math.max((a.x+c.x)/2,a.x),a.y),m=new v(l.x,c.y)}else l.y=270===d||(0===d||180===d)&&c.ya.y&&k.lefta.y?(l.x=a.x>k.right?this.computeMidOrthoPosition(a.x,k.right,!1):a.x>k.left&&(270===d&&a.yk.bottom)?this.computeMidOrthoPosition(a.x,c.x,!1):k.left,m.x=l.x,m.y=c.y):180===d&&a.x>k.right&&a.y>k.top&&a.yh.bottom)0===d&&(k.Da(a)||h.Da(c))?l.y=this.computeMidOrthoPosition(a.y,c.y,!0):c.ya.y&&(0===d||270===d)&&(l.y=this.computeMidOrthoPosition(h.bottom,Math.min(c.y,k.top),!0)),m.x=c.x,m.y=l.y;if(l.y>h.top&&l.y=a.x||a.x>=k.left&&a.x<=c.x){if(90===d||270===d)l=new v(Math.min((a.x+c.x)/2,a.x),a.y),m=new v(l.x,c.y)}else l.y=270=== +d||(0===d||180===d)&&c.ya.y||180===d&&c.xa.y||0===d&&c.x>a.x&&k.bottom>a.y)l=new v(a.x,c.y),m=new v((a.x+c.x)/2,c.y),270===d?(l.y=this.computeMidOrthoPosition(a.y,c.y,!0),m.x=c.x,m.y=l.y):180===d&&c.xa.x?(l.y=a.yk.right)? +this.computeMidOrthoPosition(a.y,c.y,!0):k.bottom,m.x=c.x,m.y=l.y):90===d&&a.yk.left&&a.xh.right)270===d&&(k.Da(a)||h.Da(c))?l.x=this.computeMidOrthoPosition(a.x,c.x,!1):c.xa.x&&(270===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right, +Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=h.top&&c.y<=a.y||a.y<=k.bottom&&a.y>=c.y){if(0===d||180===d)l=new v(a.x,Math.max((a.y+c.y)/2,a.y)),m=new v(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xa.x&&k.top=a.x?(l.y=a.y>k.bottom?this.computeMidOrthoPosition(a.y,k.bottom,!0):a.y>k.top&&(180===d&&a.xk.right)?this.computeMidOrthoPosition(a.y,c.y,!0):k.top,m.x=c.x,m.y=l.y):270===d&&a.y>k.bottom&&a.x>k.left&&a.xh.right)90===d&&(k.Da(a)||h.Da(c))?l.x=this.computeMidOrthoPosition(a.x, +c.x,!1):c.xa.x&&(90===d||180===d)&&(l.x=this.computeMidOrthoPosition(h.right,Math.min(c.x,k.left),!1)),m.x=l.x,m.y=c.y;if(l.x>h.left&&l.x=a.y||a.y>=k.top&&a.y<=c.y){if(0===d||180===d)l=new v(a.x,Math.min((a.y+c.y)/2,a.y)),m=new v(c.x,l.y)}else l.x=180===d||(90===d||270===d)&&c.xthis.ka)0===b||180===b?(d.x=a.x,d.y=c.y):(d.x=c.x,d.y=a.y),this.U(2,d.x,d.y),this.C(3,d.x,d.y);else if(c=this.n(3),0===b||180===b)D.I(d.x,c.x)?(b=0===b?Math.max(d.x,a.x):Math.min(d.x,a.x),this.U(2,b,a.y),this.U(3,b,c.y)):D.I(d.y,c.y)? +(Math.abs(a.y-d.y)<=e.km/2&&(this.U(2,d.x,a.y),this.U(3,c.x,a.y)),this.C(2,d.x,a.y)):this.U(2,a.x,d.y);else if(90===b||270===b)D.I(d.y,c.y)?(b=90===b?Math.max(d.y,a.y):Math.min(d.y,a.y),this.U(2,a.x,b),this.U(3,c.x,b)):D.I(d.x,c.x)?(Math.abs(a.x-d.x)<=e.lm/2&&(this.U(2,a.x,d.y),this.U(3,a.x,c.y)),this.C(2,a.x,d.y)):this.U(2,d.x,a.y);a=!0}else a=!1}else a=!1;a||(this.qh(l),this.qh(m))}}; +X.prototype.computeMidOrthoPosition=function(a,b){if(this.hasCurviness()){var c=this.computeCurviness();return(a+b)/2+c}return(a+b)/2};function xf(a){if(!a.Di)return!1;var b=a.points.p,c=b.length;if(4>c)return!1;a=cj(a.h,a);for(var d=1;dUm&&Rm(b,m,n)===l-Vm;)c=m,d=n,0===e?m+=h:90===e?n+=k:180===e?m-=h:n-=k,l-=Vm;if(g){if(l>Um)if(180===e||0===e)c=Math.floor(c/h)*h+h/2;else if(90===e||270===e)d=Math.floor(d/k)*k+k/2}else c=Math.floor(c/h)*h+h/2,d=Math.floor(d/k)*k+k/2;l>Um&&(g=e,m=c,n=d,0===e?(g=90,n+=k):90===e?(g=180,m-=h):180===e?(g=270,n-=k):270===e&&(g=0,m+=h),Rm(b,m,n)===l-Vm?Tm(a,b,m,n,g,!1):(m=c,n=d,0===e?(g=270,n-= +k):90===e?(g=0,m+=h):180===e?(g=90,n+=k):270===e&&(g=180,m-=h),Rm(b,m,n)===l-Vm&&Tm(a,b,m,n,g,!1)));a.Kk(c,d)}X.prototype.findClosestSegment=function(a){f&&t.k(a,v,X,"findClosestSegment:p");var b=a.x;a=a.y;for(var c=this.n(0),d=this.n(1),e=Pa(b,a,c.x,c.y,d.x,d.y),g=0,h=1;ha){var b=new I(zc),c=new Ac(0,0);b.ob.add(c);return b}var d=this.n(0).copy(),e=d.copy(),g=this.computeCurve();if(g===Kg&&3<=a&&!D.Fa(this.Mm,0))if(3===a)var h=this.n(1),b=Math.min(d.x,h.x),c=Math.min(d.y,h.y),h=this.n(2),b=Math.min(b,h.x),c=Math.min(c,h.y);else{if(this.Ub)for(h=0;h=a&&(h=a-1),k=this.n(h),e.x=Math.min(k.x,e.x),e.y=Math.min(k.y,e.y); +b=e.x;c=e.y}else{for(h=0;hE?r>q?(u.x=F-L,u.y=q-L,x.x=F+s,x.y=q+s):(u.x=F-L,u.y=q+L,x.x=F+s,x.y=q-s):r>q?(u.x=F+L,u.y=q-L,x.x= +F-s,x.y=q+s):(u.x=F+L,u.y=q+L,x.x=F-s,x.y=q-s));D.Fa(E,F)&&D.Fa(q,r)&&(q>p?(G>F?(u.x=F-L,u.y=q-L,x.x=F+s):(u.x=F+L,u.y=q-L,x.x=F-s),x.y=q+s):(G>F?(u.x=F-L,u.y=q+L,x.x=F+s):(u.x=F+L,u.y=q+L,x.x=F-s),x.y=q-s));if(D.Fa(E,F)&&D.Fa(F,G)||D.Fa(p,q)&&D.Fa(q,r))E=0.5*(E+G),p=0.5*(p+r),u.x=E,u.y=p,x.x=E,x.y=p;1===h?(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y)):2===h&&D.Fa(e.x,this.n(0).x)&&D.Fa(e.y,this.n(0).y)&&(g.x=0.5*(e.x+m.x),g.y=0.5*(e.y+m.y));K(l,g.x-b,g.y-c,k.x-b,k.y-c,m.x-b,m.y-c);d.set(k);g.set(a);e=m}}h= +e.x;e=e.y;d=this.n(this.ka-1);h=0.5*(h+d.x);e=0.5*(e+d.y);K(l,a.x-b,a.y-c,h-b,e-c,d.x-b,d.y-c)}else for(h=3;h=a&&(h=a-1),d=this.n(h-1),k=this.n(h),h===a-1&&0!==Om(this)&&(k=k.copy(),Wm(this,k,!1,D.ak)),K(l,e.x-b,e.y-c,d.x-b,d.y-c,k.x-b,k.y-c);else{e=t.M();e.assign(this.n(0));for(h=1;h=a-1){e!==n&&(0!==Om(this)&&(n=n.copy(),Wm(this,n,!1,D.ak)),Zm(this,l,-b,-c,e,n));break}h=Xm(this,n,h+1,hm.x?n.x-E:n.x+E,G=u.y>n.y?n.y+p:n.y-p,Zm(this,d,g,k,m,new v(s,F)),Vc(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):D.I(m.x,n.x)&&D.I(n.y,u.y)?(E=this.computeCorner(),p=Math.min(E,Math.abs(n.y-m.y)/2),p=E=Math.min(p,Math.abs(u.x-n.x)/2),D.I(E,0)?(Zm(this,d,g,k,m,n),x.assign(n)):(s=n.x,G=F=n.y,F=n.y>m.y?n.y-p:n.y+p,q=u.x>n.x?n.x+E: +n.x-E,Zm(this,d,g,k,m,new v(s,F)),Vc(d,n.x+g,n.y+k,q+g,G+k),x.q(q,G))):(Zm(this,d,g,k,m,n),x.assign(n))}t.B(e)}b=l.s;t.v(l)}return b};function Ym(a,b,c,d){a=c-a;if(isNaN(a)||Infinity===a||-Infinity===a)return NaN;0>a&&(a=-a);b=d-b;if(isNaN(b)||Infinity===b||-Infinity===b)return NaN;0>b&&(b=-b);return D.Fa(a,0)?b:D.Fa(b,0)?a:Math.sqrt(a*a+b*b)} +function Wm(a,b,c,d){var e=a.ka;if(!(2>e))if(c){var g=a.n(1);c=g.x-d.x;d=g.y-d.y;g=Ym(b.x,b.y,c,d);0!==g&&(e=2===e?0.5*g:g,a=Nm(a),a>e&&(a=e),c=a*(c-b.x)/g,a=a*(d-b.y)/g,b.x+=c,b.y+=a)}else g=a.n(e-2),c=g.x-d.x,d=g.y-d.y,g=Ym(b.x,b.y,c,d),0!==g&&(e=2===e?0.5*g:g,a=Om(a),a>e&&(a=e),c=a*(b.x-c)/g,a=a*(b.y-d)/g,b.x-=c,b.y-=a)} +function Xm(a,b,c,d){for(var e=a.ka,g=b;D.Fa(b.x,g.x)&&D.Fa(b.y,g.y);){if(c>=e)return e-1;g=a.n(c++)}if(!D.Fa(b.x,g.x)&&!D.Fa(b.y,g.y))return c-1;for(var h=g;D.Fa(b.x,g.x)&&D.Fa(g.x,h.x)&&(!d||(b.y>=g.y?g.y>=h.y:g.y<=h.y))||D.Fa(b.y,g.y)&&D.Fa(g.y,h.y)&&(!d||(b.x>=g.x?g.x>=h.x:g.x<=h.x));){if(c>=e)return e-1;h=a.n(c++)}return c-2} +function Zm(a,b,c,d,e,g){if(Em(a)){var h=new A("number"),k=$m(a,e,g,h),l=e.x,l=e.y;if(0p-10)m--,p=Math.max(q-5,g.x);else break;q=g.y-10+d;n=p+c;p=g.y+d;a.ze===rg?J(b,n,p,!1,!1):K(b,l,q,n,q,n,p)}else if(D.I(e.x,g.x))if(e.yp-10)m--,p=Math.max(q-5,g.y);else break;q=g.x-10+c;n=g.x+c;p+=d;a.ze===rg?J(b,n,p,!1,!1):K(b,q,l,q,p,n,p)}}b.lineTo(g.x+c,g.y+d)} +function $m(a,b,c,d){var e=a.h;if(null===e)return 0;Math.min(b.x,c.x);Math.min(b.y,c.y);Math.max(b.x,c.x);Math.max(b.y,c.y);for(e=e.ew;e.next();){var g=e.value;if(null!==g&&g.visible)for(var g=g.qb.p,h=g.length,k=0;k=h.x&&Math.min(h.y,k.y)<=m.y&&Math.max(h.y,k.y)>=m.y&&!D.I(h.y,k.y)){p.x=h.x;p.y=m.y;m=!0;break a}}else if(D.I(h.y,k.y)&&Math.min(m.y,n.y)<=h.y&&Math.max(m.y,n.y)>=h.y&&Math.min(h.x,k.x)<=m.x&&Math.max(h.x,k.x)>=m.x&&!D.I(h.x,k.x)){p.x=m.x;p.y=h.y;m=!0;break a}p.x=0;p.y=0;m=!1}m&&(D.I(a.y,b.y)?c.add(l.x):c.add(l.y));t.B(l)}} +t.A(X,{ws:"firstPickIndex"},function(){return 2>=this.ka?0:this.Ub||Hm(this)!==ub?1:0});t.A(X,{dw:"lastPickIndex"},function(){var a=this.ka;return 0===a?0:2>=a?a-1:this.Ub||Im(this)!==ub?a-2:a-1});function Em(a){a=a.ze;return a===qg||a===rg}function Gm(a,b){if(b||Em(a)){var c=a.h;null===c||c.ln.contains(a)||null===a.Ey||c.ln.add(a,a.Ey)}} +function tg(a,b){var c=a.layer;if(null!==c&&c.visible&&!c.kc){var d=c.h;if(null!==d)for(var e=!1,d=d.ew;d.next();){var g=d.value;if(g.visible)if(g===c)for(var e=!0,h=!1,g=g.qb.p,k=g.length,l=0;lb.links.count)1===b.links.count&&(c=b.links.p[0],c.Ym=null,c.Xe=0,c.Tb()),c=b.cp,null!==b&&null!==c.Rg&&c.Rg.remove(b),c=b.Qs,null!==b&&null!==c.Rg&&c.Rg.remove(b);else for(c=Math.abs(c),a=0===c%2,b=b.links.m;b.next();){var d=b.value,e=Math.abs(d.Xe),g=0===e%2;e>c&&a===g&&(d.Xe=0=a.width||0>=a.height)){var b=a.y,c=a.x+a.width,d=a.y+a.height;this.Pf=Math.floor((a.x-this.Td)/this.Td)*this.Td;this.Qf=Math.floor((b-this.Ud)/this.Ud)*this.Ud;this.Tq=Math.ceil((c+2*this.Td)/this.Td)*this.Td;this.Uq=Math.ceil((d+2*this.Ud)/this.Ud)*this.Ud;a=1+(Math.ceil((this.Tq-this.Pf)/this.Td)|0);b=1+(Math.ceil((this.Uq-this.Qf)/this.Ud)|0);if(null===this.ec||this.Zn=Um&&(a.ec[b][c]|=Sm)} +function Pm(a,b,c,d,e){if(b>a.Tq||b+da.Uq||c+eb&&(d+=b,b=0);0>c&&(g+=c,c=0);if(0>d||0>g)return!0;e=Math.min(b+d-1,a.Zn)|0;for(d=Math.min(c+g-1,a.$n)|0;b<=e;b++)for(g=c;g<=d;g++)if(0===a.ec[b][g])return!1;return!0} +function en(a,b,c,d,e,g,h,k,l){if(!(bh||cl)){var m,n;m=b|0;n=c|0;var p=a.ec[m][n];if(p>=Um&&p=a.ec[m][n]);)a.ec[m][n]=p,p+=Vm,e?n+=d:m+=d;m=e?n:m;if(e)if(0m;c+=d)en(a,b,c,1,!e,g,h,k,l),en(a,b,c,-1,!e,g,h,k,l);else if(0m;b+=d)en(a,b,c,1,!e,g,h,k,l),en(a,b,c,-1,!e,g,h, +k,l)}}function fn(a,b,c,d,e,g,h,k,l,m,n){for(var p=b|0,q=c|0,r=a.ec[p][q];0===r&&p>k&&pm&&q=Math.abs(p-d)&&1>=Math.abs(q-e))return a.abort=!0,0;p=b|0;q=c|0;r=a.ec[p][q];b=Um;for(a.ec[p][q]=b;0===r&&p>k&&pm&&q=Math.abs(h-l)&&1>=Math.abs(k-m))a.abort=!0;else{var n=g.x;b=g.y;d=g.x+g.width;var p=g.y+g.height,n=n-a.Pf,n=n/a.Td;b-=a.Qf;b/=a.Ud;d-=a.Pf;d/=a.Td;p-=a.Qf;p/=a.Ud;g=Math.max(0,Math.min(a.Zn,n|0));d=Math.min(a.Zn,Math.max(0,d|0));b=Math.max(0,Math.min(a.$n,b|0));var p=Math.min(a.$n,Math.max(0,p|0)),h=h|0,k=k|0,l=l|0, +m=m|0,n=h,q=k,r=0===c||90===c?1:-1;(c=90===c||270===c)?q=fn(a,h,k,l,m,r,c,g,d,b,p):n=fn(a,h,k,l,m,r,c,g,d,b,p);if(!a.abort){a:{c=0===e||90===e?1:-1;e=90===e||270===e;for(var r=l|0,s=m|0,u=a.ec[r][s];0===u&&r>g&&rb&&s=Math.abs(r-h)&&1>=Math.abs(s-k)){a.abort=!0;break a}r=l|0;s=m|0;u=a.ec[r][s];for(a.ec[r][s]=cn;0===u&&r>g&&rb&&s=c?180:0}a=180*Math.atan2(a.height,a.width)/Math.PI;switch(b){case t.ad|t.wd:return c>a&&c<=180+a?180:270;case t.wd|t.od:return c>180-a&&c<=360-a?270:0;case t.od|t.nd:return c>a&&c<=180+a?90:0;case t.nd|t.ad:return c>180-a&&c<=360-a?180:90;case t.ad|t.wd|t.od:return 90180+a&&c<=360- +a?270:0;case t.wd|t.od|t.nd:return 180a&&180>=c?90:0;case t.od|t.nd|t.ad:return c>a&&c<=180-a?90:c>180-a&&270>=c?180:0;case t.nd|t.ad|t.wd:return c>180-a&&c<=180+a?180:c>180+a?270:90}d&&b!==(t.ad|t.wd|t.od|t.nd)&&(c-=15,0>c&&(c+=360));return c>a&&c<180-a?90:c>=180-a&&c<=180+a?180:c>180+a&&c<360-a?270:0} +function Mm(a,b){var c=a.dg;if(0===c.length){if(!a.Ps){c=a.Ps;a.Ps=!0;var d=a.Bc.ie,e=a.dg.length=0,g=a.port.$a(wb,t.M()),h=a.port.$a(Ob,t.M()),k=t.Yj(g.x,g.y,0,0);k.Mi(h);t.B(g);t.B(h);g=t.cc(k.x+k.width/2,k.y+k.height/2);for(d=d.m;d.next();)if(h=d.value,h.ub()){var l=ub,l=h.Wc===a.port?Hm(h,a.port):Im(h,a.port);if(l.No()){var m;m=h.Wc===a.port?h.Qd:h.Wc;if(null!==m){var n=m.Q;if(null!==n){m=h.computeOtherPoint(n,m);var n=g.wi(m),l=gn(k,l,n,h.Ub),p;0===l?(p=t.od,180b.De?1:a.angleb.angle?1:0}; +Lm.prototype.computeEndSegmentLength=function(a){var b=a.link,c=b.computeEndSegmentLength(this.Bc,this.port,ub,b.Wc===this.port),d=a.Jo;if(0>d)return c;var e=a.pm;if(1>=e||!b.Ub)return c;var b=a.lw,g=a.Uo;if(a.De===t.ad||a.De===t.nd)d=e-1-d;return((a=a.De===t.ad||a.De===t.od)?b.ye&&(e=k.right);k.bottom>g&&(g=k.bottom)}}isFinite(c)&&isFinite(d)?a.q(c,d,e-c,g-d):(b=b.location,c=this.padding,a.q(b.x+c.left,b.y+c.top,0,0));return a}; +t.g(Pg,"padding",Pg.prototype.padding);t.defineProperty(Pg,{padding:"padding"},function(){return this.Ge},function(a){"number"===typeof a?(0>a&&t.ia(a,">= 0",Pg,"padding"),a=new Va(a)):(t.k(a,Va,Pg,"padding"),0>a.left&&t.ia(a.left,">= 0",Pg,"padding:val.left"),0>a.right&&t.ia(a.right,">= 0",Pg,"padding:val.right"),0>a.top&&t.ia(a.top,">= 0",Pg,"padding:val.top"),0>a.bottom&&t.ia(a.bottom,">= 0",Pg,"padding:val.bottom"));var b=this.Ge;b.K(a)||(this.Ge=a=a.W(),this.i("padding",b,a))}); +function ke(){0=c-1?(h=0,e=d,g+=k+20,k=0):h++}null!==a&&a.ye("Layout")}this.gf=!0};ke.prototype.fA=function(a){return!a.location.P()||a instanceof V&&a.$B?!0:!1};function mn(a,b,c,d,e,g,h,k){for(c=c.m;c.next();){var l=c.value;d&&!l.Oo||e&&!e(l)||l.canLayout()&&(g&&l instanceof S?l.wh||(l instanceof V&&null===l.Vb?mn(a,b,l.Kc,!1,e,g,h,k):b.add(l)):h&&l instanceof X?b.add(l):!k||!l.Kd()||l instanceof S||b.add(l))}} +t.g(ke,"arrangementOrigin",ke.prototype.sd);t.defineProperty(ke,{sd:"arrangementOrigin"},function(){return this.Np},function(a){this.Np.K(a)||(t.k(a,v,ke,"arrangementOrigin"),this.Np.assign(a),this.J())});ke.prototype.initialOrigin=ke.prototype.Pz=function(a){var b=this.group;if(null!==b){var c=b.location;if(isNaN(c.x)||isNaN(c.y))return a;a=b.placeholder;null!==a?(c=a.$a(wb),c.x+=a.padding.left,c.y+=a.padding.top):c=b.position.copy();return c}return a}; +function ra(){t.uc(this);this.Bd=null;this.clear()}t.ea("LayoutNetwork",ra);ra.prototype.clear=function(){if(this.vertexes)for(var a=this.vertexes.m;a.next();){var b=a.value;b.clear();b.network=null}if(this.edges)for(a=this.edges.m;a.next();)b=a.value,b.clear(),b.network=null;this.vertexes=new la(sa);this.edges=new la(ta);this.iA=new ia(S,sa);this.Yz=new ia(X,ta)};ra.prototype.toString=function(){return"LayoutNetwork"+(null!==this.Vb?"("+this.Vb.toString()+")":"")};t.A(ra,{Vb:"layout"},function(){return this.Bd}); +function ln(a,b){f&&null!==b&&t.k(b,ke,ra,"setLayout");a.Bd=b}ra.prototype.createVertex=function(){return new sa};ra.prototype.createEdge=function(){return new ta}; +ra.prototype.addParts=ra.prototype.ds=function(a,b){if(null!==a){void 0===b&&(b=!1);t.j(b,"boolean",ra,"addParts:toplevelonly");for(var c=a.m;c.next();){var d=c.value;if(d instanceof S&&(!b||d.Oo)&&d.canLayout()&&!d.wh)if(d instanceof V&&null===d.Vb)this.ds(d.Kc,!1);else if(null===this.wm(d)){var e=this.createVertex();e.Bc=d;this.Lk(e)}}for(c.reset();c.next();)if(d=c.value,d instanceof X&&(!b||d.Oo)&&d.canLayout()&&null===this.Mv(d)){var g=d.ca,e=d.ga;g!==e&&(g=this.Nv(g),e=this.Nv(e),null!==g&&null!== +e&&this.Dm(g,e,d))}}};ra.prototype.findGroupVertex=ra.prototype.Nv=function(a){if(null===a)return null;a=bm(a);if(null===a)return null;var b=this.wm(a);if(null!==b)return b;a=a.ib;return null!==a&&(b=this.wm(a),null!==b)?b:null};ra.prototype.addVertex=ra.prototype.Lk=function(a){if(null!==a){f&&t.k(a,sa,ra,"addVertex:vertex");this.vertexes.add(a);var b=a.Bc;null!==b&&this.iA.add(b,a);a.network=this}}; +ra.prototype.addNode=ra.prototype.eo=function(a){if(null===a)return null;f&&t.k(a,S,ra,"addNode:node");var b=this.wm(a);null===b&&(b=this.createVertex(),b.Bc=a,this.Lk(b));return b};ra.prototype.deleteVertex=ra.prototype.lD=function(a){if(null!==a&&(f&&t.k(a,sa,ra,"deleteVertex:vertex"),nn(this,a))){for(var b=a.Ue,c=b.count-1;0<=c;c--){var d=b.ta(c);this.uo(d)}b=a.Le;for(c=b.count-1;0<=c;c--)d=b.ta(c),this.uo(d)}}; +function nn(a,b){if(null===b)return!1;var c=a.vertexes.remove(b);c&&(a.iA.remove(b.Bc),b.network=null);return c}ra.prototype.deleteNode=function(a){null!==a&&(f&&t.k(a,S,ra,"deleteNode:node"),a=this.wm(a),null!==a&&this.lD(a))};ra.prototype.findVertex=ra.prototype.wm=function(a){if(null===a)return null;f&&t.k(a,S,ra,"findVertex:node");return this.iA.wa(a)}; +ra.prototype.addEdge=ra.prototype.co=function(a){if(null!==a){f&&t.k(a,ta,ra,"addEdge:edge");this.edges.add(a);var b=a.link;null!==b&&null===this.Mv(b)&&this.Yz.add(b,a);b=a.toVertex;null!==b&&b.EC(a);b=a.fromVertex;null!==b&&b.CC(a);a.network=this}}; +ra.prototype.addLink=function(a){if(null===a)return null;f&&t.k(a,X,ra,"addLink:link");var b=a.ca,c=a.ga,d=this.Mv(a);null===d?(d=this.createEdge(),d.link=a,null!==b&&(d.fromVertex=this.eo(b)),null!==c&&(d.toVertex=this.eo(c)),this.co(d)):(d.fromVertex=null!==b?this.eo(b):null,d.toVertex=null!==c?this.eo(c):null);return d};ra.prototype.deleteEdge=ra.prototype.uo=function(a){if(null!==a){f&&t.k(a,ta,ra,"deleteEdge:edge");var b=a.toVertex;null!==b&&b.kD(a);b=a.fromVertex;null!==b&&b.jD(a);on(this,a)}}; +function on(a,b){null!==b&&a.edges.remove(b)&&(a.Yz.remove(b.link),b.network=null)}ra.prototype.deleteLink=function(a){null!==a&&(f&&t.k(a,X,ra,"deleteLink:link"),a=this.Mv(a),null!==a&&this.uo(a))};ra.prototype.findEdge=ra.prototype.Mv=function(a){if(null===a)return null;f&&t.k(a,X,ra,"findEdge:link");return this.Yz.wa(a)}; +ra.prototype.linkVertexes=ra.prototype.Dm=function(a,b,c){if(null===a||null===b)return null;f&&(t.k(a,sa,ra,"linkVertexes:fromVertex"),t.k(b,sa,ra,"linkVertexes:toVertex"),null!==c&&t.k(c,X,ra,"linkVertexes:link"));if(a.network===this&&b.network===this){var d=this.createEdge();d.link=c;d.fromVertex=a;d.toVertex=b;this.co(d);return d}return null}; +ra.prototype.reverseEdge=ra.prototype.sw=function(a){if(null!==a){f&&t.k(a,ta,ra,"reverseEdge:edge");var b=a.fromVertex,c=a.toVertex;null!==b&&null!==c&&(b.jD(a),c.kD(a),a.sw(),b.EC(a),c.CC(a))}};ra.prototype.deleteSelfEdges=ra.prototype.Iv=function(){for(var a=t.yb(),b=this.edges.m;b.next();){var c=b.value;c.fromVertex===c.toVertex&&a.push(c)}b=a.length;for(c=0;cd?1:0):1:null!==d?-1:0}; +sa.smartComparer=function(a,b){f&&t.k(a,sa,sa,"smartComparer:m");f&&t.k(b,sa,sa,"smartComparer:n");if(null!==a){if(null!==b){var c=a.ed,d=b.ed;if(null!==c){if(null!==d){var c=c.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=d.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=d&&0>=a&&(d=1);var e=this.spacing.width;isFinite(e)||(e=0);var g=this.spacing.height;isFinite(g)||(g=0);b.mc("Layout");switch(this.alignment){case Nk:var h= +Math.max(this.Pk.width,1);if(!isFinite(h))for(var k=h=0;kd-1||0a)u=0,r=q,s+=x,x=0;x=Math.max(x,F);switch(p){case Lk:m=-m.width;break;default:m=0}l.moveTo(r+m,s);switch(p){case Lk:r-=E;break;default:r+=E}u++}break;case Mk:h=Math.max(this.Pk.width,1);k=x=u=0;l=t.M();for(n=0;nd-1||0a){for(L=0;Ld?1:0}; +Aj.smartComparer=function(a,b){f&&t.k(a,B,Aj,"standardComparer:a");f&&t.k(b,B,Aj,"standardComparer:b");if(null!==a){if(null!==b){var c=a.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),d=b.text.toLocaleLowerCase().split(/([+\-]?[\.]?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/),e;for(e=0;e=a.count)1===a.count&&(a=a.Ya(),a.Aa=0,a.Ma=0);else{var b=new A(vn);b.He(a.m);a=new A(vn);var c=new A(vn),b=this.sort(b);a=new A(vn);var c=new A(vn),d=this.Kx,e=this.zB,g=this.pd,h=this.nn,k=this.Lx,l=this.iq,m=this.qk,n=this.uC,p=this.Wf,q=this.Kt,d=this.Je,e=this.Rs,g= +this.CE;if(!isFinite(g)||0>=g)g=NaN;h=this.JC;if(!isFinite(h)||0>=h)h=1;k=this.kg;isFinite(k)||(k=0);l=this.Fh;if(!isFinite(l)||360l)l=360;m=this.spacing;isFinite(m)||(m=NaN);d===al&&e===bl?d=$k:d===al&&e!==bl&&(e=bl,d=this.Je);if((this.direction===Uk||this.direction===Vk)&&this.sorting!==Tk){for(var r=0;!(r>=b.length);r+=2){a.add(b.ta(r));if(r+1>=b.length)break;c.add(b.ta(r+1))}this.direction===Uk?(this.Je===al&&a.reverse(),b=new A(vn),b.He(a),b.He(c)):(this.Je===al&&c.reverse(),b=new A(vn), +b.He(c),b.He(a))}for(var s=b.length,u=n=0,r=0;rl&&(0===r||r===b.length-1)&&(x/=2);n+=x;u++}if(isNaN(g)||d===al){isNaN(m)&&(m=6);if(d!==$k&&d!==al){x=-Infinity;for(r=0;rg?(g=r,p=g*h):q=u/(360<=l?s:s-1)}this.Kx=d;this.zB=e;this.pd=g;this.nn=h;this.Lx=k;this.iq=l;this.qk=m;this.uC=n;this.Wf=p;this.Kt=q;c=[b,a,c];b=c[0];a=c[1];c=c[2];d=this.Kx;e=this.pd;h=this.Lx;k=this.iq;l=this.qk;m=this.Wf;n=this.Kt;if(this.direction!==Uk&&this.direction!==Vk||d!==al)if(this.direction===Uk||this.direction===Vk){g=0;switch(d){case Zk:g=180*zn(this,e,m,h,n)/Math.PI;break;case $k:n=b=0;g=a.Ya();null!==g&&(b=wn(g,Math.PI/2));g=c.Ya();null!== +g&&(n=wn(g,Math.PI/2));g=180*zn(this,e,m,h,l+(b+n)/2)/Math.PI;break;case Yk:g=k/b.length}if(this.direction===Uk){switch(d){case Zk:An(this,a,h,Xk);break;case $k:Bn(this,a,h,Xk);break;case Yk:Cn(this,a,k/2,h,Xk)}switch(d){case Zk:An(this,c,h+g,Wk);break;case $k:Bn(this,c,h+g,Wk);break;case Yk:Cn(this,c,k/2,h+g,Wk)}}else{switch(d){case Zk:An(this,c,h,Xk);break;case $k:Bn(this,c,h,Xk);break;case Yk:Cn(this,c,k/2,h,Xk)}switch(d){case Zk:An(this,a,h+g,Wk);break;case $k:Bn(this,a,h+g,Wk);break;case Yk:Cn(this, +a,k/2,h+g,Wk)}}}else switch(d){case Zk:An(this,b,h,this.direction);break;case $k:Bn(this,b,h,this.direction);break;case Yk:Cn(this,b,k,h,this.direction);break;case al:Dn(this,b,k,h,this.direction)}else Dn(this,b,k,h-k/2,Wk)}this.updateParts();this.network=null;this.gf=!0}; +function Cn(a,b,c,d,e){var g=a.iq,h=a.pd;a=a.Wf;d=d*Math.PI/180;c=c*Math.PI/180;for(var k=b.length,l=0;lc){for(g=d+(e===Wk?g:-g);0>g;)g+=360;g%=360;180=n.length-1)break;var p=Gn(a,l,m,n,g,e);p[0]||(p=Hn(a,l,m,n,g,e));l=p[1];m=p[2]}a.Rl++;if(!(23Math.abs(r)?Math.abs(l-g)<(n[0].width+n[n.length-1].width)/2&&(h=0):h=0Math.abs(q)?0:q;q=!1;q=Math.abs(g)>Math.abs(p)?0p:0l.Eo||Math.abs(h)h&&0a.Rl?a.pd-h/(2*Math.PI):5>n.length&&10=n.length-1)break;var q=Gn(a,l,m,n,p,e);q[0]||(q=Hn(a,l,m,n,p,e));l=q[1];m=q[2]}a.Rl++;if(!(23a.Rl?a.pd-g/(2*Math.PI):a.pd-(0h){l=b-a;if(l<-h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(l=b-a,l<-h){l=b+a;if(l>h)return b=[!1],b[1]=l,b[2]=m,b;n=!0}m=Math.sqrt(1-Math.min(1,l*l/(h*h)))*k;0>c!==n&&(m=-m);b=Math.abs(c-m)>(d[e].height+d[e+1].height)/2?[!1]:[!0];b[1]=l;b[2]=m;return b} +function Hn(a,b,c,d,e,g){var h=a.pd,k=a.Wf,l=0,m=0;a=(d[e].height+d[e+1].height)/2+a.qk;var n=!1;if(0<=b!==(g===Wk)){if(m=c-a,m<-k){m=c+a;if(m>k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}}else if(m=c+a,m>k){m=c-a;if(m<-k)return b=[!1],b[1]=l,b[2]=m,b;n=!0}l=Math.sqrt(1-Math.min(1,m*m/(k*k)))*h;0>b!==n&&(l=-l);b=Math.abs(b-l)>(d[e].width+d[e+1].width)/2?[!1]:[!0];b[1]=l;b[2]=m;return b}function tn(){this.Eo=-Infinity;this.zp=this.Qm=null} +tn.prototype.commit=function(a){if(null!==this.Qm&&null!==this.zp)for(var b=0;bMath.abs(a.nn-1))return void 0!==d&&void 0!==e?e*b:2*Math.PI*b;a=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c;var h=0,k;k=void 0!==d&&void 0!==e?e/(g+1):Math.PI/(2*(g+1));for(var l=0;l<=g;l++)var m=Math.sin(void 0!==d&&void 0!==e?d+l*e/g:l*Math.PI/(2*g)),h=h+Math.sqrt(1-a*a*m*m)*k;return void 0!==d&&void 0!==e?(b>c?b:c)*h:4*(b>c?b:c)*h}function xn(a,b,c,d,e){a=void 0!==d&&void 0!==e?yn(a,1,c,d,e):yn(a,1,c);return b/a} +function zn(a,b,c,d,e){if(0.001>Math.abs(a.nn-1))return e/b;var g=b>c?Math.sqrt(b*b-c*c)/b:Math.sqrt(c*c-b*b)/c,h=0;a=2*Math.PI/(700*a.network.vertexes.count);b>c&&(d+=Math.PI/2);for(var k=0;;k++){var l=Math.sin(d+k*a),h=h+(b>c?b:c)*Math.sqrt(1-g*g*l*l)*a;if(h>=e)return k*a}return 0} +Ok.prototype.sort=function(a){switch(this.sorting){case Rk:break;case Sk:a.reverse();break;case Pk:a.sort(this.comparer);break;case Qk:a.sort(this.comparer);a.reverse();break;case Tk:for(var b=[],c=0;ce&&(e=k,g=h)}else for(h=0;he&&(e=k,g=h);d.add(a.ta(g));b[g]=-1;g=a.ta(g);e=g.bc;for(g=g.Sb;e.next();)h=e.value,h=h.fromVertex,h=a.indexOf(h),0> +h||0<=b[h]&&b[h]++;for(;g.next();)h=g.value,h=h.toVertex,h=a.indexOf(h),0>h||0<=b[h]&&b[h]++}a=[];for(b=0;ba[b].indexOf(m)&&a[b].push(m);for(;e.next();)l=e.value,m=d.indexOf(l.fromVertex),m!==b&&0>a[b].indexOf(m)&&a[b].push(m)}k=[];for(b=0;ba[c[q]].indexOf(c[q===c.length-1?0:q+1])&&x.push(q===c.length-1?0:q+1);if(0===x.length)for(q=0;qM.indexOf(da)||RM.indexOf(da)||R=E?m+1:m)),G+=m=E&&m++,L>=E&&L++,m>L&&(M=L,L=m,m=M),L-m<(c.length+2)/2===(mr||r===m||(u=r>m?r-m:m-r,s+=rp-u?1:-1);c.splice(0>s?m:m+1,0,b);e.splice(k,1);k--}else n=!1;if(n)break;else c.push(e[0]),e.splice(0,1)}for(b=0;b=a?a:360,this.J())});t.g(Ok,"arrangement",Ok.prototype.Je);t.defineProperty(Ok,{Je:"arrangement"},function(){return this.bd},function(a){this.bd!==a&&(f&&t.k(a,ca,Ok,"arrangement"),a===al||a===$k||a===Zk||a===Yk)&&(this.bd=a,this.J())});t.g(Ok,"direction",Ok.prototype.direction); +t.defineProperty(Ok,{direction:"direction"},function(){return this.pa},function(a){this.pa!==a&&(f&&t.k(a,ca,Ok,"direction"),a===Wk||a===Xk||a===Uk||a===Vk)&&(this.pa=a,this.J())});t.g(Ok,"sorting",Ok.prototype.sorting);t.defineProperty(Ok,{sorting:"sorting"},function(){return this.lh},function(a){this.lh!==a&&(f&&t.k(a,ca,Ok,"sorting"),a===Rk||a===Sk||a===Pk||Qk||a===Tk)&&(this.lh=a,this.J())});t.g(Ok,"comparer",Ok.prototype.comparer); +t.defineProperty(Ok,{comparer:"comparer"},function(){return this.Ug},function(a){this.Ug!==a&&(f&&t.j(a,"function",Ok,"comparer"),this.Ug=a,this.J())});t.g(Ok,"spacing",Ok.prototype.spacing);t.defineProperty(Ok,{spacing:"spacing"},function(){return this.mh},function(a){this.mh!==a&&(this.mh=a,this.J())});t.g(Ok,"nodeDiameterFormula",Ok.prototype.Rs); +t.defineProperty(Ok,{Rs:"nodeDiameterFormula"},function(){return this.gr},function(a){this.gr!==a&&(f&&t.k(a,ca,Ok,"nodeDiameterFormula"),a===cl||a===bl)&&(this.gr=a,this.J())});t.A(Ok,{rG:"actualXRadius"},function(){return this.pd});t.A(Ok,{sG:"actualYRadius"},function(){return this.Wf});t.A(Ok,{MI:"actualSpacing"},function(){return this.qk});t.A(Ok,{qG:"actualCenter"},function(){return isNaN(this.sd.x)||isNaN(this.sd.y)?new v(0,0):new v(this.sd.x+this.rG,this.sd.y+this.sG)});var $k; +Ok.ConstantSpacing=$k=t.w(Ok,"ConstantSpacing",0);var Zk;Ok.ConstantDistance=Zk=t.w(Ok,"ConstantDistance",1);var Yk;Ok.ConstantAngle=Yk=t.w(Ok,"ConstantAngle",2);var al;Ok.Packed=al=t.w(Ok,"Packed",3);var Wk;Ok.Clockwise=Wk=t.w(Ok,"Clockwise",4);var Xk;Ok.Counterclockwise=Xk=t.w(Ok,"Counterclockwise",5);var Uk;Ok.BidirectionalLeft=Uk=t.w(Ok,"BidirectionalLeft",6);var Vk;Ok.BidirectionalRight=Vk=t.w(Ok,"BidirectionalRight",7);var Rk;Ok.Forwards=Rk=t.w(Ok,"Forwards",8);var Sk; +Ok.Reverse=Sk=t.w(Ok,"Reverse",9);var Pk;Ok.Ascending=Pk=t.w(Ok,"Ascending",10);var Qk;Ok.Descending=Qk=t.w(Ok,"Descending",11);var Tk;Ok.Optimized=Tk=t.w(Ok,"Optimized",12);var cl;Ok.Pythagorean=cl=t.w(Ok,"Pythagorean",13);var bl;Ok.Circular=bl=t.w(Ok,"Circular",14);function un(){ra.call(this)}t.ea("CircularNetwork",un);t.Ja(un,ra);un.prototype.createVertex=function(){return new vn};un.prototype.createEdge=function(){return new In};function vn(){sa.call(this);this.actualAngle=this.diameter=NaN} +t.ea("CircularVertex",vn);t.Ja(vn,sa);function wn(a,b){var c=a.network;if(null===c)return NaN;c=c.Vb;if(null===c)return NaN;if(c.Je===al)if(c.Rs===bl)a.diameter=Math.max(a.width,a.height);else{var c=Math.abs(Math.sin(b)),d=Math.abs(Math.cos(b));if(0===c)return a.width;if(0===d)return a.height;a.diameter=Math.min(a.height/c,a.width/d)}else a.diameter=c.Rs===bl?Math.max(a.width,a.height):Math.sqrt(a.width*a.width+a.height*a.height);return a.diameter}function In(){ta.call(this)}t.ea("CircularEdge",In); +t.Ja(In,ta);function Jn(){0k?(e=l.x+l.width/2,g=l.y+l.height/2,h[0]=new v(l.x+l.width+c.width,l.y),h[1]=new v(l.x,l.y+ +l.height+c.height),k=2):(p=Mn(h,k,e,g,l.width,l.height,c),q=h[p],r=new v(q.x+l.width+c.width,q.y),s=new v(q.x,q.y+l.height+c.height),p+1this.network.vertexes.count)return!1;var a=0,b=0,c=this.network.vertexes.m;c.next();for(var d=c.value.R;c.next();){if(c.value.R.Bf(d)&&(a++,1a.network.vertexes.count)return!1;null===a.Vf?a.Vf=new A(Sn):a.Vf.clear();a.Vf.He(a.network.vertexes);var c=a.Vf;c.sort(function(a,b){return null===a||null===b||a===b?0:b.Ef-a.Ef});for(var d=c.count-1;0<=d&&1>=c.p[d].Ef;)d--;return 1=h))){for(var n=0,p=0,q=m.count-h;qs&&(s=1);n=D.sqrt((n+s+p*p*4/(h*h))/s);h=(n-1)*l/2;n=(n-1)*q/2;g.Gb=new w(m-r.x-h,k-r.y-n,l+2*h,q+2*n);g.focus=new v(r.x+h,r.y+n)}a.network=d;return c} +function Rn(a,b,c){f&&(t.k(b,Kn,Jn,"popNetwork:oldnet"),t.o(c,Jn,"popNetwork:level"));for(c=a.network.vertexes.m;c.next();){var d=c.value;d.network=b;if(null!==d.Ng){var e=d.Ng.p[d.yA];d.Ef=e.YA;var g=e.QF,h=e.RF;d.Gb=new w(d.Aa-g,d.Ma-h,e.$A,e.XA);d.focus=new v(g,h);d.yA--}}for(c=a.network.edges.m;c.next();)c.value.network=b;a.network=b} +function Tn(a,b,c){f&&(t.k(b,Sn,Jn,"surroundNode:oldnet"),t.o(c,Jn,"surroundNode:level"));var d=b.nm;if(null!==d&&0!==d.count){c=b.Aa;var e=b.Ma,g=b.width,h=b.height;null!==b.Ng&&0=p.Ef?l++:(k=!0,m++,h+=Math.atan2(b.Ma-p.Ma,b.Aa-p.Aa))}if(0!==l)for(0>1)+m)*(0==k%2?1:-1);p.Aa=c+d*Math.cos(l);p.Ma=e+d*Math.sin(l);k++}}} +function Mn(a,b,c,d,e,g,h){var k=9E19,l=-1,m=0;a:for(;mn.y&&a[q].x-n.xn.x&&a[q].y-n.yl+h?(d=d+g-k,e=e-l-h,D.sqrt(d*d+e*e)):e+ck+m?e>l+h?(d=d-k-m,e=e-l-h,D.sqrt(d*d+e*e)):e+cl+h?e-(l+h):e+c=b.length)return!1;var c=b[0];c.forceX=0;c.forceY=0;for(var d=c.Aa,e=d,g=c.Ma,h=g,c=1;ch-g)?b.sort(function(a,b){return null===a||null===b||a===b?0:a.Aa-b.Aa}):b.sort(function(a,b){return null===a||null===b||a===b?0:a.Ma-b.Ma});for(var h=a.bh,m=0,n=0,p=0,c=0;ch||p-d>h){if(g)break}else if(l-r>h||r-l>h){if(!g)break}else{var s=Un(k,e);1>s?(d>p?(n=Math.abs(e.R.right-k.R.x),n=(1+n)*Math.random()):dr?(p=Math.abs(e.R.bottom-k.R.y),p=(1+p)*Math.random()):ds?(n=(d>p?1:-1)*(1+(e.width>k.width)?e.width: +k.width)*Math.random(),p=(l>r?1:-1)*(1+(e.height>k.height)?e.height:k.height)*Math.random()):(m=g.stiffness*(s-g.length),n=(p-d)/s*m,p=(r-l)/s*m),k.forceX+=n,k.forceY+=p,e.forceX-=n,e.forceY-=p;c=0;d=Math.max(a.bh/20,50);for(e=0;ed&&(g=d),h<-d?h=-d:h>d&&(h=d),k.Aa+=g,k.Ma+=h,c=Math.max(c,g*g+h*h));return c>a.Cz*a.Cz}Jn.prototype.moveFixedVertex=function(){}; +Jn.prototype.commitLayout=function(){this.FA();this.commitNodes();this.Gs&&this.commitLinks()};Jn.prototype.FA=function(){if(this.il)for(var a=this.network.edges.m;a.next();){var b=a.value.link;null!==b&&(b.fb=vb,b.gb=vb)}};Jn.prototype.commitNodes=function(){var a=0,b=0;if(this.HC){var c=t.qf();this.df(this.network,c);b=this.sd;a=b.x-c.x;b=b.y-c.y;t.Ic(c)}for(var c=t.qf(),d=this.network.vertexes.m;d.next();){var e=d.value;if(0!==a||0!==b)c.assign(e.R),c.x+=a,c.y+=b,e.Gb=c;e.commit()}t.Ic(c)}; +Jn.prototype.commitLinks=function(){for(var a=this.network.edges.m;a.next();)a.value.commit()};Jn.prototype.springStiffness=function(a){a=a.stiffness;return isNaN(a)?this.gn:a};Jn.prototype.springLength=function(a){a=a.length;return isNaN(a)?this.fn:a};Jn.prototype.electricalCharge=function(a){a=a.charge;return isNaN(a)?this.cn:a};Jn.prototype.electricalFieldX=function(){return 0};Jn.prototype.electricalFieldY=function(){return 0}; +Jn.prototype.gravitationalMass=function(a){a=a.mass;return isNaN(a)?this.en:a};Jn.prototype.gravitationalFieldX=function(){return 0};Jn.prototype.gravitationalFieldY=function(){return 0};Jn.prototype.isFixed=function(a){return a.isFixed};t.A(Jn,{NI:"currentIteration"},function(){return this.Gq});t.g(Jn,"arrangementSpacing",Jn.prototype.rv);t.defineProperty(Jn,{rv:"arrangementSpacing"},function(){return this.Jf},function(a){this.Jf.K(a)||(this.Jf.assign(a),this.J())});t.g(Jn,"arrangesToOrigin",Jn.prototype.HC); +t.defineProperty(Jn,{HC:"arrangesToOrigin"},function(){return this.Op},function(a){this.Op!==a&&(this.Op=a,this.J())});t.g(Jn,"setsPortSpots",Jn.prototype.il);t.defineProperty(Jn,{il:"setsPortSpots"},function(){return this.kh},function(a){this.kh!==a&&(this.kh=a,this.J())});t.g(Jn,"comments",Jn.prototype.comments);t.defineProperty(Jn,{comments:"comments"},function(){return this.Tg},function(a){this.Tg!==a&&(this.Tg=a,this.J())});t.g(Jn,"maxIterations",Jn.prototype.jw); +t.defineProperty(Jn,{jw:"maxIterations"},function(){return this.In},function(a){this.In!==a&&0<=a&&(this.In=a,this.J())});t.g(Jn,"epsilonDistance",Jn.prototype.Cz);t.defineProperty(Jn,{Cz:"epsilonDistance"},function(){return this.kq},function(a){this.kq!==a&&0b.toVertex.index&&(this.network.sw(b),b.rev=!0);break;case Xn:for(b=this.network.vertexes.m;b.next();)b.value.vo=-1,b.value.finish=-1;for(a=this.network.edges.m;a.next();)a.value.forest=!1;this.dr=0;for(b.reset();b.next();)0===b.value.bc.count&&ro(this,b.value);for(b.reset();b.next();)-1===b.value.vo&&ro(this,b.value);for(a.reset();a.next();)b=a.value,b.forest|| +(c=b.fromVertex,d=c.finish,e=b.toVertex,g=e.finish,e.vos&&0s&&0b[this.uf]&&(this.ou=b[c]-1,this.uf=c),b[c]k)for(p=k+1;pl;p--)n=d[p],n.near===m&&n.im===m.im||h++;var q,r,s,u,x,E;if(0<=c)for(l=d[k].Ue,m=0;mu||n===u&&q>s)&&h++,xn||u===n&&s>q)&&h++);if(0>=c)for(l=d[k].Le,m=0;mu||n===u&&p>x)&&h++,sn||u===n&&x>p)&&h++);g[k*e+k]=h;for(l= +k+1;l=c)for(h=d[k].Le,E=d[l].Le,m=0;m=c&&(l=k.Ue);var m=null;0<=c&&(m=k.Le);var n=0,p=0,q=k.near;null!==q&&q.layer===k.layer&&(n+=q.column-1,p++);if(null!==l)for(q=0;q=c&&(l=k.Ue);var m=null;0<=c&&(m=k.Le);var n=0,p=[],q=k.near;null!==q&&q.layer===k.layer&&(p[n]=q.column-1,n++);if(null!==l)for(q=0;q>1,g[h]=n&1?p[m]:p[m-1]+p[m]>>1)}Ao(a,b,d);return g}function Jo(a,b,c,d,e,g){if(b.component===d){b.component=c;var h,k;if(e)for(var l=b.Sb;l.next();){var m=l.value.toVertex;h=b.layer-m.layer;k=Bo(l.value);h===k&&Jo(a,m,c,d,e,g)}if(g)for(l=b.bc;l.next();)m=l.value.fromVertex,h=m.layer-b.layer,k=Bo(l.value),h===k&&Jo(a,m,c,d,e,g)}} +function Ko(a,b,c,d,e,g){if(b.component===d){b.component=c;if(e)for(var h=b.Sb,k;h.next();)k=h.value.toVertex,Ko(a,k,c,d,e,g);if(g)for(b=b.bc;b.next();)h=b.value.fromVertex,Ko(a,h,c,d,e,g)}}function eo(a){for(a=a.vertexes.m;a.next();){var b=a.value;if(b.valid)return b}return null}function fo(a){for(a=a.vertexes.m;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.Sb;d.next();)if(d.value.toVertex.valid){c=!1;break}if(c)return b}}return null} +function ho(a){for(a=a.vertexes.m;a.next();){var b=a.value;if(b.valid){for(var c=!0,d=b.bc;d.next();)if(d.value.fromVertex.valid){c=!1;break}if(c)return b}}return null}function ro(a,b){b.vo=a.dr;a.dr++;for(var c=b.Sb;c.next();){var d=c.value,e=d.toVertex;-1===e.vo&&(d.forest=!0,ro(a,e))}b.finish=a.dr;a.dr++} +Fk.prototype.assignLayers=function(){switch(this.Fn){case Lo:Mo(this);break;case No:for(var a,b=this.network.vertexes.m;b.next();)a=Oo(this,b.value),this.hb=Math.max(a,this.hb);for(b.reset();b.next();)a=b.value,a.layer=this.hb-a.layer;break;default:case Yn:Mo(this);for(b=this.network.vertexes.m;b.next();)b.value.valid=!1;for(b.reset();b.next();)0===b.value.bc.count&&Po(this,b.value);a=Infinity;for(b.reset();b.next();)a=Math.min(a,b.value.layer);this.hb=-1;for(b.reset();b.next();)b.value.layer-=a, +this.hb=Math.max(this.hb,b.value.layer)}};function Mo(a){for(var b=a.network.vertexes.m;b.next();){var c=Qo(a,b.value);a.hb=Math.max(c,a.hb)}}function Qo(a,b){var c=0;if(-1===b.layer){for(var d=b.Sb;d.next();)var e=d.value,g=Bo(e),c=Math.max(c,Qo(a,e.toVertex)+g);b.layer=c}else c=b.layer;return c}function Oo(a,b){var c=0;if(-1===b.layer){for(var d,e,g=b.bc;g.next();)e=g.value,d=Bo(e),c=Math.max(c,Oo(a,e.fromVertex)+d);b.layer=c}else c=b.layer;return c} +function Po(a,b){if(!b.valid){b.valid=!0;for(var c=b.Sb;c.next();)Po(a,c.value.toVertex);for(c=a.network.vertexes.m;c.next();)c.value.component=-1;for(var d=b.Ue.p,e=d.length,g=0;gk&&Jo(a,h.fromVertex,0,-1,!0,!1)}for(Jo(a,b,1,-1,!0,!0);0!==b.component;){for(var k=0,d=Infinity,l=0,m=null,n=a.network.vertexes.m;n.next();){var p=n.value;if(1===p.component){for(var q=0,r=!1,s=p.Ue.p,e=s.length,g=0;gd)&&!p&&(k=m,d=n)}if(0>g){for(c.reset();c.next();)g=c.value,1===g.component&&(g.layer-=e);b.component=0}else k.component=0}}}function yo(a,b,c){return 90===a.pa?c&&!b.rev||!c&&b.rev?270:90:180===a.pa?c&&!b.rev||!c&&b.rev?0:180:270===a.pa?c&&!b.rev||!c&&b.rev?90:270:c&&!b.rev||!c&&b.rev?180:0} +Fk.prototype.initializeIndices=function(){switch(this.vn){default:case Ro:for(var a,b=this.network.vertexes.m;b.next();){var c=b.value;a=c.layer;c.index=this.yd[a];this.yd[a]++}break;case Zn:b=this.network.vertexes.m;for(a=this.hb;0<=a;a--){for(;b.next();)b.value.layer===a&&-1===b.value.index&&So(this,b.value);b.reset()}break;case To:for(b=this.network.vertexes.m,a=0;a<=this.hb;a++){for(;b.next();)b.value.layer===a&&-1===b.value.index&&Uo(this,b.value);b.reset()}}}; +function So(a,b){var c=b.layer;b.index=a.yd[c];a.yd[c]++;for(var c=b.Le.Ve(),d=!0,e;d;)for(d=!1,e=0;eh.portFromColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;eh.portToColOffset&&(d=!0,c[e]=h,c[e+1]=g)}for(e=0;e=h;d--)g=Wo(this,d,-1)||g;e=this.countCrossings();e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,1)||g;e=this.countCrossings();e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g= +Wo(this,d,-1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this))}break;default:case $n:for(c=this.hb,h=0,k=a+1;(d=this.countCrossings())=h;d--)g=Wo(this,d,-1)||g;e=this.countCrossings();e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,1)||g;e=this.countCrossings();e>=a?Eo(this,b): +(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,-1)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=c;d>=h;d--)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this));for(g=!0;g;)for(g=!1,d=h;d<=c;d++)g=Wo(this,d,0)||g;e>=a?Eo(this,b):(a=e,b=Do(this))}}Eo(this,b)}; +function Vo(a,b,c){f&&(t.o(b,Fk,"medianBarycenterCrossingReduction:unfixedLayer"),t.o(c,Fk,"medianBarycenterCrossingReduction:direction"));var d=zo(a,b),e=a.yd[b],g=Io(a,b,c),h=Ho(a,b,c);for(c=0;cg+1&&(q+=4*(F-g),r+=4*(F-(g+1)))}L=d[g].Sb.m;for(L.reset();L.next();)if(G=L.value,G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g+1&&(r+=1)}L=d[g+1].bc.m;for(L.reset();L.next();)if(G=L.value,G.valid&&G.fromVertex.layer===b){G=G.fromVertex;for(F=0;d[F]!==G;)F++;Fg+1&&(q+=4*(F-(g+1)),r+=4*(F-g))}L=d[g+1].Sb.m;for(L.reset();L.next();)if(G=L.value, +G.valid&&G.toVertex.layer===b){G=G.toVertex;for(F=0;d[F]!==G;)F++;F===g&&(q+=1)}var F=G=0,L=h[d[g].index],M=k[d[g].index],W=h[d[g+1].index],T=k[d[g+1].index];-1!==L&&(G+=Math.abs(L-s),F+=Math.abs(L-E));-1!==M&&(G+=Math.abs(M-s),F+=Math.abs(M-E));-1!==W&&(G+=Math.abs(W-u),F+=Math.abs(W-x));-1!==T&&(G+=Math.abs(T-u),F+=Math.abs(T-x));if(r>1)+8*g;this.Cb*=8}if(0!==(this.ei&$o))for(b=!0;b;){b=!1;for(a=this.uf+1;a<=this.hb;a++)b=ap(this,a,1)||b;for(a=this.uf- +1;0<=a;a--)b=ap(this,a,-1)||b;b=ap(this,this.uf,0)||b}if(0!==(this.ei&bp)){for(a=this.uf+1;a<=this.hb;a++)cp(this,a,1);for(a=this.uf-1;0<=a;a--)cp(this,a,-1);cp(this,this.uf,0)}c&&(dp(this,-1),dp(this,1));if(0!==(this.ei&$o))for(b=!0;b;){b=!1;b=ap(this,this.uf,0)||b;for(a=this.uf+1;a<=this.hb;a++)b=ap(this,a,0)||b;for(a=this.uf-1;0<=a;a--)b=ap(this,a,0)||b}};function ap(a,b,c){f&&(t.o(b,Fk,"bendStraighten:unfixedLayer"),t.o(c,Fk,"bendStraighten:direction"));for(var d=!1;ep(a,b,c);)d=!0;return d} +function ep(a,b,c){f&&(t.o(b,Fk,"shiftbendStraighten:unfixedLayer"),t.o(c,Fk,"shiftbendStraighten:direction"));var d,e=zo(a,b),g=a.yd[b],h=Ho(a,b,-1);if(0c)for(d=0;dd-1||n-e[d-1].column-1>p+a.nodeMinColumnSpace(e[d-1],!1)?n-1:n,q=d+1>=g||e[d+1].column-n-1>q+a.nodeMinColumnSpace(e[d+1],!0)?n+1:n,r=0,s=0,u=0,x, +E,F,G;if(0>=c)for(var L=e[d].bc.m;L.next();)x=L.value,x.valid&&x.fromVertex.layer!==b&&(E=Co(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.fromVertex.column,r+=(Math.abs(n+G-(x+F))+1)*E,s+=(Math.abs(p+G-(x+F))+1)*E,u+=(Math.abs(q+G-(x+F))+1)*E);if(0<=c)for(L=e[d].Sb.m;L.next();)x=L.value,x.valid&&x.toVertex.layer!==b&&(E=Co(x),F=x.portFromColOffset,G=x.portToColOffset,x=x.toVertex.column,r+=(Math.abs(n+F-(x+G))+1)*E,s+=(Math.abs(p+F-(x+G))+1)*E,u+=(Math.abs(q+F-(x+G))+1)*E);G=F=E=0;x=h[e[d].index]; +L=k[e[d].index];-1!==x&&(E+=Math.abs(x-n),F+=Math.abs(x-p),G+=Math.abs(x-q));-1!==L&&(E+=Math.abs(L-n),F+=Math.abs(L-p),G+=Math.abs(L-q));if(s=h[c]?n=l:m<=h[c]&&(n=m));n!==k&&(g=!0,d[c].column=n)}Ao(a,b,d);a.normalize()} +function fp(a,b){f&&(t.o(b,Fk,"packAux:column"),t.o(1,Fk,"packAux:direction"));for(var c=!0,d=a.network.vertexes.m,e;d.next();){e=d.value;var g=a.nodeMinColumnSpace(e,!0),h=a.nodeMinColumnSpace(e,!1);if(e.column-g<=b&&e.column+h>=b){c=!1;break}}g=!1;if(c)for(d.reset();d.next();)e=d.value,e.column>b&&(e.column-=1,g=!0);return g} +function gp(a,b){f&&(t.o(b,Fk,"tightPackAux:column"),t.o(1,Fk,"tightPackAux:direction"));var c=b,c=b+1,d,e=[],g=[];for(d=0;d<=a.hb;d++)e[d]=!1,g[d]=!1;for(var h=a.network.vertexes.m;h.next();){d=h.value;var k=d.column-a.nodeMinColumnSpace(d,!0),l=d.column+a.nodeMinColumnSpace(d,!1);k<=b&&l>=b&&(e[d.layer]=!0);k<=c&&l>=c&&(g[d.layer]=!0)}k=!0;c=!1;for(d=0;d<=a.hb;d++)k=k&&!(e[d]&&g[d]);if(k)for(h.reset();h.next();)d=h.value,d.column>b&&(d.column-=1,c=!0);return c} +function dp(a,b){f&&t.o(b,Fk,"componentPack:direction");for(var c=0;c<=a.Cb;c++)for(;fp(a,c););a.normalize();for(c=0;ce?Eo(a,d):hb)for(c=a.Cb;0<=c;c--)for(d=Do(a),e=Go(a),g=e+1;ee?Eo(a,d):hc)for(d.reset();d.next();)e=d.value,e.column+a.nodeMinColumnSpace(e,!1)>=b&&(e.component=a.Rf);a.Rf++;for(d.reset();d.next();)e=d.value,-1===e.component&&(Ko(a,e,a.Rf,-1,!0,!0),a.Rf++);b=[];for(e=0;ec)for(k=a.Cb;0c)for(d.reset();d.next();)e=d.value,g[e.component]&&(e.column+=1)}Fk.prototype.commitLayout=function(){if(this.il)for(var a=xo(this,!0),b=xo(this,!1),c=this.network.edges.m,d;c.next();)d=c.value.link,null!==d&&(d.fb=a,d.gb=b);this.commitNodes();this.Gs&&this.commitLinks()}; +function xo(a,b){return 270===a.pa?b?Pb:Vb:90===a.pa?b?Vb:Pb:180===a.pa?b?Tb:Ub:b?Ub:Tb} +Fk.prototype.commitNodes=function(){this.hh=[];this.wg=[];this.sf=[];this.Ad=[];for(var a=0;a<=this.hb;a++)this.hh[a]=0,this.wg[a]=0,this.sf[a]=0,this.Ad[a]=0;for(var a=this.network.vertexes.m,b,c;a.next();)b=a.value,c=b.layer,this.hh[c]=Math.max(this.hh[c],this.nodeMinLayerSpace(b,!0)),this.wg[c]=Math.max(this.wg[c],this.nodeMinLayerSpace(b,!1));b=0;for(var d=this.En,e=0;e<=this.hb;e++)c=d,0>=this.hh[e]+this.wg[e]&&(c=0),0=Ja.R.y&&Zb<=Ja.R.bottom&&(ya=Ja.Aa+hf,Zb=Zb=Ja.R.x&&Zb<=Ja.R.right&&(ya=Ja.Ma+hf,Zb=Zbqb.y&&(hd=Rc.y>qb.y?0:Ya.xsb.x&&(Cc=se.x>sb.x?0:Sc.yb.layer?1:a.xeb.xe?1:a.Gdb.Gd?1:0:0}; +Fk.prototype.VE=function(a,b){return a instanceof ip&&b instanceof ip&&a!==b?a.Yab.Ya||a.Ghb.Gh||a.xeb.xe?1:a.Gdb.Gd?1:0:0};Fk.prototype.uw=function(a,b){return a instanceof ip&&b instanceof ip&&a!==b?a.Mdb.Md||a.Ghb.Gh||a.xeb.xe?1:a.Gdb.Gd?1:0:0};Fk.prototype.I=function(a,b){f&&(t.o(a,Fk,"isApprox:a"),t.o(b,Fk,"isApprox:b"));var c=a-b;return-1c}; +function jp(a,b,c,d){f&&(t.o(a,Fk,"isUnoccupied2:px"),t.o(b,Fk,"isUnoccupied2:py"),t.o(c,Fk,"isUnoccupied2:qx"),t.o(d,Fk,"isUnoccupied2:qy"));return!0}function zo(a,b){var c,d=a.yd[b];if(d>=a.yg.length){c=[];var e;for(e=0;ea&&(this.ei=a,this.J())});t.g(Fk,"setsPortSpots",Fk.prototype.il);t.defineProperty(Fk,{il:"setsPortSpots"},function(){return this.kh},function(a){this.kh!==a&&"boolean"===typeof a&&(this.kh=a,this.J())});t.g(Fk,"linkSpacing",Fk.prototype.Vo);t.defineProperty(Fk,{Vo:"linkSpacing"},function(){return this.hj},function(a){this.hj!==a&&(this.hj=a,this.J())});t.A(Fk,{kJ:"maxLayer"},function(){return this.hb}); +t.A(Fk,{iJ:"maxIndex"},function(){return this.ou});t.A(Fk,{hJ:"maxColumn"},function(){return this.Cb});t.A(Fk,{lJ:"minIndexLayer"},function(){return this.Yq});t.A(Fk,{jJ:"maxIndexLayer"},function(){return this.uf});var Xn;Fk.CycleDepthFirst=Xn=t.w(Fk,"CycleDepthFirst",0);var co;Fk.CycleGreedy=co=t.w(Fk,"CycleGreedy",1);var Yn;Fk.LayerOptimalLinkLength=Yn=t.w(Fk,"LayerOptimalLinkLength",0);var Lo;Fk.LayerLongestPathSink=Lo=t.w(Fk,"LayerLongestPathSink",1);var No; +Fk.LayerLongestPathSource=No=t.w(Fk,"LayerLongestPathSource",2);var Zn;Fk.InitDepthFirstOut=Zn=t.w(Fk,"InitDepthFirstOut",0);var To;Fk.InitDepthFirstIn=To=t.w(Fk,"InitDepthFirstIn",1);var Ro;Fk.InitNaive=Ro=t.w(Fk,"InitNaive",2);var Xo;Fk.AggressiveNone=Xo=t.w(Fk,"AggressiveNone",0);var $n;Fk.AggressiveLess=$n=t.w(Fk,"AggressiveLess",1);var Yo;Fk.AggressiveMore=Yo=t.w(Fk,"AggressiveMore",2);Fk.PackNone=0;var Zo;Fk.PackExpand=Zo=1;var $o;Fk.PackStraighten=$o=2;var bp;Fk.PackMedian=bp=4;var ao; +Fk.PackAll=ao=7;function bo(){ra.call(this)}t.ea("LayeredDigraphNetwork",bo);t.Ja(bo,ra);bo.prototype.createVertex=function(){return new kp};bo.prototype.createEdge=function(){return new lp};function kp(){sa.call(this);this.index=this.column=this.layer=-1;this.component=NaN;this.near=null;this.valid=!1;this.finish=this.vo=NaN;this.im=0;this.gA=this.hA=void 0}t.ea("LayeredDigraphVertex",kp);t.Ja(kp,sa); +function lp(){ta.call(this);this.forest=this.rev=this.valid=!1;this.portToPos=this.portFromPos=NaN;this.portToColOffset=this.portFromColOffset=0}t.ea("LayeredDigraphEdge",lp);t.Ja(lp,ta);function Z(){0b.level)return!1;a.removeChild(c.parent,c)}return!0} +Z.prototype.removeChild=function(a,b){f&&t.k(a,qp,Z,"removeChild:p");f&&t.k(b,qp,Z,"removeChild:c");if(null!==a&&null!==b){for(var c=a.children,d=0,e=0;eh?Zp(b,l,ab,L,M):$p(b,l,ab,L,M);ab=R[0];L=R[1];M=R[2];break;case Np:for(n=0;nu&&(xaKb&&(eq(b,-Kb,0,ua,n-1),fq(T,-Kb,0),fq(U,-Kb,0),Kb=0);p.ja.q(Kb,Na);L=Math.max(L,da);M=Math.max(M,W+(0===Ja?0:F)+ya.height);xa=da}else{0u&&(NaKb&&(eq(b,0,-Kb,ua,n-1),fq(T,0,-Kb),fq(U,0,-Kb),Kb=0);p.ja.q(xa,Kb);M=Math.max(M,R);L=Math.max(L,W+(0===Ja?0:F)+ya.width);Na=R}Ka++}0k&&(k=0),135r&&(r=0), +q===Op&&(m+=x/2+b.N.y),l+=e+d):c?(null===b.comments?e>L&&(q=jq(q,e-L,0),l=q[0],m=q[1],L=e,k=0):L=hq(b,L,k),0>k&&(l-=k,k=0),135M&&(q=jq(q,0,g-M),l=q[0],m=q[1],M=g,r=0):M=iq(b,M,r),0>r&&(m-=r,r=0),l+=e+d);if(0h[0].x?h[2].assign(h[1]):h[1].assign(h[2])),h[3].yh[0].x?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(k+e,0),q[1].q(q[0].x,g),q[2].yh[0].y?h[2].assign(h[1]):h[1].assign(h[2])),h[3].xh[0].y?h[3].assign(h[2]):h[2].assign(h[3])),q[0].q(0,r+g),q[1].q(e,q[0].y),q[2].xc?Zp(b,e,Ja,M,W):$p(b,e,Ja,M,W);Ja=W[0];M=W[1];W=W[2];break;case Np:for(k=0;kr&&(Ur&&(dap&&(p=0),135G&&(G=0));b.Ha.q(p,G);b.Ua.q(M,W)}} +function Zp(a,b,c,d,e){f&&t.k(a,qp,Z,"layoutBusChildrenPosDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ua.width;e=h.Ua.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=90===Up(a),n=0,p=0,q=0,r=0;rm&&(d-=m),e=Math.max(e,Math.max(F,q)+b+s.height),0>h.ja.x&&(c=sq(a,h.ja.x,!1,c,k))):(h.ja.q(d+b,c+k/2-h.N.y-h.Ha.y),d=Math.max(d,Math.max(E,p)+b+s.width),m=c+k/2-h.N.y-h.Ha.y,e=Math.max(e,m+s.height),0>m&&(e-=m),0>h.ja.y&&(c=sq(a,h.ja.y,!0,c,k))));a=[];a[0]=c;a[1]=d;a[2]=e;return a} +function $p(a,b,c,d,e){f&&t.k(a,qp,Z,"layoutBusChildrenNegDir:v");var g=b.length;if(0===g)return a=[],a[0]=c,a[1]=d,a[2]=e,a;if(1===g){var h=b[0];d=h.Ua.width;e=h.Ua.height;a=[];a[0]=c;a[1]=d;a[2]=e;return a}for(var k=a.nodeSpacing,l=a.rowSpacing,m=270===Up(a),n=0,p=0,q=0,r=0;rp&&(d-=p),e=Math.max(e,Math.abs(Math.min(F,q))+l+s.height),0>h.ja.x&&(c=sq(a,h.ja.x,!1,c,k))):(h.ja.q(-d-s.width-l,c+k/2-h.N.y-h.Ha.y),d=Math.max(d,Math.abs(Math.min(E,p))+l+s.width),p=c+k/2-h.N.y-h.Ha.y,e=Math.max(e,p+s.height),0>p&&(e-=p),0>h.ja.y&&(c=sq(a,h.ja.y,!0,c,k))));for(r=0;rd&&(d=c+a.width);0>c&&(d-=c);return d;case Vp:return a.width>b?a.width:b;case Wp:return 2*a.N.x>b?a.width:b+a.width-2*a.N.x;case Mp:case Bp:return d=Math.min(0,c),c=Math.max(b,c+a.width),Math.max(a.width,c-d);case Np:return a.width-a.N.x+a.nodeSpacing/2+b;case Op:return Math.max(a.width,a.N.x+a.nodeSpacing/2+b);default:return b}} +function iq(a,b,c){f&&t.k(a,qp,Z,"calculateSubheight:v");switch(a.alignment){case Kp:case gq:var d=b;c+a.height>d&&(d=c+a.height);0>c&&(d-=c);return d;case Vp:return a.height>b?a.height:b;case Wp:return 2*a.N.y>b?a.height:b+a.height-2*a.N.y;case Mp:case Bp:return d=Math.min(0,c),c=Math.max(b,c+a.height),Math.max(a.height,c-d);case Np:return a.height-a.N.y+a.nodeSpacing/2+b;case Op:return Math.max(a.height,a.N.y+a.nodeSpacing/2+b);default:return b}} +function jq(a,b,c){f&&t.k(a,ca,Z,"alignOffset:align");switch(a){case gq:b/=2;c/=2;break;case Kp:b/=2;c/=2;break;case Vp:c=b=0;break;case Wp:break;default:t.l("Unhandled alignment value "+a.toString())}a=[];a[0]=b;a[1]=c;return a}function bq(a,b,c,d,e,g){f&&t.k(a,qp,Z,"shiftRelPosAlign:v");f&&t.k(b,ca,Z,"shiftRelPosAlign:align");b=jq(b,c,d);eq(a,b[0],b[1],e,g)}function eq(a,b,c,d,e){f&&t.k(a,qp,Z,"shiftRelPos:v");if(0!==b||0!==c)for(a=a.children;d<=e;d++){var g=a[d].ja;g.x+=b;g.y+=c}} +function cq(a,b,c,d){f&&(t.k(b,qp,Z,"recordMidPoints:v"),t.j(c,"number",Z,"recordMidPoints:x"),t.j(d,"number",Z,"recordMidPoints:y"));var e=b.parent;switch(a.rf){case np:for(a=b.bc;a.next();)b=a.value,b.fromVertex===e&&b.nr.q(c,d);break;case up:for(a=b.Sb;a.next();)b=a.value,b.toVertex===e&&b.nr.q(c,d);break;default:t.l("Unhandled path value "+a.rf.toString())}}function fq(a,b,c){for(var d=0;dn.length||null===p||2>p.length))for(g= +e=0;eu&&k.yk.y&&ub.length||null===e||2>e.length)d=null;else{m=aq(a,b.length+e.length);for(d=l=k=0;lk;)u=e[l++],m[d++].q(u.x+g,u.y);e=aq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=aq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x, +k.y);k=aq(a,g);for(e=0;en.length||null===p||2>p.length))for(g=e=0;el&&k.xk.x&&lb.length||null===e||2>e.length)d=null;else{m=aq(a,b.length+e.length);for(d=l=k=0;lk;)u=e[l++],m[d++].q(u.x,u.y+g);e=aq(a,d);for(k=0;kn.length||null===l||2>l.length)e=null;else{m=aq(a,n.length+l.length);for(g=x=e=0;el;)k=n[e++],m[g++].q(k.x,k.y);k=aq(a,g);for(e=0;e=a?0:135>=a?90:225>=a?180:315>=a?270:0} +function Xp(a){f&&t.k(a,qp,Z,"computeLayerSpacing:v");var b=Up(a),b=90===b||270===b,c=a.layerSpacing;if(0=a&&(this.ra.nodeIndentPastParent=a,this.J())});t.g(Z,"nodeSpacing",Z.prototype.nodeSpacing); +t.defineProperty(Z,{nodeSpacing:"nodeSpacing"},function(){return this.ra.nodeSpacing},function(a){this.ra.nodeSpacing!==a&&(this.ra.nodeSpacing=a,this.J())});t.g(Z,"layerSpacing",Z.prototype.layerSpacing);t.defineProperty(Z,{layerSpacing:"layerSpacing"},function(){return this.ra.layerSpacing},function(a){this.ra.layerSpacing!==a&&(this.ra.layerSpacing=a,this.J())});t.g(Z,"layerSpacingParentOverlap",Z.prototype.layerSpacingParentOverlap); +t.defineProperty(Z,{layerSpacingParentOverlap:"layerSpacingParentOverlap"},function(){return this.ra.layerSpacingParentOverlap},function(a){this.ra.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.ra.layerSpacingParentOverlap=a,this.J())});t.g(Z,"compaction",Z.prototype.compaction);t.defineProperty(Z,{compaction:"compaction"},function(){return this.ra.compaction},function(a){this.ra.compaction!==a&&(f&&t.k(a,ca,Z,"compaction"),a===Rp||a===Tp)&&(this.ra.compaction=a,this.J())}); +t.g(Z,"breadthLimit",Z.prototype.breadthLimit);t.defineProperty(Z,{breadthLimit:"breadthLimit"},function(){return this.ra.breadthLimit},function(a){this.ra.breadthLimit!==a&&0<=a&&(this.ra.breadthLimit=a,this.J())});t.g(Z,"rowSpacing",Z.prototype.rowSpacing);t.defineProperty(Z,{rowSpacing:"rowSpacing"},function(){return this.ra.rowSpacing},function(a){this.ra.rowSpacing!==a&&(this.ra.rowSpacing=a,this.J())});t.g(Z,"rowIndent",Z.prototype.rowIndent); +t.defineProperty(Z,{rowIndent:"rowIndent"},function(){return this.ra.rowIndent},function(a){this.ra.rowIndent!==a&&0<=a&&(this.ra.rowIndent=a,this.J())});t.g(Z,"commentSpacing",Z.prototype.commentSpacing);t.defineProperty(Z,{commentSpacing:"commentSpacing"},function(){return this.ra.commentSpacing},function(a){this.ra.commentSpacing!==a&&(this.ra.commentSpacing=a,this.J())});t.g(Z,"commentMargin",Z.prototype.commentMargin); +t.defineProperty(Z,{commentMargin:"commentMargin"},function(){return this.ra.commentMargin},function(a){this.ra.commentMargin!==a&&(this.ra.commentMargin=a,this.J())});t.g(Z,"setsPortSpot",Z.prototype.setsPortSpot);t.defineProperty(Z,{setsPortSpot:"setsPortSpot"},function(){return this.ra.setsPortSpot},function(a){this.ra.setsPortSpot!==a&&(this.ra.setsPortSpot=a,this.J())});t.g(Z,"portSpot",Z.prototype.portSpot); +t.defineProperty(Z,{portSpot:"portSpot"},function(){return this.ra.portSpot},function(a){this.ra.portSpot.K(a)||(this.ra.portSpot=a,this.J())});t.g(Z,"setsChildPortSpot",Z.prototype.setsChildPortSpot);t.defineProperty(Z,{setsChildPortSpot:"setsChildPortSpot"},function(){return this.ra.setsChildPortSpot},function(a){this.ra.setsChildPortSpot!==a&&(this.ra.setsChildPortSpot=a,this.J())});t.g(Z,"childPortSpot",Z.prototype.childPortSpot); +t.defineProperty(Z,{childPortSpot:"childPortSpot"},function(){return this.ra.childPortSpot},function(a){this.ra.childPortSpot.K(a)||(this.ra.childPortSpot=a,this.J())});t.g(Z,"alternateSorting",Z.prototype.OG);t.defineProperty(Z,{OG:"alternateSorting"},function(){return this.qa.sorting},function(a){this.qa.sorting!==a&&(f&&t.k(a,ca,Z,"alternateSorting"),a===Gp||a===Hp||a===Ip||Jp)&&(this.qa.sorting=a,this.J())});t.g(Z,"alternateComparer",Z.prototype.CG); +t.defineProperty(Z,{CG:"alternateComparer"},function(){return this.qa.comparer},function(a){this.qa.comparer!==a&&(f&&t.j(a,"function",Z,"alternateComparer"),this.qa.comparer=a,this.J())});t.g(Z,"alternateAngle",Z.prototype.wG);t.defineProperty(Z,{wG:"alternateAngle"},function(){return this.qa.angle},function(a){this.qa.angle===a||0!==a&&90!==a&&180!==a&&270!==a||(this.qa.angle=a,this.J())});t.g(Z,"alternateAlignment",Z.prototype.vG); +t.defineProperty(Z,{vG:"alternateAlignment"},function(){return this.qa.alignment},function(a){this.qa.alignment!==a&&(f&&t.nb(a,Z,Z,"alternateAlignment"),this.qa.alignment=a,this.J())});t.g(Z,"alternateNodeIndent",Z.prototype.GG);t.defineProperty(Z,{GG:"alternateNodeIndent"},function(){return this.qa.nodeIndent},function(a){this.qa.nodeIndent!==a&&0<=a&&(this.qa.nodeIndent=a,this.J())});t.g(Z,"alternateNodeIndentPastParent",Z.prototype.HG); +t.defineProperty(Z,{HG:"alternateNodeIndentPastParent"},function(){return this.qa.nodeIndentPastParent},function(a){this.qa.nodeIndentPastParent!==a&&0<=a&&1>=a&&(this.qa.nodeIndentPastParent=a,this.J())});t.g(Z,"alternateNodeSpacing",Z.prototype.IG);t.defineProperty(Z,{IG:"alternateNodeSpacing"},function(){return this.qa.nodeSpacing},function(a){this.qa.nodeSpacing!==a&&(this.qa.nodeSpacing=a,this.J())});t.g(Z,"alternateLayerSpacing",Z.prototype.EG); +t.defineProperty(Z,{EG:"alternateLayerSpacing"},function(){return this.qa.layerSpacing},function(a){this.qa.layerSpacing!==a&&(this.qa.layerSpacing=a,this.J())});t.g(Z,"alternateLayerSpacingParentOverlap",Z.prototype.FG);t.defineProperty(Z,{FG:"alternateLayerSpacingParentOverlap"},function(){return this.qa.layerSpacingParentOverlap},function(a){this.qa.layerSpacingParentOverlap!==a&&0<=a&&1>=a&&(this.qa.layerSpacingParentOverlap=a,this.J())});t.g(Z,"alternateCompaction",Z.prototype.BG); +t.defineProperty(Z,{BG:"alternateCompaction"},function(){return this.qa.compaction},function(a){this.qa.compaction!==a&&(f&&t.k(a,ca,Z,"alternateCompaction"),a===Rp||a===Tp)&&(this.qa.compaction=a,this.J())});t.g(Z,"alternateBreadthLimit",Z.prototype.xG);t.defineProperty(Z,{xG:"alternateBreadthLimit"},function(){return this.qa.breadthLimit},function(a){this.qa.breadthLimit!==a&&0<=a&&(this.qa.breadthLimit=a,this.J())});t.g(Z,"alternateRowSpacing",Z.prototype.LG); +t.defineProperty(Z,{LG:"alternateRowSpacing"},function(){return this.qa.rowSpacing},function(a){this.qa.rowSpacing!==a&&(this.qa.rowSpacing=a,this.J())});t.g(Z,"alternateRowIndent",Z.prototype.KG);t.defineProperty(Z,{KG:"alternateRowIndent"},function(){return this.qa.rowIndent},function(a){this.qa.rowIndent!==a&&0<=a&&(this.qa.rowIndent=a,this.J())});t.g(Z,"alternateCommentSpacing",Z.prototype.AG); +t.defineProperty(Z,{AG:"alternateCommentSpacing"},function(){return this.qa.commentSpacing},function(a){this.qa.commentSpacing!==a&&(this.qa.commentSpacing=a,this.J())});t.g(Z,"alternateCommentMargin",Z.prototype.zG);t.defineProperty(Z,{zG:"alternateCommentMargin"},function(){return this.qa.commentMargin},function(a){this.qa.commentMargin!==a&&(this.qa.commentMargin=a,this.J())});t.g(Z,"alternateSetsPortSpot",Z.prototype.NG); +t.defineProperty(Z,{NG:"alternateSetsPortSpot"},function(){return this.qa.setsPortSpot},function(a){this.qa.setsPortSpot!==a&&(this.qa.setsPortSpot=a,this.J())});t.g(Z,"alternatePortSpot",Z.prototype.JG);t.defineProperty(Z,{JG:"alternatePortSpot"},function(){return this.qa.portSpot},function(a){this.qa.portSpot.K(a)||(this.qa.portSpot=a,this.J())});t.g(Z,"alternateSetsChildPortSpot",Z.prototype.MG); +t.defineProperty(Z,{MG:"alternateSetsChildPortSpot"},function(){return this.qa.setsChildPortSpot},function(a){this.qa.setsChildPortSpot!==a&&(this.qa.setsChildPortSpot=a,this.J())});t.g(Z,"alternateChildPortSpot",Z.prototype.yG);t.defineProperty(Z,{yG:"alternateChildPortSpot"},function(){return this.qa.childPortSpot},function(a){this.qa.childPortSpot.K(a)||(this.qa.childPortSpot=a,this.J())});var mp;Z.PathDefault=mp=t.w(Z,"PathDefault",-1);var np;Z.PathDestination=np=t.w(Z,"PathDestination",0);var up; +Z.PathSource=up=t.w(Z,"PathSource",1);var Gp;Z.SortingForwards=Gp=t.w(Z,"SortingForwards",10);var Hp;Z.SortingReverse=Hp=t.w(Z,"SortingReverse",11);var Ip;Z.SortingAscending=Ip=t.w(Z,"SortingAscending",12);var Jp;Z.SortingDescending=Jp=t.w(Z,"SortingDescending",13);var gq;Z.AlignmentCenterSubtrees=gq=t.w(Z,"AlignmentCenterSubtrees",20);var Kp;Z.AlignmentCenterChildren=Kp=t.w(Z,"AlignmentCenterChildren",21);var Vp;Z.AlignmentStart=Vp=t.w(Z,"AlignmentStart",22);var Wp; +Z.AlignmentEnd=Wp=t.w(Z,"AlignmentEnd",23);var Mp;Z.AlignmentBus=Mp=t.w(Z,"AlignmentBus",24);var Bp;Z.AlignmentBusBranching=Bp=t.w(Z,"AlignmentBusBranching",25);var Np;Z.AlignmentTopLeftBus=Np=t.w(Z,"AlignmentTopLeftBus",26);var Op;Z.AlignmentBottomRightBus=Op=t.w(Z,"AlignmentBottomRightBus",27);var Rp;Z.CompactionNone=Rp=t.w(Z,"CompactionNone",30);var Tp;Z.CompactionBlock=Tp=t.w(Z,"CompactionBlock",31);var op;Z.StyleLayered=op=t.w(Z,"StyleLayered",40);var Fp; +Z.StyleLastParents=Fp=t.w(Z,"StyleLastParents",41);var Ep;Z.StyleAlternating=Ep=t.w(Z,"StyleAlternating",42);var Dp;Z.StyleRootOnly=Dp=t.w(Z,"StyleRootOnly",43);var pp;Z.ArrangementVertical=pp=t.w(Z,"ArrangementVertical",50);var uq;Z.ArrangementHorizontal=uq=t.w(Z,"ArrangementHorizontal",51);var tp;Z.ArrangementFixedRoots=tp=t.w(Z,"ArrangementFixedRoots",52);function rp(){ra.call(this)}t.ea("TreeNetwork",rp);t.Ja(rp,ra);rp.prototype.createVertex=function(){return new qp};rp.prototype.createEdge=function(){return new wq}; +function qp(){sa.call(this);this.initialized=!1;this.parent=null;this.children=[];this.maxGenerationCount=this.maxChildrenCount=this.descendantCount=this.level=0;this.comments=null;this.ja=new v(0,0);this.Ua=new ea(0,0);this.Ha=new v(0,0);this.mp=this.lp=this.yI=!1;this.Zs=this.Is=null;this.sorting=Gp;this.comparer=rn;this.angle=0;this.alignment=Kp;this.nodeIndentPastParent=this.nodeIndent=0;this.nodeSpacing=20;this.layerSpacing=50;this.layerSpacingParentOverlap=0;this.compaction=Tp;this.breadthLimit= +0;this.rowSpacing=25;this.commentSpacing=this.rowIndent=10;this.commentMargin=20;this.setsPortSpot=!0;this.portSpot=vb;this.setsChildPortSpot=!0;this.childPortSpot=vb}t.ea("TreeVertex",qp);t.Ja(qp,sa); +qp.prototype.copyInheritedPropertiesFrom=function(a){null!==a&&(this.sorting=a.sorting,this.comparer=a.comparer,this.angle=a.angle,this.alignment=a.alignment,this.nodeIndent=a.nodeIndent,this.nodeIndentPastParent=a.nodeIndentPastParent,this.nodeSpacing=a.nodeSpacing,this.layerSpacing=a.layerSpacing,this.layerSpacingParentOverlap=a.layerSpacingParentOverlap,this.compaction=a.compaction,this.breadthLimit=a.breadthLimit,this.rowSpacing=a.rowSpacing,this.rowIndent=a.rowIndent,this.commentSpacing=a.commentSpacing, +this.commentMargin=a.commentMargin,this.setsPortSpot=a.setsPortSpot,this.portSpot=a.portSpot,this.setsChildPortSpot=a.setsChildPortSpot,this.childPortSpot=a.childPortSpot)};t.A(qp,{mm:"childrenCount"},function(){return this.children.length});t.g(qp,"relativePosition",qp.prototype.sI);t.defineProperty(qp,{sI:"relativePosition"},function(){return this.ja},function(a){t.k(a,v,qp,"relativePosition");this.ja.set(a)});t.g(qp,"subtreeSize",qp.prototype.GI); +t.defineProperty(qp,{GI:"subtreeSize"},function(){return this.Ua},function(a){t.k(a,ea,qp,"subtreeSize");this.Ua.set(a)});t.g(qp,"subtreeOffset",qp.prototype.FI);t.defineProperty(qp,{FI:"subtreeOffset"},function(){return this.Ha},function(a){t.k(a,v,qp,"subtreeOffset");this.Ha.set(a)});function wq(){ta.call(this);this.nr=new v(0,0)}t.ea("TreeEdge",wq);t.Ja(wq,ta); +wq.prototype.commit=function(){var a=this.link;if(null!==a&&!a.Di){var b=this.network.Vb,c=null,d=null;switch(b.rf){case np:c=this.fromVertex;d=this.toVertex;break;case up:c=this.toVertex;d=this.fromVertex;break;default:t.l("Unhandled path value "+b.rf.toString())}if(null!==c&&null!==d)if(b=this.nr,0!==b.x||0!==b.y||c.yI){var d=c.Gb,e=Up(c),g=Xp(c),h=c.rowSpacing;a.updateRoute();var k=a.ze===Kg,l=a.Ub,m,n,p,q;a.jl();if(l||k){for(m=2;4q.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Yp(c))))):c.alignment===Vp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Yp(c))))):c.alignment===Vp?(e=d.left+b.x,0===b.x&&n.xq.y+c.rowIndent&&(e=Math.min(e,Math.max(n.y,e-Yp(c))))):c.alignment===Vp?(e=d.top+b.y,0===b.y&&n.yq.x+c.rowIndent&&(e=Math.min(e,Math.max(n.x,e-Yp(c))))):c.alignment===Vp?(e=d.left+b.x,0===b.x&&n.xl?h=null:(m=parseFloat(n.getAttribute("cx")),isNaN(m)&&(m=0),n=parseFloat(n.getAttribute("cy")),isNaN(n)&&(n=0),p=new I(Lc),p.la=0,p.ma=0,p.D=2*l,p.F=2*l,h.position=new v(m-l,n-l),h.Xc=p);break;case "ellipse":p=g;h=new Y;l=parseFloat(p.getAttribute("rx"));isNaN(l)||0>l?h=null:(m=parseFloat(p.getAttribute("ry")),isNaN(m)||0>m?h=null:(n=parseFloat(p.getAttribute("cx")),isNaN(n)&&(n=0),p=parseFloat(p.getAttribute("cy")), +isNaN(p)&&(p=0),q=new I(Lc),q.la=0,q.ma=0,q.D=2*l,q.F=2*m,h.position=new v(n-l,p-m),h.Xc=q));break;case "rect":q=g;h=new Y;l=parseFloat(q.getAttribute("width"));if(isNaN(l)||0>l)h=null;else if(m=parseFloat(q.getAttribute("height")),isNaN(m)||0>m)h=null;else{n=parseFloat(q.getAttribute("x"));isNaN(n)&&(n=0);p=parseFloat(q.getAttribute("y"));isNaN(p)&&(p=0);var r=q.getAttribute("rx"),s=q.getAttribute("ry"),q=parseFloat(r);if(isNaN(q)||0>q)q=0;var u=parseFloat(s);if(isNaN(u)||0>u)u=0;!r&&s?q=u:r&&!s&& +(u=q);q=Math.min(q,l/2);u=Math.min(u,m/2);s=void 0;0===q&&0===u?(s=new I(Kc),s.la=0,s.ma=0,s.D=l,s.F=m):(s=D.sa/2,r=t.u(),J(r,q,0,!0),r.lineTo(l-q,0),K(r,l-q*s,0,l,u*s,l,u),r.lineTo(l,m-u),K(r,l,m-u*s,l-q*s,m,l-q,m),r.lineTo(q,m),K(r,q*s,m,0,m-u*s,0,m-u),r.lineTo(0,u),K(r,0,u*s,q*s,0,q,0),N(r),s=r.s,t.v(r));h.position=new v(n,p);h.Xc=s}break;case "polygon":h=Bq(g);break;case "polyline":h=Bq(g)}if(null!==h){if(h instanceof Y){l=yq(a,g,"fill");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+ +1,l.length-1),l=a["_brush"+l],h.fill=l instanceof Ud?l:"black"):h.fill=null===l?"black":"none"===l?null:l;l=yq(a,g,"stroke");null!==l&&-1!==l.indexOf("url")?(l=l.substring(l.indexOf("#")+1,l.length-1),l=a["_brush"+l],h.stroke=l instanceof Ud?l:"black"):h.stroke="none"===l?null:l;l=parseFloat(yq(a,g,"stroke-width"));isNaN(l)||(h.bb=l);l=yq(a,g,"stroke-linecap");null!==l&&(h.lF=l);if(l=yq(a,g,"stroke-dasharray")){m=l.split(",");n=[];for(l=0;lg.length)return null;for(var h,d=new A(O),k,l,m=1;m containerWidth) { - // create next button - li = $('
  • ') - .addClass('ui-state-default ui-tabs-paging-next') - .append($('') - .click(function() { page('next'); return false; }) - .html(opts.nextButton)); - - self.tablist.append(li); - buttonWidth = li.outerWidth(true); - - // create prev button - li = $('
  • ') - .addClass('ui-state-default ui-tabs-paging-prev') - .append($('') - .click(function() { page('prev'); return false; }) - .html(opts.prevButton)); - self.tablist.prepend(li); - buttonWidth += li.outerWidth(true); - - // TODO determine fix for padding issues to next button - buttonWidth += 19; - - var pageIndex = 0, pageWidth = 0, maxTabPadding = 0; - - // start calculating pageWidths - for (var i = 0; i < tabWidths.length; i++) { - // if first tab of page or selected tab's padding larger than the current max, set the maxTabPadding - if (pageWidth == 0 || selectedTabWidths[i] - tabWidths[i] > maxTabPadding) - maxTabPadding = (selectedTabWidths[i] - tabWidths[i]); - - // if first tab of page, initialize pages variable for page - if (pages[pageIndex] == null) { - pages[pageIndex] = { start: i }; - - } else if ((i > 0 && (i % opts.tabsPerPage) == 0) || (tabWidths[i] + pageWidth + buttonWidth + 12) > containerWidth) { - if ((pageWidth + maxTabPadding) > maxPageWidth) - maxPageWidth = (pageWidth + maxTabPadding); - pageIndex++; - pages[pageIndex] = { start: i }; - pageWidth = 0; - } - pages[pageIndex].end = i+1; - pageWidth += tabWidths[i]; - if (i == self.options.active) currentPage = pageIndex; - } - if ((pageWidth + maxTabPadding) > maxPageWidth) - maxPageWidth = (pageWidth + maxTabPadding); - - // hide all tabs then show tabs for current page - self.tabs.hide().slice(pages[currentPage].start, pages[currentPage].end).show(); - if (currentPage == (pages.length - 1) && !opts.cycle) - disableButton('next'); - if (currentPage == 0 && !opts.cycle) - disableButton('prev'); - - // calculate the right padding for the next button - buttonPadding = containerWidth - maxPageWidth - buttonWidth; - if (buttonPadding > 0) - $('.ui-tabs-paging-next', self.element).css({ paddingRight: buttonPadding + 'px' }); - } else { - destroy(); - } - - $(window).bind('resize', handleResize); - - initialized = true; - } - - // handles paging forward and backward - function page(direction) { - currentPage = currentPage + (direction == 'prev'?-1:1); - - if ((direction == 'prev' && currentPage < 0 && opts.cycle) || - (direction == 'next' && currentPage >= pages.length && !opts.cycle)) - currentPage = pages.length - 1; - else if ((direction == 'prev' && currentPage < 0) || - (direction == 'next' && currentPage >= pages.length && opts.cycle)) - currentPage = 0; - - var start = pages[currentPage].start; - var end = pages[currentPage].end; - self.tabs.hide().slice(start, end).show(); - - if (direction == 'prev') { - enableButton('next'); - if (opts.follow && (self.options.active < start || self.options.active > (end-1))) self.option('active', end-1); - if (!opts.cycle && start <= 0) disableButton('prev'); - } else { - enableButton('prev'); - if (opts.follow && (self.options.active < start || self.options.active > (end-1))) self.option('active', start); - if (!opts.cycle && end >= self.tabs.length) disableButton('next'); - } - } - - // change styling of next/prev buttons when disabled - function disableButton(direction) { - $('.ui-tabs-paging-'+direction, self.element).addClass('ui-tabs-paging-disabled'); - } - - function enableButton(direction) { - $('.ui-tabs-paging-'+direction, self.element).removeClass('ui-tabs-paging-disabled'); - } - - // special function defined to handle IE resize issues - function handleResize() { - if (resizeTimer) clearTimeout(resizeTimer); - - if (windowHeight != $(window).height() || windowWidth != $(window).width()) - { - resizeTimer = setTimeout(init, 100); - } - } - - // remove all paging related changes and events - function destroy() { - // remove buttons - $('.ui-tabs-paging-next', self.element).remove(); - $('.ui-tabs-paging-prev', self.element).remove(); - - // show all tabs - self.tabs.show(); - - initialized = false; - - $(window).unbind('resize', handleResize); - } - - - - // ------------- OVERRIDDEN PUBLIC FUNCTIONS ------------- - self.option = function(optionName, value) { - var retVal = uiTabsFuncs.option.apply(this, [optionName, value]); - - // if "followOnActive" is true, then move page when selection changes - if (optionName == "active") - { - // if paging is not initialized or it is not configured to - // change pages when a new tab is active, then do nothing - if (!initialized || !opts.followOnActive) - return retVal; - - // find the new page based on index of the active tab - for (var i in pages) { - var start = pages[i].start; - var end = pages[i].end; - if (value >= start && value < end) { - // if the the active tab is not within the currentPage of tabs, then change pages - if (i != currentPage) { - this.tabs.hide().slice(start, end).show(); - - currentPage = parseInt(i); - if (currentPage == 0) { - enableButton('next'); - if (!opts.cycle && start <= 0) disableButton('prev'); - } else { - enableButton('prev'); - if (!opts.cycle && end >= this.tabs.length) disableButton('next'); - } - } - break; - } - } - } - - return retVal; - } - - self.refresh = function() { - if (initialized) - { - destroy(); - - uiTabsFuncs.refresh.apply(this); - - // re-initialize paging buttons - init(); - } - - uiTabsFuncs.refresh.apply(this); - } - - - // DEPRECATED in jQuery UI 1.9 - if ( $.uiBackCompat !== false ) - { - // temporarily remove paging buttons before adding a tab - self.add = function(url, label, index) { - if (initialized) - { - destroy(); - - uiTabsFuncs.add.apply(this, [url, label, index]); - - if (opts.activeOnAdd) { - if (index == undefined) index = this.tabs.length-1; - this.option('active', index); - } - // re-initialize paging buttons - init(); - - return this; - } - - return uiTabsFuncs.add.apply(this, [url, label, index]); - } - - // temporarily remove paging buttons before removing a tab - self.remove = function(index) { - if (initialized) - { - destroy(); - uiTabsFuncs.remove.apply(this, [index]); - init(); - - return this; - } - - return uiTabsFuncs.remove.apply(this, [index]); - } - } - - - // ------------- PUBLIC FUNCTIONS ------------- - $.extend($.ui.tabs.prototype, { - // public function for removing paging - pagingDestroy: function() { - destroy(); - return this; - }, - - // public function to handle resizes that are not on the window - pagingResize: function() { - init(); - return this; - } - }); - - // initialize on startup! - init(); - } - }); - - +/* + * UI Tabs Paging extension - v1.2.2 (for jQuery 1.9.0 and jQuery UI 1.9.0) + * + * Copyright (c) 2013, http://seyfertdesign.com/jquery/ui-tabs-paging.html + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.tabs.js + */ + +(function($) { + +// overridden ui.tabs functions + var uiTabsFuncs = { + refresh: $.ui.tabs.prototype.refresh, + option: $.ui.tabs.prototype.option + }; + +// DEPRECATED in jQuery UI 1.9 + if ( $.uiBackCompat !== false ) { + uiTabsFuncs = $.extend( + uiTabsFuncs, + { + add: $.ui.tabs.prototype.add, + remove: $.ui.tabs.prototype.remove + } + ); + } + + $.extend($.ui.tabs.prototype, { + paging: function(options) { + var opts = { + tabsPerPage: 0, // Max number of tabs to display at one time. 0 automatically sizing. + nextButton: '»', // Text displayed for next button. + prevButton: '«', // Text displayed for previous button. + follow: false, // When clicking next button, automatically make first tab active. When clicking previous button automatically make last tab active. + cycle: false, // When at end of list, next button returns to first page. When at beginning of list previous button goes to end of list. + activeOnAdd: false, // When new tab is added, make tab active automatically + followOnActive: false // When tab is changed to active, automatically go move to that tab group. + }; + + opts = $.extend(opts, options); + + var self = this, initialized = false, currentPage, + buttonWidth, containerWidth, allTabsWidth, tabWidths, + maxPageWidth, pages, resizeTimer = null, + windowHeight, windowWidth; + + // initialize paging + function init() { + destroy(); + + windowHeight = $(window).height(); + windowWidth = $(window).width(); + + allTabsWidth = 0, currentPage = 0, maxPageWidth = 0, buttonWidth = 0, + pages = new Array(), tabWidths = new Array(), selectedTabWidths = new Array(); + + containerWidth = self.element.width(); + + // loops through LIs, get width of each tab when selected and unselected. + var maxDiff = 0; // the max difference between a selected and unselected tab + self.tabs.each(function(i) { + if (i == self.options.active) { + selectedTabWidths[i] = $(this).outerWidth(true); + tabWidths[i] = self.tabs.eq(i).removeClass('ui-tabs-active').outerWidth(true); + self.tabs.eq(i).addClass('ui-tabs-active'); + maxDiff = Math.min(maxDiff, Math.abs(selectedTabWidths[i] - tabWidths[i])); + allTabsWidth += tabWidths[i]; + } else { + tabWidths[i] = $(this).outerWidth(true); + selectedTabWidths[i] = self.tabs.eq(i).addClass('ui-tabs-active').outerWidth(true); + self.tabs.eq(i).removeClass('ui-tabs-active'); + maxDiff = Math.max(maxDiff, Math.abs(selectedTabWidths[i] - tabWidths[i])); + allTabsWidth += tabWidths[i]; + } + }); + + // fix padding issues with buttons + // TODO determine a better way to handle this + allTabsWidth += maxDiff + 9; + + // if the width of all tables is greater than the container's width, calculate the pages + if (allTabsWidth > containerWidth) { + // create next button + li = $('
  • ') + .addClass('ui-state-default ui-tabs-paging-next') + .append($('') + .click(function() { page('next'); return false; }) + .html(opts.nextButton)); + + self.tablist.append(li); + buttonWidth = li.outerWidth(true); + + // create prev button + li = $('
  • ') + .addClass('ui-state-default ui-tabs-paging-prev') + .append($('') + .click(function() { page('prev'); return false; }) + .html(opts.prevButton)); + self.tablist.prepend(li); + buttonWidth += li.outerWidth(true); + + // TODO determine fix for padding issues to next button + buttonWidth += 19; + + var pageIndex = 0, pageWidth = 0, maxTabPadding = 0; + + // start calculating pageWidths + for (var i = 0; i < tabWidths.length; i++) { + // if first tab of page or selected tab's padding larger than the current max, set the maxTabPadding + if (pageWidth == 0 || selectedTabWidths[i] - tabWidths[i] > maxTabPadding) + maxTabPadding = (selectedTabWidths[i] - tabWidths[i]); + + // if first tab of page, initialize pages variable for page + if (pages[pageIndex] == null) { + pages[pageIndex] = { start: i }; + + } else if ((i > 0 && (i % opts.tabsPerPage) == 0) || (tabWidths[i] + pageWidth + buttonWidth + 12) > containerWidth) { + if ((pageWidth + maxTabPadding) > maxPageWidth) + maxPageWidth = (pageWidth + maxTabPadding); + pageIndex++; + pages[pageIndex] = { start: i }; + pageWidth = 0; + } + pages[pageIndex].end = i+1; + pageWidth += tabWidths[i]; + if (i == self.options.active) currentPage = pageIndex; + } + if ((pageWidth + maxTabPadding) > maxPageWidth) + maxPageWidth = (pageWidth + maxTabPadding); + + // hide all tabs then show tabs for current page + self.tabs.hide().slice(pages[currentPage].start, pages[currentPage].end).show(); + if (currentPage == (pages.length - 1) && !opts.cycle) + disableButton('next'); + if (currentPage == 0 && !opts.cycle) + disableButton('prev'); + + // calculate the right padding for the next button + buttonPadding = containerWidth - maxPageWidth - buttonWidth; + if (buttonPadding > 0) + $('.ui-tabs-paging-next', self.element).css({ paddingRight: buttonPadding + 'px' }); + } else { + destroy(); + } + + $(window).bind('resize', handleResize); + + initialized = true; + } + + // handles paging forward and backward + function page(direction) { + currentPage = currentPage + (direction == 'prev'?-1:1); + + if ((direction == 'prev' && currentPage < 0 && opts.cycle) || + (direction == 'next' && currentPage >= pages.length && !opts.cycle)) + currentPage = pages.length - 1; + else if ((direction == 'prev' && currentPage < 0) || + (direction == 'next' && currentPage >= pages.length && opts.cycle)) + currentPage = 0; + + var start = pages[currentPage].start; + var end = pages[currentPage].end; + self.tabs.hide().slice(start, end).show(); + + if (direction == 'prev') { + enableButton('next'); + if (opts.follow && (self.options.active < start || self.options.active > (end-1))) self.option('active', end-1); + if (!opts.cycle && start <= 0) disableButton('prev'); + } else { + enableButton('prev'); + if (opts.follow && (self.options.active < start || self.options.active > (end-1))) self.option('active', start); + if (!opts.cycle && end >= self.tabs.length) disableButton('next'); + } + } + + // change styling of next/prev buttons when disabled + function disableButton(direction) { + $('.ui-tabs-paging-'+direction, self.element).addClass('ui-tabs-paging-disabled'); + } + + function enableButton(direction) { + $('.ui-tabs-paging-'+direction, self.element).removeClass('ui-tabs-paging-disabled'); + } + + // special function defined to handle IE resize issues + function handleResize() { + if (resizeTimer) clearTimeout(resizeTimer); + + if (windowHeight != $(window).height() || windowWidth != $(window).width()) + { + resizeTimer = setTimeout(init, 100); + } + } + + // remove all paging related changes and events + function destroy() { + // remove buttons + $('.ui-tabs-paging-next', self.element).remove(); + $('.ui-tabs-paging-prev', self.element).remove(); + + // show all tabs + self.tabs.show(); + + initialized = false; + + $(window).unbind('resize', handleResize); + } + + + + // ------------- OVERRIDDEN PUBLIC FUNCTIONS ------------- + self.option = function(optionName, value) { + var retVal = uiTabsFuncs.option.apply(this, [optionName, value]); + + // if "followOnActive" is true, then move page when selection changes + if (optionName == "active") + { + // if paging is not initialized or it is not configured to + // change pages when a new tab is active, then do nothing + if (!initialized || !opts.followOnActive) + return retVal; + + // find the new page based on index of the active tab + for (var i in pages) { + var start = pages[i].start; + var end = pages[i].end; + if (value >= start && value < end) { + // if the the active tab is not within the currentPage of tabs, then change pages + if (i != currentPage) { + this.tabs.hide().slice(start, end).show(); + + currentPage = parseInt(i); + if (currentPage == 0) { + enableButton('next'); + if (!opts.cycle && start <= 0) disableButton('prev'); + } else { + enableButton('prev'); + if (!opts.cycle && end >= this.tabs.length) disableButton('next'); + } + } + break; + } + } + } + + return retVal; + } + + self.refresh = function() { + if (initialized) + { + destroy(); + + uiTabsFuncs.refresh.apply(this); + + // re-initialize paging buttons + init(); + } + + uiTabsFuncs.refresh.apply(this); + } + + + // DEPRECATED in jQuery UI 1.9 + if ( $.uiBackCompat !== false ) + { + // temporarily remove paging buttons before adding a tab + self.add = function(url, label, index) { + if (initialized) + { + destroy(); + + uiTabsFuncs.add.apply(this, [url, label, index]); + + if (opts.activeOnAdd) { + if (index == undefined) index = this.tabs.length-1; + this.option('active', index); + } + // re-initialize paging buttons + init(); + + return this; + } + + return uiTabsFuncs.add.apply(this, [url, label, index]); + } + + // temporarily remove paging buttons before removing a tab + self.remove = function(index) { + if (initialized) + { + destroy(); + uiTabsFuncs.remove.apply(this, [index]); + init(); + + return this; + } + + return uiTabsFuncs.remove.apply(this, [index]); + } + } + + + // ------------- PUBLIC FUNCTIONS ------------- + $.extend($.ui.tabs.prototype, { + // public function for removing paging + pagingDestroy: function() { + destroy(); + return this; + }, + + // public function to handle resizes that are not on the window + pagingResize: function() { + init(); + return this; + } + }); + + // initialize on startup! + init(); + } + }); + + })(jQuery); \ No newline at end of file diff --git a/web/src/main/webapp/components/jquery-ui/bower.json b/web/src/main/webapp/components/jquery-ui/bower.json index a2d6a2013253..545a82ba2411 100644 --- a/web/src/main/webapp/components/jquery-ui/bower.json +++ b/web/src/main/webapp/components/jquery-ui/bower.json @@ -1,10 +1,10 @@ -{ - "name": "jquery-ui", - "version": "1.10.4", - "main": [ - "ui/jquery-ui.js" - ], - "dependencies": { - "jquery": ">=1.6" - } -} +{ + "name": "jquery-ui", + "version": "1.10.4", + "main": [ + "ui/jquery-ui.js" + ], + "dependencies": { + "jquery": ">=1.6" + } +} diff --git a/web/src/main/webapp/components/jquery.jslider/.gitignore b/web/src/main/webapp/components/jquery.jslider/.gitignore index d2b844390a98..1e0fc5a99707 100644 --- a/web/src/main/webapp/components/jquery.jslider/.gitignore +++ b/web/src/main/webapp/components/jquery.jslider/.gitignore @@ -1,2 +1,2 @@ -*/.DS_Store -.DS_Store +*/.DS_Store +.DS_Store diff --git a/web/src/main/webapp/components/jquery.jslider/MIT-LICENSE.txt b/web/src/main/webapp/components/jquery.jslider/MIT-LICENSE.txt index 8c6ac437b150..b193a88a9cbe 100644 --- a/web/src/main/webapp/components/jquery.jslider/MIT-LICENSE.txt +++ b/web/src/main/webapp/components/jquery.jslider/MIT-LICENSE.txt @@ -1,20 +1,20 @@ -The MIT License (MIT) -Copyright (c) 2012 Egor Khmelev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +The MIT License (MIT) +Copyright (c) 2012 Egor Khmelev + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/web/src/main/webapp/components/jquery.jslider/Makefile b/web/src/main/webapp/components/jquery.jslider/Makefile index 28992481c24d..0559b48e5bdc 100644 --- a/web/src/main/webapp/components/jquery.jslider/Makefile +++ b/web/src/main/webapp/components/jquery.jslider/Makefile @@ -1,15 +1,15 @@ - -css_compiler: js_compiler - mkdir -p bin - cat css/jslider.css css/jslider.blue.css css/jslider.plastic.css css/jslider.round.css css/jslider.round.plastic.css > bin/jquery.slider.all.css - java -jar tools/yuicompressor-2.4.7.jar --type=css bin/jquery.slider.all.css > bin/jquery.slider.min.css - rm -f bin/jquery.slider.all.css - -js_compiler: - mkdir -p bin - rm -f bin/jquery.slider.all.js bin/jquery.slider.min.js - cat js/jshashtable-2.1_src.js js/jquery.numberformatter-1.2.3.js js/tmpl.js js/jquery.dependClass-0.1.js js/draggable-0.1.js js/jquery.slider.js > bin/jquery.slider.all.js - uglifyjs -nc bin/jquery.slider.all.js > bin/jquery.slider.min.js - rm -f bin/jquery.slider.all.js - - + +css_compiler: js_compiler + mkdir -p bin + cat css/jslider.css css/jslider.blue.css css/jslider.plastic.css css/jslider.round.css css/jslider.round.plastic.css > bin/jquery.slider.all.css + java -jar tools/yuicompressor-2.4.7.jar --type=css bin/jquery.slider.all.css > bin/jquery.slider.min.css + rm -f bin/jquery.slider.all.css + +js_compiler: + mkdir -p bin + rm -f bin/jquery.slider.all.js bin/jquery.slider.min.js + cat js/jshashtable-2.1_src.js js/jquery.numberformatter-1.2.3.js js/tmpl.js js/jquery.dependClass-0.1.js js/draggable-0.1.js js/jquery.slider.js > bin/jquery.slider.all.js + uglifyjs -nc bin/jquery.slider.all.js > bin/jquery.slider.min.js + rm -f bin/jquery.slider.all.js + + diff --git a/web/src/main/webapp/components/jquery.jslider/README.md b/web/src/main/webapp/components/jquery.jslider/README.md index 39367c755e16..7c800ceb14f5 100644 --- a/web/src/main/webapp/components/jquery.jslider/README.md +++ b/web/src/main/webapp/components/jquery.jslider/README.md @@ -1,14 +1,14 @@ -# jQuery Slider plugin - -jQuery Slider is easy to use and multifunctional jQuery plugin. - -[Check out demos and documentations here](http://egorkhmelev.github.com/jslider/) - -## Bugs / Pull requests - -THIS PROJECT IS NOT MAINTAINED ANYMORE. You are free to fork it and start a new project. -I will add the best forks here. - -## License - -(MIT License) — Copyright © 2012 Egor Khmelev +# jQuery Slider plugin + +jQuery Slider is easy to use and multifunctional jQuery plugin. + +[Check out demos and documentations here](http://egorkhmelev.github.com/jslider/) + +## Bugs / Pull requests + +THIS PROJECT IS NOT MAINTAINED ANYMORE. You are free to fork it and start a new project. +I will add the best forks here. + +## License + +(MIT License) — Copyright © 2012 Egor Khmelev diff --git a/web/src/main/webapp/components/jquery.jslider/css/jslider.blue.css b/web/src/main/webapp/components/jquery.jslider/css/jslider.blue.css index d1c8a3e07a6c..ae378433c5fc 100644 --- a/web/src/main/webapp/components/jquery.jslider/css/jslider.blue.css +++ b/web/src/main/webapp/components/jquery.jslider/css/jslider.blue.css @@ -1,4 +1,4 @@ - - .jslider_blue .jslider-bg i, - .jslider_blue .jslider-pointer { background-image: url(../img/jslider.blue.png); } + + .jslider_blue .jslider-bg i, + .jslider_blue .jslider-pointer { background-image: url(../img/jslider.blue.png); } \ No newline at end of file diff --git a/web/src/main/webapp/components/jquery.jslider/css/jslider.css b/web/src/main/webapp/components/jquery.jslider/css/jslider.css index 684e4f69677d..0e604bdfcb27 100644 --- a/web/src/main/webapp/components/jquery.jslider/css/jslider.css +++ b/web/src/main/webapp/components/jquery.jslider/css/jslider.css @@ -1,40 +1,40 @@ - - .jslider .jslider-bg i, - .jslider .jslider-pointer { background: url(../img/jslider.png) no-repeat 0 0; } - - .jslider { display: block; width: 100%; height: 1em; position: relative; top: 0.6em; font-family: Arial, sans-serif; } - .jslider table { width: 100%; border-collapse: collapse; border: 0; } - .jslider td, .jslider th { padding: 0; vertical-align: top; text-align: left; border: 0; } - - .jslider table, - .jslider table tr, - .jslider table tr td { width: 100%; vertical-align: top; } - - .jslider .jslider-bg { position: relative; } - .jslider .jslider-bg i { height: 5px; position: absolute; font-size: 0; top: 0; } - .jslider .jslider-bg .l { width: 10%; background-position: 0 0; left: 0; } - .jslider .jslider-bg .f { width: 80%; left: 10%; background-repeat: repeat-x; background-position: 0 -20px; } - .jslider .jslider-bg .r { width: 10%; left: 90%; background-position: right 0; } - .jslider .jslider-bg .v { position: absolute; width: 60%; left: 20%; top: 0; height: 5px; background-repeat: repeat-x; background-position: 0 -40px; } - - .jslider .jslider-pointer { width: 13px; height: 15px; background-position: 0 -60px; position: absolute; left: 20%; top: -4px; margin-left: -6px; cursor: pointer; cursor: hand; } - .jslider .jslider-pointer-hover { background-position: -20px -60px; } - .jslider .jslider-pointer-to { left: 80%; } - - .jslider .jslider-label { font-size: 9px; line-height: 12px; color: black; opacity: 0.4; white-space: nowrap; padding: 0px 2px; position: absolute; top: -18px; left: 0px; } - .jslider .jslider-label-to { left: auto; right: 0; } - - .jslider .jslider-value { font-size: 9px; white-space: nowrap; padding: 1px 2px 0; position: absolute; top: -19px; left: 20%; background: white; line-height: 12px; -moz-border-radius: 2px; -webkit-border-radius: 2px; -o-border-radius: 2px; border-radius: 2px; } - .jslider .jslider-value-to { left: 80%; } - - .jslider .jslider-label small, - .jslider .jslider-value small { position: relative; top: -0.4em; } - - .jslider .jslider-scale { position: relative; top: 9px; } - .jslider .jslider-scale span { position: absolute; height: 5px; border-left: 1px solid #999; font-size: 0; } - .jslider .jslider-scale ins { font-size: 9px; text-decoration: none; position: absolute; left: 0px; top: 5px; color: #999; } - - .jslider-single .jslider-pointer-to, - .jslider-single .jslider-value-to, - .jslider-single .jslider-bg .v, - .jslider-limitless .jslider-label { display: none; } + + .jslider .jslider-bg i, + .jslider .jslider-pointer { background: url(../img/jslider.png) no-repeat 0 0; } + + .jslider { display: block; width: 100%; height: 1em; position: relative; top: 0.6em; font-family: Arial, sans-serif; } + .jslider table { width: 100%; border-collapse: collapse; border: 0; } + .jslider td, .jslider th { padding: 0; vertical-align: top; text-align: left; border: 0; } + + .jslider table, + .jslider table tr, + .jslider table tr td { width: 100%; vertical-align: top; } + + .jslider .jslider-bg { position: relative; } + .jslider .jslider-bg i { height: 5px; position: absolute; font-size: 0; top: 0; } + .jslider .jslider-bg .l { width: 10%; background-position: 0 0; left: 0; } + .jslider .jslider-bg .f { width: 80%; left: 10%; background-repeat: repeat-x; background-position: 0 -20px; } + .jslider .jslider-bg .r { width: 10%; left: 90%; background-position: right 0; } + .jslider .jslider-bg .v { position: absolute; width: 60%; left: 20%; top: 0; height: 5px; background-repeat: repeat-x; background-position: 0 -40px; } + + .jslider .jslider-pointer { width: 13px; height: 15px; background-position: 0 -60px; position: absolute; left: 20%; top: -4px; margin-left: -6px; cursor: pointer; cursor: hand; } + .jslider .jslider-pointer-hover { background-position: -20px -60px; } + .jslider .jslider-pointer-to { left: 80%; } + + .jslider .jslider-label { font-size: 9px; line-height: 12px; color: black; opacity: 0.4; white-space: nowrap; padding: 0px 2px; position: absolute; top: -18px; left: 0px; } + .jslider .jslider-label-to { left: auto; right: 0; } + + .jslider .jslider-value { font-size: 9px; white-space: nowrap; padding: 1px 2px 0; position: absolute; top: -19px; left: 20%; background: white; line-height: 12px; -moz-border-radius: 2px; -webkit-border-radius: 2px; -o-border-radius: 2px; border-radius: 2px; } + .jslider .jslider-value-to { left: 80%; } + + .jslider .jslider-label small, + .jslider .jslider-value small { position: relative; top: -0.4em; } + + .jslider .jslider-scale { position: relative; top: 9px; } + .jslider .jslider-scale span { position: absolute; height: 5px; border-left: 1px solid #999; font-size: 0; } + .jslider .jslider-scale ins { font-size: 9px; text-decoration: none; position: absolute; left: 0px; top: 5px; color: #999; } + + .jslider-single .jslider-pointer-to, + .jslider-single .jslider-value-to, + .jslider-single .jslider-bg .v, + .jslider-limitless .jslider-label { display: none; } diff --git a/web/src/main/webapp/components/jquery.jslider/css/jslider.plastic.css b/web/src/main/webapp/components/jquery.jslider/css/jslider.plastic.css index 8cdf09111f62..32b54676b8c9 100644 --- a/web/src/main/webapp/components/jquery.jslider/css/jslider.plastic.css +++ b/web/src/main/webapp/components/jquery.jslider/css/jslider.plastic.css @@ -1,3 +1,3 @@ - - .jslider_plastic .jslider-bg i, - .jslider_plastic .jslider-pointer { background-image: url(../img/jslider.plastic.png); } + + .jslider_plastic .jslider-bg i, + .jslider_plastic .jslider-pointer { background-image: url(../img/jslider.plastic.png); } diff --git a/web/src/main/webapp/components/jquery.jslider/css/jslider.round.css b/web/src/main/webapp/components/jquery.jslider/css/jslider.round.css index c9bda8c65a85..00ad952e69dc 100644 --- a/web/src/main/webapp/components/jquery.jslider/css/jslider.round.css +++ b/web/src/main/webapp/components/jquery.jslider/css/jslider.round.css @@ -1,5 +1,5 @@ - - .jslider_round .jslider-bg i, - .jslider_round .jslider-pointer { background-image: url(../img/jslider.round.png); } - - .jslider_round .jslider-pointer { width: 17px; height: 17px; top: -6px; margin-left: -8px; } + + .jslider_round .jslider-bg i, + .jslider_round .jslider-pointer { background-image: url(../img/jslider.round.png); } + + .jslider_round .jslider-pointer { width: 17px; height: 17px; top: -6px; margin-left: -8px; } diff --git a/web/src/main/webapp/components/jquery.jslider/css/jslider.round.plastic.css b/web/src/main/webapp/components/jquery.jslider/css/jslider.round.plastic.css index e644974138fa..4272e1fb055f 100644 --- a/web/src/main/webapp/components/jquery.jslider/css/jslider.round.plastic.css +++ b/web/src/main/webapp/components/jquery.jslider/css/jslider.round.plastic.css @@ -1,5 +1,5 @@ - - .jslider_round_plastic .jslider-bg i, - .jslider_round_plastic .jslider-pointer { background-image: url(../img/jslider.round.plastic.png); } - - .jslider_round_plastic .jslider-pointer { width: 18px; height: 18px; top: -7px; margin-left: -8px; } + + .jslider_round_plastic .jslider-bg i, + .jslider_round_plastic .jslider-pointer { background-image: url(../img/jslider.round.plastic.png); } + + .jslider_round_plastic .jslider-pointer { width: 18px; height: 18px; top: -7px; margin-left: -8px; } diff --git a/web/src/main/webapp/components/jquery.jslider/index.html b/web/src/main/webapp/components/jquery.jslider/index.html index 124dd2aba1c6..994b0783f3b3 100644 --- a/web/src/main/webapp/components/jquery.jslider/index.html +++ b/web/src/main/webapp/components/jquery.jslider/index.html @@ -1,152 +1,152 @@ - - - - - jSlider - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - Slider in string -
    - - -
    -
    {
    -  from: 5,
    -  to: 50,
    -  step: 2.5,
    -  round: 1,
    -  format: { format: '##.0', locale: 'de' },
    -  dimension: '&nbsp;€'
    -}
    -
    -
    - -
    - - -
    -
    {
    -  from: 5000,
    -  to: 150000,
    -  heterogeneity: ['50/50000'],
    -  step: 1000,
    -  dimension: '&nbsp;$'
    -}
    -
    -
    - -
    - - -
    -
    {
    -  from: 0,
    -  to: 500,
    -  heterogeneity: ['50/100', '75/250'],
    -  scale: [0, '|', 50, '|' , '100', '|', 250, '|', 500],
    -  limits: false,
    -  step: 1,
    -  dimension: '&nbsp;m<small>2</small>'
    -}
    -
    -
    - -
    - - -
    -
    {
    -  from: 1,
    -  to: 30,
    -  heterogeneity: ['50/5', '75/15'],
    -  scale: [1, '|', 3, '|', '5', '|', 15, '|', 30],
    -  limits: false,
    -  step: 1,
    -  dimension: '',
    -  skin: "blue"
    -}
    -
    -
    - -
    - - - -
    -
    {
    -  from: 480,
    -  to: 1020,
    -  step: 15,
    -  dimension: '',
    -  scale: ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00'],
    -  limits: false,
    -  calculate: function( value ){
    -    var hours = Math.floor( value / 60 );
    -    var mins = ( value - hours*60 );
    -    return (hours < 10 ? "0"+hours : hours) + ":" + ( mins == 0 ? "00" : mins );
    -  },
    -  onstatechange: function( value ){
    -    console.dir( this );
    -  }
    -}
    -
    -
    - -
    - - -
    - - - + + + + + jSlider + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + Slider in string +
    + + +
    +
    {
    +  from: 5,
    +  to: 50,
    +  step: 2.5,
    +  round: 1,
    +  format: { format: '##.0', locale: 'de' },
    +  dimension: '&nbsp;€'
    +}
    +
    +
    + +
    + + +
    +
    {
    +  from: 5000,
    +  to: 150000,
    +  heterogeneity: ['50/50000'],
    +  step: 1000,
    +  dimension: '&nbsp;$'
    +}
    +
    +
    + +
    + + +
    +
    {
    +  from: 0,
    +  to: 500,
    +  heterogeneity: ['50/100', '75/250'],
    +  scale: [0, '|', 50, '|' , '100', '|', 250, '|', 500],
    +  limits: false,
    +  step: 1,
    +  dimension: '&nbsp;m<small>2</small>'
    +}
    +
    +
    + +
    + + +
    +
    {
    +  from: 1,
    +  to: 30,
    +  heterogeneity: ['50/5', '75/15'],
    +  scale: [1, '|', 3, '|', '5', '|', 15, '|', 30],
    +  limits: false,
    +  step: 1,
    +  dimension: '',
    +  skin: "blue"
    +}
    +
    +
    + +
    + + + +
    +
    {
    +  from: 480,
    +  to: 1020,
    +  step: 15,
    +  dimension: '',
    +  scale: ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00'],
    +  limits: false,
    +  calculate: function( value ){
    +    var hours = Math.floor( value / 60 );
    +    var mins = ( value - hours*60 );
    +    return (hours < 10 ? "0"+hours : hours) + ":" + ( mins == 0 ? "00" : mins );
    +  },
    +  onstatechange: function( value ){
    +    console.dir( this );
    +  }
    +}
    +
    +
    + +
    + + +
    + + + \ No newline at end of file diff --git a/web/src/main/webapp/components/jquery.jslider/js/draggable-0.1.js b/web/src/main/webapp/components/jquery.jslider/js/draggable-0.1.js index 78725e565b39..73273daf82ac 100644 --- a/web/src/main/webapp/components/jquery.jslider/js/draggable-0.1.js +++ b/web/src/main/webapp/components/jquery.jslider/js/draggable-0.1.js @@ -1,196 +1,196 @@ -/** - * draggable - Class allows to make any element draggable - * - * Written by - * Egor Khmelev (hmelyoff@gmail.com) - * - * Licensed under the MIT (MIT-LICENSE.txt). - * - * @author Egor Khmelev - * @version 0.1.0-BETA ($Id$) - * - **/ - -(function( $ ){ - - function Draggable(){ - this._init.apply( this, arguments ); - }; - - Draggable.prototype.oninit = function(){ - - }; - - Draggable.prototype.events = function(){ - - }; - - Draggable.prototype.onmousedown = function(){ - this.ptr.css({ position: "absolute" }); - }; - - Draggable.prototype.onmousemove = function( evt, x, y ){ - this.ptr.css({ left: x, top: y }); - }; - - Draggable.prototype.onmouseup = function(){ - - }; - - Draggable.prototype.isDefault = { - drag: false, - clicked: false, - toclick: true, - mouseup: false - }; - - Draggable.prototype._init = function(){ - if( arguments.length > 0 ){ - this.ptr = $(arguments[0]); - this.outer = $(".draggable-outer"); - - this.is = {}; - $.extend( this.is, this.isDefault ); - - var _offset = this.ptr.offset(); - this.d = { - left: _offset.left, - top: _offset.top, - width: this.ptr.width(), - height: this.ptr.height() - }; - - this.oninit.apply( this, arguments ); - - this._events(); - } - }; - - Draggable.prototype._getPageCoords = function( event ){ - if( event.targetTouches && event.targetTouches[0] ){ - return { x: event.targetTouches[0].pageX, y: event.targetTouches[0].pageY }; - } else - return { x: event.pageX, y: event.pageY }; - }; - - Draggable.prototype._bindEvent = function( ptr, eventType, handler ){ - var self = this; - - if( this.supportTouches_ ) - ptr.get(0).addEventListener( this.events_[ eventType ], handler, false ); - - else - ptr.bind( this.events_[ eventType ], handler ); - }; - - Draggable.prototype._events = function(){ - var self = this; - - this.supportTouches_ = 'ontouchend' in document; - this.events_ = { - "click": this.supportTouches_ ? "touchstart" : "click", - "down": this.supportTouches_ ? "touchstart" : "mousedown", - "move": this.supportTouches_ ? "touchmove" : "mousemove", - "up" : this.supportTouches_ ? "touchend" : "mouseup" - }; - - this._bindEvent( $( document ), "move", function( event ){ - if( self.is.drag ){ - event.stopPropagation(); - event.preventDefault(); - self._mousemove( event ); - } - }); - this._bindEvent( $( document ), "down", function( event ){ - if( self.is.drag ){ - event.stopPropagation(); - event.preventDefault(); - } - }); - this._bindEvent( $( document ), "up", function( event ){ - self._mouseup( event ); - }); - - this._bindEvent( this.ptr, "down", function( event ){ - self._mousedown( event ); - return false; - }); - this._bindEvent( this.ptr, "up", function( event ){ - self._mouseup( event ); - }); - - this.ptr.find("a") - .click(function(){ - self.is.clicked = true; - - if( !self.is.toclick ){ - self.is.toclick = true; - return false; - } - }) - .mousedown(function( event ){ - self._mousedown( event ); - return false; - }); - - this.events(); - }; - - Draggable.prototype._mousedown = function( evt ){ - this.is.drag = true; - this.is.clicked = false; - this.is.mouseup = false; - - var _offset = this.ptr.offset(); - var coords = this._getPageCoords( evt ); - this.cx = coords.x - _offset.left; - this.cy = coords.y - _offset.top; - - $.extend(this.d, { - left: _offset.left, - top: _offset.top, - width: this.ptr.width(), - height: this.ptr.height() - }); - - if( this.outer && this.outer.get(0) ){ - this.outer.css({ height: Math.max(this.outer.height(), $(document.body).height()), overflow: "hidden" }); - } - - this.onmousedown( evt ); - }; - - Draggable.prototype._mousemove = function( evt ){ - this.is.toclick = false; - var coords = this._getPageCoords( evt ); - this.onmousemove( evt, coords.x - this.cx, coords.y - this.cy ); - }; - - Draggable.prototype._mouseup = function( evt ){ - var oThis = this; - - if( this.is.drag ){ - this.is.drag = false; - - if( this.outer && this.outer.get(0) ){ - - if( $.browser.mozilla ){ - this.outer.css({ overflow: "hidden" }); - } else { - this.outer.css({ overflow: "visible" }); - } - - if( $.browser.msie && $.browser.version == '6.0' ){ - this.outer.css({ height: "100%" }); - } else { - this.outer.css({ height: "auto" }); - } - } - - this.onmouseup( evt ); - } - }; - - window.Draggable = Draggable; - -})( jQuery ); +/** + * draggable - Class allows to make any element draggable + * + * Written by + * Egor Khmelev (hmelyoff@gmail.com) + * + * Licensed under the MIT (MIT-LICENSE.txt). + * + * @author Egor Khmelev + * @version 0.1.0-BETA ($Id$) + * + **/ + +(function( $ ){ + + function Draggable(){ + this._init.apply( this, arguments ); + }; + + Draggable.prototype.oninit = function(){ + + }; + + Draggable.prototype.events = function(){ + + }; + + Draggable.prototype.onmousedown = function(){ + this.ptr.css({ position: "absolute" }); + }; + + Draggable.prototype.onmousemove = function( evt, x, y ){ + this.ptr.css({ left: x, top: y }); + }; + + Draggable.prototype.onmouseup = function(){ + + }; + + Draggable.prototype.isDefault = { + drag: false, + clicked: false, + toclick: true, + mouseup: false + }; + + Draggable.prototype._init = function(){ + if( arguments.length > 0 ){ + this.ptr = $(arguments[0]); + this.outer = $(".draggable-outer"); + + this.is = {}; + $.extend( this.is, this.isDefault ); + + var _offset = this.ptr.offset(); + this.d = { + left: _offset.left, + top: _offset.top, + width: this.ptr.width(), + height: this.ptr.height() + }; + + this.oninit.apply( this, arguments ); + + this._events(); + } + }; + + Draggable.prototype._getPageCoords = function( event ){ + if( event.targetTouches && event.targetTouches[0] ){ + return { x: event.targetTouches[0].pageX, y: event.targetTouches[0].pageY }; + } else + return { x: event.pageX, y: event.pageY }; + }; + + Draggable.prototype._bindEvent = function( ptr, eventType, handler ){ + var self = this; + + if( this.supportTouches_ ) + ptr.get(0).addEventListener( this.events_[ eventType ], handler, false ); + + else + ptr.bind( this.events_[ eventType ], handler ); + }; + + Draggable.prototype._events = function(){ + var self = this; + + this.supportTouches_ = 'ontouchend' in document; + this.events_ = { + "click": this.supportTouches_ ? "touchstart" : "click", + "down": this.supportTouches_ ? "touchstart" : "mousedown", + "move": this.supportTouches_ ? "touchmove" : "mousemove", + "up" : this.supportTouches_ ? "touchend" : "mouseup" + }; + + this._bindEvent( $( document ), "move", function( event ){ + if( self.is.drag ){ + event.stopPropagation(); + event.preventDefault(); + self._mousemove( event ); + } + }); + this._bindEvent( $( document ), "down", function( event ){ + if( self.is.drag ){ + event.stopPropagation(); + event.preventDefault(); + } + }); + this._bindEvent( $( document ), "up", function( event ){ + self._mouseup( event ); + }); + + this._bindEvent( this.ptr, "down", function( event ){ + self._mousedown( event ); + return false; + }); + this._bindEvent( this.ptr, "up", function( event ){ + self._mouseup( event ); + }); + + this.ptr.find("a") + .click(function(){ + self.is.clicked = true; + + if( !self.is.toclick ){ + self.is.toclick = true; + return false; + } + }) + .mousedown(function( event ){ + self._mousedown( event ); + return false; + }); + + this.events(); + }; + + Draggable.prototype._mousedown = function( evt ){ + this.is.drag = true; + this.is.clicked = false; + this.is.mouseup = false; + + var _offset = this.ptr.offset(); + var coords = this._getPageCoords( evt ); + this.cx = coords.x - _offset.left; + this.cy = coords.y - _offset.top; + + $.extend(this.d, { + left: _offset.left, + top: _offset.top, + width: this.ptr.width(), + height: this.ptr.height() + }); + + if( this.outer && this.outer.get(0) ){ + this.outer.css({ height: Math.max(this.outer.height(), $(document.body).height()), overflow: "hidden" }); + } + + this.onmousedown( evt ); + }; + + Draggable.prototype._mousemove = function( evt ){ + this.is.toclick = false; + var coords = this._getPageCoords( evt ); + this.onmousemove( evt, coords.x - this.cx, coords.y - this.cy ); + }; + + Draggable.prototype._mouseup = function( evt ){ + var oThis = this; + + if( this.is.drag ){ + this.is.drag = false; + + if( this.outer && this.outer.get(0) ){ + + if( $.browser.mozilla ){ + this.outer.css({ overflow: "hidden" }); + } else { + this.outer.css({ overflow: "visible" }); + } + + if( $.browser.msie && $.browser.version == '6.0' ){ + this.outer.css({ height: "100%" }); + } else { + this.outer.css({ height: "auto" }); + } + } + + this.onmouseup( evt ); + } + }; + + window.Draggable = Draggable; + +})( jQuery ); diff --git a/web/src/main/webapp/components/jquery.jslider/js/jquery-1.7.1.js b/web/src/main/webapp/components/jquery.jslider/js/jquery-1.7.1.js index 66932b6a0e39..8ccd0ea786ea 100644 --- a/web/src/main/webapp/components/jquery.jslider/js/jquery-1.7.1.js +++ b/web/src/main/webapp/components/jquery.jslider/js/jquery-1.7.1.js @@ -1,9266 +1,9266 @@ -/*! - * jQuery JavaScript Library v1.7.1 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Mon Nov 21 21:11:03 2011 -0500 - */ -(function( window, undefined ) { - -// Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; -var jQuery = (function() { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - - // Matches dashed string for camelizing - rdashAlpha = /-([a-z]|[0-9])/ig, - rmsPrefix = /^-ms-/, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return ( letter + "" ).toUpperCase(); - }, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // The deferred used on DOM ready - readyList, - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, - - // [[Class]] -> type pairs - class2type = {}; - -jQuery.fn = jQuery.prototype = { - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // The body element only exists once, optimize finding it - if ( selector === "body" && !context && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = selector; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = quickExpr.exec( selector ); - } - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - doc = ( context ? context.ownerDocument || context : document ); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.7.1", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - toArray: function() { - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this[ this.length + num ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = this.constructor(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - - } else { - jQuery.merge( ret, elems ); - } - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - - // Add the callback - readyList.add( fn ); - - return this; - }, - - eq: function( i ) { - i = +i; - return i === -1 ? - this.slice( i ) : - this.slice( i, i + 1 ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - noConflict: function( deep ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } - - if ( deep && window.jQuery === jQuery ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.fireWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).off( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyList ) { - return; - } - - readyList = jQuery.Callbacks( "once memory" ); - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - return setTimeout( jQuery.ready, 1 ); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - // A crude way of determining if an object is a window - isWindow: function( obj ) { - return obj && typeof obj === "object" && "setInterval" in obj; - }, - - isNumeric: function( obj ) { - return !isNaN( parseFloat(obj) ) && isFinite( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw new Error( msg ); - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { - - return ( new Function( "return " + data ) )(); - - } - jQuery.error( "Invalid JSON: " + data ); - }, - - // Cross-browser xml parsing - parseXML: function( data ) { - var xml, tmp; - try { - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - } catch( e ) { - xml = undefined; - } - if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; - }, - - noop: function() {}, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } - } - } - - return object; - }, - - // Use native String.trim function wherever possible - trim: trim ? - function( text ) { - return text == null ? - "" : - trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); - - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array, i ) { - var len; - - if ( array ) { - if ( indexOf ) { - return indexOf.call( array, elem, i ); - } - - len = array.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in array && array[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var i = first.length, - j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - var ret = [], retVal; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, key, ret = [], - i = 0, - length = elems.length, - // jquery objects are treated as arrays - isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; - - // Go through the array, translating each of the items to their - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Go through every key on the object, - } else { - for ( key in elems ) { - value = callback( elems[ key ], key, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - } - - // Flatten any nested arrays - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - if ( typeof context === "string" ) { - var tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - var args = slice.call( arguments, 2 ), - proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - - return proxy; - }, - - // Mutifunctional method to get and set values to a collection - // The value/s can optionally be executed if it's a function - access: function( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - jQuery.access( elems, k, key[k], exec, fn, value ); - } - return elems; - } - - // Setting one attribute - if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); - - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - - return elems; - } - - // Getting an attribute - return length ? fn( elems[0], key ) : undefined; - }, - - now: function() { - return ( new Date() ).getTime(); - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); - } - - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); - }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; - }, - - browser: {} -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -return jQuery; - -})(); - - -// String to Object flags format cache -var flagsCache = {}; - -// Convert String-formatted flags into Object-formatted ones and store in cache -function createFlags( flags ) { - var object = flagsCache[ flags ] = {}, - i, length; - flags = flags.split( /\s+/ ); - for ( i = 0, length = flags.length; i < length; i++ ) { - object[ flags[i] ] = true; - } - return object; -} - -/* - * Create a callback list using the following parameters: - * - * flags: an optional list of space-separated flags that will change how - * the callback list behaves - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible flags: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( flags ) { - - // Convert flags from String-formatted to Object-formatted - // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; - - var // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = [], - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Add one or several callbacks to the list - add = function( args ) { - var i, - length, - elem, - type, - actual; - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - // Inspect recursively - add( elem ); - } else if ( type === "function" ) { - // Add if not in unique mode and callback is not in - if ( !flags.unique || !self.has( elem ) ) { - list.push( elem ); - } - } - } - }, - // Fire callbacks - fire = function( context, args ) { - args = args || []; - memory = !flags.memory || [ context, args ]; - firing = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { - memory = true; // Mark as halted - break; - } - } - firing = false; - if ( list ) { - if ( !flags.once ) { - if ( stack && stack.length ) { - memory = stack.shift(); - self.fireWith( memory[ 0 ], memory[ 1 ] ); - } - } else if ( memory === true ) { - self.disable(); - } else { - list = []; - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - var length = list.length; - add( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away, unless previous - // firing was halted (stopOnFalse) - } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - var args = arguments, - argIndex = 0, - argLength = args.length; - for ( ; argIndex < argLength ; argIndex++ ) { - for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ] ) { - // Handle firingIndex and firingLength - if ( firing ) { - if ( i <= firingLength ) { - firingLength--; - if ( i <= firingIndex ) { - firingIndex--; - } - } - } - // Remove the element - list.splice( i--, 1 ); - // If we have some unicity property then - // we only need to do this once - if ( flags.unique ) { - break; - } - } - } - } - } - return this; - }, - // Control if a given callback is in the list - has: function( fn ) { - if ( list ) { - var i = 0, - length = list.length; - for ( ; i < length; i++ ) { - if ( fn === list[ i ] ) { - return true; - } - } - } - return false; - }, - // Remove all callbacks from the list - empty: function() { - list = []; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory || memory === true ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( stack ) { - if ( firing ) { - if ( !flags.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( flags.once && memory ) ) { - fire( context, args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!memory; - } - }; - - return self; -}; - - - - -var // Static reference to slice - sliceDeferred = [].slice; - -jQuery.extend({ - - Deferred: function( func ) { - var doneList = jQuery.Callbacks( "once memory" ), - failList = jQuery.Callbacks( "once memory" ), - progressList = jQuery.Callbacks( "memory" ), - state = "pending", - lists = { - resolve: doneList, - reject: failList, - notify: progressList - }, - promise = { - done: doneList.add, - fail: failList.add, - progress: progressList.add, - - state: function() { - return state; - }, - - // Deprecated - isResolved: doneList.fired, - isRejected: failList.fired, - - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, - always: function() { - deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); - return this; - }, - pipe: function( fnDone, fnFail, fnProgress ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ], - progress: [ fnProgress, "notify" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - obj = promise; - } else { - for ( var key in promise ) { - obj[ key ] = promise[ key ]; - } - } - return obj; - } - }, - deferred = promise.promise({}), - key; - - for ( key in lists ) { - deferred[ key ] = lists[ key ].fire; - deferred[ key + "With" ] = lists[ key ].fireWith; - } - - // Handle state - deferred.done( function() { - state = "resolved"; - }, failList.disable, progressList.lock ).fail( function() { - state = "rejected"; - }, doneList.disable, progressList.lock ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = sliceDeferred.call( arguments, 0 ), - i = 0, - length = args.length, - pValues = new Array( length ), - count = length, - pCount = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(), - promise = deferred.promise(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( deferred, args ); - } - }; - } - function progressFunc( i ) { - return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - deferred.notifyWith( promise, pValues ); - }; - } - if ( length > 1 ) { - for ( ; i < length; i++ ) { - if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return promise; - } -}); - - - - -jQuery.support = (function() { - - var support, - all, - a, - select, - opt, - input, - marginDiv, - fragment, - tds, - events, - eventName, - i, - isSupported, - div = document.createElement( "div" ), - documentElement = document.documentElement; - - // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = "
    a"; - - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return {}; - } - - // First batch of supports tests - select = document.createElement( "select" ); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; - - support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: ( div.firstChild.nodeType === 3 ), - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, - - // Get the style information from getAttribute - // (IE uses .cssText instead) - style: /top/.test( a.getAttribute("style") ), - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: ( a.getAttribute("href") === "/a" ), - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55/.test( a.style.opacity ), - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: !!a.style.cssFloat, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: ( input.value === "on" ), - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: opt.selected, - - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - getSetAttribute: div.className !== "t", - - // Tests for enctype support on a form(#6743) - enctype: !!document.createElement("form").enctype, - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", - - // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, - deleteExpando: true, - noCloneEvent: true, - inlineBlockNeedsLayout: false, - shrinkWrapBlocks: false, - reliableMarginRight: true - }; - - // Make sure checked status is properly cloned - input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) - select.disabled = true; - support.optDisabled = !opt.disabled; - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - support.noCloneEvent = false; - }); - div.cloneNode( true ).fireEvent( "onclick" ); - } - - // Check if a radio maintains its value - // after being appended to the DOM - input = document.createElement("input"); - input.value = "t"; - input.setAttribute("type", "radio"); - support.radioValue = input.value === "t"; - - input.setAttribute("checked", "checked"); - div.appendChild( input ); - fragment = document.createDocumentFragment(); - fragment.appendChild( div.lastChild ); - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - fragment.removeChild( input ); - fragment.appendChild( div ); - - div.innerHTML = ""; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( window.getComputedStyle ) { - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.style.width = "2px"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - - // Technique from Juriy Zaytsev - // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( div.attachEvent ) { - for( i in { - submit: 1, - change: 1, - focusin: 1 - }) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; - } - } - - fragment.removeChild( div ); - - // Null elements to avoid leaks in IE - fragment = select = opt = marginDiv = div = input = null; - - // Run tests that need a body at doc ready - jQuery(function() { - var container, outer, inner, table, td, offsetSupport, - conMarginTop, ptlm, vb, style, html, - body = document.getElementsByTagName("body")[0]; - - if ( !body ) { - // Return for frameset docs that don't have a body - return; - } - - conMarginTop = 1; - ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; - vb = "visibility:hidden;border:0;"; - style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; - html = "
    " + - "" + - "
    "; - - container = document.createElement("div"); - container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; - body.insertBefore( container, body.firstChild ); - - // Construct the test element - div = document.createElement("div"); - container.appendChild( div ); - - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - div.innerHTML = "
    t
    "; - tds = div.getElementsByTagName( "td" ); - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Check if empty table cells still have offsetWidth/Height - // (IE <= 8 fail this test) - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - - // Figure out if the W3C box model works as expected - div.innerHTML = ""; - div.style.width = div.style.paddingLeft = "1px"; - jQuery.boxModel = support.boxModel = div.offsetWidth === 2; - - if ( typeof div.style.zoom !== "undefined" ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); - - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
    "; - support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); - } - - div.style.cssText = ptlm + vb; - div.innerHTML = html; - - outer = div.firstChild; - inner = outer.firstChild; - td = outer.nextSibling.firstChild.firstChild; - - offsetSupport = { - doesNotAddBorder: ( inner.offsetTop !== 5 ), - doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) - }; - - inner.style.position = "fixed"; - inner.style.top = "20px"; - - // safari subtracts parent border width here which is 5px - offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); - inner.style.position = inner.style.top = ""; - - outer.style.overflow = "hidden"; - outer.style.position = "relative"; - - offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); - offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); - - body.removeChild( container ); - div = container = null; - - jQuery.extend( support, offsetSupport ); - }); - - return support; -})(); - - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/, - rmultiDash = /([A-Z])/g; - -jQuery.extend({ - cache: {}, - - // Please use with caution - uuid: 0, - - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var privateCache, thisCache, ret, - internalKey = jQuery.expando, - getByName = typeof name === "string", - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, - isEvents = name === "events"; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - elem[ internalKey ] = id = ++jQuery.uuid; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - cache[ id ] = {}; - - // Avoids exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - privateCache = thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Users should not attempt to inspect the internal events object using jQuery.data, - // it is undocumented and subject to change. But does anyone listen? No. - if ( isEvents && !thisCache[ name ] ) { - return privateCache.events; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( getByName ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; - }, - - removeData: function( elem, name, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, l, - - // Reference to internal data cache key - internalKey = jQuery.expando, - - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ internalKey ] : internalKey; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split( " " ); - } - } - } - - for ( i = 0, l = name.length; i < l; i++ ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { - return; - } - } - - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - // Ensure that `cache` is not a window object #10080 - if ( jQuery.support.deleteExpando || !cache.setInterval ) { - delete cache[ id ]; - } else { - cache[ id ] = null; - } - - // We destroyed the cache and need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ internalKey ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( internalKey ); - } else { - elem[ internalKey ] = null; - } - } - }, - - // For internal use only. - _data: function( elem, name, data ) { - return jQuery.data( elem, name, data, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; - - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var parts, attr, name, - data = null; - - if ( typeof key === "undefined" ) { - if ( this.length ) { - data = jQuery.data( this[0] ); - - if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { - attr = this[0].attributes; - for ( var i = 0, l = attr.length; i < l; i++ ) { - name = attr[i].name; - - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.substring(5) ); - - dataAttr( this[0], name, data[ name ] ); - } - } - jQuery._data( this[0], "parsedAttrs", true ); - } - } - - return data; - - } else if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - // Try to fetch any internally stored data first - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - data = dataAttr( this[0], key, data ); - } - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - - } else { - return this.each(function() { - var self = jQuery( this ), - args = [ parts[0], value ]; - - self.triggerHandler( "setData" + parts[1] + "!", args ); - jQuery.data( this, key, value ); - self.triggerHandler( "changeData" + parts[1] + "!", args ); - }); - } - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - jQuery.isNumeric( data ) ? parseFloat( data ) : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - for ( var name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - - - - -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery._data( elem, deferDataKey ); - if ( defer && - ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && - ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery._data( elem, queueDataKey ) && - !jQuery._data( elem, markDataKey ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.fire(); - } - }, 0 ); - } -} - -jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = ( type || "fx" ) + "mark"; - jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); - if ( count ) { - jQuery._data( elem, key, count ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - - queue: function( elem, type, data ) { - var q; - if ( elem ) { - type = ( type || "fx" ) + "queue"; - q = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); - } else { - q.push( data ); - } - } - return q || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - fn = queue.shift(), - hooks = {}; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - jQuery._data( elem, type + ".run", hooks ); - fn.call( elem, function() { - jQuery.dequeue( elem, type ); - }, hooks ); - } - - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue " + type + ".run", true ); - handleQueueMarkDefer( elem, type, "queue" ); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - } - - if ( data === undefined ) { - return jQuery.queue( this[0], type ); - } - return this.each(function() { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = setTimeout( next, time ); - hooks.stop = function() { - clearTimeout( timeout ); - }; - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, object ) { - if ( typeof type !== "string" ) { - object = type; - type = undefined; - } - type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } - while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { - count++; - tmp.add( resolve ); - } - } - resolve(); - return defer.promise(); - } -}); - - - - -var rclass = /[\n\t\r]/g, - rspace = /\s+/, - rreturn = /\r/g, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - nodeHook, boolHook, fixSpecified; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.attr ); - }, - - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.prop ); - }, - - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} - }); - }, - - addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); - }); - } - - if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { - elem.className = value; - - } else { - setClass = " " + elem.className + " "; - - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { - setClass += classNames[ c ] + " "; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - classNames = ( value || "" ).split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[ c ] + " ", " "); - } - elem.className = jQuery.trim( className ); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - state = stateVal, - classNames = value.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var hooks, ret, isFunction, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var self = jQuery(this), val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, self.val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - }, - select: { - get: function( elem ) { - var value, i, max, option, - index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - i = one ? index : 0; - max = one ? index + 1 : options.length; - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - }, - - set: function( elem, value ) { - var values = jQuery.makeArray( value ); - - jQuery(elem).find("option").each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery( elem )[ name ]( value ); - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - // All attributes are lowercase - // Grab necessary hook if one is defined - if ( notxml ) { - name = name.toLowerCase(); - hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - - } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, "" + value ); - return value; - } - - } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - - ret = elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, value ) { - var propName, attrNames, name, l, - i = 0; - - if ( value && elem.nodeType === 1 ) { - attrNames = value.toLowerCase().split( rspace ); - l = attrNames.length; - - for ( ; i < l; i++ ) { - name = attrNames[ i ]; - - if ( name ) { - propName = jQuery.propFix[ name ] || name; - - // See #9699 for explanation of this approach (setting first, then removal) - jQuery.attr( elem, name, "" ); - elem.removeAttribute( getSetAttribute ? name : propName ); - - // Set corresponding property to false for boolean attributes - if ( rboolean.test( name ) && propName in elem ) { - elem[ propName ] = false; - } - } - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to it's default in case type is set after value - // This is for element creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - }, - // Use the value property for back compat - // Use the nodeHook for button elements in IE6/7 (#1954) - value: { - get: function( elem, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.get( elem, name ); - } - return name in elem ? - elem.value : - null; - }, - set: function( elem, value, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.set( elem, value, name ); - } - // Does not return so that setAttribute is also used - elem.value = value; - } - } - }, - - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - - prop: function( elem, name, value ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - return ( elem[ name ] = value ); - } - - } else { - if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - return elem[ name ]; - } - } - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - var attributeNode = elem.getAttributeNode("tabindex"); - - return attributeNode && attributeNode.specified ? - parseInt( attributeNode.value, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - } - } -}); - -// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) -jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; - -// Hook for boolean attributes -boolHook = { - get: function( elem, name ) { - // Align boolean attributes with corresponding properties - // Fall back to attribute presence where some booleans are not supported - var attrNode, - property = jQuery.prop( elem, name ); - return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? - name.toLowerCase() : - undefined; - }, - set: function( elem, value, name ) { - var propName; - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - // value is true since we know at this point it's type boolean and not false - // Set boolean attributes to the same name and set the DOM property - propName = jQuery.propFix[ name ] || name; - if ( propName in elem ) { - // Only set the IDL specifically if it already exists on the element - elem[ propName ] = true; - } - - elem.setAttribute( name, name.toLowerCase() ); - } - return name; - } -}; - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !getSetAttribute ) { - - fixSpecified = { - name: true, - id: true - }; - - // Use this for any attribute in IE6/7 - // This fixes almost every IE6/7 issue - nodeHook = jQuery.valHooks.button = { - get: function( elem, name ) { - var ret; - ret = elem.getAttributeNode( name ); - return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? - ret.nodeValue : - undefined; - }, - set: function( elem, value, name ) { - // Set the existing or create a new attribute node - var ret = elem.getAttributeNode( name ); - if ( !ret ) { - ret = document.createAttribute( name ); - elem.setAttributeNode( ret ); - } - return ( ret.nodeValue = value + "" ); - } - }; - - // Apply the nodeHook to tabindex - jQuery.attrHooks.tabindex.set = nodeHook.set; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }); - }); - - // Set contenteditable to false on removals(#10429) - // Setting to empty string throws an error as an invalid value - jQuery.attrHooks.contenteditable = { - get: nodeHook.get, - set: function( elem, value, name ) { - if ( value === "" ) { - value = "false"; - } - nodeHook.set( elem, value, name ); - } - }; -} - - -// Some attributes require a special call on IE -if ( !jQuery.support.hrefNormalized ) { - jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - get: function( elem ) { - var ret = elem.getAttribute( name, 2 ); - return ret === null ? undefined : ret; - } - }); - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; - }, - set: function( elem, value ) { - return ( elem.style.cssText = "" + value ); - } - }; -} - -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { - get: function( elem ) { - var parent = elem.parentNode; - - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - return null; - } - }); -} - -// IE6/7 call enctype encoding -if ( !jQuery.support.enctype ) { - jQuery.propFix.enctype = "encoding"; -} - -// Radios and checkboxes getter/setter -if ( !jQuery.support.checkOn ) { - jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - get: function( elem ) { - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - } - }; - }); -} -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); - } - } - }); -}); - - - - -var rformElems = /^(?:textarea|input|select)$/i, - rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, - rhoverHack = /\bhover(\.\S+)?\b/, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - quickParse = function( selector ) { - var quick = rquickIs.exec( selector ); - if ( quick ) { - // 0 1 2 3 - // [ _, tag, id, class ] - quick[1] = ( quick[1] || "" ).toLowerCase(); - quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); - } - return quick; - }, - quickIs = function( elem, m ) { - var attrs = elem.attributes || {}; - return ( - (!m[1] || elem.nodeName.toLowerCase() === m[1]) && - (!m[2] || (attrs.id || {}).value === m[2]) && - (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) - ); - }, - hoverHack = function( events ) { - return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); - }; - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - add: function( elem, types, handler, data, selector ) { - - var elemData, eventHandle, events, - t, tns, type, namespaces, handleObj, - handleObjIn, quick, handlers, special; - - // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - events = elemData.events; - if ( !events ) { - elemData.events = events = {}; - } - eventHandle = elemData.handle; - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = jQuery.trim( hoverHack(types) ).split( " " ); - for ( t = 0; t < types.length; t++ ) { - - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = ( tns[2] || "" ).split( "." ).sort(); - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: tns[1], - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - quick: quickParse( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - handlers = events[ type ]; - if ( !handlers ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener/attachEvent if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - t, tns, type, origType, namespaces, origCount, - j, events, special, handle, eventType, handleObj; - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = jQuery.trim( hoverHack( types || "" ) ).split(" "); - for ( t = 0; t < types.length; t++ ) { - tns = rtypenamespace.exec( types[t] ) || []; - type = origType = tns[1]; - namespaces = tns[2]; - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector? special.delegateType : special.bindType ) || type; - eventType = events[ type ] || []; - origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - - // Remove matching events - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !namespaces || namespaces.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - eventType.splice( j--, 1 ); - - if ( handleObj.selector ) { - eventType.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( eventType.length === 0 && origCount !== eventType.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery.removeData( elem, [ "events", "handle" ], true ); - } - }, - - // Events that are safe to short-circuit if no handlers are attached. - // Native DOM events should not be added, they may have inline handlers. - customEvent: { - "getData": true, - "setData": true, - "changeData": true - }, - - trigger: function( event, data, elem, onlyHandlers ) { - // Don't do events on text and comment nodes - if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { - return; - } - - // Event object or event type - var type = event.type || event, - namespaces = [], - cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "!" ) >= 0 ) { - // Exclusive events trigger only for the exact event (no namespaces) - type = type.slice(0, -1); - exclusive = true; - } - - if ( type.indexOf( "." ) >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - - if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { - // No jQuery handlers for this event type, and it can't have inline handlers - return; - } - - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); - - event.type = type; - event.isTrigger = true; - event.exclusive = exclusive; - event.namespace = namespaces.join( "." ); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; - - // Handle a global trigger - if ( !elem ) { - - // TODO: Stop taunting the data cache; remove global events and always attach to document - cache = jQuery.cache; - for ( i in cache ) { - if ( cache[ i ].events && cache[ i ].events[ type ] ) { - jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); - } - } - return; - } - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - eventPath = [[ elem, special.bindType || type ]]; - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; - old = null; - for ( ; cur; cur = cur.parentNode ) { - eventPath.push([ cur, bubbleType ]); - old = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old && old === elem.ownerDocument ) { - eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); - } - } - - // Fire handlers on the event path - for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { - - cur = eventPath[i][0]; - event.type = eventPath[i][1]; - - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - // Note that this is a bare JS function and not a jQuery handler - handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { - event.preventDefault(); - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && - !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - // IE<9 dies on focus/blur to hidden element (#1486) - if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; - - if ( old ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( old ) { - elem[ ontype ] = old; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event || window.event ); - - var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), - delegateCount = handlers.delegateCount, - args = [].slice.call( arguments, 0 ), - run_all = !event.exclusive && !event.namespace, - handlerQueue = [], - i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Determine handlers that should run if there are delegated events - // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { - - // Pregenerate a single jQuery object for reuse with .is() - jqcur = jQuery(this); - jqcur.context = this.ownerDocument || this; - - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - selMatch = {}; - matches = []; - jqcur[0] = cur; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = ( - handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) - ); - } - if ( selMatch[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); - } - } - } - - // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); - } - - // Run delegates first; they may want to stop propagation beneath us - for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { - matched = handlerQueue[ i ]; - event.currentTarget = matched.elem; - - for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { - handleObj = matched.matches[ j ]; - - // Triggered event must either 1) be non-exclusive and have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { - - event.data = handleObj.data; - event.handleObj = handleObj; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - return event.result; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** - props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, - originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = jQuery.Event( originalEvent ); - - for ( i = copy.length; i; ) { - prop = copy[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Target should not be a text node (#504, Safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) - if ( event.metaKey === undefined ) { - event.metaKey = event.ctrlKey; - } - - return fixHook.filter? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady - }, - - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - - focus: { - delegateType: "focusin" - }, - blur: { - delegateType: "focusout" - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, - - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -// Some plugins are using, but it's undocumented/deprecated and will be removed. -// The 1.7 special event interface should provide all the hooks needed now. -jQuery.event.handle = jQuery.event.dispatch; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // otherwise set the returnValue property of the original event to false (IE) - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var target = this, - related = event.relatedTarget, - handleObj = event.handleObj, - selector = handleObj.selector, - ret; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !form._submit_attached ) { - jQuery.event.add( form, "submit._submit", function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - }); - form._submit_attached = true; - } - }); - // return undefined since we don't need an event listener - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !jQuery.support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed && !event.isTrigger ) { - this._just_changed = false; - jQuery.event.simulate( "change", this, event, true ); - } - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - elem._change_attached = true; - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return rformElems.test( this.nodeName ); - } - }; -} - -// Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0, - handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } - }, - teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on.call( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - var handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( var type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - bind: function( types, data, fn ) { - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - return this.off( types, null, fn ); - }, - - live: function( types, data, fn ) { - jQuery( this.context ).on( types, this.selector, data, fn ); - return this; - }, - die: function( types, fn ) { - jQuery( this.context ).off( types, this.selector || "**", fn ); - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, - guid = fn.guid || jQuery.guid++, - i = 0, - toggler = function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - }; - - // link all the functions, so any of them can unbind this click handler - toggler.guid = guid; - while ( i < args.length ) { - args[ i++ ].guid = guid; - } - - return this.click( toggler ); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - if ( fn == null ) { - fn = data; - data = null; - } - - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } - - if ( rkeyEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; - } - - if ( rmouseEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; - } -}); - - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - expando = "sizcache" + (Math.random() + '').replace('.', ''), - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rReturn = /\r\n/g, - rNonWord = /\W/; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function() { - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function( selector, context, results, seed ) { - results = results || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context, seed ); - - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set, seed ); - } - } - - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - - set = ret.expr ? - Sizzle.filter( ret.expr, ret.set ) : - ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray( set ); - - } else { - prune = false; - } - - while ( parts.length ) { - cur = parts.pop(); - pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function( results ) { - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } - } - } - } - - return results; -}; - -Sizzle.matches = function( expr, set ) { - return Sizzle( expr, null, null, set ); -}; - -Sizzle.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set, i, len, match, type, left; - - if ( !expr ) { - return []; - } - - for ( i = 0, len = Expr.order.length; i < len; i++ ) { - type = Expr.order[i]; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - left = match[1]; - match.splice( 1, 1 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - type, found, item, filter, left, - i, pass, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - filter = Expr.filter[ type ]; - left = match[1]; - - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - pass = not ^ found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - - } else { - curLoop[i] = false; - } - - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Utility function for retreiving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -var getText = Sizzle.getText = function( elem ) { - var i, node, - nodeType = elem.nodeType, - ret = ""; - - if ( nodeType ) { - if ( nodeType === 1 || nodeType === 9 ) { - // Use textContent || innerText for elements - if ( typeof elem.textContent === 'string' ) { - return elem.textContent; - } else if ( typeof elem.innerText === 'string' ) { - // Replace IE's carriage returns - return elem.innerText.replace( rReturn, '' ); - } else { - // Traverse it's children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - } else { - - // If no nodeType, this is expected to be an array - for ( i = 0; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - if ( node.nodeType !== 8 ) { - ret += getText( node ); - } - } - } - return ret; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - - leftMatch: {}, - - attrMap: { - "class": "className", - "for": "htmlFor" - }, - - attrHandle: { - href: function( elem ) { - return elem.getAttribute( "href" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.test( part ), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - - ">": function( checkSet, part ) { - var elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - - "": function(checkSet, part, isXML){ - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); - } - }, - - find: { - ID: function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }, - - NAME: function( match, context ) { - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], - results = context.getElementsByName( match[1] ); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - - TAG: function( match, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace( rBackslash, "" ); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - - PSEUDO: function( match, curLoop, inplace, result, not ) { - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - - if ( !inplace ) { - result.push.apply( result, ret ); - } - - return false; - } - - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - - POS: function( match ) { - match.unshift( true ); - - return match; - } - }, - - filters: { - enabled: function( elem ) { - return elem.disabled === false && elem.type !== "hidden"; - }, - - disabled: function( elem ) { - return elem.disabled === true; - }, - - checked: function( elem ) { - return elem.checked === true; - }, - - selected: function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - parent: function( elem ) { - return !!elem.firstChild; - }, - - empty: function( elem ) { - return !elem.firstChild; - }, - - has: function( elem, i, match ) { - return !!Sizzle( match[3], elem ).length; - }, - - header: function( elem ) { - return (/h\d/i).test( elem.nodeName ); - }, - - text: function( elem ) { - var attr = elem.getAttribute( "type" ), type = elem.type; - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case - return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); - }, - - radio: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; - }, - - checkbox: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; - }, - - file: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; - }, - - password: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; - }, - - submit: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "submit" === elem.type; - }, - - image: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; - }, - - reset: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "reset" === elem.type; - }, - - button: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && "button" === elem.type || name === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - }, - - focus: function( elem ) { - return elem === elem.ownerDocument.activeElement; - } - }, - setFilters: { - first: function( elem, i ) { - return i === 0; - }, - - last: function( elem, i, match, array ) { - return i === array.length - 1; - }, - - even: function( elem, i ) { - return i % 2 === 0; - }, - - odd: function( elem, i ) { - return i % 2 === 1; - }, - - lt: function( elem, i, match ) { - return i < match[3] - 0; - }, - - gt: function( elem, i, match ) { - return i > match[3] - 0; - }, - - nth: function( elem, i, match ) { - return match[3] - 0 === i; - }, - - eq: function( elem, i, match ) { - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function( elem, match, i, array ) { - var name = match[1], - filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var first, last, - doneName, parent, cache, - count, diff, - type = match[1], - node = elem; - - switch ( type ) { - case "only": - case "first": - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - if ( type === "first" ) { - return true; - } - - node = elem; - - case "last": - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - return true; - - case "nth": - first = match[2]; - last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - doneName = match[0]; - parent = elem.parentNode; - - if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { - count = 0; - - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - - parent[ expando ] = doneName; - } - - diff = elem.nodeIndex - last; - - if ( first === 0 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - - ID: function( elem, match ) { - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - - TAG: function( elem, match ) { - return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; - }, - - CLASS: function( elem, match ) { - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - - ATTR: function( elem, match ) { - var name = match[1], - result = Sizzle.attr ? - Sizzle.attr( elem, name ) : - Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - !type && Sizzle.attr ? - result != null : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - - POS: function( elem, match, i, array ) { - var name = match[2], - filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); -} - -var makeArray = function( array, results ) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch( e ) { - makeArray = function( array, results ) { - var i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - - // Fallback to using sourceIndex (in IE) if it's available on both nodes - } else if ( a.sourceIndex && b.sourceIndex ) { - return a.sourceIndex - b.sourceIndex; - } - - var al, bl, - ap = [], - bp = [], - aup = a.parentNode, - bup = b.parentNode, - cur = aup; - - // If the nodes are siblings (or identical) we can do a quick check - if ( aup === bup ) { - return siblingCheck( a, b ); - - // If no parents were found then the nodes are disconnected - } else if ( !aup ) { - return -1; - - } else if ( !bup ) { - return 1; - } - - // Otherwise they're somewhere else in the tree so we need - // to build up a full list of the parentNodes for comparison - while ( cur ) { - ap.unshift( cur ); - cur = cur.parentNode; - } - - cur = bup; - - while ( cur ) { - bp.unshift( cur ); - cur = cur.parentNode; - } - - al = ap.length; - bl = bp.length; - - // Start walking down the tree looking for a discrepancy - for ( var i = 0; i < al && i < bl; i++ ) { - if ( ap[i] !== bp[i] ) { - return siblingCheck( ap[i], bp[i] ); - } - } - - // We ended someplace up the tree so do a sibling check - return i === al ? - siblingCheck( a, bp[i], -1 ) : - siblingCheck( ap[i], b, 1 ); - }; - - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date()).getTime(), - root = document.documentElement; - - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - - return m ? - m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? - [m] : - undefined : - []; - } - }; - - Expr.filter.ID = function( elem, match ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - - // release memory in IE - root = form = null; -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function( match, context ) { - var results = context.getElementsByTagName( match[1] ); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = ""; - - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - - Expr.attrHandle.href = function( elem ) { - return elem.getAttribute( "href", 2 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - div.innerHTML = "

    "; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function( query, context, extra, seed ) { - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && !Sizzle.isXML(context) ) { - // See if we find a selector to speed up - var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); - - if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { - // Speed-up: Sizzle("TAG") - if ( match[1] ) { - return makeArray( context.getElementsByTagName( query ), extra ); - - // Speed-up: Sizzle(".CLASS") - } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { - return makeArray( context.getElementsByClassName( match[2] ), extra ); - } - } - - if ( context.nodeType === 9 ) { - // Speed-up: Sizzle("body") - // The body element only exists once, optimize finding it - if ( query === "body" && context.body ) { - return makeArray( [ context.body ], extra ); - - // Speed-up: Sizzle("#ID") - } else if ( match && match[3] ) { - var elem = context.getElementById( match[3] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(qsaError) {} - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; - - if ( matches ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9 fails this) - var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - var ret = matches.call( node, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || !disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9, so check for that - node.document && node.document.nodeType !== 11 ) { - return ret; - } - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
    "; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function( match, context, isXML ) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function( selector, context, seed ) { - var match, - tmpSet = [], - later = "", - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet, seed ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -// Override sizzle attribute retrieval -Sizzle.attr = jQuery.attr; -Sizzle.selectors.attrMap = {}; -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})(); - - -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.POS, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - find: function( selector ) { - var self = this, - i, l; - - if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }); - } - - var ret = this.pushStack( "", "find", selector ), - length, n, r; - - for ( i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( n = length; n < ret.length; n++ ) { - for ( r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - return !!selector && ( - typeof selector === "string" ? - // If this is a positional selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - POS.test( selector ) ? - jQuery( selector, this.context ).index( this[0] ) >= 0 : - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); - }, - - closest: function( selectors, context ) { - var ret = [], i, l, cur = this[0]; - - // Array (deprecated as of jQuery 1.7) - if ( jQuery.isArray( selectors ) ) { - var level = 1; - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( i = 0; i < selectors.length; i++ ) { - - if ( jQuery( cur ).is( selectors[ i ] ) ) { - ret.push({ selector: selectors[ i ], elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - - return ret; - } - - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( i = 0, l = this.length; i < l; i++ ) { - cur = this[i]; - - while ( cur ) { - if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { - ret.push( cur ); - break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { - break; - } - } - } - } - - ret = ret.length > 1 ? jQuery.unique( ret ) : ret; - - return this.pushStack( ret, "closest", selectors ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, slice.call( arguments ).join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 ? - jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : - jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, keep ) { - - // Can't pass null or undefined to indexOf in Firefox 4 - // Set to 0 to skip string check - qualifier = qualifier || 0; - - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - var retVal = !!qualifier.call( elem, i, elem ); - return retVal === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return ( elem === qualifier ) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; - }); -} - - - - -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + - "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /", "" ], - legend: [ 1, "
    ", "
    " ], - thead: [ 1, "", "
    " ], - tr: [ 2, "", "
    " ], - td: [ 3, "", "
    " ], - col: [ 2, "", "
    " ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }, - safeFragment = createSafeFragment( document ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and - - - - - - - - - - - - - - - -
    - - - Show/Hide - - - -
    - + + + + + jSlider Show/hide test + + + + + + + + + + + + + + + + + + + + + + +
    + + + Show/Hide + + + +
    + \ No newline at end of file diff --git a/web/src/main/webapp/components/jquery.jslider/tests/zero_value.html b/web/src/main/webapp/components/jquery.jslider/tests/zero_value.html index db01ba32373c..7d9e9f874438 100644 --- a/web/src/main/webapp/components/jquery.jslider/tests/zero_value.html +++ b/web/src/main/webapp/components/jquery.jslider/tests/zero_value.html @@ -1,64 +1,64 @@ - - - - - jSlider Zero value test - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - Slider in string -
    - - -
    - Slider in string -
    - - -
    - + + + + + jSlider Zero value test + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + Slider in string +
    + + +
    + Slider in string +
    + + +
    + \ No newline at end of file diff --git a/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.js b/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.js index f3cc5651f5ec..351fba3adfb7 100644 --- a/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.js +++ b/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.js @@ -1,5939 +1,5939 @@ -/** - * @preserve - * jquery.layout 1.3.0 - Release Candidate 30.79 - * $Date: 2013-01-12 08:00:00 (Sat, 12 Jan 2013) $ - * $Rev: 303007 $ - * - * Copyright (c) 2013 Kevin Dalman (http://allpro.net) - * Based on work by Fabrizio Balliano (http://www.fabrizioballiano.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * SEE: http://layout.jquery-dev.net/LICENSE.txt - * - * Changelog: http://layout.jquery-dev.net/changelog.cfm#1.3.0.rc30.79 - * - * Docs: http://layout.jquery-dev.net/documentation.html - * Tips: http://layout.jquery-dev.net/tips.html - * Help: http://groups.google.com/group/jquery-ui-layout - */ - -/* JavaDoc Info: http://code.google.com/closure/compiler/docs/js-for-compiler.html - * {!Object} non-nullable type (never NULL) - * {?string} nullable type (sometimes NULL) - default for {Object} - * {number=} optional parameter - * {*} ALL types - */ -/* TODO for jQ 2.0 - * change .andSelf() to .addBack() - * $.fn.disableSelection won't work - */ - -// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars - -;(function ($) { - -// alias Math methods - used a lot! -var min = Math.min -, max = Math.max -, round = Math.floor - -, isStr = function (v) { return $.type(v) === "string"; } - - /** - * @param {!Object} Instance - * @param {Array.} a_fn - */ -, runPluginCallbacks = function (Instance, a_fn) { - if ($.isArray(a_fn)) - for (var i=0, c=a_fn.length; i').appendTo("body"); - var d = { width: $c.css("width") - $c[0].clientWidth, height: $c.height() - $c[0].clientHeight }; - $c.remove(); - window.scrollbarWidth = d.width; - window.scrollbarHeight = d.height; - return dim.match(/^(width|height)$/) ? d[dim] : d; - } - - - /** - * Returns hash container 'display' and 'visibility' - * - * @see $.swap() - swaps CSS, runs callback, resets CSS - * @param {!Object} $E jQuery element - * @param {boolean=} [force=false] Run even if display != none - * @return {!Object} Returns current style props, if applicable - */ -, showInvisibly: function ($E, force) { - if ($E && $E.length && (force || $E.css("display") === "none")) { // only if not *already hidden* - var s = $E[0].style - // save ONLY the 'style' props because that is what we must restore - , CSS = { display: s.display || '', visibility: s.visibility || '' }; - // show element 'invisibly' so can be measured - $E.css({ display: "block", visibility: "hidden" }); - return CSS; - } - return {}; - } - - /** - * Returns data for setting size of an element (container or a pane). - * - * @see _create(), onWindowResize() for container, plus others for pane - * @return JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc - */ -, getElementDimensions: function ($E, inset) { - var - // dimensions hash - start with current data IF passed - d = { css: {}, inset: {} } - , x = d.css // CSS hash - , i = { bottom: 0 } // TEMP insets (bottom = complier hack) - , N = $.layout.cssNum - , off = $E.offset() - , b, p, ei // TEMP border, padding - ; - d.offsetLeft = off.left; - d.offsetTop = off.top; - - if (!inset) inset = {}; // simplify logic below - - $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge - b = x["border" + e] = $.layout.borderWidth($E, e); - p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e); - ei = e.toLowerCase(); - d.inset[ei] = inset[ei] >= 0 ? inset[ei] : p; // any missing insetX value = paddingX - i[ei] = d.inset[ei] + b; // total offset of content from outer side - }); - - x.width = $E.width(); - x.height = $E.height(); - x.top = N($E,"top",true); - x.bottom = N($E,"bottom",true); - x.left = N($E,"left",true); - x.right = N($E,"right",true); - - d.outerWidth = $E.outerWidth(); - d.outerHeight = $E.outerHeight(); - // calc the TRUE inner-dimensions, even in quirks-mode! - d.innerWidth = max(0, d.outerWidth - i.left - i.right); - d.innerHeight = max(0, d.outerHeight - i.top - i.bottom); - // layoutWidth/Height is used in calcs for manual resizing - // layoutW/H only differs from innerW/H when in quirks-mode - then is like outerW/H - d.layoutWidth = $E.innerWidth(); - d.layoutHeight = $E.innerHeight(); - - //if ($E.prop('tagName') === 'BODY') { debugData( d, $E.prop('tagName') ); } // DEBUG - - //d.visible = $E.is(":visible");// && x.width > 0 && x.height > 0; - - return d; - } - -, getElementStyles: function ($E, list) { - var - CSS = {} - , style = $E[0].style - , props = list.split(",") - , sides = "Top,Bottom,Left,Right".split(",") - , attrs = "Color,Style,Width".split(",") - , p, s, a, i, j, k - ; - for (i=0; i < props.length; i++) { - p = props[i]; - if (p.match(/(border|padding|margin)$/)) - for (j=0; j < 4; j++) { - s = sides[j]; - if (p === "border") - for (k=0; k < 3; k++) { - a = attrs[k]; - CSS[p+s+a] = style[p+s+a]; - } - else - CSS[p+s] = style[p+s]; - } - else - CSS[p] = style[p]; - }; - return CSS - } - - /** - * Return the innerWidth for the current browser/doctype - * - * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() - * @param {Array.} $E Must pass a jQuery object - first element is processed - * @param {number=} outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized - * @return {number} Returns the innerWidth of the elem by subtracting padding and borders - */ -, cssWidth: function ($E, outerWidth) { - // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed - if (outerWidth <= 0) return 0; - - var bs = !$.layout.browser.boxModel ? "border-box" : $.support.boxSizing ? $E.css("boxSizing") : "content-box" - , b = $.layout.borderWidth - , n = $.layout.cssNum - , W = outerWidth - ; - // strip border and/or padding from outerWidth to get CSS Width - if (bs !== "border-box") - W -= (b($E, "Left") + b($E, "Right")); - if (bs === "content-box") - W -= (n($E, "paddingLeft") + n($E, "paddingRight")); - return max(0,W); - } - - /** - * Return the innerHeight for the current browser/doctype - * - * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() - * @param {Array.} $E Must pass a jQuery object - first element is processed - * @param {number=} outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized - * @return {number} Returns the innerHeight of the elem by subtracting padding and borders - */ -, cssHeight: function ($E, outerHeight) { - // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed - if (outerHeight <= 0) return 0; - - var bs = !$.layout.browser.boxModel ? "border-box" : $.support.boxSizing ? $E.css("boxSizing") : "content-box" - , b = $.layout.borderWidth - , n = $.layout.cssNum - , H = outerHeight - ; - // strip border and/or padding from outerHeight to get CSS Height -// if (bs !== "border-box") -// H -= (b($E, "Top") + b($E, "Bottom")); -// if (bs === "content-box") -// H -= (n($E, "paddingTop") + n($E, "paddingBottom")); - return max(0,H); - } - - /** - * Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist - * - * @see Called by many methods - * @param {Array.} $E Must pass a jQuery object - first element is processed - * @param {string} prop The name of the CSS property, eg: top, width, etc. - * @param {boolean=} [allowAuto=false] true = return 'auto' if that is value; false = return 0 - * @return {(string|number)} Usually used to get an integer value for position (top, left) or size (height, width) - */ -, cssNum: function ($E, prop, allowAuto) { - if (!$E.jquery) $E = $($E); - var CSS = $.layout.showInvisibly($E) - , p = $.css($E[0], prop, true) - , v = allowAuto && p=="auto" ? p : Math.round(parseFloat(p) || 0); - $E.css( CSS ); // RESET - return v; - } - -, borderWidth: function (el, side) { - if (el.jquery) el = el[0]; - var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left - return $.css(el, b+"Style", true) === "none" ? 0 : Math.round(parseFloat($.css(el, b+"Width", true)) || 0); - } - - /** - * Mouse-tracking utility - FUTURE REFERENCE - * - * init: if (!window.mouse) { - * window.mouse = { x: 0, y: 0 }; - * $(document).mousemove( $.layout.trackMouse ); - * } - * - * @param {Object} evt - * -, trackMouse: function (evt) { - window.mouse = { x: evt.clientX, y: evt.clientY }; - } - */ - - /** - * SUBROUTINE for preventPrematureSlideClose option - * - * @param {Object} evt - * @param {Object=} el - */ -, isMouseOverElem: function (evt, el) { - var - $E = $(el || this) - , d = $E.offset() - , T = d.top - , L = d.left - , R = L + $E.outerWidth() - , B = T + $E.outerHeight() - , x = evt.pageX // evt.clientX ? - , y = evt.pageY // evt.clientY ? - ; - // if X & Y are < 0, probably means is over an open SELECT - return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B)); - } - - /** - * Message/Logging Utility - * - * @example $.layout.msg("My message"); // log text - * @example $.layout.msg("My message", true); // alert text - * @example $.layout.msg({ foo: "bar" }, "Title"); // log hash-data, with custom title - * @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR- - * @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data - * - * @param {(Object|string)} info String message OR Hash/Array - * @param {(Boolean|string|Object)=} [popup=false] True means alert-box - can be skipped - * @param {(Object|string)=} [debugTitle=""] Title for Hash data - can be skipped - * @param {Object=} [debugOpts] Extra options for debug output - */ -, msg: function (info, popup, debugTitle, debugOpts) { - if ($.isPlainObject(info) && window.debugData) { - if (typeof popup === "string") { - debugOpts = debugTitle; - debugTitle = popup; - } - else if (typeof debugTitle === "object") { - debugOpts = debugTitle; - debugTitle = null; - } - var t = debugTitle || "log( )" - , o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts); - if (popup === true || o.display) - debugData( info, t, o ); - else if (window.console) - console.log(debugData( info, t, o )); - } - else if (popup) - alert(info); - else if (window.console) - console.log(info); - else { - var id = "#layoutLogger" - , $l = $(id); - if (!$l.length) - $l = createLog(); - $l.children("ul").append('
  • '+ info.replace(/\/g,">") +'
  • '); - } - - function createLog () { - var pos = $.support.fixedPosition ? 'fixed' : 'absolute' - , $e = $('
    ' - + '
    ' - + 'XLayout console.log
    ' - + '
      ' - + '
      ' - ).appendTo("body"); - $e.css('left', $(window).width() - $e.outerWidth() - 5) - if ($.ui.draggable) $e.draggable({ handle: ':first-child' }); - return $e; - }; - } - -}; - - -/* - * $.layout.browser REPLACES removed $.browser, with extra data - * Parsing code here adapted from jQuery 1.8 $.browse - */ -var u = navigator.userAgent.toLowerCase() -, m = /(chrome)[ \/]([\w.]+)/.exec( u ) - || /(webkit)[ \/]([\w.]+)/.exec( u ) - || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( u ) - || /(msie) ([\w.]+)/.exec( u ) - || u.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( u ) - || [] -, b = m[1] || "" -, v = m[2] || 0 -, ie = b === "msie" -; -$.layout.browser = { - version: v -, safari: b === "webkit" // webkit (NOT chrome) = safari -, webkit: b === "chrome" // chrome = webkit -, msie: ie -, isIE6: ie && v == 6 - // ONLY IE reverts to old box-model - update for older jQ onReady -, boxModel: !ie || $.support.boxModel !== false -}; -if (b) $.layout.browser[b] = true; // set CURRENT browser -/* OLD versions of jQuery only set $.support.boxModel after page is loaded - * so if this is IE, use support.boxModel to test for quirks-mode (ONLY IE changes boxModel) */ -if (ie) $(function(){ $.layout.browser.boxModel = $.support.boxModel; }); - - -// DEFAULT OPTIONS -$.layout.defaults = { -/* - * LAYOUT & LAYOUT-CONTAINER OPTIONS - * - none of these options are applicable to individual panes - */ - name: "" // Not required, but useful for buttons and used for the state-cookie -, containerClass: "ui-layout-container" // layout-container element -, inset: null // custom container-inset values (override padding) -, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) -, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event -, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky -, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized -, maskPanesEarly: false // true = create pane-masks on resizer.mouseDown instead of waiting for resizer.dragstart -, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific -, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific -, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements -, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized -, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload -, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload -, initPanes: true // false = DO NOT initialize the panes onLoad - will init later -, showErrorMessages: true // enables fatal error messages to warn developers of common errors -, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code! -// Changing this zIndex value will cause other zIndex values to automatically change -, zIndex: null // the PANE zIndex - resizers and masks will be +1 -// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships -, zIndexes: { // set _default_ z-index values here... - pane_normal: 0 // normal z-index for panes - , content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing - , resizer_normal: 2 // normal z-index for resizer-bars - , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' - , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer - , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' - } -, errors: { - pane: "pane" // description of "layout pane element" - used only in error messages - , selector: "selector" // description of "jQuery-selector" - used only in error messages - , addButtonError: "Error Adding Button\nInvalid " - , containerMissing: "UI Layout Initialization Error\nThe specified layout-container does not exist." - , centerPaneMissing: "UI Layout Initialization Error\nThe center-pane element does not exist.\nThe center-pane is a required element." - , noContainerHeight: "UI Layout Initialization Warning\nThe layout-container \"CONTAINER\" has no height.\nTherefore the layout is 0-height and hence 'invisible'!" - , callbackError: "UI Layout Callback Error\nThe EVENT callback is not a valid function." - } -/* - * PANE DEFAULT SETTINGS - * - settings under the 'panes' key become the default settings for *all panes* - * - ALL pane-options can also be set specifically for each panes, which will override these 'default values' - */ -, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings' - applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity - , closable: true // pane can open & close - , resizable: true // when open, pane can be resized - , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out - , initClosed: false // true = init pane as 'closed' - , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing - // SELECTORS - //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane - , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! - , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content' - , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector) - // GENERIC ROOT-CLASSES - for auto-generated classNames - , paneClass: "ui-layout-pane" // Layout Pane - , resizerClass: "ui-layout-resizer" // Resizer Bar - , togglerClass: "ui-layout-toggler" // Toggler Button - , buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin' - // ELEMENT SIZE & SPACING - //, size: 100 // MUST be pane-specific -initial size of pane - , minSize: 0 // when manually resizing a pane - , maxSize: 0 // ditto, 0 = no limit - , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' - , spacing_closed: 6 // ditto - when pane is 'closed' - , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides - , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' - , togglerAlign_open: "center" // top/left, bottom/right, center, OR... - , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right - , togglerContent_open: "" // text or HTML to put INSIDE the toggler - , togglerContent_closed: "" // ditto - // RESIZING OPTIONS - , resizerDblClickToggle: true // - , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes - , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed - , resizerDragOpacity: 1 // option for ui.draggable - //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar - , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES - , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask - , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes - , resizingGrid: false // grid size that the resizers will snap-to during resizing, eg: [20,20] - , livePaneResizing: false // true = LIVE Resizing as resizer is dragged - , liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged - , liveResizingTolerance: 1 // how many px change before pane resizes, to control performance - // SLIDING OPTIONS - , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' - , slideTrigger_open: "click" // click, dblclick, mouseenter - , slideTrigger_close: "mouseleave"// click, mouseleave - , slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open - , slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!) - , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? - , preventQuickSlideClose: $.layout.browser.webkit // Chrome triggers slideClosed as it is opening - , preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over a SELECT-list in IE - // PANE-SPECIFIC TIPS & MESSAGES - , tips: { - Open: "Open" // eg: "Open Pane" - , Close: "Close" - , Resize: "Resize" - , Slide: "Slide Open" - , Pin: "Pin" - , Unpin: "Un-Pin" - , noRoomToOpen: "Not enough room to show this panel." // alert if user tries to open a pane that cannot - , minSizeWarning: "Panel has reached its minimum size" // displays in browser statusbar - , maxSizeWarning: "Panel has reached its maximum size" // ditto - } - // HOT-KEYS & MISC - , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver - , enableCursorHotkey: true // enabled 'cursor' hotkeys - //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character - , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' - // PANE ANIMATION - // NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed - , fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size' - , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration - , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } - , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation - , animatePaneSizing: false // true = animate resizing after dragging resizer-bar OR sizePane() is called - /* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set: - fxName_open: "slide" // 'Open' pane animation - fnName_close: "slide" // 'Close' pane animation - fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true - fxSpeed_open: null - fxSpeed_close: null - fxSpeed_size: null - fxSettings_open: {} - fxSettings_close: {} - fxSettings_size: {} - */ - // CHILD/NESTED LAYOUTS - , children: null // Layout-options for nested/child layout - even {} is valid as options - , containerSelector: '' // if child is NOT 'directly nested', a selector to find it/them (can have more than one child layout!) - , initChildren: true // true = child layout will be created as soon as _this_ layout completes initialization - , destroyChildren: true // true = destroy child-layout if this pane is destroyed - , resizeChildren: true // true = trigger child-layout.resizeAll() when this pane is resized - // EVENT TRIGGERING - , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes - , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true - // PANE CALLBACKS - , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start - , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end - , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start - , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end - , onopen_start: null // CALLBACK when pane STARTS to Open - , onopen_end: null // CALLBACK when pane ENDS being Opened - , onclose_start: null // CALLBACK when pane STARTS to Close - , onclose_end: null // CALLBACK when pane ENDS being Closed - , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON*** - , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** - , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS - , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS - , onswap_start: null // CALLBACK when pane STARTS to Swap - , onswap_end: null // CALLBACK when pane ENDS being Swapped - , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized - , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized - } -/* - * PANE-SPECIFIC SETTINGS - * - options listed below MUST be specified per-pane - they CANNOT be set under 'panes' - * - all options under the 'panes' key can also be set specifically for any pane - * - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane - */ -, north: { - paneSelector: ".ui-layout-north" - , size: "auto" // eg: "auto", "30%", .30, 200 - , resizerCursor: "n-resize" // custom = url(myCursor.cur) - , customHotkey: "" // EITHER a charCode (43) OR a character ("o") - } -, south: { - paneSelector: ".ui-layout-south" - , size: "auto" - , resizerCursor: "s-resize" - , customHotkey: "" - } -, east: { - paneSelector: ".ui-layout-east" - , size: 200 - , resizerCursor: "e-resize" - , customHotkey: "" - } -, west: { - paneSelector: ".ui-layout-west" - , size: 200 - , resizerCursor: "w-resize" - , customHotkey: "" - } -, center: { - paneSelector: ".ui-layout-center" - , minWidth: 0 - , minHeight: 0 - } -}; - -$.layout.optionsMap = { - // layout/global options - NOT pane-options - layout: ("name,instanceKey,stateManagement,effects,inset,zIndexes,errors," - + "zIndex,scrollToBookmarkOnLoad,showErrorMessages,maskPanesEarly," - + "outset,resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay," - + "onresizeall,onresizeall_start,onresizeall_end,onload,onload_start,onload_end,onunload,onunload_start,onunload_end").split(",") -// borderPanes: [ ALL options that are NOT specified as 'layout' ] - // default.panes options that apply to the center-pane (most options apply _only_ to border-panes) -, center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad," - + "showOverflowOnHover,maskContents,maskObjects,liveContentResizing," - + "containerSelector,children,initChildren,resizeChildren,destroyChildren," - + "onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",") - // options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key -, noDefault: ("paneSelector,resizerCursor,customHotkey").split(",") -}; - -/** - * Processes options passed in converts flat-format data into subkey (JSON) format - * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName - * Plugins may also call this method so they can transform their own data - * - * @param {!Object} hash Data/options passed by user - may be a single level or nested levels - * @param {boolean=} [addKeys=false] Should the primary layout.options keys be added if they do not exist? - * @return {Object} Returns hash of minWidth & minHeight - */ -$.layout.transformData = function (hash, addKeys) { - var json = addKeys ? { panes: {}, center: {} } : {} // init return object - , branch, optKey, keys, key, val, i, c; - - if (typeof hash !== "object") return json; // no options passed - - // convert all 'flat-keys' to 'sub-key' format - for (optKey in hash) { - branch = json; - val = hash[ optKey ]; - keys = optKey.split("__"); // eg: west__size or north__fxSettings__duration - c = keys.length - 1; - // convert underscore-delimited to subkeys - for (i=0; i <= c; i++) { - key = keys[i]; - if (i === c) { // last key = value - if ($.isPlainObject( val )) - branch[key] = $.layout.transformData( val ); // RECURSE - else - branch[key] = val; - } - else { - if (!branch[key]) - branch[key] = {}; // create the subkey - // recurse to sub-key for next loop - if not done - branch = branch[key]; - } - } - } - return json; -}; - -// INTERNAL CONFIG DATA - DO NOT CHANGE THIS! -$.layout.backwardCompatibility = { - // data used by renameOldOptions() - map: { - // OLD Option Name: NEW Option Name - applyDefaultStyles: "applyDemoStyles" - // CHILD/NESTED LAYOUTS - , childOptions: "children" - , initChildLayout: "initChildren" - , destroyChildLayout: "destroyChildren" - , resizeChildLayout: "resizeChildren" - , resizeNestedLayout: "resizeChildren" - // MISC Options - , resizeWhileDragging: "livePaneResizing" - , resizeContentWhileDragging: "liveContentResizing" - , triggerEventsWhileDragging: "triggerEventsDuringLiveResize" - , maskIframesOnResize: "maskContents" - // STATE MANAGEMENT - , useStateCookie: "stateManagement.enabled" - , "cookie.autoLoad": "stateManagement.autoLoad" - , "cookie.autoSave": "stateManagement.autoSave" - , "cookie.keys": "stateManagement.stateKeys" - , "cookie.name": "stateManagement.cookie.name" - , "cookie.domain": "stateManagement.cookie.domain" - , "cookie.path": "stateManagement.cookie.path" - , "cookie.expires": "stateManagement.cookie.expires" - , "cookie.secure": "stateManagement.cookie.secure" - // OLD Language options - , noRoomToOpenTip: "tips.noRoomToOpen" - , togglerTip_open: "tips.Close" // open = Close - , togglerTip_closed: "tips.Open" // closed = Open - , resizerTip: "tips.Resize" - , sliderTip: "tips.Slide" - } - -/** -* @param {Object} opts -*/ -, renameOptions: function (opts) { - var map = $.layout.backwardCompatibility.map - , oldData, newData, value - ; - for (var itemPath in map) { - oldData = getBranch( itemPath ); - value = oldData.branch[ oldData.key ]; - if (value !== undefined) { - newData = getBranch( map[itemPath], true ); - newData.branch[ newData.key ] = value; - delete oldData.branch[ oldData.key ]; - } - } - - /** - * @param {string} path - * @param {boolean=} [create=false] Create path if does not exist - */ - function getBranch (path, create) { - var a = path.split(".") // split keys into array - , c = a.length - 1 - , D = { branch: opts, key: a[c] } // init branch at top & set key (last item) - , i = 0, k, undef; - for (; i 0) { - if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { - $E.show().data('autoHidden', false); - if (!browser.mozilla) // FireFox refreshes iframes - IE does not - // make hidden, then visible to 'refresh' display after animation - $E.css(_c.hidden).css(_c.visible); - } - } - else if (autoHide && !$E.data('autoHidden')) - $E.hide().data('autoHidden', true); - } - - /** - * @param {(string|!Object)} el - * @param {number=} outerHeight - * @param {boolean=} [autoHide=false] - */ -, setOuterHeight = function (el, outerHeight, autoHide) { - var $E = el, h; - if (isStr(el)) $E = $Ps[el]; // west - else if (!el.jquery) $E = $(el); - h = cssH($E, outerHeight); - $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent - if (h > 0 && $E.innerWidth() > 0) { - if (autoHide && $E.data('autoHidden')) { - $E.show().data('autoHidden', false); - if (!browser.mozilla) // FireFox refreshes iframes - IE does not - $E.css(_c.hidden).css(_c.visible); - } - } - else if (autoHide && !$E.data('autoHidden')) - $E.hide().data('autoHidden', true); - } - - - /** - * Converts any 'size' params to a pixel/integer size, if not already - * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated - * - /** - * @param {string} pane - * @param {(string|number)=} size - * @param {string=} [dir] - * @return {number} - */ -, _parseSize = function (pane, size, dir) { - if (!dir) dir = _c[pane].dir; - - if (isStr(size) && size.match(/%/)) - size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal - - if (size === 0) - return 0; - else if (size >= 1) - return parseInt(size, 10); - - var o = options, avail = 0; - if (dir=="horz") // north or south or center.minHeight - avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); - else if (dir=="vert") // east or west or center.minWidth - avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); - - if (size === -1) // -1 == 100% - return avail; - else if (size > 0) // percentage, eg: .25 - return round(avail * size); - else if (pane=="center") - return 0; - else { // size < 0 || size=='auto' || size==Missing || size==Invalid - // auto-size the pane - var dim = (dir === "horz" ? "height" : "width") - , $P = $Ps[pane] - , $C = dim === 'height' ? $Cs[pane] : false - , vis = $.layout.showInvisibly($P) // show pane invisibly if hidden - , szP = $P.css(dim) // SAVE current pane size - , szC = $C ? $C.css(dim) : 0 // SAVE current content size - ; - $P.css(dim, "auto"); - if ($C) $C.css(dim, "auto"); - size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE - $P.css(dim, szP).css(vis); // RESET size & visibility - if ($C) $C.css(dim, szC); - return size; - } - } - - /** - * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added - * - * @param {(string|!Object)} pane - * @param {boolean=} [inclSpace=false] - * @return {number} Returns EITHER Width for east/west panes OR Height for north/south panes - */ -, getPaneSize = function (pane, inclSpace) { - var - $P = $Ps[pane] - , o = options[pane] - , s = state[pane] - , oSp = (inclSpace ? o.spacing_open : 0) - , cSp = (inclSpace ? o.spacing_closed : 0) - ; - if (!$P || s.isHidden) - return 0; - else if (s.isClosed || (s.isSliding && inclSpace)) - return cSp; - else if (_c[pane].dir === "horz") - return $P.outerHeight() + oSp; - else // dir === "vert" - return $P.outerWidth() + oSp; - } - - /** - * Calculate min/max pane dimensions and limits for resizing - * - * @param {string} pane - * @param {boolean=} [slide=false] - */ -, setSizeLimits = function (pane, slide) { - if (!isInitialized()) return; - var - o = options[pane] - , s = state[pane] - , c = _c[pane] - , dir = c.dir - , type = c.sizeType.toLowerCase() - , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param - , $P = $Ps[pane] - , paneSpacing = o.spacing_open - // measure the pane on the *opposite side* from this pane - , altPane = _c.oppositeEdge[pane] - , altS = state[altPane] - , $altP = $Ps[altPane] - , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) - , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) - // limitSize prevents this pane from 'overlapping' opposite pane - , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) - , minCenterDims = cssMinDims("center") - , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) - // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them - , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) - , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) - , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) - , r = s.resizerPosition = {} // used to set resizing limits - , top = sC.inset.top - , left = sC.inset.left - , W = sC.innerWidth - , H = sC.innerHeight - , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east - ; - switch (pane) { - case "north": r.min = top + minSize; - r.max = top + maxSize; - break; - case "west": r.min = left + minSize; - r.max = left + maxSize; - break; - case "south": r.min = top + H - maxSize - rW; - r.max = top + H - minSize - rW; - break; - case "east": r.min = left + W - maxSize - rW; - r.max = left + W - minSize - rW; - break; - }; - } - - /** - * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes - * - * @return JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height - */ -, calcNewCenterPaneDims = function () { - var d = { - top: getPaneSize("north", true) // true = include 'spacing' value for pane - , bottom: getPaneSize("south", true) - , left: getPaneSize("west", true) - , right: getPaneSize("east", true) - , width: 0 - , height: 0 - }; - - // NOTE: sC = state.container - // calc center-pane outer dimensions - d.width = sC.innerWidth - d.left - d.right; // outerWidth - d.height = sC.innerHeight - d.bottom - d.top; // outerHeight - // add the 'container border/padding' to get final positions relative to the container - d.top += sC.inset.top; - d.bottom += sC.inset.bottom; - d.left += sC.inset.left; - d.right += sC.inset.right; - - return d; - } - - - /** - * @param {!Object} el - * @param {boolean=} [allStates=false] - */ -, getHoverClasses = function (el, allStates) { - var - $El = $(el) - , type = $El.data("layoutRole") - , pane = $El.data("layoutEdge") - , o = options[pane] - , root = o[type +"Class"] - , _pane = "-"+ pane // eg: "-west" - , _open = "-open" - , _closed = "-closed" - , _slide = "-sliding" - , _hover = "-hover " // NOTE the trailing space - , _state = $El.hasClass(root+_closed) ? _closed : _open - , _alt = _state === _closed ? _open : _closed - , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) - ; - if (allStates) // when 'removing' classes, also remove alternate-state classes - classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); - - if (type=="resizer" && $El.hasClass(root+_slide)) - classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); - - return $.trim(classes); - } -, addHover = function (evt, el) { - var $E = $(el || this); - if (evt && $E.data("layoutRole") === "toggler") - evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar - $E.addClass( getHoverClasses($E) ); - } -, removeHover = function (evt, el) { - var $E = $(el || this); - $E.removeClass( getHoverClasses($E, true) ); - } - -, onResizerEnter = function (evt) { // ALSO called by toggler.mouseenter - var pane = $(this).data("layoutEdge") - , s = state[pane] - ; - // ignore closed-panes and mouse moving back & forth over resizer! - // also ignore if ANY pane is currently resizing - if ( s.isClosed || s.isResizing || state.paneResizing ) return; - - if ($.fn.disableSelection) - $("body").disableSelection(); - if (options.maskPanesEarly) - showMasks( pane, { resizing: true }); - } -, onResizerLeave = function (evt, el) { - var e = el || this // el is only passed when called by the timer - , pane = $(e).data("layoutEdge") - , name = pane +"ResizerLeave" - ; - timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set - timer.clear(name); // cancel enableSelection timer - may re/set below - // this method calls itself on a timer because it needs to allow - // enough time for dragging to kick-in and set the isResizing flag - // dragging has a 100ms delay set, so this delay must be >100 - if (!el) // 1st call - mouseleave event - timer.set(name, function(){ onResizerLeave(evt, e); }, 200); - // if user is resizing, then dragStop will enableSelection(), so can skip it here - else if ( !state.paneResizing ) { // 2nd call - by timer - if ($.fn.enableSelection) - $("body").enableSelection(); - if (options.maskPanesEarly) - hideMasks(); - } - } - -/* - * ########################### - * INITIALIZATION METHODS - * ########################### - */ - - /** - * Initialize the layout - called automatically whenever an instance of layout is created - * - * @see none - triggered onInit - * @return mixed true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort - */ -, _create = function () { - // initialize config/options - initOptions(); - var o = options - , s = state; - - // TEMP state so isInitialized returns true during init process - s.creatingLayout = true; - - // init plugins for this layout, if there are any (eg: stateManagement) - runPluginCallbacks( Instance, $.layout.onCreate ); - - // options & state have been initialized, so now run beforeLoad callback - // onload will CANCEL layout creation if it returns false - if (false === _runCallbacks("onload_start")) - return 'cancel'; - - // initialize the container element - _initContainer(); - - // bind hotkey function - keyDown - if required - initHotkeys(); - - // bind window.onunload - $(window).bind("unload."+ sID, unload); - - // init plugins for this layout, if there are any (eg: customButtons) - runPluginCallbacks( Instance, $.layout.onLoad ); - - // if layout elements are hidden, then layout WILL NOT complete initialization! - // initLayoutElements will set initialized=true and run the onload callback IF successful - if (o.initPanes) _initLayoutElements(); - - delete s.creatingLayout; - - return state.initialized; - } - - /** - * Initialize the layout IF not already - * - * @see All methods in Instance run this test - * @return boolean true = layoutElements have been initialized | false = panes are not initialized (yet) - */ -, isInitialized = function () { - if (state.initialized || state.creatingLayout) return true; // already initialized - else return _initLayoutElements(); // try to init panes NOW - } - - /** - * Initialize the layout - called automatically whenever an instance of layout is created - * - * @see _create() & isInitialized - * @param {boolean=} [retry=false] // indicates this is a 2nd try - * @return An object pointer to the instance created - */ -, _initLayoutElements = function (retry) { - // initialize config/options - var o = options; - // CANNOT init panes inside a hidden container! - if (!$N.is(":visible")) { - // handle Chrome bug where popup window 'has no height' - // if layout is BODY element, try again in 50ms - // SEE: http://layout.jquery-dev.net/samples/test_popup_window.html - if ( !retry && browser.webkit && $N[0].tagName === "BODY" ) - setTimeout(function(){ _initLayoutElements(true); }, 50); - return false; - } - - // a center pane is required, so make sure it exists - if (!getPane("center").length) { - return _log( o.errors.centerPaneMissing ); - } - - // TEMP state so isInitialized returns true during init process - state.creatingLayout = true; - - // update Container dims - $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values - - // initialize all layout elements - initPanes(); // size & position panes - calls initHandles() - which calls initResizable() - - if (o.scrollToBookmarkOnLoad) { - var l = self.location; - if (l.hash) l.replace( l.hash ); // scrollTo Bookmark - } - - // check to see if this layout 'nested' inside a pane - if (Instance.hasParentLayout) - o.resizeWithWindow = false; - // bind resizeAll() for 'this layout instance' to window.resize event - else if (o.resizeWithWindow) - $(window).bind("resize."+ sID, windowResize); - - delete state.creatingLayout; - state.initialized = true; - - // init plugins for this layout, if there are any - runPluginCallbacks( Instance, $.layout.onReady ); - - // now run the onload callback, if exists - _runCallbacks("onload_end"); - - return true; // elements initialized successfully - } - - /** - * Initialize nested layouts for a specific pane - can optionally pass layout-options - * - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - * @param {Object=} [opts] Layout-options - if passed, will OVERRRIDE options[pane].children - * @return An object pointer to the layout instance created - or null - */ -, createChildren = function (evt_or_pane, opts) { - var pane = evtPane.call(this, evt_or_pane) - , $P = $Ps[pane] - ; - if (!$P) return; - var $C = $Cs[pane] - , s = state[pane] - , o = options[pane] - , sm = options.stateManagement || {} - , cos = opts ? (o.children = opts) : o.children - ; - if ( $.isPlainObject( cos ) ) - cos = [ cos ]; // convert a hash to a 1-elem array - else if (!cos || !$.isArray( cos )) - return; - - $.each( cos, function (idx, co) { - if ( !$.isPlainObject( co ) ) return; - - // determine which element is supposed to be the 'child container' - // if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane - var $containers = co.containerSelector ? $P.find( co.containerSelector ) : ($C || $P); - - $containers.each(function(){ - var $cont = $(this) - , child = $cont.data("layout") // see if a child-layout ALREADY exists on this element - ; - // if no layout exists, but children are set, try to create the layout now - if (!child) { - // TODO: see about moving this to the stateManagement plugin, as a method - // set a unique child-instance key for this layout, if not already set - setInstanceKey({ container: $cont, options: co }, s ); - // If THIS layout has a hash in stateManagement.autoLoad, - // then see if it also contains state-data for this child-layout - // If so, copy the stateData to child.options.stateManagement.autoLoad - if ( sm.includeChildren && state.stateData[pane] ) { - // THIS layout's state was cached when its state was loaded - var paneChildren = state.stateData[pane].children || {} - , childState = paneChildren[ co.instanceKey ] - , co_sm = co.stateManagement || (co.stateManagement = { autoLoad: true }) - ; - // COPY the stateData into the autoLoad key - if ( co_sm.autoLoad === true && childState ) { - co_sm.autoSave = false; // disable autoSave because saving handled by parent-layout - co_sm.includeChildren = true; // cascade option - FOR NOW - co_sm.autoLoad = $.extend(true, {}, childState); // COPY the state-hash - } - } - - // create the layout - child = $cont.layout( co ); - - // if successful, update data - if (child) { - // add the child and update all layout-pointers - // MAY have already been done by child-layout calling parent.refreshChildren() - refreshChildren( pane, child ); - } - } - }); - }); - } - -, setInstanceKey = function (child, parentPaneState) { - // create a named key for use in state and instance branches - var $c = child.container - , o = child.options - , sm = o.stateManagement - , key = o.instanceKey || $c.data("layoutInstanceKey") - ; - if (!key) key = (sm && sm.cookie ? sm.cookie.name : '') || o.name; // look for a name/key - if (!key) key = "layout"+ (++parentPaneState.childIdx); // if no name/key found, generate one - else key = key.replace(/[^\w-]/gi, '_').replace(/_{2,}/g, '_'); // ensure is valid as a hash key - o.instanceKey = key; - $c.data("layoutInstanceKey", key); // useful if layout is destroyed and then recreated - return key; - } - - /** - * @param {string} pane The pane being opened, ie: north, south, east, or west - * @param {Object=} newChild New child-layout Instance to add to this pane - */ -, refreshChildren = function (pane, newChild) { - var $P = $Ps[pane] - , pC = children[pane] - , s = state[pane] - , o - ; - // check for destroy()ed layouts and update the child pointers & arrays - if ($.isPlainObject( pC )) { - $.each( pC, function (key, child) { - if (child.destroyed) delete pC[key] - }); - // if no more children, remove the children hash - if ($.isEmptyObject( pC )) - pC = children[pane] = null; // clear children hash - } - - // see if there is a directly-nested layout inside this pane - // if there is, then there can be only ONE child-layout, so check that... - if (!newChild && !pC) { - newChild = $P.data("layout"); - } - - // if a newChild instance was passed, add it to children[pane] - if (newChild) { - // update child.state - newChild.hasParentLayout = true; // set parent-flag in child - // instanceKey is a key-name used in both state and children - o = newChild.options; - // set a unique child-instance key for this layout, if not already set - setInstanceKey( newChild, s ); - // add pointer to pane.children hash - if (!pC) pC = children[pane] = {}; // create an empty children hash - pC[ o.instanceKey ] = newChild.container.data("layout"); // add childLayout instance - } - - // ALWAYS refresh the pane.children alias, even if null - Instance[pane].children = children[pane]; - - // if newChild was NOT passed - see if there is a child layout NOW - if (!newChild) { - createChildren(pane); // MAY create a child and re-call this method - } - } - -, windowResize = function () { - var o = options - , delay = Number(o.resizeWithWindowDelay); - if (delay < 10) delay = 100; // MUST have a delay! - // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway - timer.clear("winResize"); // if already running - timer.set("winResize", function(){ - timer.clear("winResize"); - timer.clear("winResizeRepeater"); - var dims = elDims( $N, o.inset ); - // only trigger resizeAll() if container has changed size - if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight) - resizeAll(); - }, delay); - // ALSO set fixed-delay timer, if not already running - if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater(); - } - -, setWindowResizeRepeater = function () { - var delay = Number(options.resizeWithWindowMaxDelay); - if (delay > 0) - timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); - } - -, unload = function () { - var o = options; - - _runCallbacks("onunload_start"); - - // trigger plugin callabacks for this layout (eg: stateManagement) - runPluginCallbacks( Instance, $.layout.onUnload ); - - _runCallbacks("onunload_end"); - } - - /** - * Validate and initialize container CSS and events - * - * @see _create() - */ -, _initContainer = function () { - var - N = $N[0] - , $H = $("html") - , tag = sC.tagName = N.tagName - , id = sC.id = N.id - , cls = sC.className = N.className - , o = options - , name = o.name - , props = "position,margin,padding,border" - , css = "layoutCSS" - , CSS = {} - , hid = "hidden" // used A LOT! - // see if this container is a 'pane' inside an outer-layout - , parent = $N.data("parentLayout") // parent-layout Instance - , pane = $N.data("layoutEdge") // pane-name in parent-layout - , isChild = parent && pane - , num = $.layout.cssNum - , $parent, n - ; - // sC = state.container - sC.selector = $N.selector.split(".slice")[0]; - sC.ref = (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages - sC.isBody = (tag === "BODY"); - - // try to find a parent-layout - if (!isChild && !sC.isBody) { - $parent = $N.closest("."+ $.layout.defaults.panes.paneClass); - parent = $parent.data("parentLayout"); - pane = $parent.data("layoutEdge"); - isChild = parent && pane; - } - - $N .data({ - layout: Instance - , layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID - }) - .addClass(o.containerClass) - ; - var layoutMethods = { - destroy: '' - , initPanes: '' - , resizeAll: 'resizeAll' - , resize: 'resizeAll' - }; - // loop hash and bind all methods - include layoutID namespacing - for (name in layoutMethods) { - $N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]); - } - - // if this container is another layout's 'pane', then set child/parent pointers - if (isChild) { - // update parent flag - Instance.hasParentLayout = true; - // set pointers to THIS child-layout (Instance) in parent-layout - parent.refreshChildren( pane, Instance ); - } - - // SAVE original container CSS for use in destroy() - if (!$N.data(css)) { - // handle props like overflow different for BODY & HTML - has 'system default' values - if (sC.isBody) { - // SAVE CSS - $N.data(css, $.extend( styles($N, props), { - height: $N.css("height") - , overflow: $N.css("overflow") - , overflowX: $N.css("overflowX") - , overflowY: $N.css("overflowY") - })); - // ALSO SAVE CSS - $H.data(css, $.extend( styles($H, 'padding'), { - height: "auto" // FF would return a fixed px-size! - , overflow: $H.css("overflow") - , overflowX: $H.css("overflowX") - , overflowY: $H.css("overflowY") - })); - } - else // handle props normally for non-body elements - $N.data(css, styles($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY") ); - } - - try { - // common container CSS - CSS = { - overflow: hid - , overflowX: hid - , overflowY: hid - }; - $N.css( CSS ); - - if (o.inset && !$.isPlainObject(o.inset)) { - // can specify a single number for equal outset all-around - n = parseInt(o.inset, 10) || 0 - o.inset = { - top: n - , bottom: n - , left: n - , right: n - }; - } - - // format html & body if this is a full page layout - if (sC.isBody) { - // if HTML has padding, use this as an outer-spacing around BODY - if (!o.outset) { - // use padding from parent-elem (HTML) as outset - o.outset = { - top: num($H, "paddingTop") - , bottom: num($H, "paddingBottom") - , left: num($H, "paddingLeft") - , right: num($H, "paddingRight") - }; - } - else if (!$.isPlainObject(o.outset)) { - // can specify a single number for equal outset all-around - n = parseInt(o.outset, 10) || 0 - o.outset = { - top: n - , bottom: n - , left: n - , right: n - }; - } - // HTML - $H.css( CSS ).css({ - height: "100%" - , border: "none" // no border or padding allowed when using height = 100% - , padding: 0 // ditto - , margin: 0 - }); - // BODY - if (browser.isIE6) { - // IE6 CANNOT use the trick of setting absolute positioning on all 4 sides - must have 'height' - $N.css({ - width: "100%" - , height: "100%" - , border: "none" // no border or padding allowed when using height = 100% - , padding: 0 // ditto - , margin: 0 - , position: "relative" - }); - // convert body padding to an inset option - the border cannot be measured in IE6! - if (!o.inset) o.inset = elDims( $N ).inset; - } - else { // use absolute positioning for BODY to allow borders & padding without overflow - $N.css({ - width: "auto" - , height: "auto" - , margin: 0 - , position: "absolute" // allows for border and padding on BODY - }); - // apply edge-positioning created above - $N.css( o.outset ); - } - // set current layout-container dimensions - $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values - } - else { - // container MUST have 'position' - var p = $N.css("position"); - if (!p || !p.match(/(fixed|absolute|relative)/)) - $N.css("position","relative"); - - // set current layout-container dimensions - if ( $N.is(":visible") ) { - $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT change insetX (padding) values - if (sC.innerHeight < 1) // container has no 'height' - warn developer - _log( o.errors.noContainerHeight.replace(/CONTAINER/, sC.ref) ); - } - } - - // if container has min-width/height, then enable scrollbar(s) - if ( num($N, "minWidth") ) $N.parent().css("overflowX","auto"); - if ( num($N, "minHeight") ) $N.parent().css("overflowY","auto"); - - } catch (ex) {} - } - - /** - * Bind layout hotkeys - if options enabled - * - * @see _create() and addPane() - * @param {string=} [panes=""] The edge(s) to process - */ -, initHotkeys = function (panes) { - panes = panes ? panes.split(",") : _c.borderPanes; - // bind keyDown to capture hotkeys, if option enabled for ANY pane - $.each(panes, function (i, pane) { - var o = options[pane]; - if (o.enableCursorHotkey || o.customHotkey) { - $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE - return false; // BREAK - binding was done - } - }); - } - - /** - * Build final OPTIONS data - * - * @see _create() - */ -, initOptions = function () { - var data, d, pane, key, val, i, c, o; - - // reprocess user's layout-options to have correct options sub-key structure - opts = $.layout.transformData( opts, true ); // panes = default subkey - - // auto-rename old options for backward compatibility - opts = $.layout.backwardCompatibility.renameAllOptions( opts ); - - // if user-options has 'panes' key (pane-defaults), clean it... - if (!$.isEmptyObject(opts.panes)) { - // REMOVE any pane-defaults that MUST be set per-pane - data = $.layout.optionsMap.noDefault; - for (i=0, c=data.length; i 0) { - z.pane_normal = zo; - z.content_mask = max(zo+1, z.content_mask); // MIN = +1 - z.resizer_normal = max(zo+2, z.resizer_normal); // MIN = +2 - } - - // DELETE 'panes' key now that we are done - values were copied to EACH pane - delete options.panes; - - - function createFxOptions ( pane ) { - var o = options[pane] - , d = options.panes; - // ensure fxSettings key to avoid errors - if (!o.fxSettings) o.fxSettings = {}; - if (!d.fxSettings) d.fxSettings = {}; - - $.each(["_open","_close","_size"], function (i,n) { - var - sName = "fxName"+ n - , sSpeed = "fxSpeed"+ n - , sSettings = "fxSettings"+ n - // recalculate fxName according to specificity rules - , fxName = o[sName] = - o[sName] // options.west.fxName_open - || d[sName] // options.panes.fxName_open - || o.fxName // options.west.fxName - || d.fxName // options.panes.fxName - || "none" // MEANS $.layout.defaults.panes.fxName == "" || false || null || 0 - , fxExists = $.effects && ($.effects[fxName] || ($.effects.effect && $.effects.effect[fxName])) - ; - // validate fxName to ensure is valid effect - MUST have effect-config data in options.effects - if (fxName === "none" || !options.effects[fxName] || !fxExists) - fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName - - // set vars for effects subkeys to simplify logic - var fx = options.effects[fxName] || {} // effects.slide - , fx_all = fx.all || null // effects.slide.all - , fx_pane = fx[pane] || null // effects.slide.west - ; - // create fxSpeed[_open|_close|_size] - o[sSpeed] = - o[sSpeed] // options.west.fxSpeed_open - || d[sSpeed] // options.west.fxSpeed_open - || o.fxSpeed // options.west.fxSpeed - || d.fxSpeed // options.panes.fxSpeed - || null // DEFAULT - let fxSetting.duration control speed - ; - // create fxSettings[_open|_close|_size] - o[sSettings] = $.extend( - true - , {} - , fx_all // effects.slide.all - , fx_pane // effects.slide.west - , d.fxSettings // options.panes.fxSettings - , o.fxSettings // options.west.fxSettings - , d[sSettings] // options.panes.fxSettings_open - , o[sSettings] // options.west.fxSettings_open - ); - }); - - // DONE creating action-specific-settings for this pane, - // so DELETE generic options - are no longer meaningful - delete o.fxName; - delete o.fxSpeed; - delete o.fxSettings; - } - } - - /** - * Initialize module objects, styling, size and position for all panes - * - * @see _initElements() - * @param {string} pane The pane to process - */ -, getPane = function (pane) { - var sel = options[pane].paneSelector - if (sel.substr(0,1)==="#") // ID selector - // NOTE: elements selected 'by ID' DO NOT have to be 'children' - return $N.find(sel).eq(0); - else { // class or other selector - var $P = $N.children(sel).eq(0); - // look for the pane nested inside a 'form' element - return $P.length ? $P : $N.children("form:first").children(sel).eq(0); - } - } - - /** - * @param {Object=} evt - */ -, initPanes = function (evt) { - // stopPropagation if called by trigger("layoutinitpanes") - use evtPane utility - evtPane(evt); - - // NOTE: do north & south FIRST so we can measure their height - do center LAST - $.each(_c.allPanes, function (idx, pane) { - addPane( pane, true ); - }); - - // init the pane-handles NOW in case we have to hide or close the pane below - initHandles(); - - // now that all panes have been initialized and initially-sized, - // make sure there is really enough space available for each pane - $.each(_c.borderPanes, function (i, pane) { - if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN - setSizeLimits(pane); - makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() - } - }); - // size center-pane AGAIN in case we 'closed' a border-pane in loop above - sizeMidPanes("center"); - - // Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing! - // Before RC30.3, there was a 10ms delay here, but that caused layout - // to load asynchrously, which is BAD, so try skipping delay for now - - // process pane contents and callbacks, and init/resize child-layout if exists - $.each(_c.allPanes, function (idx, pane) { - afterInitPane(pane); - }); - } - - /** - * Add a pane to the layout - subroutine of initPanes() - * - * @see initPanes() - * @param {string} pane The pane to process - * @param {boolean=} [force=false] Size content after init - */ -, addPane = function (pane, force) { - if (!force && !isInitialized()) return; - var - o = options[pane] - , s = state[pane] - , c = _c[pane] - , dir = c.dir - , fx = s.fx - , spacing = o.spacing_open || 0 - , isCenter = (pane === "center") - , CSS = {} - , $P = $Ps[pane] - , size, minSize, maxSize, child - ; - // if pane-pointer already exists, remove the old one first - if ($P) - removePane( pane, false, true, false ); - else - $Cs[pane] = false; // init - - $P = $Ps[pane] = getPane(pane); - if (!$P.length) { - $Ps[pane] = false; // logic - return; - } - - // SAVE original Pane CSS - if (!$P.data("layoutCSS")) { - var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; - $P.data("layoutCSS", styles($P, props)); - } - - // create alias for pane data in Instance - initHandles will add more - Instance[pane] = { - name: pane - , pane: $Ps[pane] - , content: $Cs[pane] - , options: options[pane] - , state: state[pane] - , children: children[pane] - }; - - // add classes, attributes & events - $P .data({ - parentLayout: Instance // pointer to Layout Instance - , layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - , layoutRole: "pane" - }) - .css(c.cssReq).css("zIndex", options.zIndexes.pane_normal) - .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles - .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' - .bind("mouseenter."+ sID, addHover ) - .bind("mouseleave."+ sID, removeHover ) - ; - var paneMethods = { - hide: '' - , show: '' - , toggle: '' - , close: '' - , open: '' - , slideOpen: '' - , slideClose: '' - , slideToggle: '' - , size: 'sizePane' - , sizePane: 'sizePane' - , sizeContent: '' - , sizeHandles: '' - , enableClosable: '' - , disableClosable: '' - , enableSlideable: '' - , disableSlideable: '' - , enableResizable: '' - , disableResizable: '' - , swapPanes: 'swapPanes' - , swap: 'swapPanes' - , move: 'swapPanes' - , removePane: 'removePane' - , remove: 'removePane' - , createChildren: '' - , resizeChildren: '' - , resizeAll: 'resizeAll' - , resizeLayout: 'resizeAll' - } - , name; - // loop hash and bind all methods - include layoutID namespacing - for (name in paneMethods) { - $P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]); - } - - // see if this pane has a 'scrolling-content element' - initContent(pane, false); // false = do NOT sizeContent() - called later - - if (!isCenter) { - // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) - // if o.size is auto or not valid, then MEASURE the pane and use that as its 'size' - size = s.size = _parseSize(pane, o.size); - minSize = _parseSize(pane,o.minSize) || 1; - maxSize = _parseSize(pane,o.maxSize) || 100000; - if (size > 0) size = max(min(size, maxSize), minSize); - s.autoResize = o.autoResize; // used with percentage sizes - - // state for border-panes - s.isClosed = false; // true = pane is closed - s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes - s.isResizing= false; // true = pane is in process of being resized - s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! - - // array for 'pin buttons' whose classNames are auto-updated on pane-open/-close - if (!s.pins) s.pins = []; - } - // states common to ALL panes - s.tagName = $P[0].tagName; - s.edge = pane; // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going) - s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically - s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic - - // init pane positioning - setPanePosition( pane ); - - // if pane is not visible, - if (dir === "horz") // north or south pane - CSS.height = cssH($P, size); - else if (dir === "vert") // east or west pane - CSS.width = cssW($P, size); - //else if (isCenter) {} - - $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes - if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback - - // if manually adding a pane AFTER layout initialization, then... - if (state.initialized) { - initHandles( pane ); - initHotkeys( pane ); - } - - // close or hide the pane if specified in settings - if (o.initClosed && o.closable && !o.initHidden) - close(pane, true, true); // true, true = force, noAnimation - else if (o.initHidden || o.initClosed) - hide(pane); // will be completely invisible - no resizer or spacing - else if (!s.noRoom) - // make the pane visible - in case was initially hidden - $P.css("display","block"); - // ELSE setAsOpen() - called later by initHandles() - - // RESET visibility now - pane will appear IF display:block - $P.css("visibility","visible"); - - // check option for auto-handling of pop-ups & drop-downs - if (o.showOverflowOnHover) - $P.hover( allowOverflow, resetOverflow ); - - // if manually adding a pane AFTER layout initialization, then... - if (state.initialized) { - afterInitPane( pane ); - } - } - -, afterInitPane = function (pane) { - var $P = $Ps[pane] - , s = state[pane] - , o = options[pane] - ; - if (!$P) return; - - // see if there is a directly-nested layout inside this pane - if ($P.data("layout")) - refreshChildren( pane, $P.data("layout") ); - - // process pane contents and callbacks, and init/resize child-layout if exists - if (s.isVisible) { // pane is OPEN - if (state.initialized) // this pane was added AFTER layout was created - resizeAll(); // will also sizeContent - else - sizeContent(pane); - - if (o.triggerEventsOnLoad) - _runCallbacks("onresize_end", pane); - else // automatic if onresize called, otherwise call it specifically - // resize child - IF inner-layout already exists (created before this layout) - resizeChildren(pane, true); // a previously existing childLayout - } - - // init childLayouts - even if pane is not visible - if (o.initChildren && o.children) - createChildren(pane); - } - - /** - * @param {string=} panes The pane(s) to process - */ -, setPanePosition = function (panes) { - panes = panes ? panes.split(",") : _c.borderPanes; - - // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV - $.each(panes, function (i, pane) { - var $P = $Ps[pane] - , $R = $Rs[pane] - , o = options[pane] - , s = state[pane] - , side = _c[pane].side - , CSS = {} - ; - if (!$P) return; // pane does not exist - skip - - // set css-position to account for container borders & padding - switch (pane) { - case "north": CSS.top = sC.inset.top; - CSS.left = sC.inset.left; - CSS.right = sC.inset.right; - break; - case "south": CSS.bottom = sC.inset.bottom; - CSS.left = sC.inset.left; - CSS.right = sC.inset.right; - break; - case "west": CSS.left = sC.inset.left; // top, bottom & height set by sizeMidPanes() - break; - case "east": CSS.right = sC.inset.right; // ditto - break; - case "center": // top, left, width & height set by sizeMidPanes() - } - // apply position - $P.css(CSS); - - // update resizer position - if ($R && s.isClosed) - $R.css(side, sC.inset[side]); - else if ($R && !s.isHidden) - $R.css(side, sC.inset[side] + getPaneSize(pane)); - }); - } - - /** - * Initialize module objects, styling, size and position for all resize bars and toggler buttons - * - * @see _create() - * @param {string=} [panes=""] The edge(s) to process - */ -, initHandles = function (panes) { - panes = panes ? panes.split(",") : _c.borderPanes; - - // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV - $.each(panes, function (i, pane) { - var $P = $Ps[pane]; - $Rs[pane] = false; // INIT - $Ts[pane] = false; - if (!$P) return; // pane does not exist - skip - - var o = options[pane] - , s = state[pane] - , c = _c[pane] - , paneId = o.paneSelector.substr(0,1) === "#" ? o.paneSelector.substr(1) : "" - , rClass = o.resizerClass - , tClass = o.togglerClass - , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) - , _pane = "-"+ pane // used for classNames - , _state = (s.isVisible ? "-open" : "-closed") // used for classNames - , I = Instance[pane] - // INIT RESIZER BAR - , $R = I.resizer = $Rs[pane] = $("
      ") - // INIT TOGGLER BUTTON - , $T = I.toggler = (o.closable ? $Ts[pane] = $("
      ") : false) - ; - - //if (s.isVisible && o.resizable) ... handled by initResizable - if (!s.isVisible && o.slidable) - $R.attr("title", o.tips.Slide).css("cursor", o.sliderCursor); - - $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" - .attr("id", paneId ? paneId +"-resizer" : "" ) - .data({ - parentLayout: Instance - , layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - , layoutRole: "resizer" - }) - .css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal) - .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles - .addClass(rClass +" "+ rClass+_pane) - .hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead - .hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter - .appendTo($N) // append DIV to container - ; - if (o.resizerDblClickToggle) - $R.bind("dblclick."+ sID, toggle ); - - if ($T) { - $T // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" - .attr("id", paneId ? paneId +"-toggler" : "" ) - .data({ - parentLayout: Instance - , layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - , layoutRole: "toggler" - }) - .css(_c.togglers.cssReq) // add base/required styles - .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles - .addClass(tClass +" "+ tClass+_pane) - .hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead - .bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer - .appendTo($R) // append SPAN to resizer DIV - ; - // ADD INNER-SPANS TO TOGGLER - if (o.togglerContent_open) // ui-layout-open - $(""+ o.togglerContent_open +"") - .data({ - layoutEdge: pane - , layoutRole: "togglerContent" - }) - .data("layoutRole", "togglerContent") - .data("layoutEdge", pane) - .addClass("content content-open") - .css("display","none") - .appendTo( $T ) - //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead! - ; - if (o.togglerContent_closed) // ui-layout-closed - $(""+ o.togglerContent_closed +"") - .data({ - layoutEdge: pane - , layoutRole: "togglerContent" - }) - .addClass("content content-closed") - .css("display","none") - .appendTo( $T ) - //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead! - ; - // ADD TOGGLER.click/.hover - enableClosable(pane); - } - - // add Draggable events - initResizable(pane); - - // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" - if (s.isVisible) - setAsOpen(pane); // onOpen will be called, but NOT onResize - else { - setAsClosed(pane); // onClose will be called - bindStartSlidingEvents(pane, true); // will enable events IF option is set - } - - }); - - // SET ALL HANDLE DIMENSIONS - sizeHandles(); - } - - - /** - * Initialize scrolling ui-layout-content div - if exists - * - * @see initPane() - or externally after an Ajax injection - * @param {string} pane The pane to process - * @param {boolean=} [resize=true] Size content after init - */ -, initContent = function (pane, resize) { - if (!isInitialized()) return; - var - o = options[pane] - , sel = o.contentSelector - , I = Instance[pane] - , $P = $Ps[pane] - , $C - ; - if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent) - ? $P.find(sel).eq(0) // match 1-element only - : $P.children(sel).eq(0) - ; - if ($C && $C.length) { - $C.data("layoutRole", "content"); - // SAVE original Content CSS - if (!$C.data("layoutCSS")) - $C.data("layoutCSS", styles($C, "height")); - $C.css( _c.content.cssReq ); - if (o.applyDemoStyles) { - $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div - $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane - } - // ensure no vertical scrollbar on pane - will mess up measurements - if ($P.css("overflowX").match(/(scroll|auto)/)) { - $P.css("overflow", "hidden"); - } - state[pane].content = {}; // init content state - if (resize !== false) sizeContent(pane); - // sizeContent() is called AFTER init of all elements - } - else - I.content = $Cs[pane] = false; - } - - - /** - * Add resize-bars to all panes that specify it in options - * -dependancy: $.fn.resizable - will skip if not found - * - * @see _create() - * @param {string=} [panes=""] The edge(s) to process - */ -, initResizable = function (panes) { - var draggingAvailable = $.layout.plugins.draggable - , side // set in start() - ; - panes = panes ? panes.split(",") : _c.borderPanes; - - $.each(panes, function (idx, pane) { - var o = options[pane]; - if (!draggingAvailable || !$Ps[pane] || !o.resizable) { - o.resizable = false; - return true; // skip to next - } - - var s = state[pane] - , z = options.zIndexes - , c = _c[pane] - , side = c.dir=="horz" ? "top" : "left" - , $P = $Ps[pane] - , $R = $Rs[pane] - , base = o.resizerClass - , lastPos = 0 // used when live-resizing - , r, live // set in start because may change - // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process - , resizerClass = base+"-drag" // resizer-drag - , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag - // 'helper' class is applied to the CLONED resizer-bar while it is being dragged - , helperClass = base+"-dragging" // resizer-dragging - , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging - , helperLimitClass = base+"-dragging-limit" // resizer-drag - , helperPaneLimitClass = base+"-"+pane+"-dragging-limit" // resizer-north-drag - , helperClassesSet = false // logic var - ; - - if (!s.isClosed) - $R.attr("title", o.tips.Resize) - .css("cursor", o.resizerCursor); // n-resize, s-resize, etc - - $R.draggable({ - containment: $N[0] // limit resizing to layout container - , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis - , delay: 0 - , distance: 1 - , grid: o.resizingGrid - // basic format for helper - style it using class: .ui-draggable-dragging - , helper: "clone" - , opacity: o.resizerDragOpacity - , addClasses: false // avoid ui-state-disabled class when disabled - //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed - , zIndex: z.resizer_drag - - , start: function (e, ui) { - // REFRESH options & state pointers in case we used swapPanes - o = options[pane]; - s = state[pane]; - // re-read options - live = o.livePaneResizing; - - // ondrag_start callback - will CANCEL hide if returns false - // TODO: dragging CANNOT be cancelled like this, so see if there is a way? - if (false === _runCallbacks("ondrag_start", pane)) return false; - - s.isResizing = true; // prevent pane from closing while resizing - state.paneResizing = pane; // easy to see if ANY pane is resizing - timer.clear(pane+"_closeSlider"); // just in case already triggered - - // SET RESIZER LIMITS - used in drag() - setSizeLimits(pane); // update pane/resizer state - r = s.resizerPosition; - lastPos = ui.position[ side ] - - $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes - helperClassesSet = false; // reset logic var - see drag() - - // DISABLE TEXT SELECTION (probably already done by resizer.mouseOver) - $('body').disableSelection(); - - // MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS - showMasks( pane, { resizing: true }); - } - - , drag: function (e, ui) { - if (!helperClassesSet) { // can only add classes after clone has been added to the DOM - //$(".ui-draggable-dragging") - ui.helper - .addClass( helperClass +" "+ helperPaneClass ) // add helper classes - .css({ right: "auto", bottom: "auto" }) // fix dir="rtl" issue - .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar - ; - helperClassesSet = true; - // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! - if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding); - } - // CONTAIN RESIZER-BAR TO RESIZING LIMITS - var limit = 0; - if (ui.position[side] < r.min) { - ui.position[side] = r.min; - limit = -1; - } - else if (ui.position[side] > r.max) { - ui.position[side] = r.max; - limit = 1; - } - // ADD/REMOVE dragging-limit CLASS - if (limit) { - ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit - window.defaultStatus = (limit>0 && pane.match(/(north|west)/)) || (limit<0 && pane.match(/(south|east)/)) ? o.tips.maxSizeWarning : o.tips.minSizeWarning; - } - else { - ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit - window.defaultStatus = ""; - } - // DYNAMICALLY RESIZE PANES IF OPTION ENABLED - // won't trigger unless resizer has actually moved! - if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) { - lastPos = ui.position[side]; - resizePanes(e, ui, pane) - } - } - - , stop: function (e, ui) { - $('body').enableSelection(); // RE-ENABLE TEXT SELECTION - window.defaultStatus = ""; // clear 'resizing limit' message from statusbar - $R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer - s.isResizing = false; - state.paneResizing = false; // easy to see if ANY pane is resizing - resizePanes(e, ui, pane, true); // true = resizingDone - } - - }); - }); - - /** - * resizePanes - * - * Sub-routine called from stop() - and drag() if livePaneResizing - * - * @param {!Object} evt - * @param {!Object} ui - * @param {string} pane - * @param {boolean=} [resizingDone=false] - */ - var resizePanes = function (evt, ui, pane, resizingDone) { - var dragPos = ui.position - , c = _c[pane] - , o = options[pane] - , s = state[pane] - , resizerPos - ; - switch (pane) { - case "north": resizerPos = dragPos.top; break; - case "west": resizerPos = dragPos.left; break; - case "south": resizerPos = sC.layoutHeight - dragPos.top - o.spacing_open; break; - case "east": resizerPos = sC.layoutWidth - dragPos.left - o.spacing_open; break; - }; - // remove container margin from resizer position to get the pane size - var newSize = resizerPos - sC.inset[c.side]; - - // Disable OR Resize Mask(s) created in drag.start - if (!resizingDone) { - // ensure we meet liveResizingTolerance criteria - if (Math.abs(newSize - s.size) < o.liveResizingTolerance) - return; // SKIP resize this time - // resize the pane - manualSizePane(pane, newSize, false, true); // true = noAnimation - sizeMasks(); // resize all visible masks - } - else { // resizingDone - // ondrag_end callback - if (false !== _runCallbacks("ondrag_end", pane)) - manualSizePane(pane, newSize, false, true); // true = noAnimation - hideMasks(true); // true = force hiding all masks even if one is 'sliding' - if (s.isSliding) // RE-SHOW 'object-masks' so objects won't show through sliding pane - showMasks( pane, { resizing: true }); - } - }; - } - - /** - * sizeMask - * - * Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane - * Called when mask created, and during livePaneResizing - */ -, sizeMask = function () { - var $M = $(this) - , pane = $M.data("layoutMask") // eg: "west" - , s = state[pane] - ; - // only masks over an IFRAME-pane need manual resizing - if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes - $M.css({ - top: s.offsetTop - , left: s.offsetLeft - , width: s.outerWidth - , height: s.outerHeight - }); - /* ALT Method... - var $P = $Ps[pane]; - $M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight }); - */ - } -, sizeMasks = function () { - $Ms.each( sizeMask ); // resize all 'visible' masks - } - - /** - * @param {string} pane The pane being resized, animated or isSliding - * @param {Object=} [args] (optional) Options: which masks to apply, and to which panes - */ -, showMasks = function (pane, args) { - var c = _c[pane] - , panes = ["center"] - , z = options.zIndexes - , a = $.extend({ - objectsOnly: false - , animation: false - , resizing: true - , sliding: state[pane].isSliding - }, args ) - , o, s - ; - if (a.resizing) - panes.push( pane ); - if (a.sliding) - panes.push( _c.oppositeEdge[pane] ); // ADD the oppositeEdge-pane - - if (c.dir === "horz") { - panes.push("west"); - panes.push("east"); - } - - $.each(panes, function(i,p){ - s = state[p]; - o = options[p]; - if (s.isVisible && ( o.maskObjects || (!a.objectsOnly && o.maskContents) )) { - getMasks(p).each(function(){ - sizeMask.call(this); - this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1 - this.style.display = "block"; - }); - } - }); - } - - /** - * @param {boolean=} force Hide masks even if a pane is sliding - */ -, hideMasks = function (force) { - // ensure no pane is resizing - could be a timing issue - if (force || !state.paneResizing) { - $Ms.hide(); // hide ALL masks - } - // if ANY pane is sliding, then DO NOT remove masks from panes with maskObjects enabled - else if (!force && !$.isEmptyObject( state.panesSliding )) { - var i = $Ms.length - 1 - , p, $M; - for (; i >= 0; i--) { - $M = $Ms.eq(i); - p = $M.data("layoutMask"); - if (!options[p].maskObjects) { - $M.hide(); - } - } - } - } - - /** - * @param {string} pane - */ -, getMasks = function (pane) { - var $Masks = $([]) - , $M, i = 0, c = $Ms.length - ; - for (; i CSS - if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET CSS - $N.css( $N.data(css) ).removeData(css); - - // trigger plugins for this layout, if there are any - runPluginCallbacks( Instance, $.layout.onDestroy ); - - // trigger state-management and onunload callback - unload(); - - // clear the Instance of everything except for container & options (so could recreate) - // RE-CREATE: myLayout = myLayout.container.layout( myLayout.options ); - for (var n in Instance) - if (!n.match(/^(container|options)$/)) delete Instance[ n ]; - // add a 'destroyed' flag to make it easy to check - Instance.destroyed = true; - - // if this is a child layout, CLEAR the child-pointer in the parent - /* for now the pointer REMAINS, but with only container, options and destroyed keys - if (parentPane) { - var layout = parentPane.pane.data("parentLayout") - , key = layout.options.instanceKey || 'error'; - // THIS SYNTAX MAY BE WRONG! - parentPane.children[key] = layout.children[ parentPane.name ].children[key] = null; - } - */ - - return Instance; // for coding convenience - } - - /** - * Remove a pane from the layout - subroutine of destroy() - * - * @see destroy() - * @param {(string|Object)} evt_or_pane The pane to process - * @param {boolean=} [remove=false] Remove the DOM element? - * @param {boolean=} [skipResize=false] Skip calling resizeAll()? - * @param {boolean=} [destroyChild=true] Destroy Child-layouts? If not passed, obeys options setting - */ -, removePane = function (evt_or_pane, remove, skipResize, destroyChild) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $P = $Ps[pane] - , $C = $Cs[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - ; - // NOTE: elements can still exist even after remove() - // so check for missing data(), which is cleared by removed() - if ($P && $.isEmptyObject( $P.data() )) $P = false; - if ($C && $.isEmptyObject( $C.data() )) $C = false; - if ($R && $.isEmptyObject( $R.data() )) $R = false; - if ($T && $.isEmptyObject( $T.data() )) $T = false; - - if ($P) $P.stop(true, true); - - var o = options[pane] - , s = state[pane] - , d = "layout" - , css = "layoutCSS" - , pC = children[pane] - , hasChildren = $.isPlainObject( pC ) && !$.isEmptyObject( pC ) - , destroy = destroyChild !== undefined ? destroyChild : o.destroyChildren - ; - // FIRST destroy the child-layout(s) - if (hasChildren && destroy) { - $.each( pC, function (key, child) { - if (!child.destroyed) - child.destroy(true);// tell child-layout to destroy ALL its child-layouts too - if (child.destroyed) // destroy was successful - delete pC[key]; - }); - // if no more children, remove the children hash - if ($.isEmptyObject( pC )) { - pC = children[pane] = null; // clear children hash - hasChildren = false; - } - } - - // Note: can't 'remove' a pane element with non-destroyed children - if ($P && remove && !hasChildren) - $P.remove(); // remove the pane-element and everything inside it - else if ($P && $P[0]) { - // create list of ALL pane-classes that need to be removed - var root = o.paneClass // default="ui-layout-pane" - , pRoot = root +"-"+ pane // eg: "ui-layout-pane-west" - , _open = "-open" - , _sliding= "-sliding" - , _closed = "-closed" - , classes = [ root, root+_open, root+_closed, root+_sliding, // generic classes - pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ] // pane-specific classes - ; - $.merge(classes, getHoverClasses($P, true)); // ADD hover-classes - // remove all Layout classes from pane-element - $P .removeClass( classes.join(" ") ) // remove ALL pane-classes - .removeData("parentLayout") - .removeData("layoutPane") - .removeData("layoutRole") - .removeData("layoutEdge") - .removeData("autoHidden") // in case set - .unbind("."+ sID) // remove ALL Layout events - // TODO: remove these extra unbind commands when jQuery is fixed - //.unbind("mouseenter"+ sID) - //.unbind("mouseleave"+ sID) - ; - // do NOT reset CSS if this pane/content is STILL the container of a nested layout! - // the nested layout will reset its 'container' CSS when/if it is destroyed - if (hasChildren && $C) { - // a content-div may not have a specific width, so give it one to contain the Layout - $C.width( $C.width() ); - $.each( pC, function (key, child) { - child.resizeAll(); // resize the Layout - }); - } - else if ($C) - $C.css( $C.data(css) ).removeData(css).removeData("layoutRole"); - // remove pane AFTER content in case there was a nested layout - if (!$P.data(d)) - $P.css( $P.data(css) ).removeData(css); - } - - // REMOVE pane resizer and toggler elements - if ($T) $T.remove(); - if ($R) $R.remove(); - - // CLEAR all pointers and state data - Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = false; - s = { removed: true }; - - if (!skipResize) - resizeAll(); - } - - -/* - * ########################### - * ACTION METHODS - * ########################### - */ - - /** - * @param {string} pane - */ -, _hidePane = function (pane) { - var $P = $Ps[pane] - , o = options[pane] - , s = $P[0].style - ; - if (o.useOffscreenClose) { - if (!$P.data(_c.offscreenReset)) - $P.data(_c.offscreenReset, { left: s.left, right: s.right }); - $P.css( _c.offscreenCSS ); - } - else - $P.hide().removeData(_c.offscreenReset); - } - - /** - * @param {string} pane - */ -, _showPane = function (pane) { - var $P = $Ps[pane] - , o = options[pane] - , off = _c.offscreenCSS - , old = $P.data(_c.offscreenReset) - , s = $P[0].style - ; - $P .show() // ALWAYS show, just in case - .removeData(_c.offscreenReset); - if (o.useOffscreenClose && old) { - if (s.left == off.left) - s.left = old.left; - if (s.right == off.right) - s.right = old.right; - } - } - - - /** - * Completely 'hides' a pane, including its spacing - as if it does not exist - * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it - * - * @param {(string|Object)} evt_or_pane The pane being hidden, ie: north, south, east, or west - * @param {boolean=} [noAnimation=false] - */ -, hide = function (evt_or_pane, noAnimation) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - ; - if (!$P || s.isHidden) return; // pane does not exist OR is already hidden - - // onhide_start callback - will CANCEL hide if returns false - if (state.initialized && false === _runCallbacks("onhide_start", pane)) return; - - s.isSliding = false; // just in case - delete state.panesSliding[pane]; - - // now hide the elements - if ($R) $R.hide(); // hide resizer-bar - if (!state.initialized || s.isClosed) { - s.isClosed = true; // to trigger open-animation on show() - s.isHidden = true; - s.isVisible = false; - if (!state.initialized) - _hidePane(pane); // no animation when loading page - sizeMidPanes(_c[pane].dir === "horz" ? "" : "center"); - if (state.initialized || o.triggerEventsOnLoad) - _runCallbacks("onhide_end", pane); - } - else { - s.isHiding = true; // used by onclose - close(pane, false, noAnimation); // adjust all panes to fit - } - } - - /** - * Show a hidden pane - show as 'closed' by default unless openPane = true - * - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - * @param {boolean=} [openPane=false] - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [noAlert=false] - */ -, show = function (evt_or_pane, openPane, noAnimation, noAlert) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - ; - if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden - - // onshow_start callback - will CANCEL show if returns false - if (false === _runCallbacks("onshow_start", pane)) return; - - s.isShowing = true; // used by onopen/onclose - //s.isHidden = false; - will be set by open/close - if not cancelled - s.isSliding = false; // just in case - delete state.panesSliding[pane]; - - // now show the elements - //if ($R) $R.show(); - will be shown by open/close - if (openPane === false) - close(pane, true); // true = force - else - open(pane, false, noAnimation, noAlert); // adjust all panes to fit - } - - - /** - * Toggles a pane open/closed by calling either open or close - * - * @param {(string|Object)} evt_or_pane The pane being toggled, ie: north, south, east, or west - * @param {boolean=} [slide=false] - */ -, toggle = function (evt_or_pane, slide) { - if (!isInitialized()) return; - var evt = evtObj(evt_or_pane) - , pane = evtPane.call(this, evt_or_pane) - , s = state[pane] - ; - if (evt) // called from to $R.dblclick OR triggerPaneEvent - evt.stopImmediatePropagation(); - if (s.isHidden) - show(pane); // will call 'open' after unhiding it - else if (s.isClosed) - open(pane, !!slide); - else - close(pane); - } - - - /** - * Utility method used during init or other auto-processes - * - * @param {string} pane The pane being closed - * @param {boolean=} [setHandles=false] - */ -, _closePane = function (pane, setHandles) { - var - $P = $Ps[pane] - , s = state[pane] - ; - _hidePane(pane); - s.isClosed = true; - s.isVisible = false; - if (setHandles) setAsClosed(pane); - } - - /** - * Close the specified pane (animation optional), and resize all other panes as needed - * - * @param {(string|Object)} evt_or_pane The pane being closed, ie: north, south, east, or west - * @param {boolean=} [force=false] - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [skipCallback=false] - */ -, close = function (evt_or_pane, force, noAnimation, skipCallback) { - var pane = evtPane.call(this, evt_or_pane); - // if pane has been initialized, but NOT the complete layout, close pane instantly - if (!state.initialized && $Ps[pane]) { - _closePane(pane, true); // INIT pane as closed - return; - } - if (!isInitialized()) return; - - var - $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , c = _c[pane] - , doFX, isShowing, isHiding, wasSliding; - - // QUEUE in case another action/animation is in progress - $N.queue(function( queueNext ){ - - if ( !$P - || (!o.closable && !s.isShowing && !s.isHiding) // invalid request // (!o.resizable && !o.closable) ??? - || (!force && s.isClosed && !s.isShowing) // already closed - ) return queueNext(); - - // onclose_start callback - will CANCEL hide if returns false - // SKIP if just 'showing' a hidden pane as 'closed' - var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane); - - // transfer logic vars to temp vars - isShowing = s.isShowing; - isHiding = s.isHiding; - wasSliding = s.isSliding; - // now clear the logic vars (REQUIRED before aborting) - delete s.isShowing; - delete s.isHiding; - - if (abort) return queueNext(); - - doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none"); - s.isMoving = true; - s.isClosed = true; - s.isVisible = false; - // update isHidden BEFORE sizing panes - if (isHiding) s.isHidden = true; - else if (isShowing) s.isHidden = false; - - if (s.isSliding) // pane is being closed, so UNBIND trigger events - bindStopSlidingEvents(pane, false); // will set isSliding=false - else // resize panes adjacent to this one - sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback - - // if this pane has a resizer bar, move it NOW - before animation - setAsClosed(pane); - - // CLOSE THE PANE - if (doFX) { // animate the close - lockPaneForFX(pane, true); // need to set left/top so animation will work - $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { - lockPaneForFX(pane, false); // undo - if (s.isClosed) close_2(); - queueNext(); - }); - } - else { // hide the pane without animation - _hidePane(pane); - close_2(); - queueNext(); - }; - }); - - // SUBROUTINE - function close_2 () { - s.isMoving = false; - bindStartSlidingEvents(pane, true); // will enable if o.slidable = true - - // if opposite-pane was autoClosed, see if it can be autoOpened now - var altPane = _c.oppositeEdge[pane]; - if (state[ altPane ].noRoom) { - setSizeLimits( altPane ); - makePaneFit( altPane ); - } - - if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { - // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' - if (!isShowing) _runCallbacks("onclose_end", pane); - // onhide OR onshow callback - if (isShowing) _runCallbacks("onshow_end", pane); - if (isHiding) _runCallbacks("onhide_end", pane); - } - } - } - - /** - * @param {string} pane The pane just closed, ie: north, south, east, or west - */ -, setAsClosed = function (pane) { - if (!$Rs[pane]) return; // handles not initialized yet! - var - $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , side = _c[pane].side - , rClass = o.resizerClass - , tClass = o.togglerClass - , _pane = "-"+ pane // used for classNames - , _open = "-open" - , _sliding= "-sliding" - , _closed = "-closed" - ; - $R - .css(side, sC.inset[side]) // move the resizer - .removeClass( rClass+_open +" "+ rClass+_pane+_open ) - .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) - .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) - ; - // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvents? - if (o.resizable && $.layout.plugins.draggable) - $R - .draggable("disable") - .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here - .css("cursor", "default") - .attr("title","") - ; - - // if pane has a toggler button, adjust that too - if ($T) { - $T - .removeClass( tClass+_open +" "+ tClass+_pane+_open ) - .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) - .attr("title", o.tips.Open) // may be blank - ; - // toggler-content - if exists - $T.children(".content-open").hide(); - $T.children(".content-closed").css("display","block"); - } - - // sync any 'pin buttons' - syncPinBtns(pane, false); - - if (state.initialized) { - // resize 'length' and position togglers for adjacent panes - sizeHandles(); - } - } - - /** - * Open the specified pane (animation optional), and resize all other panes as needed - * - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - * @param {boolean=} [slide=false] - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [noAlert=false] - */ -, open = function (evt_or_pane, slide, noAnimation, noAlert) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , c = _c[pane] - , doFX, isShowing - ; - // QUEUE in case another action/animation is in progress - $N.queue(function( queueNext ){ - - if ( !$P - || (!o.resizable && !o.closable && !s.isShowing) // invalid request - || (s.isVisible && !s.isSliding) // already open - ) return queueNext(); - - // pane can ALSO be unhidden by just calling show(), so handle this scenario - if (s.isHidden && !s.isShowing) { - queueNext(); // call before show() because it needs the queue free - show(pane, true); - return; - } - - if (s.autoResize && s.size != o.size) // resize pane to original size set in options - sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize - else - // make sure there is enough space available to open the pane - setSizeLimits(pane, slide); - - // onopen_start callback - will CANCEL open if returns false - var cbReturn = _runCallbacks("onopen_start", pane); - - if (cbReturn === "abort") - return queueNext(); - - // update pane-state again in case options were changed in onopen_start - if (cbReturn !== "NC") // NC = "No Callback" - setSizeLimits(pane, slide); - - if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! - syncPinBtns(pane, false); // make sure pin-buttons are reset - if (!noAlert && o.tips.noRoomToOpen) - alert(o.tips.noRoomToOpen); - return queueNext(); // ABORT - } - - if (slide) // START Sliding - will set isSliding=true - bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane - else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead - bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false - else if (o.slidable) - bindStartSlidingEvents(pane, false); // UNBIND trigger events - - s.noRoom = false; // will be reset by makePaneFit if 'noRoom' - makePaneFit(pane); - - // transfer logic var to temp var - isShowing = s.isShowing; - // now clear the logic var - delete s.isShowing; - - doFX = !noAnimation && s.isClosed && (o.fxName_open != "none"); - s.isMoving = true; - s.isVisible = true; - s.isClosed = false; - // update isHidden BEFORE sizing panes - WHY??? Old? - if (isShowing) s.isHidden = false; - - if (doFX) { // ANIMATE - // mask adjacent panes with objects - lockPaneForFX(pane, true); // need to set left/top so animation will work - $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { - lockPaneForFX(pane, false); // undo - if (s.isVisible) open_2(); // continue - queueNext(); - }); - } - else { // no animation - _showPane(pane);// just show pane and... - open_2(); // continue - queueNext(); - }; - }); - - // SUBROUTINE - function open_2 () { - s.isMoving = false; - - // cure iframe display issues - _fixIframe(pane); - - // NOTE: if isSliding, then other panes are NOT 'resized' - if (!s.isSliding) { // resize all panes adjacent to this one - sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback - } - - // set classes, position handles and execute callbacks... - setAsOpen(pane); - }; - - } - - /** - * @param {string} pane The pane just opened, ie: north, south, east, or west - * @param {boolean=} [skipCallback=false] - */ -, setAsOpen = function (pane, skipCallback) { - var - $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , o = options[pane] - , s = state[pane] - , side = _c[pane].side - , rClass = o.resizerClass - , tClass = o.togglerClass - , _pane = "-"+ pane // used for classNames - , _open = "-open" - , _closed = "-closed" - , _sliding= "-sliding" - ; - $R - .css(side, sC.inset[side] + getPaneSize(pane)) // move the resizer - .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) - .addClass( rClass+_open +" "+ rClass+_pane+_open ) - ; - if (s.isSliding) - $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) - else // in case 'was sliding' - $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) - - removeHover( 0, $R ); // remove hover classes - if (o.resizable && $.layout.plugins.draggable) - $R .draggable("enable") - .css("cursor", o.resizerCursor) - .attr("title", o.tips.Resize); - else if (!s.isSliding) - $R.css("cursor", "default"); // n-resize, s-resize, etc - - // if pane also has a toggler button, adjust that too - if ($T) { - $T .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) - .addClass( tClass+_open +" "+ tClass+_pane+_open ) - .attr("title", o.tips.Close); // may be blank - removeHover( 0, $T ); // remove hover classes - // toggler-content - if exists - $T.children(".content-closed").hide(); - $T.children(".content-open").css("display","block"); - } - - // sync any 'pin buttons' - syncPinBtns(pane, !s.isSliding); - - // update pane-state dimensions - BEFORE resizing content - $.extend(s, elDims($P)); - - if (state.initialized) { - // resize resizer & toggler sizes for all panes - sizeHandles(); - // resize content every time pane opens - to be sure - sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving' - } - - if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { - // onopen callback - _runCallbacks("onopen_end", pane); - // onshow callback - TODO: should this be here? - if (s.isShowing) _runCallbacks("onshow_end", pane); - - // ALSO call onresize because layout-size *may* have changed while pane was closed - if (state.initialized) - _runCallbacks("onresize_end", pane); - } - - // TODO: Somehow sizePane("north") is being called after this point??? - } - - - /** - * slideOpen / slideClose / slideToggle - * - * Pass-though methods for sliding - */ -, slideOpen = function (evt_or_pane) { - if (!isInitialized()) return; - var evt = evtObj(evt_or_pane) - , pane = evtPane.call(this, evt_or_pane) - , s = state[pane] - , delay = options[pane].slideDelay_open - ; - // prevent event from triggering on NEW resizer binding created below - if (evt) evt.stopImmediatePropagation(); - - if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0) - // trigger = mouseenter - use a delay - timer.set(pane+"_openSlider", open_NOW, delay); - else - open_NOW(); // will unbind events if is already open - - /** - * SUBROUTINE for timed open - */ - function open_NOW () { - if (!s.isClosed) // skip if no longer closed! - bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane - else if (!s.isMoving) - open(pane, true); // true = slide - open() will handle binding - }; - } - -, slideClose = function (evt_or_pane) { - if (!isInitialized()) return; - var evt = evtObj(evt_or_pane) - , pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - , delay = s.isMoving ? 1000 : 300 // MINIMUM delay - option may override - ; - if (s.isClosed || s.isResizing) - return; // skip if already closed OR in process of resizing - else if (o.slideTrigger_close === "click") - close_NOW(); // close immediately onClick - else if (o.preventQuickSlideClose && s.isMoving) - return; // handle Chrome quick-close on slide-open - else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane])) - return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE - else if (evt) // trigger = mouseleave - use a delay - // 1 sec delay if 'opening', else .3 sec - timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay)); - else // called programically - close_NOW(); - - /** - * SUBROUTINE for timed close - */ - function close_NOW () { - if (s.isClosed) // skip 'close' if already closed! - bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here? - else if (!s.isMoving) - close(pane); // close will handle unbinding - }; - } - - /** - * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west - */ -, slideToggle = function (evt_or_pane) { - var pane = evtPane.call(this, evt_or_pane); - toggle(pane, true); - } - - - /** - * Must set left/top on East/South panes so animation will work properly - * - * @param {string} pane The pane to lock, 'east' or 'south' - any other is ignored! - * @param {boolean} doLock true = set left/top, false = remove - */ -, lockPaneForFX = function (pane, doLock) { - var $P = $Ps[pane] - , s = state[pane] - , o = options[pane] - , z = options.zIndexes - ; - if (doLock) { - showMasks( pane, { animation: true, objectsOnly: true }); - $P.css({ zIndex: z.pane_animate }); // overlay all elements during animation - if (pane=="south") - $P.css({ top: sC.inset.top + sC.innerHeight - $P.outerHeight() }); - else if (pane=="east") - $P.css({ left: sC.inset.left + sC.innerWidth - $P.outerWidth() }); - } - else { // animation DONE - RESET CSS - hideMasks(); - $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); - if (pane=="south") - $P.css({ top: "auto" }); - // if pane is positioned 'off-screen', then DO NOT screw with it! - else if (pane=="east" && !$P.css("left").match(/\-99999/)) - $P.css({ left: "auto" }); - // fix anti-aliasing in IE - only needed for animations that change opacity - if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) - $P[0].style.removeAttribute('filter'); - } - } - - - /** - * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger - * - * @see open(), close() - * @param {string} pane The pane to enable/disable, 'north', 'south', etc. - * @param {boolean} enable Enable or Disable sliding? - */ -, bindStartSlidingEvents = function (pane, enable) { - var o = options[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , evtName = o.slideTrigger_open.toLowerCase() - ; - if (!$R || (enable && !o.slidable)) return; - - // make sure we have a valid event - if (evtName.match(/mouseover/)) - evtName = o.slideTrigger_open = "mouseenter"; - else if (!evtName.match(/(click|dblclick|mouseenter)/)) - evtName = o.slideTrigger_open = "click"; - - // must remove double-click-toggle when using dblclick-slide - if (o.resizerDblClickToggle && evtName.match(/click/)) { - $R[enable ? "unbind" : "bind"]('dblclick.'+ sID, toggle) - } - - $R - // add or remove event - [enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen) - // set the appropriate cursor & title/tip - .css("cursor", enable ? o.sliderCursor : "default") - .attr("title", enable ? o.tips.Slide : "") - ; - } - - /** - * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed - * Also increases zIndex when pane is sliding open - * See bindStartSlidingEvents for code to control 'slide open' - * - * @see slideOpen(), slideClose() - * @param {string} pane The pane to process, 'north', 'south', etc. - * @param {boolean} enable Enable or Disable events? - */ -, bindStopSlidingEvents = function (pane, enable) { - var o = options[pane] - , s = state[pane] - , c = _c[pane] - , z = options.zIndexes - , evtName = o.slideTrigger_close.toLowerCase() - , action = (enable ? "bind" : "unbind") - , $P = $Ps[pane] - , $R = $Rs[pane] - ; - timer.clear(pane+"_closeSlider"); // just in case - - if (enable) { - s.isSliding = true; - state.panesSliding[pane] = true; - // remove 'slideOpen' event from resizer - // ALSO will raise the zIndex of the pane & resizer - bindStartSlidingEvents(pane, false); - } - else { - s.isSliding = false; - delete state.panesSliding[pane]; - } - - // RE/SET zIndex - increases when pane is sliding-open, resets to normal when not - $P.css("zIndex", enable ? z.pane_sliding : z.pane_normal); - $R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1 - - // make sure we have a valid event - if (!evtName.match(/(click|mouseleave)/)) - evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout' - - // add/remove slide triggers - $R[action](evtName, slideClose); // base event on resize - // need extra events for mouseleave - if (evtName === "mouseleave") { - // also close on pane.mouseleave - $P[action]("mouseleave."+ sID, slideClose); - // cancel timer when mouse moves between 'pane' and 'resizer' - $R[action]("mouseenter."+ sID, cancelMouseOut); - $P[action]("mouseenter."+ sID, cancelMouseOut); - } - - if (!enable) - timer.clear(pane+"_closeSlider"); - else if (evtName === "click" && !o.resizable) { - // IF pane is not resizable (which already has a cursor and tip) - // then set the a cursor & title/tip on resizer when sliding - $R.css("cursor", enable ? o.sliderCursor : "default"); - $R.attr("title", enable ? o.tips.Close : ""); // use Toggler-tip, eg: "Close Pane" - } - - // SUBROUTINE for mouseleave timer clearing - function cancelMouseOut (evt) { - timer.clear(pane+"_closeSlider"); - evt.stopPropagation(); - } - } - - - /** - * Hides/closes a pane if there is insufficient room - reverses this when there is room again - * MUST have already called setSizeLimits() before calling this method - * - * @param {string} pane The pane being resized - * @param {boolean=} [isOpening=false] Called from onOpen? - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [force=false] - */ -, makePaneFit = function (pane, isOpening, skipCallback, force) { - var o = options[pane] - , s = state[pane] - , c = _c[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , isSidePane = c.dir==="vert" - , hasRoom = false - ; - // special handling for center & east/west panes - if (pane === "center" || (isSidePane && s.noVerticalRoom)) { - // see if there is enough room to display the pane - // ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); - hasRoom = (s.maxHeight >= 0); - if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now - _showPane(pane); - if ($R) $R.show(); - s.isVisible = true; - s.noRoom = false; - if (isSidePane) s.noVerticalRoom = false; - _fixIframe(pane); - } - else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now - _hidePane(pane); - if ($R) $R.hide(); - s.isVisible = false; - s.noRoom = true; - } - } - - // see if there is enough room to fit the border-pane - if (pane === "center") { - // ignore center in this block - } - else if (s.minSize <= s.maxSize) { // pane CAN fit - hasRoom = true; - if (s.size > s.maxSize) // pane is too big - shrink it - sizePane(pane, s.maxSize, skipCallback, true, force); // true = noAnimation - else if (s.size < s.minSize) // pane is too small - enlarge it - sizePane(pane, s.minSize, skipCallback, true, force); // true = noAnimation - // need s.isVisible because new pseudoClose method keeps pane visible, but off-screen - else if ($R && s.isVisible && $P.is(":visible")) { - // make sure resizer-bar is positioned correctly - // handles situation where nested layout was 'hidden' when initialized - var pos = s.size + sC.inset[c.side]; - if ($.layout.cssNum( $R, c.side ) != pos) $R.css( c.side, pos ); - } - - // if was previously hidden due to noRoom, then RESET because NOW there is room - if (s.noRoom) { - // s.noRoom state will be set by open or show - if (s.wasOpen && o.closable) { - if (o.autoReopen) - open(pane, false, true, true); // true = noAnimation, true = noAlert - else // leave the pane closed, so just update state - s.noRoom = false; - } - else - show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert - } - } - else { // !hasRoom - pane CANNOT fit - if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... - s.noRoom = true; // update state - s.wasOpen = !s.isClosed && !s.isSliding; - if (s.isClosed){} // SKIP - else if (o.closable) // 'close' if possible - close(pane, true, true); // true = force, true = noAnimation - else // 'hide' pane if cannot just be closed - hide(pane, true); // true = noAnimation - } - } - } - - - /** - * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' - * - * @param {(string|Object)} evt_or_pane The pane being resized - * @param {number} size The *desired* new size for this pane - will be validated - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [force=false] Force resizing even if does not seem necessary - */ -, manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , o = options[pane] - , s = state[pane] - // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... - , forceResize = force || (o.livePaneResizing && !s.isResizing) - ; - // ANY call to manualSizePane disables autoResize - ie, percentage sizing - s.autoResize = false; - // flow-through... - sizePane(pane, size, skipCallback, noAnimation, forceResize); // will animate resize if option enabled - } - - /** - * sizePane is called only by internal methods whenever a pane needs to be resized - * - * @param {(string|Object)} evt_or_pane The pane being resized - * @param {number} size The *desired* new size for this pane - will be validated - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [noAnimation=false] - * @param {boolean=} [force=false] Force resizing even if does not seem necessary - */ -, sizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) // probably NEVER called from event? - , o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , side = _c[pane].side - , dimName = _c[pane].sizeType.toLowerCase() - , skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize - , doFX = noAnimation !== true && o.animatePaneSizing - , oldSize, newSize - ; - // QUEUE in case another action/animation is in progress - $N.queue(function( queueNext ){ - // calculate 'current' min/max sizes - setSizeLimits(pane); // update pane-state - oldSize = s.size; - size = _parseSize(pane, size); // handle percentages & auto - size = max(size, _parseSize(pane, o.minSize)); - size = min(size, s.maxSize); - if (size < s.minSize) { // not enough room for pane! - queueNext(); // call before makePaneFit() because it needs the queue free - makePaneFit(pane, false, skipCallback); // will hide or close pane - return; - } - - // IF newSize is same as oldSize, then nothing to do - abort - if (!force && size === oldSize) - return queueNext(); - - s.newSize = size; - - // onresize_start callback CANNOT cancel resizing because this would break the layout! - if (!skipCallback && state.initialized && s.isVisible) - _runCallbacks("onresize_start", pane); - - // resize the pane, and make sure its visible - newSize = cssSize(pane, size); - - if (doFX && $P.is(":visible")) { // ANIMATE - var fx = $.layout.effects.size[pane] || $.layout.effects.size.all - , easing = o.fxSettings_size.easing || fx.easing - , z = options.zIndexes - , props = {}; - props[ dimName ] = newSize +'px'; - s.isMoving = true; - // overlay all elements during animation - $P.css({ zIndex: z.pane_animate }) - .show().animate( props, o.fxSpeed_size, easing, function(){ - // reset zIndex after animation - $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); - s.isMoving = false; - delete s.newSize; - sizePane_2(); // continue - queueNext(); - }); - } - else { // no animation - $P.css( dimName, newSize ); // resize pane - delete s.newSize; - // if pane is visible, then - if ($P.is(":visible")) - sizePane_2(); // continue - else { - // pane is NOT VISIBLE, so just update state data... - // when pane is *next opened*, it will have the new size - s.size = size; // update state.size - $.extend(s, elDims($P)); // update state dimensions - } - queueNext(); - }; - - }); - - // SUBROUTINE - function sizePane_2 () { - /* Panes are sometimes not sized precisely in some browsers!? - * This code will resize the pane up to 3 times to nudge the pane to the correct size - */ - var actual = dimName==='width' ? $P.outerWidth() : $P.outerHeight() - , tries = [{ - pane: pane - , count: 1 - , target: size - , actual: actual - , correct: (size === actual) - , attempt: size - , cssSize: newSize - }] - , lastTry = tries[0] - , thisTry = {} - , msg = 'Inaccurate size after resizing the '+ pane +'-pane.' - ; - while ( !lastTry.correct ) { - thisTry = { pane: pane, count: lastTry.count+1, target: size }; - - if (lastTry.actual > size) - thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size)); - else // lastTry.actual < size - thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual)); - - thisTry.cssSize = cssSize(pane, thisTry.attempt); - $P.css( dimName, thisTry.cssSize ); - - thisTry.actual = dimName=='width' ? $P.outerWidth() : $P.outerHeight(); - thisTry.correct = (size === thisTry.actual); - - // log attempts and alert the user of this *non-fatal error* (if showDebugMessages) - if ( tries.length === 1) { - _log(msg, false, true); - _log(lastTry, false, true); - } - _log(thisTry, false, true); - // after 4 tries, is as close as its gonna get! - if (tries.length > 3) break; - - tries.push( thisTry ); - lastTry = tries[ tries.length - 1 ]; - } - // END TESTING CODE - - // update pane-state dimensions - s.size = size; - $.extend(s, elDims($P)); - - if (s.isVisible && $P.is(":visible")) { - // reposition the resizer-bar - if ($R) $R.css( side, size + sC.inset[side] ); - // resize the content-div - sizeContent(pane); - } - - if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) - _runCallbacks("onresize_end", pane); - - // resize all the adjacent panes, and adjust their toggler buttons - // when skipCallback passed, it means the controlling method will handle 'other panes' - if (!skipCallback) { - // also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize - if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force); - sizeHandles(); - } - - // if opposite-pane was autoClosed, see if it can be autoOpened now - var altPane = _c.oppositeEdge[pane]; - if (size < oldSize && state[ altPane ].noRoom) { - setSizeLimits( altPane ); - makePaneFit( altPane, false, skipCallback ); - } - - // DEBUG - ALERT user/developer so they know there was a sizing problem - if (tries.length > 1) - _log(msg +'\nSee the Error Console for details.', true, true); - } - } - - /** - * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide() - * @param {(Array.|string)} panes The pane(s) being resized, comma-delmited string - * @param {boolean=} [skipCallback=false] Should the onresize callback be run? - * @param {boolean=} [force=false] - */ -, sizeMidPanes = function (panes, skipCallback, force) { - panes = (panes ? panes : "east,west,center").split(","); - - $.each(panes, function (i, pane) { - if (!$Ps[pane]) return; // NO PANE - skip - var - o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , isCenter= (pane=="center") - , hasRoom = true - , CSS = {} - // if pane is not visible, show it invisibly NOW rather than for *each call* in this script - , visCSS = $.layout.showInvisibly($P) - - , newCenter = calcNewCenterPaneDims() - ; - - // update pane-state dimensions - $.extend(s, elDims($P)); - - if (pane === "center") { - if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight) { - $P.css(visCSS); - return true; // SKIP - pane already the correct size - } - // set state for makePaneFit() logic - $.extend(s, cssMinDims(pane), { - maxWidth: newCenter.width - , maxHeight: newCenter.height - }); - CSS = newCenter; - s.newWidth = CSS.width; - s.newHeight = CSS.height; - // convert OUTER width/height to CSS width/height - CSS.width = cssW($P, CSS.width); - // NEW - allow pane to extend 'below' visible area rather than hide it - CSS.height = cssH($P, CSS.height); - hasRoom = CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW - - // during layout init, try to shrink east/west panes to make room for center - if (!state.initialized && o.minWidth > newCenter.width) { - var - reqPx = o.minWidth - s.outerWidth - , minE = options.east.minSize || 0 - , minW = options.west.minSize || 0 - , sizeE = state.east.size - , sizeW = state.west.size - , newE = sizeE - , newW = sizeW - ; - if (reqPx > 0 && state.east.isVisible && sizeE > minE) { - newE = max( sizeE-minE, sizeE-reqPx ); - reqPx -= sizeE-newE; - } - if (reqPx > 0 && state.west.isVisible && sizeW > minW) { - newW = max( sizeW-minW, sizeW-reqPx ); - reqPx -= sizeW-newW; - } - // IF we found enough extra space, then resize the border panes as calculated - if (reqPx === 0) { - if (sizeE && sizeE != minE) - sizePane('east', newE, true, true, force); // true = skipCallback/noAnimation - initPanes will handle when done - if (sizeW && sizeW != minW) - sizePane('west', newW, true, true, force); // true = skipCallback/noAnimation - // now start over! - sizeMidPanes('center', skipCallback, force); - $P.css(visCSS); - return; // abort this loop - } - } - } - else { // for east and west, set only the height, which is same as center height - // set state.min/maxWidth/Height for makePaneFit() logic - if (s.isVisible && !s.noVerticalRoom) - $.extend(s, elDims($P), cssMinDims(pane)) - if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight) { - $P.css(visCSS); - return true; // SKIP - pane already the correct size - } - // east/west have same top, bottom & height as center - CSS.top = newCenter.top; - CSS.bottom = newCenter.bottom; - s.newSize = newCenter.height - // NEW - allow pane to extend 'below' visible area rather than hide it - CSS.height = cssH($P, newCenter.height); - s.maxHeight = CSS.height; - hasRoom = (s.maxHeight >= 0); // ALWAYS TRUE NOW - if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic - } - - if (hasRoom) { - // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized - if (!skipCallback && state.initialized) - _runCallbacks("onresize_start", pane); - - $P.css(CSS); // apply the CSS to pane - if (pane !== "center") - sizeHandles(pane); // also update resizer length - if (s.noRoom && !s.isClosed && !s.isHidden) - makePaneFit(pane); // will re-open/show auto-closed/hidden pane - if (s.isVisible) { - $.extend(s, elDims($P)); // update pane dimensions - if (state.initialized) sizeContent(pane); // also resize the contents, if exists - } - } - else if (!s.noRoom && s.isVisible) // no room for pane - makePaneFit(pane); // will hide or close pane - - // reset visibility, if necessary - $P.css(visCSS); - - delete s.newSize; - delete s.newWidth; - delete s.newHeight; - - if (!s.isVisible) - return true; // DONE - next pane - - /* - * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes - * Normally these panes have only 'left' & 'right' positions so pane auto-sizes - * ALSO required when pane is an IFRAME because will NOT default to 'full width' - * TODO: Can I use width:100% for a north/south iframe? - * TODO: Sounds like a job for $P.outerWidth( sC.innerWidth ) SETTER METHOD - */ - if (pane === "center") { // finished processing midPanes - var fix = browser.isIE6 || !browser.boxModel; - if ($Ps.north && (fix || state.north.tagName=="IFRAME")) - $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); - if ($Ps.south && (fix || state.south.tagName=="IFRAME")) - $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); - } - - // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized - if (!skipCallback && state.initialized) - _runCallbacks("onresize_end", pane); - }); - } - - - /** - * @see window.onresize(), callbacks or custom code - * @param {(Object|boolean)=} evt_or_refresh If 'true', then also reset pane-positioning - */ -, resizeAll = function (evt_or_refresh) { - var oldW = sC.innerWidth - , oldH = sC.innerHeight - ; - // stopPropagation if called by trigger("layoutdestroy") - use evtPane utility - evtPane(evt_or_refresh); - - // cannot size layout when 'container' is hidden or collapsed - if (!$N.is(":visible")) return; - - if (!state.initialized) { - _initLayoutElements(); - return; // no need to resize since we just initialized! - } - - if (evt_or_refresh === true && $.isPlainObject(options.outset)) { - // update container CSS in case outset option has changed - $N.css( options.outset ); - } - // UPDATE container dimensions - $.extend(sC, elDims( $N, options.inset )); - if (!sC.outerHeight) return; - - // if 'true' passed, refresh pane & handle positioning too - if (evt_or_refresh === true) { - setPanePosition(); - } - - // onresizeall_start will CANCEL resizing if returns false - // state.container has already been set, so user can access this info for calcuations - if (false === _runCallbacks("onresizeall_start")) return false; - - var // see if container is now 'smaller' than before - shrunkH = (sC.innerHeight < oldH) - , shrunkW = (sC.innerWidth < oldW) - , $P, o, s - ; - // NOTE special order for sizing: S-N-E-W - $.each(["south","north","east","west"], function (i, pane) { - if (!$Ps[pane]) return; // no pane - SKIP - o = options[pane]; - s = state[pane]; - if (s.autoResize && s.size != o.size) // resize pane to original size set in options - sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize - else { - setSizeLimits(pane); - makePaneFit(pane, false, true, true); // true=skipCallback/forceResize - } - }); - - sizeMidPanes("", true, true); // true=skipCallback/forceResize - sizeHandles(); // reposition the toggler elements - - // trigger all individual pane callbacks AFTER layout has finished resizing - $.each(_c.allPanes, function (i, pane) { - $P = $Ps[pane]; - if (!$P) return; // SKIP - if (state[pane].isVisible) // undefined for non-existent panes - _runCallbacks("onresize_end", pane); // callback - if exists - }); - - _runCallbacks("onresizeall_end"); - //_triggerLayoutEvent(pane, 'resizeall'); - } - - /** - * Whenever a pane resizes or opens that has a nested layout, trigger resizeAll - * - * @param {(string|Object)} evt_or_pane The pane just resized or opened - */ -, resizeChildren = function (evt_or_pane, skipRefresh) { - var pane = evtPane.call(this, evt_or_pane); - - if (!options[pane].resizeChildren) return; - - // ensure the pane-children are up-to-date - if (!skipRefresh) refreshChildren( pane ); - var pC = children[pane]; - if ($.isPlainObject( pC )) { - // resize one or more children - $.each( pC, function (key, child) { - if (!child.destroyed) child.resizeAll(); - }); - } - } - - /** - * IF pane has a content-div, then resize all elements inside pane to fit pane-height - * - * @param {(string|Object)} evt_or_panes The pane(s) being resized - * @param {boolean=} [remeasure=false] Should the content (header/footer) be remeasured? - */ -, sizeContent = function (evt_or_panes, remeasure) { - if (!isInitialized()) return; - - var panes = evtPane.call(this, evt_or_panes); - panes = panes ? panes.split(",") : _c.allPanes; - - $.each(panes, function (idx, pane) { - var - $P = $Ps[pane] - , $C = $Cs[pane] - , o = options[pane] - , s = state[pane] - , m = s.content // m = measurements - ; - if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip - - // if content-element was REMOVED, update OR remove the pointer - if (!$C.length) { - initContent(pane, false); // false = do NOT sizeContent() - already there! - if (!$C) return; // no replacement element found - pointer have been removed - } - - // onsizecontent_start will CANCEL resizing if returns false - if (false === _runCallbacks("onsizecontent_start", pane)) return; - - // skip re-measuring offsets if live-resizing - if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) { - _measure(); - // if any footers are below pane-bottom, they may not measure correctly, - // so allow pane overflow and re-measure - if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") { - $P.css("overflow", "visible"); - _measure(); // remeasure while overflowing - $P.css("overflow", "hidden"); - } - } - // NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders - var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom); - - if (!$C.is(":visible") || m.height != newH) { - // size the Content element to fit new pane-size - will autoHide if not enough room - setOuterHeight($C, newH, true); // true=autoHide - m.height = newH; // save new height - }; - - if (state.initialized) - _runCallbacks("onsizecontent_end", pane); - - function _below ($E) { - return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0)); - }; - - function _measure () { - var - ignore = options[pane].contentIgnoreSelector - , $Fs = $C.nextAll().not(".ui-layout-mask").not(ignore || ":lt(0)") // not :lt(0) = ALL - , $Fs_vis = $Fs.filter(':visible') - , $F = $Fs_vis.filter(':last') - ; - m = { - top: $C[0].offsetTop - , height: $C.outerHeight() - , numFooters: $Fs.length - , hiddenFooters: $Fs.length - $Fs_vis.length - , spaceBelow: 0 // correct if no content footer ($E) - } - m.spaceAbove = m.top; // just for state - not used in calc - m.bottom = m.top + m.height; - if ($F.length) - //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom) - m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F); - else // no footer - check marginBottom on Content element itself - m.spaceBelow = _below($C); - }; - }); - } - - - /** - * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary - * - * @see initHandles(), open(), close(), resizeAll() - * @param {(string|Object)=} evt_or_panes The pane(s) being resized - */ -, sizeHandles = function (evt_or_panes) { - var panes = evtPane.call(this, evt_or_panes) - panes = panes ? panes.split(",") : _c.borderPanes; - - $.each(panes, function (i, pane) { - var - o = options[pane] - , s = state[pane] - , $P = $Ps[pane] - , $R = $Rs[pane] - , $T = $Ts[pane] - , $TC - ; - if (!$P || !$R) return; - - var - dir = _c[pane].dir - , _state = (s.isClosed ? "_closed" : "_open") - , spacing = o["spacing"+ _state] - , togAlign = o["togglerAlign"+ _state] - , togLen = o["togglerLength"+ _state] - , paneLen - , left - , offset - , CSS = {} - ; - - if (spacing === 0) { - $R.hide(); - return; - } - else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason - $R.show(); // in case was previously hidden - - // Resizer Bar is ALWAYS same width/height of pane it is attached to - if (dir === "horz") { // north/south - //paneLen = $P.outerWidth(); // s.outerWidth || - paneLen = sC.innerWidth; // handle offscreen-panes - s.resizerLength = paneLen; - left = $.layout.cssNum($P, "left") - $R.css({ - width: cssW($R, paneLen) // account for borders & padding - , height: cssH($R, spacing) // ditto - , left: left > -9999 ? left : sC.inset.left // handle offscreen-panes - }); - } - else { // east/west - paneLen = $P.outerHeight(); // s.outerHeight || - s.resizerLength = paneLen; - $R.css({ - height: cssH($R, paneLen) // account for borders & padding - , width: cssW($R, spacing) // ditto - , top: sC.inset.top + getPaneSize("north", true) // TODO: what if no North pane? - //, top: $.layout.cssNum($Ps["center"], "top") - }); - } - - // remove hover classes - removeHover( o, $R ); - - if ($T) { - if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) { - $T.hide(); // always HIDE the toggler when 'sliding' - return; - } - else - $T.show(); // in case was previously hidden - - if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) { - togLen = paneLen; - offset = 0; - } - else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed - if (isStr(togAlign)) { - switch (togAlign) { - case "top": - case "left": offset = 0; - break; - case "bottom": - case "right": offset = paneLen - togLen; - break; - case "middle": - case "center": - default: offset = round((paneLen - togLen) / 2); // 'default' catches typos - } - } - else { // togAlign = number - var x = parseInt(togAlign, 10); // - if (togAlign >= 0) offset = x; - else offset = paneLen - togLen + x; // NOTE: x is negative! - } - } - - if (dir === "horz") { // north/south - var width = cssW($T, togLen); - $T.css({ - width: width // account for borders & padding - , height: cssH($T, spacing) // ditto - , left: offset // TODO: VERIFY that toggler positions correctly for ALL values - , top: 0 - }); - // CENTER the toggler content SPAN - $T.children(".content").each(function(){ - $TC = $(this); - $TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative - }); - } - else { // east/west - var height = cssH($T, togLen); - $T.css({ - height: height // account for borders & padding - , width: cssW($T, spacing) // ditto - , top: offset // POSITION the toggler - , left: 0 - }); - // CENTER the toggler content SPAN - $T.children(".content").each(function(){ - $TC = $(this); - $TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative - }); - } - - // remove ALL hover classes - removeHover( 0, $T ); - } - - // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now - if (!state.initialized && (o.initHidden || s.isHidden)) { - $R.hide(); - if ($T) $T.hide(); - } - }); - } - - - /** - * @param {(string|Object)} evt_or_pane - */ -, enableClosable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $T = $Ts[pane] - , o = options[pane] - ; - if (!$T) return; - o.closable = true; - $T .bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); }) - .css("visibility", "visible") - .css("cursor", "pointer") - .attr("title", state[pane].isClosed ? o.tips.Open : o.tips.Close) // may be blank - .show(); - } - /** - * @param {(string|Object)} evt_or_pane - * @param {boolean=} [hide=false] - */ -, disableClosable = function (evt_or_pane, hide) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $T = $Ts[pane] - ; - if (!$T) return; - options[pane].closable = false; - // is closable is disable, then pane MUST be open! - if (state[pane].isClosed) open(pane, false, true); - $T .unbind("."+ sID) - .css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues - .css("cursor", "default") - .attr("title", ""); - } - - - /** - * @param {(string|Object)} evt_or_pane - */ -, enableSlidable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - ; - if (!$R || !$R.data('draggable')) return; - options[pane].slidable = true; - if (state[pane].isClosed) - bindStartSlidingEvents(pane, true); - } - /** - * @param {(string|Object)} evt_or_pane - */ -, disableSlidable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - ; - if (!$R) return; - options[pane].slidable = false; - if (state[pane].isSliding) - close(pane, false, true); - else { - bindStartSlidingEvents(pane, false); - $R .css("cursor", "default") - .attr("title", ""); - removeHover(null, $R[0]); // in case currently hovered - } - } - - - /** - * @param {(string|Object)} evt_or_pane - */ -, enableResizable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - , o = options[pane] - ; - if (!$R || !$R.data('draggable')) return; - o.resizable = true; - $R.draggable("enable"); - if (!state[pane].isClosed) - $R .css("cursor", o.resizerCursor) - .attr("title", o.tips.Resize); - } - /** - * @param {(string|Object)} evt_or_pane - */ -, disableResizable = function (evt_or_pane) { - if (!isInitialized()) return; - var pane = evtPane.call(this, evt_or_pane) - , $R = $Rs[pane] - ; - if (!$R || !$R.data('draggable')) return; - options[pane].resizable = false; - $R .draggable("disable") - .css("cursor", "default") - .attr("title", ""); - removeHover(null, $R[0]); // in case currently hovered - } - - - /** - * Move a pane from source-side (eg, west) to target-side (eg, east) - * If pane exists on target-side, move that to source-side, ie, 'swap' the panes - * - * @param {(string|Object)} evt_or_pane1 The pane/edge being swapped - * @param {string} pane2 ditto - */ -, swapPanes = function (evt_or_pane1, pane2) { - if (!isInitialized()) return; - var pane1 = evtPane.call(this, evt_or_pane1); - // change state.edge NOW so callbacks can know where pane is headed... - state[pane1].edge = pane2; - state[pane2].edge = pane1; - // run these even if NOT state.initialized - if (false === _runCallbacks("onswap_start", pane1) - || false === _runCallbacks("onswap_start", pane2) - ) { - state[pane1].edge = pane1; // reset - state[pane2].edge = pane2; - return; - } - - var - oPane1 = copy( pane1 ) - , oPane2 = copy( pane2 ) - , sizes = {} - ; - sizes[pane1] = oPane1 ? oPane1.state.size : 0; - sizes[pane2] = oPane2 ? oPane2.state.size : 0; - - // clear pointers & state - $Ps[pane1] = false; - $Ps[pane2] = false; - state[pane1] = {}; - state[pane2] = {}; - - // ALWAYS remove the resizer & toggler elements - if ($Ts[pane1]) $Ts[pane1].remove(); - if ($Ts[pane2]) $Ts[pane2].remove(); - if ($Rs[pane1]) $Rs[pane1].remove(); - if ($Rs[pane2]) $Rs[pane2].remove(); - $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false; - - // transfer element pointers and data to NEW Layout keys - move( oPane1, pane2 ); - move( oPane2, pane1 ); - - // cleanup objects - oPane1 = oPane2 = sizes = null; - - // make panes 'visible' again - if ($Ps[pane1]) $Ps[pane1].css(_c.visible); - if ($Ps[pane2]) $Ps[pane2].css(_c.visible); - - // fix any size discrepancies caused by swap - resizeAll(); - - // run these even if NOT state.initialized - _runCallbacks("onswap_end", pane1); - _runCallbacks("onswap_end", pane2); - - return; - - function copy (n) { // n = pane - var - $P = $Ps[n] - , $C = $Cs[n] - ; - return !$P ? false : { - pane: n - , P: $P ? $P[0] : false - , C: $C ? $C[0] : false - , state: $.extend(true, {}, state[n]) - , options: $.extend(true, {}, options[n]) - } - }; - - function move (oPane, pane) { - if (!oPane) return; - var - P = oPane.P - , C = oPane.C - , oldPane = oPane.pane - , c = _c[pane] - // save pane-options that should be retained - , s = $.extend(true, {}, state[pane]) - , o = options[pane] - // RETAIN side-specific FX Settings - more below - , fx = { resizerCursor: o.resizerCursor } - , re, size, pos - ; - $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { - fx[k +"_open"] = o[k +"_open"]; - fx[k +"_close"] = o[k +"_close"]; - fx[k +"_size"] = o[k +"_size"]; - }); - - // update object pointers and attributes - $Ps[pane] = $(P) - .data({ - layoutPane: Instance[pane] // NEW pointer to pane-alias-object - , layoutEdge: pane - }) - .css(_c.hidden) - .css(c.cssReq) - ; - $Cs[pane] = C ? $(C) : false; - - // set options and state - options[pane] = $.extend(true, {}, oPane.options, fx); - state[pane] = $.extend(true, {}, oPane.state); - - // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west - re = new RegExp(o.paneClass +"-"+ oldPane, "g"); - P.className = P.className.replace(re, o.paneClass +"-"+ pane); - - // ALWAYS regenerate the resizer & toggler elements - initHandles(pane); // create the required resizer & toggler - - // if moving to different orientation, then keep 'target' pane size - if (c.dir != _c[oldPane].dir) { - size = sizes[pane] || 0; - setSizeLimits(pane); // update pane-state - size = max(size, state[pane].minSize); - // use manualSizePane to disable autoResize - not useful after panes are swapped - manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation - } - else // move the resizer here - $Rs[pane].css(c.side, sC.inset[c.side] + (state[pane].isVisible ? getPaneSize(pane) : 0)); - - - // ADD CLASSNAMES & SLIDE-BINDINGS - if (oPane.state.isVisible && !s.isVisible) - setAsOpen(pane, true); // true = skipCallback - else { - setAsClosed(pane); - bindStartSlidingEvents(pane, true); // will enable events IF option is set - } - - // DESTROY the object - oPane = null; - }; - } - - - /** - * INTERNAL method to sync pin-buttons when pane is opened or closed - * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes - * - * @see open(), setAsOpen(), setAsClosed() - * @param {string} pane These are the params returned to callbacks by layout() - * @param {boolean} doPin True means set the pin 'down', False means 'up' - */ -, syncPinBtns = function (pane, doPin) { - if ($.layout.plugins.buttons) - $.each(state[pane].pins, function (i, selector) { - $.layout.buttons.setPinState(Instance, $(selector), pane, doPin); - }); - } - -; // END var DECLARATIONS - - /** - * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed - * - * @see document.keydown() - */ - function keyDown (evt) { - if (!evt) return true; - var code = evt.keyCode; - if (code < 33) return true; // ignore special keys: ENTER, TAB, etc - - var - PANE = { - 38: "north" // Up Cursor - $.ui.keyCode.UP - , 40: "south" // Down Cursor - $.ui.keyCode.DOWN - , 37: "west" // Left Cursor - $.ui.keyCode.LEFT - , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT - } - , ALT = evt.altKey // no worky! - , SHIFT = evt.shiftKey - , CTRL = evt.ctrlKey - , CURSOR = (CTRL && code >= 37 && code <= 40) - , o, k, m, pane - ; - - if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey - pane = PANE[code]; - else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey - $.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey - o = options[p]; - k = o.customHotkey; - m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" - if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches - if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches - pane = p; - return false; // BREAK - } - } - }); - - // validate pane - if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) - return true; - - toggle(pane); - - evt.stopPropagation(); - evt.returnValue = false; // CANCEL key - return false; - }; - - -/* - * ###################################### - * UTILITY METHODS - * called externally or by initButtons - * ###################################### - */ - - /** - * Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work - * - * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event - */ - function allowOverflow (el) { - if (!isInitialized()) return; - if (this && this.tagName) el = this; // BOUND to element - var $P; - if (isStr(el)) - $P = $Ps[el]; - else if ($(el).data("layoutRole")) - $P = $(el); - else - $(el).parents().each(function(){ - if ($(this).data("layoutRole")) { - $P = $(this); - return false; // BREAK - } - }); - if (!$P || !$P.length) return; // INVALID - - var - pane = $P.data("layoutEdge") - , s = state[pane] - ; - - // if pane is already raised, then reset it before doing it again! - // this would happen if allowOverflow is attached to BOTH the pane and an element - if (s.cssSaved) - resetOverflow(pane); // reset previous CSS before continuing - - // if pane is raised by sliding or resizing, or its closed, then abort - if (s.isSliding || s.isResizing || s.isClosed) { - s.cssSaved = false; - return; - } - - var - newCSS = { zIndex: (options.zIndexes.resizer_normal + 1) } - , curCSS = {} - , of = $P.css("overflow") - , ofX = $P.css("overflowX") - , ofY = $P.css("overflowY") - ; - // determine which, if any, overflow settings need to be changed - if (of != "visible") { - curCSS.overflow = of; - newCSS.overflow = "visible"; - } - if (ofX && !ofX.match(/(visible|auto)/)) { - curCSS.overflowX = ofX; - newCSS.overflowX = "visible"; - } - if (ofY && !ofY.match(/(visible|auto)/)) { - curCSS.overflowY = ofX; - newCSS.overflowY = "visible"; - } - - // save the current overflow settings - even if blank! - s.cssSaved = curCSS; - - // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' - $P.css( newCSS ); - - // make sure the zIndex of all other panes is normal - $.each(_c.allPanes, function(i, p) { - if (p != pane) resetOverflow(p); - }); - - }; - /** - * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event - */ - function resetOverflow (el) { - if (!isInitialized()) return; - if (this && this.tagName) el = this; // BOUND to element - var $P; - if (isStr(el)) - $P = $Ps[el]; - else if ($(el).data("layoutRole")) - $P = $(el); - else - $(el).parents().each(function(){ - if ($(this).data("layoutRole")) { - $P = $(this); - return false; // BREAK - } - }); - if (!$P || !$P.length) return; // INVALID - - var - pane = $P.data("layoutEdge") - , s = state[pane] - , CSS = s.cssSaved || {} - ; - // reset the zIndex - if (!s.isSliding && !s.isResizing) - $P.css("zIndex", options.zIndexes.pane_normal); - - // reset Overflow - if necessary - $P.css( CSS ); - - // clear var - s.cssSaved = false; - }; - -/* - * ##################### - * CREATE/RETURN LAYOUT - * ##################### - */ - - // validate that container exists - var $N = $(this).eq(0); // FIRST matching Container element - if (!$N.length) { - return _log( options.errors.containerMissing ); - }; - - // Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout") - // return the Instance-pointer if layout has already been initialized - if ($N.data("layoutContainer") && $N.data("layout")) - return $N.data("layout"); // cached pointer - - // init global vars - var - $Ps = {} // Panes x5 - set in initPanes() - , $Cs = {} // Content x5 - set in initPanes() - , $Rs = {} // Resizers x4 - set in initHandles() - , $Ts = {} // Togglers x4 - set in initHandles() - , $Ms = $([]) // Masks - up to 2 masks per pane (IFRAME + DIV) - // aliases for code brevity - , sC = state.container // alias for easy access to 'container dimensions' - , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" - ; - - // create Instance object to expose data & option Properties, and primary action Methods - var Instance = { - // layout data - options: options // property - options hash - , state: state // property - dimensions hash - // object pointers - , container: $N // property - object pointers for layout container - , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center - , contents: $Cs // property - object pointers for ALL Content: contents.north, contents.center - , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north - , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north - // border-pane open/close - , hide: hide // method - ditto - , show: show // method - ditto - , toggle: toggle // method - pass a 'pane' ("north", "west", etc) - , open: open // method - ditto - , close: close // method - ditto - , slideOpen: slideOpen // method - ditto - , slideClose: slideClose // method - ditto - , slideToggle: slideToggle // method - ditto - // pane actions - , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data - , _sizePane: sizePane // method -intended for user by plugins only! - , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' - , sizeContent: sizeContent // method - pass a 'pane' - , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them - , showMasks: showMasks // method - pass a 'pane' OR list of panes - default = all panes with mask option set - , hideMasks: hideMasks // method - ditto' - // pane element methods - , initContent: initContent // method - ditto - , addPane: addPane // method - pass a 'pane' - , removePane: removePane // method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem - , createChildren: createChildren // method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].children - , refreshChildren: refreshChildren // method - pass a 'pane' and a layout-instance - // special pane option setting - , enableClosable: enableClosable // method - pass a 'pane' - , disableClosable: disableClosable // method - ditto - , enableSlidable: enableSlidable // method - ditto - , disableSlidable: disableSlidable // method - ditto - , enableResizable: enableResizable // method - ditto - , disableResizable: disableResizable// method - ditto - // utility methods for panes - , allowOverflow: allowOverflow // utility - pass calling element (this) - , resetOverflow: resetOverflow // utility - ditto - // layout control - , destroy: destroy // method - no parameters - , initPanes: isInitialized // method - no parameters - , resizeAll: resizeAll // method - no parameters - // callback triggering - , runCallbacks: _runCallbacks // method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west") - // alias collections of options, state and children - created in addPane and extended elsewhere - , hasParentLayout: false // set by initContainer() - , children: children // pointers to child-layouts, eg: Instance.children.west.layoutName - , north: false // alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], children: children[pane] } - , south: false // ditto - , west: false // ditto - , east: false // ditto - , center: false // ditto - }; - - // create the border layout NOW - if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation - return null; - else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later - return Instance; // return the Instance object - -} - - -})( jQuery ); -// END Layout - keep internal vars internal! - - - -// START Plugins - shared wrapper, no global vars -(function ($) { - - -/** - * jquery.layout.state 1.0 - * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ - * - * Copyright (c) 2012 - * Kevin Dalman (http://allpro.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * @requires: UI Layout 1.3.0.rc30.1 or higher - * @requires: $.ui.cookie (above) - * - * @see: http://groups.google.com/group/jquery-ui-layout - */ -/* - * State-management options stored in options.stateManagement, which includes a .cookie hash - * Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden - * - * // STATE/COOKIE OPTIONS - * @example $(el).layout({ - stateManagement: { - enabled: true - , stateKeys: "east.size,west.size,east.isClosed,west.isClosed" - , cookie: { name: "appLayout", path: "/" } - } - }) - * @example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies - * @example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } }) - * @example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" }) - * - * // STATE/COOKIE METHODS - * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); - * @example myLayout.loadCookie(); - * @example myLayout.deleteCookie(); - * @example var JSON = myLayout.readState(); // CURRENT Layout State - * @example var JSON = myLayout.readCookie(); // SAVED Layout State (from cookie) - * @example var JSON = myLayout.state.stateData; // LAST LOADED Layout State (cookie saved in layout.state hash) - * - * CUSTOM STATE-MANAGEMENT (eg, saved in a database) - * @example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" ); - * @example myLayout.loadState( JSON ); - */ - -/** - * UI COOKIE UTILITY - * - * A $.cookie OR $.ui.cookie namespace *should be standard*, but until then... - * This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin - * NOTE: This utility is REQUIRED by the layout.state plugin - * - * Cookie methods in Layout are created as part of State Management - */ -if (!$.ui) $.ui = {}; -$.ui.cookie = { - - // cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6 - acceptsCookies: !!navigator.cookieEnabled - -, read: function (name) { - var c = document.cookie - , cs = c ? c.split(';') : [] - , pair // loop var - ; - for (var i=0, n=cs.length; i < n; i++) { - pair = $.trim(cs[i]).split('='); // name=value pair - if (pair[0] == name) // found the layout cookie - return decodeURIComponent(pair[1]); - } - return null; - } - -, write: function (name, val, cookieOpts) { - var params = "" - , date = "" - , clear = false - , o = cookieOpts || {} - , x = o.expires || null - , t = $.type(x) - ; - if (t === "date") - date = x; - else if (t === "string" && x > 0) { - x = parseInt(x,10); - t = "number"; - } - if (t === "number") { - date = new Date(); - if (x > 0) - date.setDate(date.getDate() + x); - else { - date.setFullYear(1970); - clear = true; - } - } - if (date) params += ";expires="+ date.toUTCString(); - if (o.path) params += ";path="+ o.path; - if (o.domain) params += ";domain="+ o.domain; - if (o.secure) params += ";secure"; - document.cookie = name +"="+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie - } - -, clear: function (name) { - $.ui.cookie.write(name, "", {expires: -1}); - } - -}; -// if cookie.jquery.js is not loaded, create an alias to replicate it -// this may be useful to other plugins or code dependent on that plugin -if (!$.cookie) $.cookie = function (k, v, o) { - var C = $.ui.cookie; - if (v === null) - C.clear(k); - else if (v === undefined) - return C.read(k); - else - C.write(k, v, o); -}; - - -// tell Layout that the state plugin is available -$.layout.plugins.stateManagement = true; - -// Add State-Management options to layout.defaults -$.layout.config.optionRootKeys.push("stateManagement"); -$.layout.defaults.stateManagement = { - enabled: false // true = enable state-management, even if not using cookies -, autoSave: true // Save a state-cookie when page exits? -, autoLoad: true // Load the state-cookie when Layout inits? -, animateLoad: true // animate panes when loading state into an active layout -, includeChildren: true // recurse into child layouts to include their state as well - // List state-data to save - must be pane-specific -, stateKeys: "north.size,south.size,east.size,west.size,"+ - "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ - "north.isHidden,south.isHidden,east.isHidden,west.isHidden" -, cookie: { - name: "" // If not specified, will use Layout.name, else just "Layout" - , domain: "" // blank = current domain - , path: "" // blank = current page, "/" = entire website - , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' - , secure: false - } -}; -// Set stateManagement as a layout-option, NOT a pane-option -$.layout.optionsMap.layout.push("stateManagement"); - -/* - * State Management methods - */ -$.layout.state = { - - /** - * Get the current layout state and save it to a cookie - * - * myLayout.saveCookie( keys, cookieOpts ) - * - * @param {Object} inst - * @param {(string|Array)=} keys - * @param {Object=} cookieOpts - */ - saveCookie: function (inst, keys, cookieOpts) { - var o = inst.options - , sm = o.stateManagement - , oC = $.extend(true, {}, sm.cookie, cookieOpts || null) - , data = inst.state.stateData = inst.readState( keys || sm.stateKeys ) // read current panes-state - ; - $.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC ); - return $.extend(true, {}, data); // return COPY of state.stateData data - } - - /** - * Remove the state cookie - * - * @param {Object} inst - */ -, deleteCookie: function (inst) { - var o = inst.options; - $.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" ); - } - - /** - * Read & return data from the cookie - as JSON - * - * @param {Object} inst - */ -, readCookie: function (inst) { - var o = inst.options; - var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" ); - // convert cookie string back to a hash and return it - return c ? $.layout.state.decodeJSON(c) : {}; - } - - /** - * Get data from the cookie and USE IT to loadState - * - * @param {Object} inst - */ -, loadCookie: function (inst) { - var c = $.layout.state.readCookie(inst); // READ the cookie - if (c) { - inst.state.stateData = $.extend(true, {}, c); // SET state.stateData - inst.loadState(c); // LOAD the retrieved state - } - return c; - } - - /** - * Update layout options from the cookie, if one exists - * - * @param {Object} inst - * @param {Object=} stateData - * @param {boolean=} animate - */ -, loadState: function (inst, data, opts) { - if (!$.isPlainObject( data ) || $.isEmptyObject( data )) return; - - // normalize data & cache in the state object - data = inst.state.stateData = $.layout.transformData( data ); // panes = default subkey - - // add missing/default state-restore options - var smo = inst.options.stateManagement; - opts = $.extend({ - animateLoad: false //smo.animateLoad - , includeChildren: smo.includeChildren - }, opts ); - - if (!inst.state.initialized) { - /* - * layout NOT initialized, so just update its options - */ - // MUST remove pane.children keys before applying to options - // use a copy so we don't remove keys from original data - var o = $.extend(true, {}, data); - //delete o.center; // center has no state-data - only children - $.each($.layout.config.allPanes, function (idx, pane) { - if (o[pane]) delete o[pane].children; - }); - // update CURRENT layout-options with saved state data - $.extend(true, inst.options, o); - } - else { - /* - * layout already initialized, so modify layout's configuration - */ - var noAnimate = !opts.animateLoad - , o, c, h, state, open - ; - $.each($.layout.config.borderPanes, function (idx, pane) { - o = data[ pane ]; - if (!$.isPlainObject( o )) return; // no key, skip pane - - s = o.size; - c = o.initClosed; - h = o.initHidden; - ar = o.autoResize - state = inst.state[pane]; - open = state.isVisible; - - // reset autoResize - if (ar) - state.autoResize = ar; - // resize BEFORE opening - if (!open) - inst._sizePane(pane, s, false, false, false); // false=skipCallback/noAnimation/forceResize - // open/close as necessary - DO NOT CHANGE THIS ORDER! - if (h === true) inst.hide(pane, noAnimate); - else if (c === true) inst.close(pane, false, noAnimate); - else if (c === false) inst.open (pane, false, noAnimate); - else if (h === false) inst.show (pane, false, noAnimate); - // resize AFTER any other actions - if (open) - inst._sizePane(pane, s, false, false, noAnimate); // animate resize if option passed - }); - - /* - * RECURSE INTO CHILD-LAYOUTS - */ - if (opts.includeChildren) { - var paneStateChildren, childState; - $.each(inst.children, function (pane, paneChildren) { - paneStateChildren = data[pane] ? data[pane].children : 0; - if (paneStateChildren && paneChildren) { - $.each(paneChildren, function (stateKey, child) { - childState = paneStateChildren[stateKey]; - if (child && childState) - child.loadState( childState ); - }); - } - }); - } - } - } - - /** - * Get the *current layout state* and return it as a hash - * - * @param {Object=} inst // Layout instance to get state for - * @param {object=} [opts] // State-Managements override options - */ -, readState: function (inst, opts) { - // backward compatility - if ($.type(opts) === 'string') opts = { keys: opts }; - if (!opts) opts = {}; - var sm = inst.options.stateManagement - , ic = opts.includeChildren - , recurse = ic !== undefined ? ic : sm.includeChildren - , keys = opts.stateKeys || sm.stateKeys - , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } - , state = inst.state - , panes = $.layout.config.allPanes - , data = {} - , pair, pane, key, val - , ps, pC, child, array, count, branch - ; - if ($.isArray(keys)) keys = keys.join(","); - // convert keys to an array and change delimiters from '__' to '.' - keys = keys.replace(/__/g, ".").split(','); - // loop keys and create a data hash - for (var i=0, n=keys.length; i < n; i++) { - pair = keys[i].split("."); - pane = pair[0]; - key = pair[1]; - if ($.inArray(pane, panes) < 0) continue; // bad pane! - val = state[ pane ][ key ]; - if (val == undefined) continue; - if (key=="isClosed" && state[pane]["isSliding"]) - val = true; // if sliding, then *really* isClosed - ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; - } - - // recurse into the child-layouts for each pane - if (recurse) { - $.each(panes, function (idx, pane) { - pC = inst.children[pane]; - ps = state.stateData[pane]; - if ($.isPlainObject( pC ) && !$.isEmptyObject( pC )) { - // ensure a key exists for this 'pane', eg: branch = data.center - branch = data[pane] || (data[pane] = {}); - if (!branch.children) branch.children = {}; - $.each( pC, function (key, child) { - // ONLY read state from an initialize layout - if ( child.state.initialized ) - branch.children[ key ] = $.layout.state.readState( child ); - // if we have PREVIOUS (onLoad) state for this child-layout, KEEP IT! - else if ( ps && ps.children && ps.children[ key ] ) { - branch.children[ key ] = $.extend(true, {}, ps.children[ key ] ); - } - }); - } - }); - } - - return data; - } - - /** - * Stringify a JSON hash so can save in a cookie or db-field - */ -, encodeJSON: function (JSON) { - return parse(JSON); - function parse (h) { - var D=[], i=0, k, v, t // k = key, v = value - , a = $.isArray(h) - ; - for (k in h) { - v = h[k]; - t = typeof v; - if (t == 'string') // STRING - add quotes - v = '"'+ v +'"'; - else if (t == 'object') // SUB-KEY - recurse into it - v = parse(v); - D[i++] = (!a ? '"'+ k +'":' : '') + v; - } - return (a ? '[' : '{') + D.join(',') + (a ? ']' : '}'); - }; - } - - /** - * Convert stringified JSON back to a hash object - * @see $.parseJSON(), adding in jQuery 1.4.1 - */ -, decodeJSON: function (str) { - try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; } - catch (e) { return {}; } - } - - -, _create: function (inst) { - var _ = $.layout.state - , o = inst.options - , sm = o.stateManagement - ; - // ADD State-Management plugin methods to inst - $.extend( inst, { - // readCookie - update options from cookie - returns hash of cookie data - readCookie: function () { return _.readCookie(inst); } - // deleteCookie - , deleteCookie: function () { _.deleteCookie(inst); } - // saveCookie - optionally pass keys-list and cookie-options (hash) - , saveCookie: function (keys, cookieOpts) { return _.saveCookie(inst, keys, cookieOpts); } - // loadCookie - readCookie and use to loadState() - returns hash of cookie data - , loadCookie: function () { return _.loadCookie(inst); } - // loadState - pass a hash of state to use to update options - , loadState: function (stateData, opts) { _.loadState(inst, stateData, opts); } - // readState - returns hash of current layout-state - , readState: function (keys) { return _.readState(inst, keys); } - // add JSON utility methods too... - , encodeJSON: _.encodeJSON - , decodeJSON: _.decodeJSON - }); - - // init state.stateData key, even if plugin is initially disabled - inst.state.stateData = {}; - - // autoLoad MUST BE one of: data-array, data-hash, callback-function, or TRUE - if ( !sm.autoLoad ) return; - - // When state-data exists in the autoLoad key USE IT, - // even if stateManagement.enabled == false - if ($.isPlainObject( sm.autoLoad )) { - if (!$.isEmptyObject( sm.autoLoad )) { - inst.loadState( sm.autoLoad ); - } - } - else if ( sm.enabled ) { - // update the options from cookie or callback - // if options is a function, call it to get stateData - if ($.isFunction( sm.autoLoad )) { - var d = {}; - try { - d = sm.autoLoad( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn - } catch (e) {} - if (d && $.isPlainObject( d ) && !$.isEmptyObject( d )) - inst.loadState(d); - } - else // any other truthy value will trigger loadCookie - inst.loadCookie(); - } - } - -, _unload: function (inst) { - var sm = inst.options.stateManagement; - if (sm.enabled && sm.autoSave) { - // if options is a function, call it to save the stateData - if ($.isFunction( sm.autoSave )) { - try { - sm.autoSave( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn - } catch (e) {} - } - else // any truthy value will trigger saveCookie - inst.saveCookie(); - } - } - -}; - -// add state initialization method to Layout's onCreate array of functions -$.layout.onCreate.push( $.layout.state._create ); -$.layout.onUnload.push( $.layout.state._unload ); - - - - -/** - * jquery.layout.buttons 1.0 - * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ - * - * Copyright (c) 2012 - * Kevin Dalman (http://allpro.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * @requires: UI Layout 1.3.0.rc30.1 or higher - * - * @see: http://groups.google.com/group/jquery-ui-layout - * - * Docs: [ to come ] - * Tips: [ to come ] - */ - -// tell Layout that the state plugin is available -$.layout.plugins.buttons = true; - -// Add buttons options to layout.defaults -$.layout.defaults.autoBindCustomButtons = false; -// Specify autoBindCustomButtons as a layout-option, NOT a pane-option -$.layout.optionsMap.layout.push("autoBindCustomButtons"); - -/* - * Button methods - */ -$.layout.buttons = { - - /** - * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons - * - * @see _create() - * - * @param {Object} inst Layout Instance object - */ - init: function (inst) { - var pre = "ui-layout-button-" - , layout = inst.options.name || "" - , name; - $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { - $.each($.layout.config.borderPanes, function (ii, pane) { - $("."+pre+action+"-"+pane).each(function(){ - // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' - name = $(this).data("layoutName") || $(this).attr("layoutName"); - if (name == undefined || name === layout) - inst.bindButton(this, action, pane); - }); - }); - }); - } - - /** - * Helper function to validate params received by addButton utilities - * - * Two classes are added to the element, based on the buttonClass... - * The type of button is appended to create the 2nd className: - * - ui-layout-button-pin // action btnClass - * - ui-layout-button-pin-west // action btnClass + pane - * - ui-layout-button-toggle - * - ui-layout-button-open - * - ui-layout-button-close - * - * @param {Object} inst Layout Instance object - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - * - * @return {Array.} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null - */ -, get: function (inst, selector, pane, action) { - var $E = $(selector) - , o = inst.options - , err = o.errors.addButtonError - ; - if (!$E.length) { // element not found - $.layout.msg(err +" "+ o.errors.selector +": "+ selector, true); - } - else if ($.inArray(pane, $.layout.config.borderPanes) < 0) { // invalid 'pane' sepecified - $.layout.msg(err +" "+ o.errors.pane +": "+ pane, true); - $E = $(""); // NO BUTTON - } - else { // VALID - var btn = o[pane].buttonClass +"-"+ action; - $E .addClass( btn +" "+ btn +"-"+ pane ) - .data("layoutName", o.name); // add layout identifier - even if blank! - } - return $E; - } - - - /** - * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc. - * - * @param {Object} inst Layout Instance object - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} action - * @param {string} pane - */ -, bind: function (inst, selector, action, pane) { - var _ = $.layout.buttons; - switch (action.toLowerCase()) { - case "toggle": _.addToggle (inst, selector, pane); break; - case "open": _.addOpen (inst, selector, pane); break; - case "close": _.addClose (inst, selector, pane); break; - case "pin": _.addPin (inst, selector, pane); break; - case "toggle-slide": _.addToggle (inst, selector, pane, true); break; - case "open-slide": _.addOpen (inst, selector, pane, true); break; - } - return inst; - } - - /** - * Add a custom Toggler button for a pane - * - * @param {Object} inst Layout Instance object - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - * @param {boolean=} slide true = slide-open, false = pin-open - */ -, addToggle: function (inst, selector, pane, slide) { - $.layout.buttons.get(inst, selector, pane, "toggle") - .click(function(evt){ - inst.toggle(pane, !!slide); - evt.stopPropagation(); - }); - return inst; - } - - /** - * Add a custom Open button for a pane - * - * @param {Object} inst Layout Instance object - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - * @param {boolean=} slide true = slide-open, false = pin-open - */ -, addOpen: function (inst, selector, pane, slide) { - $.layout.buttons.get(inst, selector, pane, "open") - .attr("title", inst.options[pane].tips.Open) - .click(function (evt) { - inst.open(pane, !!slide); - evt.stopPropagation(); - }); - return inst; - } - - /** - * Add a custom Close button for a pane - * - * @param {Object} inst Layout Instance object - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. - */ -, addClose: function (inst, selector, pane) { - $.layout.buttons.get(inst, selector, pane, "close") - .attr("title", inst.options[pane].tips.Close) - .click(function (evt) { - inst.close(pane); - evt.stopPropagation(); - }); - return inst; - } - - /** - * Add a custom Pin button for a pane - * - * Four classes are added to the element, based on the paneClass for the associated pane... - * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: - * - ui-layout-pane-pin - * - ui-layout-pane-west-pin - * - ui-layout-pane-pin-up - * - ui-layout-pane-west-pin-up - * - * @param {Object} inst Layout Instance object - * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" - * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc. - */ -, addPin: function (inst, selector, pane) { - var _ = $.layout.buttons - , $E = _.get(inst, selector, pane, "pin"); - if ($E.length) { - var s = inst.state[pane]; - $E.click(function (evt) { - _.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed)); - if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open - else inst.close( pane ); // slide-closed - evt.stopPropagation(); - }); - // add up/down pin attributes and classes - _.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding)); - // add this pin to the pane data so we can 'sync it' automatically - // PANE.pins key is an array so we can store multiple pins for each pane - s.pins.push( selector ); // just save the selector string - } - return inst; - } - - /** - * Change the class of the pin button to make it look 'up' or 'down' - * - * @see addPin(), syncPins() - * - * @param {Object} inst Layout Instance object - * @param {Array.} $Pin The pin-span element in a jQuery wrapper - * @param {string} pane These are the params returned to callbacks by layout() - * @param {boolean} doPin true = set the pin 'down', false = set it 'up' - */ -, setPinState: function (inst, $Pin, pane, doPin) { - var updown = $Pin.attr("pin"); - if (updown && doPin === (updown=="down")) return; // already in correct state - var - o = inst.options[pane] - , pin = o.buttonClass +"-pin" - , side = pin +"-"+ pane - , UP = pin +"-up "+ side +"-up" - , DN = pin +"-down "+side +"-down" - ; - $Pin - .attr("pin", doPin ? "down" : "up") // logic - .attr("title", doPin ? o.tips.Unpin : o.tips.Pin) - .removeClass( doPin ? UP : DN ) - .addClass( doPin ? DN : UP ) - ; - } - - /** - * INTERNAL function to sync 'pin buttons' when pane is opened or closed - * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes - * - * @see open(), close() - * - * @param {Object} inst Layout Instance object - * @param {string} pane These are the params returned to callbacks by layout() - * @param {boolean} doPin True means set the pin 'down', False means 'up' - */ -, syncPinBtns: function (inst, pane, doPin) { - // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE - $.each(inst.state[pane].pins, function (i, selector) { - $.layout.buttons.setPinState(inst, $(selector), pane, doPin); - }); - } - - -, _load: function (inst) { - var _ = $.layout.buttons; - // ADD Button methods to Layout Instance - // Note: sel = jQuery Selector string - $.extend( inst, { - bindButton: function (sel, action, pane) { return _.bind(inst, sel, action, pane); } - // DEPRECATED METHODS - , addToggleBtn: function (sel, pane, slide) { return _.addToggle(inst, sel, pane, slide); } - , addOpenBtn: function (sel, pane, slide) { return _.addOpen(inst, sel, pane, slide); } - , addCloseBtn: function (sel, pane) { return _.addClose(inst, sel, pane); } - , addPinBtn: function (sel, pane) { return _.addPin(inst, sel, pane); } - }); - - // init state array to hold pin-buttons - for (var i=0; i<4; i++) { - var pane = $.layout.config.borderPanes[i]; - inst.state[pane].pins = []; - } - - // auto-init buttons onLoad if option is enabled - if ( inst.options.autoBindCustomButtons ) - _.init(inst); - } - -, _unload: function (inst) { - // TODO: unbind all buttons??? - } - -}; - -// add initialization method to Layout's onLoad array of functions -$.layout.onLoad.push( $.layout.buttons._load ); -//$.layout.onUnload.push( $.layout.buttons._unload ); - - - -/** - * jquery.layout.browserZoom 1.0 - * $Date: 2011-12-29 08:00:00 (Thu, 29 Dec 2011) $ - * - * Copyright (c) 2012 - * Kevin Dalman (http://allpro.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * @requires: UI Layout 1.3.0.rc30.1 or higher - * - * @see: http://groups.google.com/group/jquery-ui-layout - * - * TODO: Extend logic to handle other problematic zooming in browsers - * TODO: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event - */ - -// tell Layout that the plugin is available -$.layout.plugins.browserZoom = true; - -$.layout.defaults.browserZoomCheckInterval = 1000; -$.layout.optionsMap.layout.push("browserZoomCheckInterval"); - -/* - * browserZoom methods - */ -$.layout.browserZoom = { - - _init: function (inst) { - // abort if browser does not need this check - if ($.layout.browserZoom.ratio() !== false) - $.layout.browserZoom._setTimer(inst); - } - -, _setTimer: function (inst) { - // abort if layout destroyed or browser does not need this check - if (inst.destroyed) return; - var o = inst.options - , s = inst.state - // don't need check if inst has parentLayout, but check occassionally in case parent destroyed! - // MINIMUM 100ms interval, for performance - , ms = inst.hasParentLayout ? 5000 : Math.max( o.browserZoomCheckInterval, 100 ) - ; - // set the timer - setTimeout(function(){ - if (inst.destroyed || !o.resizeWithWindow) return; - var d = $.layout.browserZoom.ratio(); - if (d !== s.browserZoom) { - s.browserZoom = d; - inst.resizeAll(); - } - // set a NEW timeout - $.layout.browserZoom._setTimer(inst); - } - , ms ); - } - -, ratio: function () { - var w = window - , s = screen - , d = document - , dE = d.documentElement || d.body - , b = $.layout.browser - , v = b.version - , r, sW, cW - ; - // we can ignore all browsers that fire window.resize event onZoom - if ((b.msie && v > 8) - || !b.msie - ) return false; // don't need to track zoom - - if (s.deviceXDPI && s.systemXDPI) // syntax compiler hack - return calc(s.deviceXDPI, s.systemXDPI); - // everything below is just for future reference! - if (b.webkit && (r = d.body.getBoundingClientRect)) - return calc((r.left - r.right), d.body.offsetWidth); - if (b.webkit && (sW = w.outerWidth)) - return calc(sW, w.innerWidth); - if ((sW = s.width) && (cW = dE.clientWidth)) - return calc(sW, cW); - return false; // no match, so cannot - or don't need to - track zoom - - function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); } - } - -}; -// add initialization method to Layout's onLoad array of functions -$.layout.onReady.push( $.layout.browserZoom._init ); - - +/** + * @preserve + * jquery.layout 1.3.0 - Release Candidate 30.79 + * $Date: 2013-01-12 08:00:00 (Sat, 12 Jan 2013) $ + * $Rev: 303007 $ + * + * Copyright (c) 2013 Kevin Dalman (http://allpro.net) + * Based on work by Fabrizio Balliano (http://www.fabrizioballiano.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * SEE: http://layout.jquery-dev.net/LICENSE.txt + * + * Changelog: http://layout.jquery-dev.net/changelog.cfm#1.3.0.rc30.79 + * + * Docs: http://layout.jquery-dev.net/documentation.html + * Tips: http://layout.jquery-dev.net/tips.html + * Help: http://groups.google.com/group/jquery-ui-layout + */ + +/* JavaDoc Info: http://code.google.com/closure/compiler/docs/js-for-compiler.html + * {!Object} non-nullable type (never NULL) + * {?string} nullable type (sometimes NULL) - default for {Object} + * {number=} optional parameter + * {*} ALL types + */ +/* TODO for jQ 2.0 + * change .andSelf() to .addBack() + * $.fn.disableSelection won't work + */ + +// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars + +;(function ($) { + +// alias Math methods - used a lot! +var min = Math.min +, max = Math.max +, round = Math.floor + +, isStr = function (v) { return $.type(v) === "string"; } + + /** + * @param {!Object} Instance + * @param {Array.} a_fn + */ +, runPluginCallbacks = function (Instance, a_fn) { + if ($.isArray(a_fn)) + for (var i=0, c=a_fn.length; i').appendTo("body"); + var d = { width: $c.css("width") - $c[0].clientWidth, height: $c.height() - $c[0].clientHeight }; + $c.remove(); + window.scrollbarWidth = d.width; + window.scrollbarHeight = d.height; + return dim.match(/^(width|height)$/) ? d[dim] : d; + } + + + /** + * Returns hash container 'display' and 'visibility' + * + * @see $.swap() - swaps CSS, runs callback, resets CSS + * @param {!Object} $E jQuery element + * @param {boolean=} [force=false] Run even if display != none + * @return {!Object} Returns current style props, if applicable + */ +, showInvisibly: function ($E, force) { + if ($E && $E.length && (force || $E.css("display") === "none")) { // only if not *already hidden* + var s = $E[0].style + // save ONLY the 'style' props because that is what we must restore + , CSS = { display: s.display || '', visibility: s.visibility || '' }; + // show element 'invisibly' so can be measured + $E.css({ display: "block", visibility: "hidden" }); + return CSS; + } + return {}; + } + + /** + * Returns data for setting size of an element (container or a pane). + * + * @see _create(), onWindowResize() for container, plus others for pane + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc + */ +, getElementDimensions: function ($E, inset) { + var + // dimensions hash - start with current data IF passed + d = { css: {}, inset: {} } + , x = d.css // CSS hash + , i = { bottom: 0 } // TEMP insets (bottom = complier hack) + , N = $.layout.cssNum + , off = $E.offset() + , b, p, ei // TEMP border, padding + ; + d.offsetLeft = off.left; + d.offsetTop = off.top; + + if (!inset) inset = {}; // simplify logic below + + $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge + b = x["border" + e] = $.layout.borderWidth($E, e); + p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e); + ei = e.toLowerCase(); + d.inset[ei] = inset[ei] >= 0 ? inset[ei] : p; // any missing insetX value = paddingX + i[ei] = d.inset[ei] + b; // total offset of content from outer side + }); + + x.width = $E.width(); + x.height = $E.height(); + x.top = N($E,"top",true); + x.bottom = N($E,"bottom",true); + x.left = N($E,"left",true); + x.right = N($E,"right",true); + + d.outerWidth = $E.outerWidth(); + d.outerHeight = $E.outerHeight(); + // calc the TRUE inner-dimensions, even in quirks-mode! + d.innerWidth = max(0, d.outerWidth - i.left - i.right); + d.innerHeight = max(0, d.outerHeight - i.top - i.bottom); + // layoutWidth/Height is used in calcs for manual resizing + // layoutW/H only differs from innerW/H when in quirks-mode - then is like outerW/H + d.layoutWidth = $E.innerWidth(); + d.layoutHeight = $E.innerHeight(); + + //if ($E.prop('tagName') === 'BODY') { debugData( d, $E.prop('tagName') ); } // DEBUG + + //d.visible = $E.is(":visible");// && x.width > 0 && x.height > 0; + + return d; + } + +, getElementStyles: function ($E, list) { + var + CSS = {} + , style = $E[0].style + , props = list.split(",") + , sides = "Top,Bottom,Left,Right".split(",") + , attrs = "Color,Style,Width".split(",") + , p, s, a, i, j, k + ; + for (i=0; i < props.length; i++) { + p = props[i]; + if (p.match(/(border|padding|margin)$/)) + for (j=0; j < 4; j++) { + s = sides[j]; + if (p === "border") + for (k=0; k < 3; k++) { + a = attrs[k]; + CSS[p+s+a] = style[p+s+a]; + } + else + CSS[p+s] = style[p+s]; + } + else + CSS[p] = style[p]; + }; + return CSS + } + + /** + * Return the innerWidth for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerWidth of the elem by subtracting padding and borders + */ +, cssWidth: function ($E, outerWidth) { + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerWidth <= 0) return 0; + + var bs = !$.layout.browser.boxModel ? "border-box" : $.support.boxSizing ? $E.css("boxSizing") : "content-box" + , b = $.layout.borderWidth + , n = $.layout.cssNum + , W = outerWidth + ; + // strip border and/or padding from outerWidth to get CSS Width + if (bs !== "border-box") + W -= (b($E, "Left") + b($E, "Right")); + if (bs === "content-box") + W -= (n($E, "paddingLeft") + n($E, "paddingRight")); + return max(0,W); + } + + /** + * Return the innerHeight for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerHeight of the elem by subtracting padding and borders + */ +, cssHeight: function ($E, outerHeight) { + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerHeight <= 0) return 0; + + var bs = !$.layout.browser.boxModel ? "border-box" : $.support.boxSizing ? $E.css("boxSizing") : "content-box" + , b = $.layout.borderWidth + , n = $.layout.cssNum + , H = outerHeight + ; + // strip border and/or padding from outerHeight to get CSS Height +// if (bs !== "border-box") +// H -= (b($E, "Top") + b($E, "Bottom")); +// if (bs === "content-box") +// H -= (n($E, "paddingTop") + n($E, "paddingBottom")); + return max(0,H); + } + + /** + * Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist + * + * @see Called by many methods + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {string} prop The name of the CSS property, eg: top, width, etc. + * @param {boolean=} [allowAuto=false] true = return 'auto' if that is value; false = return 0 + * @return {(string|number)} Usually used to get an integer value for position (top, left) or size (height, width) + */ +, cssNum: function ($E, prop, allowAuto) { + if (!$E.jquery) $E = $($E); + var CSS = $.layout.showInvisibly($E) + , p = $.css($E[0], prop, true) + , v = allowAuto && p=="auto" ? p : Math.round(parseFloat(p) || 0); + $E.css( CSS ); // RESET + return v; + } + +, borderWidth: function (el, side) { + if (el.jquery) el = el[0]; + var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left + return $.css(el, b+"Style", true) === "none" ? 0 : Math.round(parseFloat($.css(el, b+"Width", true)) || 0); + } + + /** + * Mouse-tracking utility - FUTURE REFERENCE + * + * init: if (!window.mouse) { + * window.mouse = { x: 0, y: 0 }; + * $(document).mousemove( $.layout.trackMouse ); + * } + * + * @param {Object} evt + * +, trackMouse: function (evt) { + window.mouse = { x: evt.clientX, y: evt.clientY }; + } + */ + + /** + * SUBROUTINE for preventPrematureSlideClose option + * + * @param {Object} evt + * @param {Object=} el + */ +, isMouseOverElem: function (evt, el) { + var + $E = $(el || this) + , d = $E.offset() + , T = d.top + , L = d.left + , R = L + $E.outerWidth() + , B = T + $E.outerHeight() + , x = evt.pageX // evt.clientX ? + , y = evt.pageY // evt.clientY ? + ; + // if X & Y are < 0, probably means is over an open SELECT + return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B)); + } + + /** + * Message/Logging Utility + * + * @example $.layout.msg("My message"); // log text + * @example $.layout.msg("My message", true); // alert text + * @example $.layout.msg({ foo: "bar" }, "Title"); // log hash-data, with custom title + * @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR- + * @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data + * + * @param {(Object|string)} info String message OR Hash/Array + * @param {(Boolean|string|Object)=} [popup=false] True means alert-box - can be skipped + * @param {(Object|string)=} [debugTitle=""] Title for Hash data - can be skipped + * @param {Object=} [debugOpts] Extra options for debug output + */ +, msg: function (info, popup, debugTitle, debugOpts) { + if ($.isPlainObject(info) && window.debugData) { + if (typeof popup === "string") { + debugOpts = debugTitle; + debugTitle = popup; + } + else if (typeof debugTitle === "object") { + debugOpts = debugTitle; + debugTitle = null; + } + var t = debugTitle || "log( )" + , o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts); + if (popup === true || o.display) + debugData( info, t, o ); + else if (window.console) + console.log(debugData( info, t, o )); + } + else if (popup) + alert(info); + else if (window.console) + console.log(info); + else { + var id = "#layoutLogger" + , $l = $(id); + if (!$l.length) + $l = createLog(); + $l.children("ul").append('
    • '+ info.replace(/\/g,">") +'
    • '); + } + + function createLog () { + var pos = $.support.fixedPosition ? 'fixed' : 'absolute' + , $e = $('
      ' + + '
      ' + + 'XLayout console.log
      ' + + '
        ' + + '
        ' + ).appendTo("body"); + $e.css('left', $(window).width() - $e.outerWidth() - 5) + if ($.ui.draggable) $e.draggable({ handle: ':first-child' }); + return $e; + }; + } + +}; + + +/* + * $.layout.browser REPLACES removed $.browser, with extra data + * Parsing code here adapted from jQuery 1.8 $.browse + */ +var u = navigator.userAgent.toLowerCase() +, m = /(chrome)[ \/]([\w.]+)/.exec( u ) + || /(webkit)[ \/]([\w.]+)/.exec( u ) + || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( u ) + || /(msie) ([\w.]+)/.exec( u ) + || u.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( u ) + || [] +, b = m[1] || "" +, v = m[2] || 0 +, ie = b === "msie" +; +$.layout.browser = { + version: v +, safari: b === "webkit" // webkit (NOT chrome) = safari +, webkit: b === "chrome" // chrome = webkit +, msie: ie +, isIE6: ie && v == 6 + // ONLY IE reverts to old box-model - update for older jQ onReady +, boxModel: !ie || $.support.boxModel !== false +}; +if (b) $.layout.browser[b] = true; // set CURRENT browser +/* OLD versions of jQuery only set $.support.boxModel after page is loaded + * so if this is IE, use support.boxModel to test for quirks-mode (ONLY IE changes boxModel) */ +if (ie) $(function(){ $.layout.browser.boxModel = $.support.boxModel; }); + + +// DEFAULT OPTIONS +$.layout.defaults = { +/* + * LAYOUT & LAYOUT-CONTAINER OPTIONS + * - none of these options are applicable to individual panes + */ + name: "" // Not required, but useful for buttons and used for the state-cookie +, containerClass: "ui-layout-container" // layout-container element +, inset: null // custom container-inset values (override padding) +, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) +, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event +, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky +, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized +, maskPanesEarly: false // true = create pane-masks on resizer.mouseDown instead of waiting for resizer.dragstart +, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific +, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific +, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements +, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized +, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload +, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload +, initPanes: true // false = DO NOT initialize the panes onLoad - will init later +, showErrorMessages: true // enables fatal error messages to warn developers of common errors +, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code! +// Changing this zIndex value will cause other zIndex values to automatically change +, zIndex: null // the PANE zIndex - resizers and masks will be +1 +// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships +, zIndexes: { // set _default_ z-index values here... + pane_normal: 0 // normal z-index for panes + , content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing + , resizer_normal: 2 // normal z-index for resizer-bars + , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' + , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer + , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' + } +, errors: { + pane: "pane" // description of "layout pane element" - used only in error messages + , selector: "selector" // description of "jQuery-selector" - used only in error messages + , addButtonError: "Error Adding Button\nInvalid " + , containerMissing: "UI Layout Initialization Error\nThe specified layout-container does not exist." + , centerPaneMissing: "UI Layout Initialization Error\nThe center-pane element does not exist.\nThe center-pane is a required element." + , noContainerHeight: "UI Layout Initialization Warning\nThe layout-container \"CONTAINER\" has no height.\nTherefore the layout is 0-height and hence 'invisible'!" + , callbackError: "UI Layout Callback Error\nThe EVENT callback is not a valid function." + } +/* + * PANE DEFAULT SETTINGS + * - settings under the 'panes' key become the default settings for *all panes* + * - ALL pane-options can also be set specifically for each panes, which will override these 'default values' + */ +, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings' + applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity + , closable: true // pane can open & close + , resizable: true // when open, pane can be resized + , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out + , initClosed: false // true = init pane as 'closed' + , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing + // SELECTORS + //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane + , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! + , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content' + , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector) + // GENERIC ROOT-CLASSES - for auto-generated classNames + , paneClass: "ui-layout-pane" // Layout Pane + , resizerClass: "ui-layout-resizer" // Resizer Bar + , togglerClass: "ui-layout-toggler" // Toggler Button + , buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin' + // ELEMENT SIZE & SPACING + //, size: 100 // MUST be pane-specific -initial size of pane + , minSize: 0 // when manually resizing a pane + , maxSize: 0 // ditto, 0 = no limit + , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' + , spacing_closed: 6 // ditto - when pane is 'closed' + , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides + , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' + , togglerAlign_open: "center" // top/left, bottom/right, center, OR... + , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right + , togglerContent_open: "" // text or HTML to put INSIDE the toggler + , togglerContent_closed: "" // ditto + // RESIZING OPTIONS + , resizerDblClickToggle: true // + , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes + , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed + , resizerDragOpacity: 1 // option for ui.draggable + //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar + , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES + , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask + , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes + , resizingGrid: false // grid size that the resizers will snap-to during resizing, eg: [20,20] + , livePaneResizing: false // true = LIVE Resizing as resizer is dragged + , liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged + , liveResizingTolerance: 1 // how many px change before pane resizes, to control performance + // SLIDING OPTIONS + , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' + , slideTrigger_open: "click" // click, dblclick, mouseenter + , slideTrigger_close: "mouseleave"// click, mouseleave + , slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open + , slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!) + , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? + , preventQuickSlideClose: $.layout.browser.webkit // Chrome triggers slideClosed as it is opening + , preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + // PANE-SPECIFIC TIPS & MESSAGES + , tips: { + Open: "Open" // eg: "Open Pane" + , Close: "Close" + , Resize: "Resize" + , Slide: "Slide Open" + , Pin: "Pin" + , Unpin: "Un-Pin" + , noRoomToOpen: "Not enough room to show this panel." // alert if user tries to open a pane that cannot + , minSizeWarning: "Panel has reached its minimum size" // displays in browser statusbar + , maxSizeWarning: "Panel has reached its maximum size" // ditto + } + // HOT-KEYS & MISC + , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver + , enableCursorHotkey: true // enabled 'cursor' hotkeys + //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character + , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' + // PANE ANIMATION + // NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed + , fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size' + , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration + , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } + , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation + , animatePaneSizing: false // true = animate resizing after dragging resizer-bar OR sizePane() is called + /* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set: + fxName_open: "slide" // 'Open' pane animation + fnName_close: "slide" // 'Close' pane animation + fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true + fxSpeed_open: null + fxSpeed_close: null + fxSpeed_size: null + fxSettings_open: {} + fxSettings_close: {} + fxSettings_size: {} + */ + // CHILD/NESTED LAYOUTS + , children: null // Layout-options for nested/child layout - even {} is valid as options + , containerSelector: '' // if child is NOT 'directly nested', a selector to find it/them (can have more than one child layout!) + , initChildren: true // true = child layout will be created as soon as _this_ layout completes initialization + , destroyChildren: true // true = destroy child-layout if this pane is destroyed + , resizeChildren: true // true = trigger child-layout.resizeAll() when this pane is resized + // EVENT TRIGGERING + , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes + , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true + // PANE CALLBACKS + , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start + , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end + , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start + , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end + , onopen_start: null // CALLBACK when pane STARTS to Open + , onopen_end: null // CALLBACK when pane ENDS being Opened + , onclose_start: null // CALLBACK when pane STARTS to Close + , onclose_end: null // CALLBACK when pane ENDS being Closed + , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON*** + , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** + , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS + , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS + , onswap_start: null // CALLBACK when pane STARTS to Swap + , onswap_end: null // CALLBACK when pane ENDS being Swapped + , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized + , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized + } +/* + * PANE-SPECIFIC SETTINGS + * - options listed below MUST be specified per-pane - they CANNOT be set under 'panes' + * - all options under the 'panes' key can also be set specifically for any pane + * - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane + */ +, north: { + paneSelector: ".ui-layout-north" + , size: "auto" // eg: "auto", "30%", .30, 200 + , resizerCursor: "n-resize" // custom = url(myCursor.cur) + , customHotkey: "" // EITHER a charCode (43) OR a character ("o") + } +, south: { + paneSelector: ".ui-layout-south" + , size: "auto" + , resizerCursor: "s-resize" + , customHotkey: "" + } +, east: { + paneSelector: ".ui-layout-east" + , size: 200 + , resizerCursor: "e-resize" + , customHotkey: "" + } +, west: { + paneSelector: ".ui-layout-west" + , size: 200 + , resizerCursor: "w-resize" + , customHotkey: "" + } +, center: { + paneSelector: ".ui-layout-center" + , minWidth: 0 + , minHeight: 0 + } +}; + +$.layout.optionsMap = { + // layout/global options - NOT pane-options + layout: ("name,instanceKey,stateManagement,effects,inset,zIndexes,errors," + + "zIndex,scrollToBookmarkOnLoad,showErrorMessages,maskPanesEarly," + + "outset,resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay," + + "onresizeall,onresizeall_start,onresizeall_end,onload,onload_start,onload_end,onunload,onunload_start,onunload_end").split(",") +// borderPanes: [ ALL options that are NOT specified as 'layout' ] + // default.panes options that apply to the center-pane (most options apply _only_ to border-panes) +, center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad," + + "showOverflowOnHover,maskContents,maskObjects,liveContentResizing," + + "containerSelector,children,initChildren,resizeChildren,destroyChildren," + + "onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",") + // options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key +, noDefault: ("paneSelector,resizerCursor,customHotkey").split(",") +}; + +/** + * Processes options passed in converts flat-format data into subkey (JSON) format + * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName + * Plugins may also call this method so they can transform their own data + * + * @param {!Object} hash Data/options passed by user - may be a single level or nested levels + * @param {boolean=} [addKeys=false] Should the primary layout.options keys be added if they do not exist? + * @return {Object} Returns hash of minWidth & minHeight + */ +$.layout.transformData = function (hash, addKeys) { + var json = addKeys ? { panes: {}, center: {} } : {} // init return object + , branch, optKey, keys, key, val, i, c; + + if (typeof hash !== "object") return json; // no options passed + + // convert all 'flat-keys' to 'sub-key' format + for (optKey in hash) { + branch = json; + val = hash[ optKey ]; + keys = optKey.split("__"); // eg: west__size or north__fxSettings__duration + c = keys.length - 1; + // convert underscore-delimited to subkeys + for (i=0; i <= c; i++) { + key = keys[i]; + if (i === c) { // last key = value + if ($.isPlainObject( val )) + branch[key] = $.layout.transformData( val ); // RECURSE + else + branch[key] = val; + } + else { + if (!branch[key]) + branch[key] = {}; // create the subkey + // recurse to sub-key for next loop - if not done + branch = branch[key]; + } + } + } + return json; +}; + +// INTERNAL CONFIG DATA - DO NOT CHANGE THIS! +$.layout.backwardCompatibility = { + // data used by renameOldOptions() + map: { + // OLD Option Name: NEW Option Name + applyDefaultStyles: "applyDemoStyles" + // CHILD/NESTED LAYOUTS + , childOptions: "children" + , initChildLayout: "initChildren" + , destroyChildLayout: "destroyChildren" + , resizeChildLayout: "resizeChildren" + , resizeNestedLayout: "resizeChildren" + // MISC Options + , resizeWhileDragging: "livePaneResizing" + , resizeContentWhileDragging: "liveContentResizing" + , triggerEventsWhileDragging: "triggerEventsDuringLiveResize" + , maskIframesOnResize: "maskContents" + // STATE MANAGEMENT + , useStateCookie: "stateManagement.enabled" + , "cookie.autoLoad": "stateManagement.autoLoad" + , "cookie.autoSave": "stateManagement.autoSave" + , "cookie.keys": "stateManagement.stateKeys" + , "cookie.name": "stateManagement.cookie.name" + , "cookie.domain": "stateManagement.cookie.domain" + , "cookie.path": "stateManagement.cookie.path" + , "cookie.expires": "stateManagement.cookie.expires" + , "cookie.secure": "stateManagement.cookie.secure" + // OLD Language options + , noRoomToOpenTip: "tips.noRoomToOpen" + , togglerTip_open: "tips.Close" // open = Close + , togglerTip_closed: "tips.Open" // closed = Open + , resizerTip: "tips.Resize" + , sliderTip: "tips.Slide" + } + +/** +* @param {Object} opts +*/ +, renameOptions: function (opts) { + var map = $.layout.backwardCompatibility.map + , oldData, newData, value + ; + for (var itemPath in map) { + oldData = getBranch( itemPath ); + value = oldData.branch[ oldData.key ]; + if (value !== undefined) { + newData = getBranch( map[itemPath], true ); + newData.branch[ newData.key ] = value; + delete oldData.branch[ oldData.key ]; + } + } + + /** + * @param {string} path + * @param {boolean=} [create=false] Create path if does not exist + */ + function getBranch (path, create) { + var a = path.split(".") // split keys into array + , c = a.length - 1 + , D = { branch: opts, key: a[c] } // init branch at top & set key (last item) + , i = 0, k, undef; + for (; i 0) { + if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + // make hidden, then visible to 'refresh' display after animation + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + /** + * @param {(string|!Object)} el + * @param {number=} outerHeight + * @param {boolean=} [autoHide=false] + */ +, setOuterHeight = function (el, outerHeight, autoHide) { + var $E = el, h; + if (isStr(el)) $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + h = cssH($E, outerHeight); + $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent + if (h > 0 && $E.innerWidth() > 0) { + if (autoHide && $E.data('autoHidden')) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + + /** + * Converts any 'size' params to a pixel/integer size, if not already + * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated + * + /** + * @param {string} pane + * @param {(string|number)=} size + * @param {string=} [dir] + * @return {number} + */ +, _parseSize = function (pane, size, dir) { + if (!dir) dir = _c[pane].dir; + + if (isStr(size) && size.match(/%/)) + size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal + + if (size === 0) + return 0; + else if (size >= 1) + return parseInt(size, 10); + + var o = options, avail = 0; + if (dir=="horz") // north or south or center.minHeight + avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); + else if (dir=="vert") // east or west or center.minWidth + avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); + + if (size === -1) // -1 == 100% + return avail; + else if (size > 0) // percentage, eg: .25 + return round(avail * size); + else if (pane=="center") + return 0; + else { // size < 0 || size=='auto' || size==Missing || size==Invalid + // auto-size the pane + var dim = (dir === "horz" ? "height" : "width") + , $P = $Ps[pane] + , $C = dim === 'height' ? $Cs[pane] : false + , vis = $.layout.showInvisibly($P) // show pane invisibly if hidden + , szP = $P.css(dim) // SAVE current pane size + , szC = $C ? $C.css(dim) : 0 // SAVE current content size + ; + $P.css(dim, "auto"); + if ($C) $C.css(dim, "auto"); + size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE + $P.css(dim, szP).css(vis); // RESET size & visibility + if ($C) $C.css(dim, szC); + return size; + } + } + + /** + * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added + * + * @param {(string|!Object)} pane + * @param {boolean=} [inclSpace=false] + * @return {number} Returns EITHER Width for east/west panes OR Height for north/south panes + */ +, getPaneSize = function (pane, inclSpace) { + var + $P = $Ps[pane] + , o = options[pane] + , s = state[pane] + , oSp = (inclSpace ? o.spacing_open : 0) + , cSp = (inclSpace ? o.spacing_closed : 0) + ; + if (!$P || s.isHidden) + return 0; + else if (s.isClosed || (s.isSliding && inclSpace)) + return cSp; + else if (_c[pane].dir === "horz") + return $P.outerHeight() + oSp; + else // dir === "vert" + return $P.outerWidth() + oSp; + } + + /** + * Calculate min/max pane dimensions and limits for resizing + * + * @param {string} pane + * @param {boolean=} [slide=false] + */ +, setSizeLimits = function (pane, slide) { + if (!isInitialized()) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , type = c.sizeType.toLowerCase() + , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param + , $P = $Ps[pane] + , paneSpacing = o.spacing_open + // measure the pane on the *opposite side* from this pane + , altPane = _c.oppositeEdge[pane] + , altS = state[altPane] + , $altP = $Ps[altPane] + , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) + , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) + // limitSize prevents this pane from 'overlapping' opposite pane + , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) + , minCenterDims = cssMinDims("center") + , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) + // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them + , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) + , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) + , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) + , r = s.resizerPosition = {} // used to set resizing limits + , top = sC.inset.top + , left = sC.inset.left + , W = sC.innerWidth + , H = sC.innerHeight + , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east + ; + switch (pane) { + case "north": r.min = top + minSize; + r.max = top + maxSize; + break; + case "west": r.min = left + minSize; + r.max = left + maxSize; + break; + case "south": r.min = top + H - maxSize - rW; + r.max = top + H - minSize - rW; + break; + case "east": r.min = left + W - maxSize - rW; + r.max = left + W - minSize - rW; + break; + }; + } + + /** + * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes + * + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height + */ +, calcNewCenterPaneDims = function () { + var d = { + top: getPaneSize("north", true) // true = include 'spacing' value for pane + , bottom: getPaneSize("south", true) + , left: getPaneSize("west", true) + , right: getPaneSize("east", true) + , width: 0 + , height: 0 + }; + + // NOTE: sC = state.container + // calc center-pane outer dimensions + d.width = sC.innerWidth - d.left - d.right; // outerWidth + d.height = sC.innerHeight - d.bottom - d.top; // outerHeight + // add the 'container border/padding' to get final positions relative to the container + d.top += sC.inset.top; + d.bottom += sC.inset.bottom; + d.left += sC.inset.left; + d.right += sC.inset.right; + + return d; + } + + + /** + * @param {!Object} el + * @param {boolean=} [allStates=false] + */ +, getHoverClasses = function (el, allStates) { + var + $El = $(el) + , type = $El.data("layoutRole") + , pane = $El.data("layoutEdge") + , o = options[pane] + , root = o[type +"Class"] + , _pane = "-"+ pane // eg: "-west" + , _open = "-open" + , _closed = "-closed" + , _slide = "-sliding" + , _hover = "-hover " // NOTE the trailing space + , _state = $El.hasClass(root+_closed) ? _closed : _open + , _alt = _state === _closed ? _open : _closed + , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) + ; + if (allStates) // when 'removing' classes, also remove alternate-state classes + classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); + + if (type=="resizer" && $El.hasClass(root+_slide)) + classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); + + return $.trim(classes); + } +, addHover = function (evt, el) { + var $E = $(el || this); + if (evt && $E.data("layoutRole") === "toggler") + evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar + $E.addClass( getHoverClasses($E) ); + } +, removeHover = function (evt, el) { + var $E = $(el || this); + $E.removeClass( getHoverClasses($E, true) ); + } + +, onResizerEnter = function (evt) { // ALSO called by toggler.mouseenter + var pane = $(this).data("layoutEdge") + , s = state[pane] + ; + // ignore closed-panes and mouse moving back & forth over resizer! + // also ignore if ANY pane is currently resizing + if ( s.isClosed || s.isResizing || state.paneResizing ) return; + + if ($.fn.disableSelection) + $("body").disableSelection(); + if (options.maskPanesEarly) + showMasks( pane, { resizing: true }); + } +, onResizerLeave = function (evt, el) { + var e = el || this // el is only passed when called by the timer + , pane = $(e).data("layoutEdge") + , name = pane +"ResizerLeave" + ; + timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set + timer.clear(name); // cancel enableSelection timer - may re/set below + // this method calls itself on a timer because it needs to allow + // enough time for dragging to kick-in and set the isResizing flag + // dragging has a 100ms delay set, so this delay must be >100 + if (!el) // 1st call - mouseleave event + timer.set(name, function(){ onResizerLeave(evt, e); }, 200); + // if user is resizing, then dragStop will enableSelection(), so can skip it here + else if ( !state.paneResizing ) { // 2nd call - by timer + if ($.fn.enableSelection) + $("body").enableSelection(); + if (options.maskPanesEarly) + hideMasks(); + } + } + +/* + * ########################### + * INITIALIZATION METHODS + * ########################### + */ + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see none - triggered onInit + * @return mixed true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort + */ +, _create = function () { + // initialize config/options + initOptions(); + var o = options + , s = state; + + // TEMP state so isInitialized returns true during init process + s.creatingLayout = true; + + // init plugins for this layout, if there are any (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onCreate ); + + // options & state have been initialized, so now run beforeLoad callback + // onload will CANCEL layout creation if it returns false + if (false === _runCallbacks("onload_start")) + return 'cancel'; + + // initialize the container element + _initContainer(); + + // bind hotkey function - keyDown - if required + initHotkeys(); + + // bind window.onunload + $(window).bind("unload."+ sID, unload); + + // init plugins for this layout, if there are any (eg: customButtons) + runPluginCallbacks( Instance, $.layout.onLoad ); + + // if layout elements are hidden, then layout WILL NOT complete initialization! + // initLayoutElements will set initialized=true and run the onload callback IF successful + if (o.initPanes) _initLayoutElements(); + + delete s.creatingLayout; + + return state.initialized; + } + + /** + * Initialize the layout IF not already + * + * @see All methods in Instance run this test + * @return boolean true = layoutElements have been initialized | false = panes are not initialized (yet) + */ +, isInitialized = function () { + if (state.initialized || state.creatingLayout) return true; // already initialized + else return _initLayoutElements(); // try to init panes NOW + } + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see _create() & isInitialized + * @param {boolean=} [retry=false] // indicates this is a 2nd try + * @return An object pointer to the instance created + */ +, _initLayoutElements = function (retry) { + // initialize config/options + var o = options; + // CANNOT init panes inside a hidden container! + if (!$N.is(":visible")) { + // handle Chrome bug where popup window 'has no height' + // if layout is BODY element, try again in 50ms + // SEE: http://layout.jquery-dev.net/samples/test_popup_window.html + if ( !retry && browser.webkit && $N[0].tagName === "BODY" ) + setTimeout(function(){ _initLayoutElements(true); }, 50); + return false; + } + + // a center pane is required, so make sure it exists + if (!getPane("center").length) { + return _log( o.errors.centerPaneMissing ); + } + + // TEMP state so isInitialized returns true during init process + state.creatingLayout = true; + + // update Container dims + $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values + + // initialize all layout elements + initPanes(); // size & position panes - calls initHandles() - which calls initResizable() + + if (o.scrollToBookmarkOnLoad) { + var l = self.location; + if (l.hash) l.replace( l.hash ); // scrollTo Bookmark + } + + // check to see if this layout 'nested' inside a pane + if (Instance.hasParentLayout) + o.resizeWithWindow = false; + // bind resizeAll() for 'this layout instance' to window.resize event + else if (o.resizeWithWindow) + $(window).bind("resize."+ sID, windowResize); + + delete state.creatingLayout; + state.initialized = true; + + // init plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onReady ); + + // now run the onload callback, if exists + _runCallbacks("onload_end"); + + return true; // elements initialized successfully + } + + /** + * Initialize nested layouts for a specific pane - can optionally pass layout-options + * + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {Object=} [opts] Layout-options - if passed, will OVERRRIDE options[pane].children + * @return An object pointer to the layout instance created - or null + */ +, createChildren = function (evt_or_pane, opts) { + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + ; + if (!$P) return; + var $C = $Cs[pane] + , s = state[pane] + , o = options[pane] + , sm = options.stateManagement || {} + , cos = opts ? (o.children = opts) : o.children + ; + if ( $.isPlainObject( cos ) ) + cos = [ cos ]; // convert a hash to a 1-elem array + else if (!cos || !$.isArray( cos )) + return; + + $.each( cos, function (idx, co) { + if ( !$.isPlainObject( co ) ) return; + + // determine which element is supposed to be the 'child container' + // if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane + var $containers = co.containerSelector ? $P.find( co.containerSelector ) : ($C || $P); + + $containers.each(function(){ + var $cont = $(this) + , child = $cont.data("layout") // see if a child-layout ALREADY exists on this element + ; + // if no layout exists, but children are set, try to create the layout now + if (!child) { + // TODO: see about moving this to the stateManagement plugin, as a method + // set a unique child-instance key for this layout, if not already set + setInstanceKey({ container: $cont, options: co }, s ); + // If THIS layout has a hash in stateManagement.autoLoad, + // then see if it also contains state-data for this child-layout + // If so, copy the stateData to child.options.stateManagement.autoLoad + if ( sm.includeChildren && state.stateData[pane] ) { + // THIS layout's state was cached when its state was loaded + var paneChildren = state.stateData[pane].children || {} + , childState = paneChildren[ co.instanceKey ] + , co_sm = co.stateManagement || (co.stateManagement = { autoLoad: true }) + ; + // COPY the stateData into the autoLoad key + if ( co_sm.autoLoad === true && childState ) { + co_sm.autoSave = false; // disable autoSave because saving handled by parent-layout + co_sm.includeChildren = true; // cascade option - FOR NOW + co_sm.autoLoad = $.extend(true, {}, childState); // COPY the state-hash + } + } + + // create the layout + child = $cont.layout( co ); + + // if successful, update data + if (child) { + // add the child and update all layout-pointers + // MAY have already been done by child-layout calling parent.refreshChildren() + refreshChildren( pane, child ); + } + } + }); + }); + } + +, setInstanceKey = function (child, parentPaneState) { + // create a named key for use in state and instance branches + var $c = child.container + , o = child.options + , sm = o.stateManagement + , key = o.instanceKey || $c.data("layoutInstanceKey") + ; + if (!key) key = (sm && sm.cookie ? sm.cookie.name : '') || o.name; // look for a name/key + if (!key) key = "layout"+ (++parentPaneState.childIdx); // if no name/key found, generate one + else key = key.replace(/[^\w-]/gi, '_').replace(/_{2,}/g, '_'); // ensure is valid as a hash key + o.instanceKey = key; + $c.data("layoutInstanceKey", key); // useful if layout is destroyed and then recreated + return key; + } + + /** + * @param {string} pane The pane being opened, ie: north, south, east, or west + * @param {Object=} newChild New child-layout Instance to add to this pane + */ +, refreshChildren = function (pane, newChild) { + var $P = $Ps[pane] + , pC = children[pane] + , s = state[pane] + , o + ; + // check for destroy()ed layouts and update the child pointers & arrays + if ($.isPlainObject( pC )) { + $.each( pC, function (key, child) { + if (child.destroyed) delete pC[key] + }); + // if no more children, remove the children hash + if ($.isEmptyObject( pC )) + pC = children[pane] = null; // clear children hash + } + + // see if there is a directly-nested layout inside this pane + // if there is, then there can be only ONE child-layout, so check that... + if (!newChild && !pC) { + newChild = $P.data("layout"); + } + + // if a newChild instance was passed, add it to children[pane] + if (newChild) { + // update child.state + newChild.hasParentLayout = true; // set parent-flag in child + // instanceKey is a key-name used in both state and children + o = newChild.options; + // set a unique child-instance key for this layout, if not already set + setInstanceKey( newChild, s ); + // add pointer to pane.children hash + if (!pC) pC = children[pane] = {}; // create an empty children hash + pC[ o.instanceKey ] = newChild.container.data("layout"); // add childLayout instance + } + + // ALWAYS refresh the pane.children alias, even if null + Instance[pane].children = children[pane]; + + // if newChild was NOT passed - see if there is a child layout NOW + if (!newChild) { + createChildren(pane); // MAY create a child and re-call this method + } + } + +, windowResize = function () { + var o = options + , delay = Number(o.resizeWithWindowDelay); + if (delay < 10) delay = 100; // MUST have a delay! + // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway + timer.clear("winResize"); // if already running + timer.set("winResize", function(){ + timer.clear("winResize"); + timer.clear("winResizeRepeater"); + var dims = elDims( $N, o.inset ); + // only trigger resizeAll() if container has changed size + if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight) + resizeAll(); + }, delay); + // ALSO set fixed-delay timer, if not already running + if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater(); + } + +, setWindowResizeRepeater = function () { + var delay = Number(options.resizeWithWindowMaxDelay); + if (delay > 0) + timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); + } + +, unload = function () { + var o = options; + + _runCallbacks("onunload_start"); + + // trigger plugin callabacks for this layout (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onUnload ); + + _runCallbacks("onunload_end"); + } + + /** + * Validate and initialize container CSS and events + * + * @see _create() + */ +, _initContainer = function () { + var + N = $N[0] + , $H = $("html") + , tag = sC.tagName = N.tagName + , id = sC.id = N.id + , cls = sC.className = N.className + , o = options + , name = o.name + , props = "position,margin,padding,border" + , css = "layoutCSS" + , CSS = {} + , hid = "hidden" // used A LOT! + // see if this container is a 'pane' inside an outer-layout + , parent = $N.data("parentLayout") // parent-layout Instance + , pane = $N.data("layoutEdge") // pane-name in parent-layout + , isChild = parent && pane + , num = $.layout.cssNum + , $parent, n + ; + // sC = state.container + sC.selector = $N.selector.split(".slice")[0]; + sC.ref = (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages + sC.isBody = (tag === "BODY"); + + // try to find a parent-layout + if (!isChild && !sC.isBody) { + $parent = $N.closest("."+ $.layout.defaults.panes.paneClass); + parent = $parent.data("parentLayout"); + pane = $parent.data("layoutEdge"); + isChild = parent && pane; + } + + $N .data({ + layout: Instance + , layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID + }) + .addClass(o.containerClass) + ; + var layoutMethods = { + destroy: '' + , initPanes: '' + , resizeAll: 'resizeAll' + , resize: 'resizeAll' + }; + // loop hash and bind all methods - include layoutID namespacing + for (name in layoutMethods) { + $N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]); + } + + // if this container is another layout's 'pane', then set child/parent pointers + if (isChild) { + // update parent flag + Instance.hasParentLayout = true; + // set pointers to THIS child-layout (Instance) in parent-layout + parent.refreshChildren( pane, Instance ); + } + + // SAVE original container CSS for use in destroy() + if (!$N.data(css)) { + // handle props like overflow different for BODY & HTML - has 'system default' values + if (sC.isBody) { + // SAVE CSS + $N.data(css, $.extend( styles($N, props), { + height: $N.css("height") + , overflow: $N.css("overflow") + , overflowX: $N.css("overflowX") + , overflowY: $N.css("overflowY") + })); + // ALSO SAVE CSS + $H.data(css, $.extend( styles($H, 'padding'), { + height: "auto" // FF would return a fixed px-size! + , overflow: $H.css("overflow") + , overflowX: $H.css("overflowX") + , overflowY: $H.css("overflowY") + })); + } + else // handle props normally for non-body elements + $N.data(css, styles($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY") ); + } + + try { + // common container CSS + CSS = { + overflow: hid + , overflowX: hid + , overflowY: hid + }; + $N.css( CSS ); + + if (o.inset && !$.isPlainObject(o.inset)) { + // can specify a single number for equal outset all-around + n = parseInt(o.inset, 10) || 0 + o.inset = { + top: n + , bottom: n + , left: n + , right: n + }; + } + + // format html & body if this is a full page layout + if (sC.isBody) { + // if HTML has padding, use this as an outer-spacing around BODY + if (!o.outset) { + // use padding from parent-elem (HTML) as outset + o.outset = { + top: num($H, "paddingTop") + , bottom: num($H, "paddingBottom") + , left: num($H, "paddingLeft") + , right: num($H, "paddingRight") + }; + } + else if (!$.isPlainObject(o.outset)) { + // can specify a single number for equal outset all-around + n = parseInt(o.outset, 10) || 0 + o.outset = { + top: n + , bottom: n + , left: n + , right: n + }; + } + // HTML + $H.css( CSS ).css({ + height: "100%" + , border: "none" // no border or padding allowed when using height = 100% + , padding: 0 // ditto + , margin: 0 + }); + // BODY + if (browser.isIE6) { + // IE6 CANNOT use the trick of setting absolute positioning on all 4 sides - must have 'height' + $N.css({ + width: "100%" + , height: "100%" + , border: "none" // no border or padding allowed when using height = 100% + , padding: 0 // ditto + , margin: 0 + , position: "relative" + }); + // convert body padding to an inset option - the border cannot be measured in IE6! + if (!o.inset) o.inset = elDims( $N ).inset; + } + else { // use absolute positioning for BODY to allow borders & padding without overflow + $N.css({ + width: "auto" + , height: "auto" + , margin: 0 + , position: "absolute" // allows for border and padding on BODY + }); + // apply edge-positioning created above + $N.css( o.outset ); + } + // set current layout-container dimensions + $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT include insetX values + } + else { + // container MUST have 'position' + var p = $N.css("position"); + if (!p || !p.match(/(fixed|absolute|relative)/)) + $N.css("position","relative"); + + // set current layout-container dimensions + if ( $N.is(":visible") ) { + $.extend(sC, elDims( $N, o.inset )); // passing inset means DO NOT change insetX (padding) values + if (sC.innerHeight < 1) // container has no 'height' - warn developer + _log( o.errors.noContainerHeight.replace(/CONTAINER/, sC.ref) ); + } + } + + // if container has min-width/height, then enable scrollbar(s) + if ( num($N, "minWidth") ) $N.parent().css("overflowX","auto"); + if ( num($N, "minHeight") ) $N.parent().css("overflowY","auto"); + + } catch (ex) {} + } + + /** + * Bind layout hotkeys - if options enabled + * + * @see _create() and addPane() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHotkeys = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + // bind keyDown to capture hotkeys, if option enabled for ANY pane + $.each(panes, function (i, pane) { + var o = options[pane]; + if (o.enableCursorHotkey || o.customHotkey) { + $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE + return false; // BREAK - binding was done + } + }); + } + + /** + * Build final OPTIONS data + * + * @see _create() + */ +, initOptions = function () { + var data, d, pane, key, val, i, c, o; + + // reprocess user's layout-options to have correct options sub-key structure + opts = $.layout.transformData( opts, true ); // panes = default subkey + + // auto-rename old options for backward compatibility + opts = $.layout.backwardCompatibility.renameAllOptions( opts ); + + // if user-options has 'panes' key (pane-defaults), clean it... + if (!$.isEmptyObject(opts.panes)) { + // REMOVE any pane-defaults that MUST be set per-pane + data = $.layout.optionsMap.noDefault; + for (i=0, c=data.length; i 0) { + z.pane_normal = zo; + z.content_mask = max(zo+1, z.content_mask); // MIN = +1 + z.resizer_normal = max(zo+2, z.resizer_normal); // MIN = +2 + } + + // DELETE 'panes' key now that we are done - values were copied to EACH pane + delete options.panes; + + + function createFxOptions ( pane ) { + var o = options[pane] + , d = options.panes; + // ensure fxSettings key to avoid errors + if (!o.fxSettings) o.fxSettings = {}; + if (!d.fxSettings) d.fxSettings = {}; + + $.each(["_open","_close","_size"], function (i,n) { + var + sName = "fxName"+ n + , sSpeed = "fxSpeed"+ n + , sSettings = "fxSettings"+ n + // recalculate fxName according to specificity rules + , fxName = o[sName] = + o[sName] // options.west.fxName_open + || d[sName] // options.panes.fxName_open + || o.fxName // options.west.fxName + || d.fxName // options.panes.fxName + || "none" // MEANS $.layout.defaults.panes.fxName == "" || false || null || 0 + , fxExists = $.effects && ($.effects[fxName] || ($.effects.effect && $.effects.effect[fxName])) + ; + // validate fxName to ensure is valid effect - MUST have effect-config data in options.effects + if (fxName === "none" || !options.effects[fxName] || !fxExists) + fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName + + // set vars for effects subkeys to simplify logic + var fx = options.effects[fxName] || {} // effects.slide + , fx_all = fx.all || null // effects.slide.all + , fx_pane = fx[pane] || null // effects.slide.west + ; + // create fxSpeed[_open|_close|_size] + o[sSpeed] = + o[sSpeed] // options.west.fxSpeed_open + || d[sSpeed] // options.west.fxSpeed_open + || o.fxSpeed // options.west.fxSpeed + || d.fxSpeed // options.panes.fxSpeed + || null // DEFAULT - let fxSetting.duration control speed + ; + // create fxSettings[_open|_close|_size] + o[sSettings] = $.extend( + true + , {} + , fx_all // effects.slide.all + , fx_pane // effects.slide.west + , d.fxSettings // options.panes.fxSettings + , o.fxSettings // options.west.fxSettings + , d[sSettings] // options.panes.fxSettings_open + , o[sSettings] // options.west.fxSettings_open + ); + }); + + // DONE creating action-specific-settings for this pane, + // so DELETE generic options - are no longer meaningful + delete o.fxName; + delete o.fxSpeed; + delete o.fxSettings; + } + } + + /** + * Initialize module objects, styling, size and position for all panes + * + * @see _initElements() + * @param {string} pane The pane to process + */ +, getPane = function (pane) { + var sel = options[pane].paneSelector + if (sel.substr(0,1)==="#") // ID selector + // NOTE: elements selected 'by ID' DO NOT have to be 'children' + return $N.find(sel).eq(0); + else { // class or other selector + var $P = $N.children(sel).eq(0); + // look for the pane nested inside a 'form' element + return $P.length ? $P : $N.children("form:first").children(sel).eq(0); + } + } + + /** + * @param {Object=} evt + */ +, initPanes = function (evt) { + // stopPropagation if called by trigger("layoutinitpanes") - use evtPane utility + evtPane(evt); + + // NOTE: do north & south FIRST so we can measure their height - do center LAST + $.each(_c.allPanes, function (idx, pane) { + addPane( pane, true ); + }); + + // init the pane-handles NOW in case we have to hide or close the pane below + initHandles(); + + // now that all panes have been initialized and initially-sized, + // make sure there is really enough space available for each pane + $.each(_c.borderPanes, function (i, pane) { + if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN + setSizeLimits(pane); + makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() + } + }); + // size center-pane AGAIN in case we 'closed' a border-pane in loop above + sizeMidPanes("center"); + + // Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing! + // Before RC30.3, there was a 10ms delay here, but that caused layout + // to load asynchrously, which is BAD, so try skipping delay for now + + // process pane contents and callbacks, and init/resize child-layout if exists + $.each(_c.allPanes, function (idx, pane) { + afterInitPane(pane); + }); + } + + /** + * Add a pane to the layout - subroutine of initPanes() + * + * @see initPanes() + * @param {string} pane The pane to process + * @param {boolean=} [force=false] Size content after init + */ +, addPane = function (pane, force) { + if (!force && !isInitialized()) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , fx = s.fx + , spacing = o.spacing_open || 0 + , isCenter = (pane === "center") + , CSS = {} + , $P = $Ps[pane] + , size, minSize, maxSize, child + ; + // if pane-pointer already exists, remove the old one first + if ($P) + removePane( pane, false, true, false ); + else + $Cs[pane] = false; // init + + $P = $Ps[pane] = getPane(pane); + if (!$P.length) { + $Ps[pane] = false; // logic + return; + } + + // SAVE original Pane CSS + if (!$P.data("layoutCSS")) { + var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; + $P.data("layoutCSS", styles($P, props)); + } + + // create alias for pane data in Instance - initHandles will add more + Instance[pane] = { + name: pane + , pane: $Ps[pane] + , content: $Cs[pane] + , options: options[pane] + , state: state[pane] + , children: children[pane] + }; + + // add classes, attributes & events + $P .data({ + parentLayout: Instance // pointer to Layout Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "pane" + }) + .css(c.cssReq).css("zIndex", options.zIndexes.pane_normal) + .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles + .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' + .bind("mouseenter."+ sID, addHover ) + .bind("mouseleave."+ sID, removeHover ) + ; + var paneMethods = { + hide: '' + , show: '' + , toggle: '' + , close: '' + , open: '' + , slideOpen: '' + , slideClose: '' + , slideToggle: '' + , size: 'sizePane' + , sizePane: 'sizePane' + , sizeContent: '' + , sizeHandles: '' + , enableClosable: '' + , disableClosable: '' + , enableSlideable: '' + , disableSlideable: '' + , enableResizable: '' + , disableResizable: '' + , swapPanes: 'swapPanes' + , swap: 'swapPanes' + , move: 'swapPanes' + , removePane: 'removePane' + , remove: 'removePane' + , createChildren: '' + , resizeChildren: '' + , resizeAll: 'resizeAll' + , resizeLayout: 'resizeAll' + } + , name; + // loop hash and bind all methods - include layoutID namespacing + for (name in paneMethods) { + $P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]); + } + + // see if this pane has a 'scrolling-content element' + initContent(pane, false); // false = do NOT sizeContent() - called later + + if (!isCenter) { + // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) + // if o.size is auto or not valid, then MEASURE the pane and use that as its 'size' + size = s.size = _parseSize(pane, o.size); + minSize = _parseSize(pane,o.minSize) || 1; + maxSize = _parseSize(pane,o.maxSize) || 100000; + if (size > 0) size = max(min(size, maxSize), minSize); + s.autoResize = o.autoResize; // used with percentage sizes + + // state for border-panes + s.isClosed = false; // true = pane is closed + s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes + s.isResizing= false; // true = pane is in process of being resized + s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! + + // array for 'pin buttons' whose classNames are auto-updated on pane-open/-close + if (!s.pins) s.pins = []; + } + // states common to ALL panes + s.tagName = $P[0].tagName; + s.edge = pane; // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going) + s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically + s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic + + // init pane positioning + setPanePosition( pane ); + + // if pane is not visible, + if (dir === "horz") // north or south pane + CSS.height = cssH($P, size); + else if (dir === "vert") // east or west pane + CSS.width = cssW($P, size); + //else if (isCenter) {} + + $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes + if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback + + // if manually adding a pane AFTER layout initialization, then... + if (state.initialized) { + initHandles( pane ); + initHotkeys( pane ); + } + + // close or hide the pane if specified in settings + if (o.initClosed && o.closable && !o.initHidden) + close(pane, true, true); // true, true = force, noAnimation + else if (o.initHidden || o.initClosed) + hide(pane); // will be completely invisible - no resizer or spacing + else if (!s.noRoom) + // make the pane visible - in case was initially hidden + $P.css("display","block"); + // ELSE setAsOpen() - called later by initHandles() + + // RESET visibility now - pane will appear IF display:block + $P.css("visibility","visible"); + + // check option for auto-handling of pop-ups & drop-downs + if (o.showOverflowOnHover) + $P.hover( allowOverflow, resetOverflow ); + + // if manually adding a pane AFTER layout initialization, then... + if (state.initialized) { + afterInitPane( pane ); + } + } + +, afterInitPane = function (pane) { + var $P = $Ps[pane] + , s = state[pane] + , o = options[pane] + ; + if (!$P) return; + + // see if there is a directly-nested layout inside this pane + if ($P.data("layout")) + refreshChildren( pane, $P.data("layout") ); + + // process pane contents and callbacks, and init/resize child-layout if exists + if (s.isVisible) { // pane is OPEN + if (state.initialized) // this pane was added AFTER layout was created + resizeAll(); // will also sizeContent + else + sizeContent(pane); + + if (o.triggerEventsOnLoad) + _runCallbacks("onresize_end", pane); + else // automatic if onresize called, otherwise call it specifically + // resize child - IF inner-layout already exists (created before this layout) + resizeChildren(pane, true); // a previously existing childLayout + } + + // init childLayouts - even if pane is not visible + if (o.initChildren && o.children) + createChildren(pane); + } + + /** + * @param {string=} panes The pane(s) to process + */ +, setPanePosition = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes, function (i, pane) { + var $P = $Ps[pane] + , $R = $Rs[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side + , CSS = {} + ; + if (!$P) return; // pane does not exist - skip + + // set css-position to account for container borders & padding + switch (pane) { + case "north": CSS.top = sC.inset.top; + CSS.left = sC.inset.left; + CSS.right = sC.inset.right; + break; + case "south": CSS.bottom = sC.inset.bottom; + CSS.left = sC.inset.left; + CSS.right = sC.inset.right; + break; + case "west": CSS.left = sC.inset.left; // top, bottom & height set by sizeMidPanes() + break; + case "east": CSS.right = sC.inset.right; // ditto + break; + case "center": // top, left, width & height set by sizeMidPanes() + } + // apply position + $P.css(CSS); + + // update resizer position + if ($R && s.isClosed) + $R.css(side, sC.inset[side]); + else if ($R && !s.isHidden) + $R.css(side, sC.inset[side] + getPaneSize(pane)); + }); + } + + /** + * Initialize module objects, styling, size and position for all resize bars and toggler buttons + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHandles = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes, function (i, pane) { + var $P = $Ps[pane]; + $Rs[pane] = false; // INIT + $Ts[pane] = false; + if (!$P) return; // pane does not exist - skip + + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , paneId = o.paneSelector.substr(0,1) === "#" ? o.paneSelector.substr(1) : "" + , rClass = o.resizerClass + , tClass = o.togglerClass + , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) + , _pane = "-"+ pane // used for classNames + , _state = (s.isVisible ? "-open" : "-closed") // used for classNames + , I = Instance[pane] + // INIT RESIZER BAR + , $R = I.resizer = $Rs[pane] = $("
        ") + // INIT TOGGLER BUTTON + , $T = I.toggler = (o.closable ? $Ts[pane] = $("
        ") : false) + ; + + //if (s.isVisible && o.resizable) ... handled by initResizable + if (!s.isVisible && o.slidable) + $R.attr("title", o.tips.Slide).css("cursor", o.sliderCursor); + + $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" + .attr("id", paneId ? paneId +"-resizer" : "" ) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "resizer" + }) + .css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal) + .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles + .addClass(rClass +" "+ rClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead + .hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter + .appendTo($N) // append DIV to container + ; + if (o.resizerDblClickToggle) + $R.bind("dblclick."+ sID, toggle ); + + if ($T) { + $T // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" + .attr("id", paneId ? paneId +"-toggler" : "" ) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "toggler" + }) + .css(_c.togglers.cssReq) // add base/required styles + .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles + .addClass(tClass +" "+ tClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead + .bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer + .appendTo($R) // append SPAN to resizer DIV + ; + // ADD INNER-SPANS TO TOGGLER + if (o.togglerContent_open) // ui-layout-open + $(""+ o.togglerContent_open +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-open") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead! + ; + if (o.togglerContent_closed) // ui-layout-closed + $(""+ o.togglerContent_closed +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .addClass("content content-closed") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead! + ; + // ADD TOGGLER.click/.hover + enableClosable(pane); + } + + // add Draggable events + initResizable(pane); + + // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" + if (s.isVisible) + setAsOpen(pane); // onOpen will be called, but NOT onResize + else { + setAsClosed(pane); // onClose will be called + bindStartSlidingEvents(pane, true); // will enable events IF option is set + } + + }); + + // SET ALL HANDLE DIMENSIONS + sizeHandles(); + } + + + /** + * Initialize scrolling ui-layout-content div - if exists + * + * @see initPane() - or externally after an Ajax injection + * @param {string} pane The pane to process + * @param {boolean=} [resize=true] Size content after init + */ +, initContent = function (pane, resize) { + if (!isInitialized()) return; + var + o = options[pane] + , sel = o.contentSelector + , I = Instance[pane] + , $P = $Ps[pane] + , $C + ; + if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent) + ? $P.find(sel).eq(0) // match 1-element only + : $P.children(sel).eq(0) + ; + if ($C && $C.length) { + $C.data("layoutRole", "content"); + // SAVE original Content CSS + if (!$C.data("layoutCSS")) + $C.data("layoutCSS", styles($C, "height")); + $C.css( _c.content.cssReq ); + if (o.applyDemoStyles) { + $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div + $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane + } + // ensure no vertical scrollbar on pane - will mess up measurements + if ($P.css("overflowX").match(/(scroll|auto)/)) { + $P.css("overflow", "hidden"); + } + state[pane].content = {}; // init content state + if (resize !== false) sizeContent(pane); + // sizeContent() is called AFTER init of all elements + } + else + I.content = $Cs[pane] = false; + } + + + /** + * Add resize-bars to all panes that specify it in options + * -dependancy: $.fn.resizable - will skip if not found + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initResizable = function (panes) { + var draggingAvailable = $.layout.plugins.draggable + , side // set in start() + ; + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (idx, pane) { + var o = options[pane]; + if (!draggingAvailable || !$Ps[pane] || !o.resizable) { + o.resizable = false; + return true; // skip to next + } + + var s = state[pane] + , z = options.zIndexes + , c = _c[pane] + , side = c.dir=="horz" ? "top" : "left" + , $P = $Ps[pane] + , $R = $Rs[pane] + , base = o.resizerClass + , lastPos = 0 // used when live-resizing + , r, live // set in start because may change + // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process + , resizerClass = base+"-drag" // resizer-drag + , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag + // 'helper' class is applied to the CLONED resizer-bar while it is being dragged + , helperClass = base+"-dragging" // resizer-dragging + , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging + , helperLimitClass = base+"-dragging-limit" // resizer-drag + , helperPaneLimitClass = base+"-"+pane+"-dragging-limit" // resizer-north-drag + , helperClassesSet = false // logic var + ; + + if (!s.isClosed) + $R.attr("title", o.tips.Resize) + .css("cursor", o.resizerCursor); // n-resize, s-resize, etc + + $R.draggable({ + containment: $N[0] // limit resizing to layout container + , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis + , delay: 0 + , distance: 1 + , grid: o.resizingGrid + // basic format for helper - style it using class: .ui-draggable-dragging + , helper: "clone" + , opacity: o.resizerDragOpacity + , addClasses: false // avoid ui-state-disabled class when disabled + //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed + , zIndex: z.resizer_drag + + , start: function (e, ui) { + // REFRESH options & state pointers in case we used swapPanes + o = options[pane]; + s = state[pane]; + // re-read options + live = o.livePaneResizing; + + // ondrag_start callback - will CANCEL hide if returns false + // TODO: dragging CANNOT be cancelled like this, so see if there is a way? + if (false === _runCallbacks("ondrag_start", pane)) return false; + + s.isResizing = true; // prevent pane from closing while resizing + state.paneResizing = pane; // easy to see if ANY pane is resizing + timer.clear(pane+"_closeSlider"); // just in case already triggered + + // SET RESIZER LIMITS - used in drag() + setSizeLimits(pane); // update pane/resizer state + r = s.resizerPosition; + lastPos = ui.position[ side ] + + $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes + helperClassesSet = false; // reset logic var - see drag() + + // DISABLE TEXT SELECTION (probably already done by resizer.mouseOver) + $('body').disableSelection(); + + // MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS + showMasks( pane, { resizing: true }); + } + + , drag: function (e, ui) { + if (!helperClassesSet) { // can only add classes after clone has been added to the DOM + //$(".ui-draggable-dragging") + ui.helper + .addClass( helperClass +" "+ helperPaneClass ) // add helper classes + .css({ right: "auto", bottom: "auto" }) // fix dir="rtl" issue + .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar + ; + helperClassesSet = true; + // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! + if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding); + } + // CONTAIN RESIZER-BAR TO RESIZING LIMITS + var limit = 0; + if (ui.position[side] < r.min) { + ui.position[side] = r.min; + limit = -1; + } + else if (ui.position[side] > r.max) { + ui.position[side] = r.max; + limit = 1; + } + // ADD/REMOVE dragging-limit CLASS + if (limit) { + ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit + window.defaultStatus = (limit>0 && pane.match(/(north|west)/)) || (limit<0 && pane.match(/(south|east)/)) ? o.tips.maxSizeWarning : o.tips.minSizeWarning; + } + else { + ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit + window.defaultStatus = ""; + } + // DYNAMICALLY RESIZE PANES IF OPTION ENABLED + // won't trigger unless resizer has actually moved! + if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) { + lastPos = ui.position[side]; + resizePanes(e, ui, pane) + } + } + + , stop: function (e, ui) { + $('body').enableSelection(); // RE-ENABLE TEXT SELECTION + window.defaultStatus = ""; // clear 'resizing limit' message from statusbar + $R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer + s.isResizing = false; + state.paneResizing = false; // easy to see if ANY pane is resizing + resizePanes(e, ui, pane, true); // true = resizingDone + } + + }); + }); + + /** + * resizePanes + * + * Sub-routine called from stop() - and drag() if livePaneResizing + * + * @param {!Object} evt + * @param {!Object} ui + * @param {string} pane + * @param {boolean=} [resizingDone=false] + */ + var resizePanes = function (evt, ui, pane, resizingDone) { + var dragPos = ui.position + , c = _c[pane] + , o = options[pane] + , s = state[pane] + , resizerPos + ; + switch (pane) { + case "north": resizerPos = dragPos.top; break; + case "west": resizerPos = dragPos.left; break; + case "south": resizerPos = sC.layoutHeight - dragPos.top - o.spacing_open; break; + case "east": resizerPos = sC.layoutWidth - dragPos.left - o.spacing_open; break; + }; + // remove container margin from resizer position to get the pane size + var newSize = resizerPos - sC.inset[c.side]; + + // Disable OR Resize Mask(s) created in drag.start + if (!resizingDone) { + // ensure we meet liveResizingTolerance criteria + if (Math.abs(newSize - s.size) < o.liveResizingTolerance) + return; // SKIP resize this time + // resize the pane + manualSizePane(pane, newSize, false, true); // true = noAnimation + sizeMasks(); // resize all visible masks + } + else { // resizingDone + // ondrag_end callback + if (false !== _runCallbacks("ondrag_end", pane)) + manualSizePane(pane, newSize, false, true); // true = noAnimation + hideMasks(true); // true = force hiding all masks even if one is 'sliding' + if (s.isSliding) // RE-SHOW 'object-masks' so objects won't show through sliding pane + showMasks( pane, { resizing: true }); + } + }; + } + + /** + * sizeMask + * + * Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane + * Called when mask created, and during livePaneResizing + */ +, sizeMask = function () { + var $M = $(this) + , pane = $M.data("layoutMask") // eg: "west" + , s = state[pane] + ; + // only masks over an IFRAME-pane need manual resizing + if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes + $M.css({ + top: s.offsetTop + , left: s.offsetLeft + , width: s.outerWidth + , height: s.outerHeight + }); + /* ALT Method... + var $P = $Ps[pane]; + $M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight }); + */ + } +, sizeMasks = function () { + $Ms.each( sizeMask ); // resize all 'visible' masks + } + + /** + * @param {string} pane The pane being resized, animated or isSliding + * @param {Object=} [args] (optional) Options: which masks to apply, and to which panes + */ +, showMasks = function (pane, args) { + var c = _c[pane] + , panes = ["center"] + , z = options.zIndexes + , a = $.extend({ + objectsOnly: false + , animation: false + , resizing: true + , sliding: state[pane].isSliding + }, args ) + , o, s + ; + if (a.resizing) + panes.push( pane ); + if (a.sliding) + panes.push( _c.oppositeEdge[pane] ); // ADD the oppositeEdge-pane + + if (c.dir === "horz") { + panes.push("west"); + panes.push("east"); + } + + $.each(panes, function(i,p){ + s = state[p]; + o = options[p]; + if (s.isVisible && ( o.maskObjects || (!a.objectsOnly && o.maskContents) )) { + getMasks(p).each(function(){ + sizeMask.call(this); + this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1 + this.style.display = "block"; + }); + } + }); + } + + /** + * @param {boolean=} force Hide masks even if a pane is sliding + */ +, hideMasks = function (force) { + // ensure no pane is resizing - could be a timing issue + if (force || !state.paneResizing) { + $Ms.hide(); // hide ALL masks + } + // if ANY pane is sliding, then DO NOT remove masks from panes with maskObjects enabled + else if (!force && !$.isEmptyObject( state.panesSliding )) { + var i = $Ms.length - 1 + , p, $M; + for (; i >= 0; i--) { + $M = $Ms.eq(i); + p = $M.data("layoutMask"); + if (!options[p].maskObjects) { + $M.hide(); + } + } + } + } + + /** + * @param {string} pane + */ +, getMasks = function (pane) { + var $Masks = $([]) + , $M, i = 0, c = $Ms.length + ; + for (; i CSS + if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET CSS + $N.css( $N.data(css) ).removeData(css); + + // trigger plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onDestroy ); + + // trigger state-management and onunload callback + unload(); + + // clear the Instance of everything except for container & options (so could recreate) + // RE-CREATE: myLayout = myLayout.container.layout( myLayout.options ); + for (var n in Instance) + if (!n.match(/^(container|options)$/)) delete Instance[ n ]; + // add a 'destroyed' flag to make it easy to check + Instance.destroyed = true; + + // if this is a child layout, CLEAR the child-pointer in the parent + /* for now the pointer REMAINS, but with only container, options and destroyed keys + if (parentPane) { + var layout = parentPane.pane.data("parentLayout") + , key = layout.options.instanceKey || 'error'; + // THIS SYNTAX MAY BE WRONG! + parentPane.children[key] = layout.children[ parentPane.name ].children[key] = null; + } + */ + + return Instance; // for coding convenience + } + + /** + * Remove a pane from the layout - subroutine of destroy() + * + * @see destroy() + * @param {(string|Object)} evt_or_pane The pane to process + * @param {boolean=} [remove=false] Remove the DOM element? + * @param {boolean=} [skipResize=false] Skip calling resizeAll()? + * @param {boolean=} [destroyChild=true] Destroy Child-layouts? If not passed, obeys options setting + */ +, removePane = function (evt_or_pane, remove, skipResize, destroyChild) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $C = $Cs[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + ; + // NOTE: elements can still exist even after remove() + // so check for missing data(), which is cleared by removed() + if ($P && $.isEmptyObject( $P.data() )) $P = false; + if ($C && $.isEmptyObject( $C.data() )) $C = false; + if ($R && $.isEmptyObject( $R.data() )) $R = false; + if ($T && $.isEmptyObject( $T.data() )) $T = false; + + if ($P) $P.stop(true, true); + + var o = options[pane] + , s = state[pane] + , d = "layout" + , css = "layoutCSS" + , pC = children[pane] + , hasChildren = $.isPlainObject( pC ) && !$.isEmptyObject( pC ) + , destroy = destroyChild !== undefined ? destroyChild : o.destroyChildren + ; + // FIRST destroy the child-layout(s) + if (hasChildren && destroy) { + $.each( pC, function (key, child) { + if (!child.destroyed) + child.destroy(true);// tell child-layout to destroy ALL its child-layouts too + if (child.destroyed) // destroy was successful + delete pC[key]; + }); + // if no more children, remove the children hash + if ($.isEmptyObject( pC )) { + pC = children[pane] = null; // clear children hash + hasChildren = false; + } + } + + // Note: can't 'remove' a pane element with non-destroyed children + if ($P && remove && !hasChildren) + $P.remove(); // remove the pane-element and everything inside it + else if ($P && $P[0]) { + // create list of ALL pane-classes that need to be removed + var root = o.paneClass // default="ui-layout-pane" + , pRoot = root +"-"+ pane // eg: "ui-layout-pane-west" + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + , classes = [ root, root+_open, root+_closed, root+_sliding, // generic classes + pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ] // pane-specific classes + ; + $.merge(classes, getHoverClasses($P, true)); // ADD hover-classes + // remove all Layout classes from pane-element + $P .removeClass( classes.join(" ") ) // remove ALL pane-classes + .removeData("parentLayout") + .removeData("layoutPane") + .removeData("layoutRole") + .removeData("layoutEdge") + .removeData("autoHidden") // in case set + .unbind("."+ sID) // remove ALL Layout events + // TODO: remove these extra unbind commands when jQuery is fixed + //.unbind("mouseenter"+ sID) + //.unbind("mouseleave"+ sID) + ; + // do NOT reset CSS if this pane/content is STILL the container of a nested layout! + // the nested layout will reset its 'container' CSS when/if it is destroyed + if (hasChildren && $C) { + // a content-div may not have a specific width, so give it one to contain the Layout + $C.width( $C.width() ); + $.each( pC, function (key, child) { + child.resizeAll(); // resize the Layout + }); + } + else if ($C) + $C.css( $C.data(css) ).removeData(css).removeData("layoutRole"); + // remove pane AFTER content in case there was a nested layout + if (!$P.data(d)) + $P.css( $P.data(css) ).removeData(css); + } + + // REMOVE pane resizer and toggler elements + if ($T) $T.remove(); + if ($R) $R.remove(); + + // CLEAR all pointers and state data + Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = false; + s = { removed: true }; + + if (!skipResize) + resizeAll(); + } + + +/* + * ########################### + * ACTION METHODS + * ########################### + */ + + /** + * @param {string} pane + */ +, _hidePane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , s = $P[0].style + ; + if (o.useOffscreenClose) { + if (!$P.data(_c.offscreenReset)) + $P.data(_c.offscreenReset, { left: s.left, right: s.right }); + $P.css( _c.offscreenCSS ); + } + else + $P.hide().removeData(_c.offscreenReset); + } + + /** + * @param {string} pane + */ +, _showPane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , off = _c.offscreenCSS + , old = $P.data(_c.offscreenReset) + , s = $P[0].style + ; + $P .show() // ALWAYS show, just in case + .removeData(_c.offscreenReset); + if (o.useOffscreenClose && old) { + if (s.left == off.left) + s.left = old.left; + if (s.right == off.right) + s.right = old.right; + } + } + + + /** + * Completely 'hides' a pane, including its spacing - as if it does not exist + * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it + * + * @param {(string|Object)} evt_or_pane The pane being hidden, ie: north, south, east, or west + * @param {boolean=} [noAnimation=false] + */ +, hide = function (evt_or_pane, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || s.isHidden) return; // pane does not exist OR is already hidden + + // onhide_start callback - will CANCEL hide if returns false + if (state.initialized && false === _runCallbacks("onhide_start", pane)) return; + + s.isSliding = false; // just in case + delete state.panesSliding[pane]; + + // now hide the elements + if ($R) $R.hide(); // hide resizer-bar + if (!state.initialized || s.isClosed) { + s.isClosed = true; // to trigger open-animation on show() + s.isHidden = true; + s.isVisible = false; + if (!state.initialized) + _hidePane(pane); // no animation when loading page + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center"); + if (state.initialized || o.triggerEventsOnLoad) + _runCallbacks("onhide_end", pane); + } + else { + s.isHiding = true; // used by onclose + close(pane, false, noAnimation); // adjust all panes to fit + } + } + + /** + * Show a hidden pane - show as 'closed' by default unless openPane = true + * + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [openPane=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, show = function (evt_or_pane, openPane, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden + + // onshow_start callback - will CANCEL show if returns false + if (false === _runCallbacks("onshow_start", pane)) return; + + s.isShowing = true; // used by onopen/onclose + //s.isHidden = false; - will be set by open/close - if not cancelled + s.isSliding = false; // just in case + delete state.panesSliding[pane]; + + // now show the elements + //if ($R) $R.show(); - will be shown by open/close + if (openPane === false) + close(pane, true); // true = force + else + open(pane, false, noAnimation, noAlert); // adjust all panes to fit + } + + + /** + * Toggles a pane open/closed by calling either open or close + * + * @param {(string|Object)} evt_or_pane The pane being toggled, ie: north, south, east, or west + * @param {boolean=} [slide=false] + */ +, toggle = function (evt_or_pane, slide) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + ; + if (evt) // called from to $R.dblclick OR triggerPaneEvent + evt.stopImmediatePropagation(); + if (s.isHidden) + show(pane); // will call 'open' after unhiding it + else if (s.isClosed) + open(pane, !!slide); + else + close(pane); + } + + + /** + * Utility method used during init or other auto-processes + * + * @param {string} pane The pane being closed + * @param {boolean=} [setHandles=false] + */ +, _closePane = function (pane, setHandles) { + var + $P = $Ps[pane] + , s = state[pane] + ; + _hidePane(pane); + s.isClosed = true; + s.isVisible = false; + if (setHandles) setAsClosed(pane); + } + + /** + * Close the specified pane (animation optional), and resize all other panes as needed + * + * @param {(string|Object)} evt_or_pane The pane being closed, ie: north, south, east, or west + * @param {boolean=} [force=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [skipCallback=false] + */ +, close = function (evt_or_pane, force, noAnimation, skipCallback) { + var pane = evtPane.call(this, evt_or_pane); + // if pane has been initialized, but NOT the complete layout, close pane instantly + if (!state.initialized && $Ps[pane]) { + _closePane(pane, true); // INIT pane as closed + return; + } + if (!isInitialized()) return; + + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing, isHiding, wasSliding; + + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.closable && !s.isShowing && !s.isHiding) // invalid request // (!o.resizable && !o.closable) ??? + || (!force && s.isClosed && !s.isShowing) // already closed + ) return queueNext(); + + // onclose_start callback - will CANCEL hide if returns false + // SKIP if just 'showing' a hidden pane as 'closed' + var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane); + + // transfer logic vars to temp vars + isShowing = s.isShowing; + isHiding = s.isHiding; + wasSliding = s.isSliding; + // now clear the logic vars (REQUIRED before aborting) + delete s.isShowing; + delete s.isHiding; + + if (abort) return queueNext(); + + doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none"); + s.isMoving = true; + s.isClosed = true; + s.isVisible = false; + // update isHidden BEFORE sizing panes + if (isHiding) s.isHidden = true; + else if (isShowing) s.isHidden = false; + + if (s.isSliding) // pane is being closed, so UNBIND trigger events + bindStopSlidingEvents(pane, false); // will set isSliding=false + else // resize panes adjacent to this one + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback + + // if this pane has a resizer bar, move it NOW - before animation + setAsClosed(pane); + + // CLOSE THE PANE + if (doFX) { // animate the close + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { + lockPaneForFX(pane, false); // undo + if (s.isClosed) close_2(); + queueNext(); + }); + } + else { // hide the pane without animation + _hidePane(pane); + close_2(); + queueNext(); + }; + }); + + // SUBROUTINE + function close_2 () { + s.isMoving = false; + bindStartSlidingEvents(pane, true); // will enable if o.slidable = true + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane ); + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { + // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' + if (!isShowing) _runCallbacks("onclose_end", pane); + // onhide OR onshow callback + if (isShowing) _runCallbacks("onshow_end", pane); + if (isHiding) _runCallbacks("onhide_end", pane); + } + } + } + + /** + * @param {string} pane The pane just closed, ie: north, south, east, or west + */ +, setAsClosed = function (pane) { + if (!$Rs[pane]) return; // handles not initialized yet! + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + ; + $R + .css(side, sC.inset[side]) // move the resizer + .removeClass( rClass+_open +" "+ rClass+_pane+_open ) + .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) + ; + // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvents? + if (o.resizable && $.layout.plugins.draggable) + $R + .draggable("disable") + .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here + .css("cursor", "default") + .attr("title","") + ; + + // if pane has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_open +" "+ tClass+_pane+_open ) + .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .attr("title", o.tips.Open) // may be blank + ; + // toggler-content - if exists + $T.children(".content-open").hide(); + $T.children(".content-closed").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, false); + + if (state.initialized) { + // resize 'length' and position togglers for adjacent panes + sizeHandles(); + } + } + + /** + * Open the specified pane (animation optional), and resize all other panes as needed + * + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [slide=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, open = function (evt_or_pane, slide, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing + ; + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.resizable && !o.closable && !s.isShowing) // invalid request + || (s.isVisible && !s.isSliding) // already open + ) return queueNext(); + + // pane can ALSO be unhidden by just calling show(), so handle this scenario + if (s.isHidden && !s.isShowing) { + queueNext(); // call before show() because it needs the queue free + show(pane, true); + return; + } + + if (s.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize + else + // make sure there is enough space available to open the pane + setSizeLimits(pane, slide); + + // onopen_start callback - will CANCEL open if returns false + var cbReturn = _runCallbacks("onopen_start", pane); + + if (cbReturn === "abort") + return queueNext(); + + // update pane-state again in case options were changed in onopen_start + if (cbReturn !== "NC") // NC = "No Callback" + setSizeLimits(pane, slide); + + if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! + syncPinBtns(pane, false); // make sure pin-buttons are reset + if (!noAlert && o.tips.noRoomToOpen) + alert(o.tips.noRoomToOpen); + return queueNext(); // ABORT + } + + if (slide) // START Sliding - will set isSliding=true + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead + bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false + else if (o.slidable) + bindStartSlidingEvents(pane, false); // UNBIND trigger events + + s.noRoom = false; // will be reset by makePaneFit if 'noRoom' + makePaneFit(pane); + + // transfer logic var to temp var + isShowing = s.isShowing; + // now clear the logic var + delete s.isShowing; + + doFX = !noAnimation && s.isClosed && (o.fxName_open != "none"); + s.isMoving = true; + s.isVisible = true; + s.isClosed = false; + // update isHidden BEFORE sizing panes - WHY??? Old? + if (isShowing) s.isHidden = false; + + if (doFX) { // ANIMATE + // mask adjacent panes with objects + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { + lockPaneForFX(pane, false); // undo + if (s.isVisible) open_2(); // continue + queueNext(); + }); + } + else { // no animation + _showPane(pane);// just show pane and... + open_2(); // continue + queueNext(); + }; + }); + + // SUBROUTINE + function open_2 () { + s.isMoving = false; + + // cure iframe display issues + _fixIframe(pane); + + // NOTE: if isSliding, then other panes are NOT 'resized' + if (!s.isSliding) { // resize all panes adjacent to this one + sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback + } + + // set classes, position handles and execute callbacks... + setAsOpen(pane); + }; + + } + + /** + * @param {string} pane The pane just opened, ie: north, south, east, or west + * @param {boolean=} [skipCallback=false] + */ +, setAsOpen = function (pane, skipCallback) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _closed = "-closed" + , _sliding= "-sliding" + ; + $R + .css(side, sC.inset[side] + getPaneSize(pane)) // move the resizer + .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .addClass( rClass+_open +" "+ rClass+_pane+_open ) + ; + if (s.isSliding) + $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + else // in case 'was sliding' + $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + + removeHover( 0, $R ); // remove hover classes + if (o.resizable && $.layout.plugins.draggable) + $R .draggable("enable") + .css("cursor", o.resizerCursor) + .attr("title", o.tips.Resize); + else if (!s.isSliding) + $R.css("cursor", "default"); // n-resize, s-resize, etc + + // if pane also has a toggler button, adjust that too + if ($T) { + $T .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .addClass( tClass+_open +" "+ tClass+_pane+_open ) + .attr("title", o.tips.Close); // may be blank + removeHover( 0, $T ); // remove hover classes + // toggler-content - if exists + $T.children(".content-closed").hide(); + $T.children(".content-open").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, !s.isSliding); + + // update pane-state dimensions - BEFORE resizing content + $.extend(s, elDims($P)); + + if (state.initialized) { + // resize resizer & toggler sizes for all panes + sizeHandles(); + // resize content every time pane opens - to be sure + sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving' + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { + // onopen callback + _runCallbacks("onopen_end", pane); + // onshow callback - TODO: should this be here? + if (s.isShowing) _runCallbacks("onshow_end", pane); + + // ALSO call onresize because layout-size *may* have changed while pane was closed + if (state.initialized) + _runCallbacks("onresize_end", pane); + } + + // TODO: Somehow sizePane("north") is being called after this point??? + } + + + /** + * slideOpen / slideClose / slideToggle + * + * Pass-though methods for sliding + */ +, slideOpen = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + , delay = options[pane].slideDelay_open + ; + // prevent event from triggering on NEW resizer binding created below + if (evt) evt.stopImmediatePropagation(); + + if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0) + // trigger = mouseenter - use a delay + timer.set(pane+"_openSlider", open_NOW, delay); + else + open_NOW(); // will unbind events if is already open + + /** + * SUBROUTINE for timed open + */ + function open_NOW () { + if (!s.isClosed) // skip if no longer closed! + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (!s.isMoving) + open(pane, true); // true = slide - open() will handle binding + }; + } + +, slideClose = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , delay = s.isMoving ? 1000 : 300 // MINIMUM delay - option may override + ; + if (s.isClosed || s.isResizing) + return; // skip if already closed OR in process of resizing + else if (o.slideTrigger_close === "click") + close_NOW(); // close immediately onClick + else if (o.preventQuickSlideClose && s.isMoving) + return; // handle Chrome quick-close on slide-open + else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane])) + return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + else if (evt) // trigger = mouseleave - use a delay + // 1 sec delay if 'opening', else .3 sec + timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay)); + else // called programically + close_NOW(); + + /** + * SUBROUTINE for timed close + */ + function close_NOW () { + if (s.isClosed) // skip 'close' if already closed! + bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here? + else if (!s.isMoving) + close(pane); // close will handle unbinding + }; + } + + /** + * @param {(string|Object)} evt_or_pane The pane being opened, ie: north, south, east, or west + */ +, slideToggle = function (evt_or_pane) { + var pane = evtPane.call(this, evt_or_pane); + toggle(pane, true); + } + + + /** + * Must set left/top on East/South panes so animation will work properly + * + * @param {string} pane The pane to lock, 'east' or 'south' - any other is ignored! + * @param {boolean} doLock true = set left/top, false = remove + */ +, lockPaneForFX = function (pane, doLock) { + var $P = $Ps[pane] + , s = state[pane] + , o = options[pane] + , z = options.zIndexes + ; + if (doLock) { + showMasks( pane, { animation: true, objectsOnly: true }); + $P.css({ zIndex: z.pane_animate }); // overlay all elements during animation + if (pane=="south") + $P.css({ top: sC.inset.top + sC.innerHeight - $P.outerHeight() }); + else if (pane=="east") + $P.css({ left: sC.inset.left + sC.innerWidth - $P.outerWidth() }); + } + else { // animation DONE - RESET CSS + hideMasks(); + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + if (pane=="south") + $P.css({ top: "auto" }); + // if pane is positioned 'off-screen', then DO NOT screw with it! + else if (pane=="east" && !$P.css("left").match(/\-99999/)) + $P.css({ left: "auto" }); + // fix anti-aliasing in IE - only needed for animations that change opacity + if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) + $P[0].style.removeAttribute('filter'); + } + } + + + /** + * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger + * + * @see open(), close() + * @param {string} pane The pane to enable/disable, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable sliding? + */ +, bindStartSlidingEvents = function (pane, enable) { + var o = options[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , evtName = o.slideTrigger_open.toLowerCase() + ; + if (!$R || (enable && !o.slidable)) return; + + // make sure we have a valid event + if (evtName.match(/mouseover/)) + evtName = o.slideTrigger_open = "mouseenter"; + else if (!evtName.match(/(click|dblclick|mouseenter)/)) + evtName = o.slideTrigger_open = "click"; + + // must remove double-click-toggle when using dblclick-slide + if (o.resizerDblClickToggle && evtName.match(/click/)) { + $R[enable ? "unbind" : "bind"]('dblclick.'+ sID, toggle) + } + + $R + // add or remove event + [enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen) + // set the appropriate cursor & title/tip + .css("cursor", enable ? o.sliderCursor : "default") + .attr("title", enable ? o.tips.Slide : "") + ; + } + + /** + * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed + * Also increases zIndex when pane is sliding open + * See bindStartSlidingEvents for code to control 'slide open' + * + * @see slideOpen(), slideClose() + * @param {string} pane The pane to process, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable events? + */ +, bindStopSlidingEvents = function (pane, enable) { + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , z = options.zIndexes + , evtName = o.slideTrigger_close.toLowerCase() + , action = (enable ? "bind" : "unbind") + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + timer.clear(pane+"_closeSlider"); // just in case + + if (enable) { + s.isSliding = true; + state.panesSliding[pane] = true; + // remove 'slideOpen' event from resizer + // ALSO will raise the zIndex of the pane & resizer + bindStartSlidingEvents(pane, false); + } + else { + s.isSliding = false; + delete state.panesSliding[pane]; + } + + // RE/SET zIndex - increases when pane is sliding-open, resets to normal when not + $P.css("zIndex", enable ? z.pane_sliding : z.pane_normal); + $R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1 + + // make sure we have a valid event + if (!evtName.match(/(click|mouseleave)/)) + evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout' + + // add/remove slide triggers + $R[action](evtName, slideClose); // base event on resize + // need extra events for mouseleave + if (evtName === "mouseleave") { + // also close on pane.mouseleave + $P[action]("mouseleave."+ sID, slideClose); + // cancel timer when mouse moves between 'pane' and 'resizer' + $R[action]("mouseenter."+ sID, cancelMouseOut); + $P[action]("mouseenter."+ sID, cancelMouseOut); + } + + if (!enable) + timer.clear(pane+"_closeSlider"); + else if (evtName === "click" && !o.resizable) { + // IF pane is not resizable (which already has a cursor and tip) + // then set the a cursor & title/tip on resizer when sliding + $R.css("cursor", enable ? o.sliderCursor : "default"); + $R.attr("title", enable ? o.tips.Close : ""); // use Toggler-tip, eg: "Close Pane" + } + + // SUBROUTINE for mouseleave timer clearing + function cancelMouseOut (evt) { + timer.clear(pane+"_closeSlider"); + evt.stopPropagation(); + } + } + + + /** + * Hides/closes a pane if there is insufficient room - reverses this when there is room again + * MUST have already called setSizeLimits() before calling this method + * + * @param {string} pane The pane being resized + * @param {boolean=} [isOpening=false] Called from onOpen? + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, makePaneFit = function (pane, isOpening, skipCallback, force) { + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isSidePane = c.dir==="vert" + , hasRoom = false + ; + // special handling for center & east/west panes + if (pane === "center" || (isSidePane && s.noVerticalRoom)) { + // see if there is enough room to display the pane + // ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); + hasRoom = (s.maxHeight >= 0); + if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now + _showPane(pane); + if ($R) $R.show(); + s.isVisible = true; + s.noRoom = false; + if (isSidePane) s.noVerticalRoom = false; + _fixIframe(pane); + } + else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now + _hidePane(pane); + if ($R) $R.hide(); + s.isVisible = false; + s.noRoom = true; + } + } + + // see if there is enough room to fit the border-pane + if (pane === "center") { + // ignore center in this block + } + else if (s.minSize <= s.maxSize) { // pane CAN fit + hasRoom = true; + if (s.size > s.maxSize) // pane is too big - shrink it + sizePane(pane, s.maxSize, skipCallback, true, force); // true = noAnimation + else if (s.size < s.minSize) // pane is too small - enlarge it + sizePane(pane, s.minSize, skipCallback, true, force); // true = noAnimation + // need s.isVisible because new pseudoClose method keeps pane visible, but off-screen + else if ($R && s.isVisible && $P.is(":visible")) { + // make sure resizer-bar is positioned correctly + // handles situation where nested layout was 'hidden' when initialized + var pos = s.size + sC.inset[c.side]; + if ($.layout.cssNum( $R, c.side ) != pos) $R.css( c.side, pos ); + } + + // if was previously hidden due to noRoom, then RESET because NOW there is room + if (s.noRoom) { + // s.noRoom state will be set by open or show + if (s.wasOpen && o.closable) { + if (o.autoReopen) + open(pane, false, true, true); // true = noAnimation, true = noAlert + else // leave the pane closed, so just update state + s.noRoom = false; + } + else + show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert + } + } + else { // !hasRoom - pane CANNOT fit + if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... + s.noRoom = true; // update state + s.wasOpen = !s.isClosed && !s.isSliding; + if (s.isClosed){} // SKIP + else if (o.closable) // 'close' if possible + close(pane, true, true); // true = force, true = noAnimation + else // 'hide' pane if cannot just be closed + hide(pane, true); // true = noAnimation + } + } + } + + + /** + * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' + * + * @param {(string|Object)} evt_or_pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [force=false] Force resizing even if does not seem necessary + */ +, manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... + , forceResize = force || (o.livePaneResizing && !s.isResizing) + ; + // ANY call to manualSizePane disables autoResize - ie, percentage sizing + s.autoResize = false; + // flow-through... + sizePane(pane, size, skipCallback, noAnimation, forceResize); // will animate resize if option enabled + } + + /** + * sizePane is called only by internal methods whenever a pane needs to be resized + * + * @param {(string|Object)} evt_or_pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [force=false] Force resizing even if does not seem necessary + */ +, sizePane = function (evt_or_pane, size, skipCallback, noAnimation, force) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) // probably NEVER called from event? + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , side = _c[pane].side + , dimName = _c[pane].sizeType.toLowerCase() + , skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize + , doFX = noAnimation !== true && o.animatePaneSizing + , oldSize, newSize + ; + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + // calculate 'current' min/max sizes + setSizeLimits(pane); // update pane-state + oldSize = s.size; + size = _parseSize(pane, size); // handle percentages & auto + size = max(size, _parseSize(pane, o.minSize)); + size = min(size, s.maxSize); + if (size < s.minSize) { // not enough room for pane! + queueNext(); // call before makePaneFit() because it needs the queue free + makePaneFit(pane, false, skipCallback); // will hide or close pane + return; + } + + // IF newSize is same as oldSize, then nothing to do - abort + if (!force && size === oldSize) + return queueNext(); + + s.newSize = size; + + // onresize_start callback CANNOT cancel resizing because this would break the layout! + if (!skipCallback && state.initialized && s.isVisible) + _runCallbacks("onresize_start", pane); + + // resize the pane, and make sure its visible + newSize = cssSize(pane, size); + + if (doFX && $P.is(":visible")) { // ANIMATE + var fx = $.layout.effects.size[pane] || $.layout.effects.size.all + , easing = o.fxSettings_size.easing || fx.easing + , z = options.zIndexes + , props = {}; + props[ dimName ] = newSize +'px'; + s.isMoving = true; + // overlay all elements during animation + $P.css({ zIndex: z.pane_animate }) + .show().animate( props, o.fxSpeed_size, easing, function(){ + // reset zIndex after animation + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + s.isMoving = false; + delete s.newSize; + sizePane_2(); // continue + queueNext(); + }); + } + else { // no animation + $P.css( dimName, newSize ); // resize pane + delete s.newSize; + // if pane is visible, then + if ($P.is(":visible")) + sizePane_2(); // continue + else { + // pane is NOT VISIBLE, so just update state data... + // when pane is *next opened*, it will have the new size + s.size = size; // update state.size + $.extend(s, elDims($P)); // update state dimensions + } + queueNext(); + }; + + }); + + // SUBROUTINE + function sizePane_2 () { + /* Panes are sometimes not sized precisely in some browsers!? + * This code will resize the pane up to 3 times to nudge the pane to the correct size + */ + var actual = dimName==='width' ? $P.outerWidth() : $P.outerHeight() + , tries = [{ + pane: pane + , count: 1 + , target: size + , actual: actual + , correct: (size === actual) + , attempt: size + , cssSize: newSize + }] + , lastTry = tries[0] + , thisTry = {} + , msg = 'Inaccurate size after resizing the '+ pane +'-pane.' + ; + while ( !lastTry.correct ) { + thisTry = { pane: pane, count: lastTry.count+1, target: size }; + + if (lastTry.actual > size) + thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size)); + else // lastTry.actual < size + thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual)); + + thisTry.cssSize = cssSize(pane, thisTry.attempt); + $P.css( dimName, thisTry.cssSize ); + + thisTry.actual = dimName=='width' ? $P.outerWidth() : $P.outerHeight(); + thisTry.correct = (size === thisTry.actual); + + // log attempts and alert the user of this *non-fatal error* (if showDebugMessages) + if ( tries.length === 1) { + _log(msg, false, true); + _log(lastTry, false, true); + } + _log(thisTry, false, true); + // after 4 tries, is as close as its gonna get! + if (tries.length > 3) break; + + tries.push( thisTry ); + lastTry = tries[ tries.length - 1 ]; + } + // END TESTING CODE + + // update pane-state dimensions + s.size = size; + $.extend(s, elDims($P)); + + if (s.isVisible && $P.is(":visible")) { + // reposition the resizer-bar + if ($R) $R.css( side, size + sC.inset[side] ); + // resize the content-div + sizeContent(pane); + } + + if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) + _runCallbacks("onresize_end", pane); + + // resize all the adjacent panes, and adjust their toggler buttons + // when skipCallback passed, it means the controlling method will handle 'other panes' + if (!skipCallback) { + // also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize + if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force); + sizeHandles(); + } + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (size < oldSize && state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane, false, skipCallback ); + } + + // DEBUG - ALERT user/developer so they know there was a sizing problem + if (tries.length > 1) + _log(msg +'\nSee the Error Console for details.', true, true); + } + } + + /** + * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide() + * @param {(Array.|string)} panes The pane(s) being resized, comma-delmited string + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, sizeMidPanes = function (panes, skipCallback, force) { + panes = (panes ? panes : "east,west,center").split(","); + + $.each(panes, function (i, pane) { + if (!$Ps[pane]) return; // NO PANE - skip + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isCenter= (pane=="center") + , hasRoom = true + , CSS = {} + // if pane is not visible, show it invisibly NOW rather than for *each call* in this script + , visCSS = $.layout.showInvisibly($P) + + , newCenter = calcNewCenterPaneDims() + ; + + // update pane-state dimensions + $.extend(s, elDims($P)); + + if (pane === "center") { + if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight) { + $P.css(visCSS); + return true; // SKIP - pane already the correct size + } + // set state for makePaneFit() logic + $.extend(s, cssMinDims(pane), { + maxWidth: newCenter.width + , maxHeight: newCenter.height + }); + CSS = newCenter; + s.newWidth = CSS.width; + s.newHeight = CSS.height; + // convert OUTER width/height to CSS width/height + CSS.width = cssW($P, CSS.width); + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, CSS.height); + hasRoom = CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW + + // during layout init, try to shrink east/west panes to make room for center + if (!state.initialized && o.minWidth > newCenter.width) { + var + reqPx = o.minWidth - s.outerWidth + , minE = options.east.minSize || 0 + , minW = options.west.minSize || 0 + , sizeE = state.east.size + , sizeW = state.west.size + , newE = sizeE + , newW = sizeW + ; + if (reqPx > 0 && state.east.isVisible && sizeE > minE) { + newE = max( sizeE-minE, sizeE-reqPx ); + reqPx -= sizeE-newE; + } + if (reqPx > 0 && state.west.isVisible && sizeW > minW) { + newW = max( sizeW-minW, sizeW-reqPx ); + reqPx -= sizeW-newW; + } + // IF we found enough extra space, then resize the border panes as calculated + if (reqPx === 0) { + if (sizeE && sizeE != minE) + sizePane('east', newE, true, true, force); // true = skipCallback/noAnimation - initPanes will handle when done + if (sizeW && sizeW != minW) + sizePane('west', newW, true, true, force); // true = skipCallback/noAnimation + // now start over! + sizeMidPanes('center', skipCallback, force); + $P.css(visCSS); + return; // abort this loop + } + } + } + else { // for east and west, set only the height, which is same as center height + // set state.min/maxWidth/Height for makePaneFit() logic + if (s.isVisible && !s.noVerticalRoom) + $.extend(s, elDims($P), cssMinDims(pane)) + if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight) { + $P.css(visCSS); + return true; // SKIP - pane already the correct size + } + // east/west have same top, bottom & height as center + CSS.top = newCenter.top; + CSS.bottom = newCenter.bottom; + s.newSize = newCenter.height + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, newCenter.height); + s.maxHeight = CSS.height; + hasRoom = (s.maxHeight >= 0); // ALWAYS TRUE NOW + if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic + } + + if (hasRoom) { + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_start", pane); + + $P.css(CSS); // apply the CSS to pane + if (pane !== "center") + sizeHandles(pane); // also update resizer length + if (s.noRoom && !s.isClosed && !s.isHidden) + makePaneFit(pane); // will re-open/show auto-closed/hidden pane + if (s.isVisible) { + $.extend(s, elDims($P)); // update pane dimensions + if (state.initialized) sizeContent(pane); // also resize the contents, if exists + } + } + else if (!s.noRoom && s.isVisible) // no room for pane + makePaneFit(pane); // will hide or close pane + + // reset visibility, if necessary + $P.css(visCSS); + + delete s.newSize; + delete s.newWidth; + delete s.newHeight; + + if (!s.isVisible) + return true; // DONE - next pane + + /* + * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes + * Normally these panes have only 'left' & 'right' positions so pane auto-sizes + * ALSO required when pane is an IFRAME because will NOT default to 'full width' + * TODO: Can I use width:100% for a north/south iframe? + * TODO: Sounds like a job for $P.outerWidth( sC.innerWidth ) SETTER METHOD + */ + if (pane === "center") { // finished processing midPanes + var fix = browser.isIE6 || !browser.boxModel; + if ($Ps.north && (fix || state.north.tagName=="IFRAME")) + $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); + if ($Ps.south && (fix || state.south.tagName=="IFRAME")) + $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); + } + + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_end", pane); + }); + } + + + /** + * @see window.onresize(), callbacks or custom code + * @param {(Object|boolean)=} evt_or_refresh If 'true', then also reset pane-positioning + */ +, resizeAll = function (evt_or_refresh) { + var oldW = sC.innerWidth + , oldH = sC.innerHeight + ; + // stopPropagation if called by trigger("layoutdestroy") - use evtPane utility + evtPane(evt_or_refresh); + + // cannot size layout when 'container' is hidden or collapsed + if (!$N.is(":visible")) return; + + if (!state.initialized) { + _initLayoutElements(); + return; // no need to resize since we just initialized! + } + + if (evt_or_refresh === true && $.isPlainObject(options.outset)) { + // update container CSS in case outset option has changed + $N.css( options.outset ); + } + // UPDATE container dimensions + $.extend(sC, elDims( $N, options.inset )); + if (!sC.outerHeight) return; + + // if 'true' passed, refresh pane & handle positioning too + if (evt_or_refresh === true) { + setPanePosition(); + } + + // onresizeall_start will CANCEL resizing if returns false + // state.container has already been set, so user can access this info for calcuations + if (false === _runCallbacks("onresizeall_start")) return false; + + var // see if container is now 'smaller' than before + shrunkH = (sC.innerHeight < oldH) + , shrunkW = (sC.innerWidth < oldW) + , $P, o, s + ; + // NOTE special order for sizing: S-N-E-W + $.each(["south","north","east","west"], function (i, pane) { + if (!$Ps[pane]) return; // no pane - SKIP + o = options[pane]; + s = state[pane]; + if (s.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/noAnimation/forceResize + else { + setSizeLimits(pane); + makePaneFit(pane, false, true, true); // true=skipCallback/forceResize + } + }); + + sizeMidPanes("", true, true); // true=skipCallback/forceResize + sizeHandles(); // reposition the toggler elements + + // trigger all individual pane callbacks AFTER layout has finished resizing + $.each(_c.allPanes, function (i, pane) { + $P = $Ps[pane]; + if (!$P) return; // SKIP + if (state[pane].isVisible) // undefined for non-existent panes + _runCallbacks("onresize_end", pane); // callback - if exists + }); + + _runCallbacks("onresizeall_end"); + //_triggerLayoutEvent(pane, 'resizeall'); + } + + /** + * Whenever a pane resizes or opens that has a nested layout, trigger resizeAll + * + * @param {(string|Object)} evt_or_pane The pane just resized or opened + */ +, resizeChildren = function (evt_or_pane, skipRefresh) { + var pane = evtPane.call(this, evt_or_pane); + + if (!options[pane].resizeChildren) return; + + // ensure the pane-children are up-to-date + if (!skipRefresh) refreshChildren( pane ); + var pC = children[pane]; + if ($.isPlainObject( pC )) { + // resize one or more children + $.each( pC, function (key, child) { + if (!child.destroyed) child.resizeAll(); + }); + } + } + + /** + * IF pane has a content-div, then resize all elements inside pane to fit pane-height + * + * @param {(string|Object)} evt_or_panes The pane(s) being resized + * @param {boolean=} [remeasure=false] Should the content (header/footer) be remeasured? + */ +, sizeContent = function (evt_or_panes, remeasure) { + if (!isInitialized()) return; + + var panes = evtPane.call(this, evt_or_panes); + panes = panes ? panes.split(",") : _c.allPanes; + + $.each(panes, function (idx, pane) { + var + $P = $Ps[pane] + , $C = $Cs[pane] + , o = options[pane] + , s = state[pane] + , m = s.content // m = measurements + ; + if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip + + // if content-element was REMOVED, update OR remove the pointer + if (!$C.length) { + initContent(pane, false); // false = do NOT sizeContent() - already there! + if (!$C) return; // no replacement element found - pointer have been removed + } + + // onsizecontent_start will CANCEL resizing if returns false + if (false === _runCallbacks("onsizecontent_start", pane)) return; + + // skip re-measuring offsets if live-resizing + if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) { + _measure(); + // if any footers are below pane-bottom, they may not measure correctly, + // so allow pane overflow and re-measure + if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") { + $P.css("overflow", "visible"); + _measure(); // remeasure while overflowing + $P.css("overflow", "hidden"); + } + } + // NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders + var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom); + + if (!$C.is(":visible") || m.height != newH) { + // size the Content element to fit new pane-size - will autoHide if not enough room + setOuterHeight($C, newH, true); // true=autoHide + m.height = newH; // save new height + }; + + if (state.initialized) + _runCallbacks("onsizecontent_end", pane); + + function _below ($E) { + return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0)); + }; + + function _measure () { + var + ignore = options[pane].contentIgnoreSelector + , $Fs = $C.nextAll().not(".ui-layout-mask").not(ignore || ":lt(0)") // not :lt(0) = ALL + , $Fs_vis = $Fs.filter(':visible') + , $F = $Fs_vis.filter(':last') + ; + m = { + top: $C[0].offsetTop + , height: $C.outerHeight() + , numFooters: $Fs.length + , hiddenFooters: $Fs.length - $Fs_vis.length + , spaceBelow: 0 // correct if no content footer ($E) + } + m.spaceAbove = m.top; // just for state - not used in calc + m.bottom = m.top + m.height; + if ($F.length) + //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom) + m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F); + else // no footer - check marginBottom on Content element itself + m.spaceBelow = _below($C); + }; + }); + } + + + /** + * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary + * + * @see initHandles(), open(), close(), resizeAll() + * @param {(string|Object)=} evt_or_panes The pane(s) being resized + */ +, sizeHandles = function (evt_or_panes) { + var panes = evtPane.call(this, evt_or_panes) + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (i, pane) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , $TC + ; + if (!$P || !$R) return; + + var + dir = _c[pane].dir + , _state = (s.isClosed ? "_closed" : "_open") + , spacing = o["spacing"+ _state] + , togAlign = o["togglerAlign"+ _state] + , togLen = o["togglerLength"+ _state] + , paneLen + , left + , offset + , CSS = {} + ; + + if (spacing === 0) { + $R.hide(); + return; + } + else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason + $R.show(); // in case was previously hidden + + // Resizer Bar is ALWAYS same width/height of pane it is attached to + if (dir === "horz") { // north/south + //paneLen = $P.outerWidth(); // s.outerWidth || + paneLen = sC.innerWidth; // handle offscreen-panes + s.resizerLength = paneLen; + left = $.layout.cssNum($P, "left") + $R.css({ + width: cssW($R, paneLen) // account for borders & padding + , height: cssH($R, spacing) // ditto + , left: left > -9999 ? left : sC.inset.left // handle offscreen-panes + }); + } + else { // east/west + paneLen = $P.outerHeight(); // s.outerHeight || + s.resizerLength = paneLen; + $R.css({ + height: cssH($R, paneLen) // account for borders & padding + , width: cssW($R, spacing) // ditto + , top: sC.inset.top + getPaneSize("north", true) // TODO: what if no North pane? + //, top: $.layout.cssNum($Ps["center"], "top") + }); + } + + // remove hover classes + removeHover( o, $R ); + + if ($T) { + if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) { + $T.hide(); // always HIDE the toggler when 'sliding' + return; + } + else + $T.show(); // in case was previously hidden + + if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) { + togLen = paneLen; + offset = 0; + } + else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed + if (isStr(togAlign)) { + switch (togAlign) { + case "top": + case "left": offset = 0; + break; + case "bottom": + case "right": offset = paneLen - togLen; + break; + case "middle": + case "center": + default: offset = round((paneLen - togLen) / 2); // 'default' catches typos + } + } + else { // togAlign = number + var x = parseInt(togAlign, 10); // + if (togAlign >= 0) offset = x; + else offset = paneLen - togLen + x; // NOTE: x is negative! + } + } + + if (dir === "horz") { // north/south + var width = cssW($T, togLen); + $T.css({ + width: width // account for borders & padding + , height: cssH($T, spacing) // ditto + , left: offset // TODO: VERIFY that toggler positions correctly for ALL values + , top: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative + }); + } + else { // east/west + var height = cssH($T, togLen); + $T.css({ + height: height // account for borders & padding + , width: cssW($T, spacing) // ditto + , top: offset // POSITION the toggler + , left: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative + }); + } + + // remove ALL hover classes + removeHover( 0, $T ); + } + + // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now + if (!state.initialized && (o.initHidden || s.isHidden)) { + $R.hide(); + if ($T) $T.hide(); + } + }); + } + + + /** + * @param {(string|Object)} evt_or_pane + */ +, enableClosable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + , o = options[pane] + ; + if (!$T) return; + o.closable = true; + $T .bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); }) + .css("visibility", "visible") + .css("cursor", "pointer") + .attr("title", state[pane].isClosed ? o.tips.Open : o.tips.Close) // may be blank + .show(); + } + /** + * @param {(string|Object)} evt_or_pane + * @param {boolean=} [hide=false] + */ +, disableClosable = function (evt_or_pane, hide) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + ; + if (!$T) return; + options[pane].closable = false; + // is closable is disable, then pane MUST be open! + if (state[pane].isClosed) open(pane, false, true); + $T .unbind("."+ sID) + .css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues + .css("cursor", "default") + .attr("title", ""); + } + + + /** + * @param {(string|Object)} evt_or_pane + */ +, enableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].slidable = true; + if (state[pane].isClosed) + bindStartSlidingEvents(pane, true); + } + /** + * @param {(string|Object)} evt_or_pane + */ +, disableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R) return; + options[pane].slidable = false; + if (state[pane].isSliding) + close(pane, false, true); + else { + bindStartSlidingEvents(pane, false); + $R .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + } + + + /** + * @param {(string|Object)} evt_or_pane + */ +, enableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + , o = options[pane] + ; + if (!$R || !$R.data('draggable')) return; + o.resizable = true; + $R.draggable("enable"); + if (!state[pane].isClosed) + $R .css("cursor", o.resizerCursor) + .attr("title", o.tips.Resize); + } + /** + * @param {(string|Object)} evt_or_pane + */ +, disableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].resizable = false; + $R .draggable("disable") + .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + + + /** + * Move a pane from source-side (eg, west) to target-side (eg, east) + * If pane exists on target-side, move that to source-side, ie, 'swap' the panes + * + * @param {(string|Object)} evt_or_pane1 The pane/edge being swapped + * @param {string} pane2 ditto + */ +, swapPanes = function (evt_or_pane1, pane2) { + if (!isInitialized()) return; + var pane1 = evtPane.call(this, evt_or_pane1); + // change state.edge NOW so callbacks can know where pane is headed... + state[pane1].edge = pane2; + state[pane2].edge = pane1; + // run these even if NOT state.initialized + if (false === _runCallbacks("onswap_start", pane1) + || false === _runCallbacks("onswap_start", pane2) + ) { + state[pane1].edge = pane1; // reset + state[pane2].edge = pane2; + return; + } + + var + oPane1 = copy( pane1 ) + , oPane2 = copy( pane2 ) + , sizes = {} + ; + sizes[pane1] = oPane1 ? oPane1.state.size : 0; + sizes[pane2] = oPane2 ? oPane2.state.size : 0; + + // clear pointers & state + $Ps[pane1] = false; + $Ps[pane2] = false; + state[pane1] = {}; + state[pane2] = {}; + + // ALWAYS remove the resizer & toggler elements + if ($Ts[pane1]) $Ts[pane1].remove(); + if ($Ts[pane2]) $Ts[pane2].remove(); + if ($Rs[pane1]) $Rs[pane1].remove(); + if ($Rs[pane2]) $Rs[pane2].remove(); + $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false; + + // transfer element pointers and data to NEW Layout keys + move( oPane1, pane2 ); + move( oPane2, pane1 ); + + // cleanup objects + oPane1 = oPane2 = sizes = null; + + // make panes 'visible' again + if ($Ps[pane1]) $Ps[pane1].css(_c.visible); + if ($Ps[pane2]) $Ps[pane2].css(_c.visible); + + // fix any size discrepancies caused by swap + resizeAll(); + + // run these even if NOT state.initialized + _runCallbacks("onswap_end", pane1); + _runCallbacks("onswap_end", pane2); + + return; + + function copy (n) { // n = pane + var + $P = $Ps[n] + , $C = $Cs[n] + ; + return !$P ? false : { + pane: n + , P: $P ? $P[0] : false + , C: $C ? $C[0] : false + , state: $.extend(true, {}, state[n]) + , options: $.extend(true, {}, options[n]) + } + }; + + function move (oPane, pane) { + if (!oPane) return; + var + P = oPane.P + , C = oPane.C + , oldPane = oPane.pane + , c = _c[pane] + // save pane-options that should be retained + , s = $.extend(true, {}, state[pane]) + , o = options[pane] + // RETAIN side-specific FX Settings - more below + , fx = { resizerCursor: o.resizerCursor } + , re, size, pos + ; + $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { + fx[k +"_open"] = o[k +"_open"]; + fx[k +"_close"] = o[k +"_close"]; + fx[k +"_size"] = o[k +"_size"]; + }); + + // update object pointers and attributes + $Ps[pane] = $(P) + .data({ + layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + }) + .css(_c.hidden) + .css(c.cssReq) + ; + $Cs[pane] = C ? $(C) : false; + + // set options and state + options[pane] = $.extend(true, {}, oPane.options, fx); + state[pane] = $.extend(true, {}, oPane.state); + + // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west + re = new RegExp(o.paneClass +"-"+ oldPane, "g"); + P.className = P.className.replace(re, o.paneClass +"-"+ pane); + + // ALWAYS regenerate the resizer & toggler elements + initHandles(pane); // create the required resizer & toggler + + // if moving to different orientation, then keep 'target' pane size + if (c.dir != _c[oldPane].dir) { + size = sizes[pane] || 0; + setSizeLimits(pane); // update pane-state + size = max(size, state[pane].minSize); + // use manualSizePane to disable autoResize - not useful after panes are swapped + manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation + } + else // move the resizer here + $Rs[pane].css(c.side, sC.inset[c.side] + (state[pane].isVisible ? getPaneSize(pane) : 0)); + + + // ADD CLASSNAMES & SLIDE-BINDINGS + if (oPane.state.isVisible && !s.isVisible) + setAsOpen(pane, true); // true = skipCallback + else { + setAsClosed(pane); + bindStartSlidingEvents(pane, true); // will enable events IF option is set + } + + // DESTROY the object + oPane = null; + }; + } + + + /** + * INTERNAL method to sync pin-buttons when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), setAsOpen(), setAsClosed() + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns = function (pane, doPin) { + if ($.layout.plugins.buttons) + $.each(state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(Instance, $(selector), pane, doPin); + }); + } + +; // END var DECLARATIONS + + /** + * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed + * + * @see document.keydown() + */ + function keyDown (evt) { + if (!evt) return true; + var code = evt.keyCode; + if (code < 33) return true; // ignore special keys: ENTER, TAB, etc + + var + PANE = { + 38: "north" // Up Cursor - $.ui.keyCode.UP + , 40: "south" // Down Cursor - $.ui.keyCode.DOWN + , 37: "west" // Left Cursor - $.ui.keyCode.LEFT + , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT + } + , ALT = evt.altKey // no worky! + , SHIFT = evt.shiftKey + , CTRL = evt.ctrlKey + , CURSOR = (CTRL && code >= 37 && code <= 40) + , o, k, m, pane + ; + + if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey + pane = PANE[code]; + else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey + $.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey + o = options[p]; + k = o.customHotkey; + m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" + if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches + if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches + pane = p; + return false; // BREAK + } + } + }); + + // validate pane + if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) + return true; + + toggle(pane); + + evt.stopPropagation(); + evt.returnValue = false; // CANCEL key + return false; + }; + + +/* + * ###################################### + * UTILITY METHODS + * called externally or by initButtons + * ###################################### + */ + + /** + * Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work + * + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function allowOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + ; + + // if pane is already raised, then reset it before doing it again! + // this would happen if allowOverflow is attached to BOTH the pane and an element + if (s.cssSaved) + resetOverflow(pane); // reset previous CSS before continuing + + // if pane is raised by sliding or resizing, or its closed, then abort + if (s.isSliding || s.isResizing || s.isClosed) { + s.cssSaved = false; + return; + } + + var + newCSS = { zIndex: (options.zIndexes.resizer_normal + 1) } + , curCSS = {} + , of = $P.css("overflow") + , ofX = $P.css("overflowX") + , ofY = $P.css("overflowY") + ; + // determine which, if any, overflow settings need to be changed + if (of != "visible") { + curCSS.overflow = of; + newCSS.overflow = "visible"; + } + if (ofX && !ofX.match(/(visible|auto)/)) { + curCSS.overflowX = ofX; + newCSS.overflowX = "visible"; + } + if (ofY && !ofY.match(/(visible|auto)/)) { + curCSS.overflowY = ofX; + newCSS.overflowY = "visible"; + } + + // save the current overflow settings - even if blank! + s.cssSaved = curCSS; + + // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' + $P.css( newCSS ); + + // make sure the zIndex of all other panes is normal + $.each(_c.allPanes, function(i, p) { + if (p != pane) resetOverflow(p); + }); + + }; + /** + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function resetOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + , CSS = s.cssSaved || {} + ; + // reset the zIndex + if (!s.isSliding && !s.isResizing) + $P.css("zIndex", options.zIndexes.pane_normal); + + // reset Overflow - if necessary + $P.css( CSS ); + + // clear var + s.cssSaved = false; + }; + +/* + * ##################### + * CREATE/RETURN LAYOUT + * ##################### + */ + + // validate that container exists + var $N = $(this).eq(0); // FIRST matching Container element + if (!$N.length) { + return _log( options.errors.containerMissing ); + }; + + // Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout") + // return the Instance-pointer if layout has already been initialized + if ($N.data("layoutContainer") && $N.data("layout")) + return $N.data("layout"); // cached pointer + + // init global vars + var + $Ps = {} // Panes x5 - set in initPanes() + , $Cs = {} // Content x5 - set in initPanes() + , $Rs = {} // Resizers x4 - set in initHandles() + , $Ts = {} // Togglers x4 - set in initHandles() + , $Ms = $([]) // Masks - up to 2 masks per pane (IFRAME + DIV) + // aliases for code brevity + , sC = state.container // alias for easy access to 'container dimensions' + , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" + ; + + // create Instance object to expose data & option Properties, and primary action Methods + var Instance = { + // layout data + options: options // property - options hash + , state: state // property - dimensions hash + // object pointers + , container: $N // property - object pointers for layout container + , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center + , contents: $Cs // property - object pointers for ALL Content: contents.north, contents.center + , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north + , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north + // border-pane open/close + , hide: hide // method - ditto + , show: show // method - ditto + , toggle: toggle // method - pass a 'pane' ("north", "west", etc) + , open: open // method - ditto + , close: close // method - ditto + , slideOpen: slideOpen // method - ditto + , slideClose: slideClose // method - ditto + , slideToggle: slideToggle // method - ditto + // pane actions + , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data + , _sizePane: sizePane // method -intended for user by plugins only! + , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' + , sizeContent: sizeContent // method - pass a 'pane' + , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them + , showMasks: showMasks // method - pass a 'pane' OR list of panes - default = all panes with mask option set + , hideMasks: hideMasks // method - ditto' + // pane element methods + , initContent: initContent // method - ditto + , addPane: addPane // method - pass a 'pane' + , removePane: removePane // method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem + , createChildren: createChildren // method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].children + , refreshChildren: refreshChildren // method - pass a 'pane' and a layout-instance + // special pane option setting + , enableClosable: enableClosable // method - pass a 'pane' + , disableClosable: disableClosable // method - ditto + , enableSlidable: enableSlidable // method - ditto + , disableSlidable: disableSlidable // method - ditto + , enableResizable: enableResizable // method - ditto + , disableResizable: disableResizable// method - ditto + // utility methods for panes + , allowOverflow: allowOverflow // utility - pass calling element (this) + , resetOverflow: resetOverflow // utility - ditto + // layout control + , destroy: destroy // method - no parameters + , initPanes: isInitialized // method - no parameters + , resizeAll: resizeAll // method - no parameters + // callback triggering + , runCallbacks: _runCallbacks // method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west") + // alias collections of options, state and children - created in addPane and extended elsewhere + , hasParentLayout: false // set by initContainer() + , children: children // pointers to child-layouts, eg: Instance.children.west.layoutName + , north: false // alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], children: children[pane] } + , south: false // ditto + , west: false // ditto + , east: false // ditto + , center: false // ditto + }; + + // create the border layout NOW + if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation + return null; + else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later + return Instance; // return the Instance object + +} + + +})( jQuery ); +// END Layout - keep internal vars internal! + + + +// START Plugins - shared wrapper, no global vars +(function ($) { + + +/** + * jquery.layout.state 1.0 + * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ + * + * Copyright (c) 2012 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @requires: UI Layout 1.3.0.rc30.1 or higher + * @requires: $.ui.cookie (above) + * + * @see: http://groups.google.com/group/jquery-ui-layout + */ +/* + * State-management options stored in options.stateManagement, which includes a .cookie hash + * Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden + * + * // STATE/COOKIE OPTIONS + * @example $(el).layout({ + stateManagement: { + enabled: true + , stateKeys: "east.size,west.size,east.isClosed,west.isClosed" + , cookie: { name: "appLayout", path: "/" } + } + }) + * @example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies + * @example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } }) + * @example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" }) + * + * // STATE/COOKIE METHODS + * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); + * @example myLayout.loadCookie(); + * @example myLayout.deleteCookie(); + * @example var JSON = myLayout.readState(); // CURRENT Layout State + * @example var JSON = myLayout.readCookie(); // SAVED Layout State (from cookie) + * @example var JSON = myLayout.state.stateData; // LAST LOADED Layout State (cookie saved in layout.state hash) + * + * CUSTOM STATE-MANAGEMENT (eg, saved in a database) + * @example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" ); + * @example myLayout.loadState( JSON ); + */ + +/** + * UI COOKIE UTILITY + * + * A $.cookie OR $.ui.cookie namespace *should be standard*, but until then... + * This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin + * NOTE: This utility is REQUIRED by the layout.state plugin + * + * Cookie methods in Layout are created as part of State Management + */ +if (!$.ui) $.ui = {}; +$.ui.cookie = { + + // cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6 + acceptsCookies: !!navigator.cookieEnabled + +, read: function (name) { + var c = document.cookie + , cs = c ? c.split(';') : [] + , pair // loop var + ; + for (var i=0, n=cs.length; i < n; i++) { + pair = $.trim(cs[i]).split('='); // name=value pair + if (pair[0] == name) // found the layout cookie + return decodeURIComponent(pair[1]); + } + return null; + } + +, write: function (name, val, cookieOpts) { + var params = "" + , date = "" + , clear = false + , o = cookieOpts || {} + , x = o.expires || null + , t = $.type(x) + ; + if (t === "date") + date = x; + else if (t === "string" && x > 0) { + x = parseInt(x,10); + t = "number"; + } + if (t === "number") { + date = new Date(); + if (x > 0) + date.setDate(date.getDate() + x); + else { + date.setFullYear(1970); + clear = true; + } + } + if (date) params += ";expires="+ date.toUTCString(); + if (o.path) params += ";path="+ o.path; + if (o.domain) params += ";domain="+ o.domain; + if (o.secure) params += ";secure"; + document.cookie = name +"="+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie + } + +, clear: function (name) { + $.ui.cookie.write(name, "", {expires: -1}); + } + +}; +// if cookie.jquery.js is not loaded, create an alias to replicate it +// this may be useful to other plugins or code dependent on that plugin +if (!$.cookie) $.cookie = function (k, v, o) { + var C = $.ui.cookie; + if (v === null) + C.clear(k); + else if (v === undefined) + return C.read(k); + else + C.write(k, v, o); +}; + + +// tell Layout that the state plugin is available +$.layout.plugins.stateManagement = true; + +// Add State-Management options to layout.defaults +$.layout.config.optionRootKeys.push("stateManagement"); +$.layout.defaults.stateManagement = { + enabled: false // true = enable state-management, even if not using cookies +, autoSave: true // Save a state-cookie when page exits? +, autoLoad: true // Load the state-cookie when Layout inits? +, animateLoad: true // animate panes when loading state into an active layout +, includeChildren: true // recurse into child layouts to include their state as well + // List state-data to save - must be pane-specific +, stateKeys: "north.size,south.size,east.size,west.size,"+ + "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ + "north.isHidden,south.isHidden,east.isHidden,west.isHidden" +, cookie: { + name: "" // If not specified, will use Layout.name, else just "Layout" + , domain: "" // blank = current domain + , path: "" // blank = current page, "/" = entire website + , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' + , secure: false + } +}; +// Set stateManagement as a layout-option, NOT a pane-option +$.layout.optionsMap.layout.push("stateManagement"); + +/* + * State Management methods + */ +$.layout.state = { + + /** + * Get the current layout state and save it to a cookie + * + * myLayout.saveCookie( keys, cookieOpts ) + * + * @param {Object} inst + * @param {(string|Array)=} keys + * @param {Object=} cookieOpts + */ + saveCookie: function (inst, keys, cookieOpts) { + var o = inst.options + , sm = o.stateManagement + , oC = $.extend(true, {}, sm.cookie, cookieOpts || null) + , data = inst.state.stateData = inst.readState( keys || sm.stateKeys ) // read current panes-state + ; + $.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC ); + return $.extend(true, {}, data); // return COPY of state.stateData data + } + + /** + * Remove the state cookie + * + * @param {Object} inst + */ +, deleteCookie: function (inst) { + var o = inst.options; + $.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" ); + } + + /** + * Read & return data from the cookie - as JSON + * + * @param {Object} inst + */ +, readCookie: function (inst) { + var o = inst.options; + var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" ); + // convert cookie string back to a hash and return it + return c ? $.layout.state.decodeJSON(c) : {}; + } + + /** + * Get data from the cookie and USE IT to loadState + * + * @param {Object} inst + */ +, loadCookie: function (inst) { + var c = $.layout.state.readCookie(inst); // READ the cookie + if (c) { + inst.state.stateData = $.extend(true, {}, c); // SET state.stateData + inst.loadState(c); // LOAD the retrieved state + } + return c; + } + + /** + * Update layout options from the cookie, if one exists + * + * @param {Object} inst + * @param {Object=} stateData + * @param {boolean=} animate + */ +, loadState: function (inst, data, opts) { + if (!$.isPlainObject( data ) || $.isEmptyObject( data )) return; + + // normalize data & cache in the state object + data = inst.state.stateData = $.layout.transformData( data ); // panes = default subkey + + // add missing/default state-restore options + var smo = inst.options.stateManagement; + opts = $.extend({ + animateLoad: false //smo.animateLoad + , includeChildren: smo.includeChildren + }, opts ); + + if (!inst.state.initialized) { + /* + * layout NOT initialized, so just update its options + */ + // MUST remove pane.children keys before applying to options + // use a copy so we don't remove keys from original data + var o = $.extend(true, {}, data); + //delete o.center; // center has no state-data - only children + $.each($.layout.config.allPanes, function (idx, pane) { + if (o[pane]) delete o[pane].children; + }); + // update CURRENT layout-options with saved state data + $.extend(true, inst.options, o); + } + else { + /* + * layout already initialized, so modify layout's configuration + */ + var noAnimate = !opts.animateLoad + , o, c, h, state, open + ; + $.each($.layout.config.borderPanes, function (idx, pane) { + o = data[ pane ]; + if (!$.isPlainObject( o )) return; // no key, skip pane + + s = o.size; + c = o.initClosed; + h = o.initHidden; + ar = o.autoResize + state = inst.state[pane]; + open = state.isVisible; + + // reset autoResize + if (ar) + state.autoResize = ar; + // resize BEFORE opening + if (!open) + inst._sizePane(pane, s, false, false, false); // false=skipCallback/noAnimation/forceResize + // open/close as necessary - DO NOT CHANGE THIS ORDER! + if (h === true) inst.hide(pane, noAnimate); + else if (c === true) inst.close(pane, false, noAnimate); + else if (c === false) inst.open (pane, false, noAnimate); + else if (h === false) inst.show (pane, false, noAnimate); + // resize AFTER any other actions + if (open) + inst._sizePane(pane, s, false, false, noAnimate); // animate resize if option passed + }); + + /* + * RECURSE INTO CHILD-LAYOUTS + */ + if (opts.includeChildren) { + var paneStateChildren, childState; + $.each(inst.children, function (pane, paneChildren) { + paneStateChildren = data[pane] ? data[pane].children : 0; + if (paneStateChildren && paneChildren) { + $.each(paneChildren, function (stateKey, child) { + childState = paneStateChildren[stateKey]; + if (child && childState) + child.loadState( childState ); + }); + } + }); + } + } + } + + /** + * Get the *current layout state* and return it as a hash + * + * @param {Object=} inst // Layout instance to get state for + * @param {object=} [opts] // State-Managements override options + */ +, readState: function (inst, opts) { + // backward compatility + if ($.type(opts) === 'string') opts = { keys: opts }; + if (!opts) opts = {}; + var sm = inst.options.stateManagement + , ic = opts.includeChildren + , recurse = ic !== undefined ? ic : sm.includeChildren + , keys = opts.stateKeys || sm.stateKeys + , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } + , state = inst.state + , panes = $.layout.config.allPanes + , data = {} + , pair, pane, key, val + , ps, pC, child, array, count, branch + ; + if ($.isArray(keys)) keys = keys.join(","); + // convert keys to an array and change delimiters from '__' to '.' + keys = keys.replace(/__/g, ".").split(','); + // loop keys and create a data hash + for (var i=0, n=keys.length; i < n; i++) { + pair = keys[i].split("."); + pane = pair[0]; + key = pair[1]; + if ($.inArray(pane, panes) < 0) continue; // bad pane! + val = state[ pane ][ key ]; + if (val == undefined) continue; + if (key=="isClosed" && state[pane]["isSliding"]) + val = true; // if sliding, then *really* isClosed + ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; + } + + // recurse into the child-layouts for each pane + if (recurse) { + $.each(panes, function (idx, pane) { + pC = inst.children[pane]; + ps = state.stateData[pane]; + if ($.isPlainObject( pC ) && !$.isEmptyObject( pC )) { + // ensure a key exists for this 'pane', eg: branch = data.center + branch = data[pane] || (data[pane] = {}); + if (!branch.children) branch.children = {}; + $.each( pC, function (key, child) { + // ONLY read state from an initialize layout + if ( child.state.initialized ) + branch.children[ key ] = $.layout.state.readState( child ); + // if we have PREVIOUS (onLoad) state for this child-layout, KEEP IT! + else if ( ps && ps.children && ps.children[ key ] ) { + branch.children[ key ] = $.extend(true, {}, ps.children[ key ] ); + } + }); + } + }); + } + + return data; + } + + /** + * Stringify a JSON hash so can save in a cookie or db-field + */ +, encodeJSON: function (JSON) { + return parse(JSON); + function parse (h) { + var D=[], i=0, k, v, t // k = key, v = value + , a = $.isArray(h) + ; + for (k in h) { + v = h[k]; + t = typeof v; + if (t == 'string') // STRING - add quotes + v = '"'+ v +'"'; + else if (t == 'object') // SUB-KEY - recurse into it + v = parse(v); + D[i++] = (!a ? '"'+ k +'":' : '') + v; + } + return (a ? '[' : '{') + D.join(',') + (a ? ']' : '}'); + }; + } + + /** + * Convert stringified JSON back to a hash object + * @see $.parseJSON(), adding in jQuery 1.4.1 + */ +, decodeJSON: function (str) { + try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; } + catch (e) { return {}; } + } + + +, _create: function (inst) { + var _ = $.layout.state + , o = inst.options + , sm = o.stateManagement + ; + // ADD State-Management plugin methods to inst + $.extend( inst, { + // readCookie - update options from cookie - returns hash of cookie data + readCookie: function () { return _.readCookie(inst); } + // deleteCookie + , deleteCookie: function () { _.deleteCookie(inst); } + // saveCookie - optionally pass keys-list and cookie-options (hash) + , saveCookie: function (keys, cookieOpts) { return _.saveCookie(inst, keys, cookieOpts); } + // loadCookie - readCookie and use to loadState() - returns hash of cookie data + , loadCookie: function () { return _.loadCookie(inst); } + // loadState - pass a hash of state to use to update options + , loadState: function (stateData, opts) { _.loadState(inst, stateData, opts); } + // readState - returns hash of current layout-state + , readState: function (keys) { return _.readState(inst, keys); } + // add JSON utility methods too... + , encodeJSON: _.encodeJSON + , decodeJSON: _.decodeJSON + }); + + // init state.stateData key, even if plugin is initially disabled + inst.state.stateData = {}; + + // autoLoad MUST BE one of: data-array, data-hash, callback-function, or TRUE + if ( !sm.autoLoad ) return; + + // When state-data exists in the autoLoad key USE IT, + // even if stateManagement.enabled == false + if ($.isPlainObject( sm.autoLoad )) { + if (!$.isEmptyObject( sm.autoLoad )) { + inst.loadState( sm.autoLoad ); + } + } + else if ( sm.enabled ) { + // update the options from cookie or callback + // if options is a function, call it to get stateData + if ($.isFunction( sm.autoLoad )) { + var d = {}; + try { + d = sm.autoLoad( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn + } catch (e) {} + if (d && $.isPlainObject( d ) && !$.isEmptyObject( d )) + inst.loadState(d); + } + else // any other truthy value will trigger loadCookie + inst.loadCookie(); + } + } + +, _unload: function (inst) { + var sm = inst.options.stateManagement; + if (sm.enabled && sm.autoSave) { + // if options is a function, call it to save the stateData + if ($.isFunction( sm.autoSave )) { + try { + sm.autoSave( inst, inst.state, inst.options, inst.options.name || '' ); // try to get data from fn + } catch (e) {} + } + else // any truthy value will trigger saveCookie + inst.saveCookie(); + } + } + +}; + +// add state initialization method to Layout's onCreate array of functions +$.layout.onCreate.push( $.layout.state._create ); +$.layout.onUnload.push( $.layout.state._unload ); + + + + +/** + * jquery.layout.buttons 1.0 + * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ + * + * Copyright (c) 2012 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @requires: UI Layout 1.3.0.rc30.1 or higher + * + * @see: http://groups.google.com/group/jquery-ui-layout + * + * Docs: [ to come ] + * Tips: [ to come ] + */ + +// tell Layout that the state plugin is available +$.layout.plugins.buttons = true; + +// Add buttons options to layout.defaults +$.layout.defaults.autoBindCustomButtons = false; +// Specify autoBindCustomButtons as a layout-option, NOT a pane-option +$.layout.optionsMap.layout.push("autoBindCustomButtons"); + +/* + * Button methods + */ +$.layout.buttons = { + + /** + * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons + * + * @see _create() + * + * @param {Object} inst Layout Instance object + */ + init: function (inst) { + var pre = "ui-layout-button-" + , layout = inst.options.name || "" + , name; + $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { + $.each($.layout.config.borderPanes, function (ii, pane) { + $("."+pre+action+"-"+pane).each(function(){ + // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' + name = $(this).data("layoutName") || $(this).attr("layoutName"); + if (name == undefined || name === layout) + inst.bindButton(this, action, pane); + }); + }); + }); + } + + /** + * Helper function to validate params received by addButton utilities + * + * Two classes are added to the element, based on the buttonClass... + * The type of button is appended to create the 2nd className: + * - ui-layout-button-pin // action btnClass + * - ui-layout-button-pin-west // action btnClass + pane + * - ui-layout-button-toggle + * - ui-layout-button-open + * - ui-layout-button-close + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * + * @return {Array.} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null + */ +, get: function (inst, selector, pane, action) { + var $E = $(selector) + , o = inst.options + , err = o.errors.addButtonError + ; + if (!$E.length) { // element not found + $.layout.msg(err +" "+ o.errors.selector +": "+ selector, true); + } + else if ($.inArray(pane, $.layout.config.borderPanes) < 0) { // invalid 'pane' sepecified + $.layout.msg(err +" "+ o.errors.pane +": "+ pane, true); + $E = $(""); // NO BUTTON + } + else { // VALID + var btn = o[pane].buttonClass +"-"+ action; + $E .addClass( btn +" "+ btn +"-"+ pane ) + .data("layoutName", o.name); // add layout identifier - even if blank! + } + return $E; + } + + + /** + * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc. + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} action + * @param {string} pane + */ +, bind: function (inst, selector, action, pane) { + var _ = $.layout.buttons; + switch (action.toLowerCase()) { + case "toggle": _.addToggle (inst, selector, pane); break; + case "open": _.addOpen (inst, selector, pane); break; + case "close": _.addClose (inst, selector, pane); break; + case "pin": _.addPin (inst, selector, pane); break; + case "toggle-slide": _.addToggle (inst, selector, pane, true); break; + case "open-slide": _.addOpen (inst, selector, pane, true); break; + } + return inst; + } + + /** + * Add a custom Toggler button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addToggle: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "toggle") + .click(function(evt){ + inst.toggle(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Open button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addOpen: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "open") + .attr("title", inst.options[pane].tips.Open) + .click(function (evt) { + inst.open(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Close button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + */ +, addClose: function (inst, selector, pane) { + $.layout.buttons.get(inst, selector, pane, "close") + .attr("title", inst.options[pane].tips.Close) + .click(function (evt) { + inst.close(pane); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Pin button for a pane + * + * Four classes are added to the element, based on the paneClass for the associated pane... + * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: + * - ui-layout-pane-pin + * - ui-layout-pane-west-pin + * - ui-layout-pane-pin-up + * - ui-layout-pane-west-pin-up + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc. + */ +, addPin: function (inst, selector, pane) { + var _ = $.layout.buttons + , $E = _.get(inst, selector, pane, "pin"); + if ($E.length) { + var s = inst.state[pane]; + $E.click(function (evt) { + _.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed)); + if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open + else inst.close( pane ); // slide-closed + evt.stopPropagation(); + }); + // add up/down pin attributes and classes + _.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding)); + // add this pin to the pane data so we can 'sync it' automatically + // PANE.pins key is an array so we can store multiple pins for each pane + s.pins.push( selector ); // just save the selector string + } + return inst; + } + + /** + * Change the class of the pin button to make it look 'up' or 'down' + * + * @see addPin(), syncPins() + * + * @param {Object} inst Layout Instance object + * @param {Array.} $Pin The pin-span element in a jQuery wrapper + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin true = set the pin 'down', false = set it 'up' + */ +, setPinState: function (inst, $Pin, pane, doPin) { + var updown = $Pin.attr("pin"); + if (updown && doPin === (updown=="down")) return; // already in correct state + var + o = inst.options[pane] + , pin = o.buttonClass +"-pin" + , side = pin +"-"+ pane + , UP = pin +"-up "+ side +"-up" + , DN = pin +"-down "+side +"-down" + ; + $Pin + .attr("pin", doPin ? "down" : "up") // logic + .attr("title", doPin ? o.tips.Unpin : o.tips.Pin) + .removeClass( doPin ? UP : DN ) + .addClass( doPin ? DN : UP ) + ; + } + + /** + * INTERNAL function to sync 'pin buttons' when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), close() + * + * @param {Object} inst Layout Instance object + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns: function (inst, pane, doPin) { + // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE + $.each(inst.state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(inst, $(selector), pane, doPin); + }); + } + + +, _load: function (inst) { + var _ = $.layout.buttons; + // ADD Button methods to Layout Instance + // Note: sel = jQuery Selector string + $.extend( inst, { + bindButton: function (sel, action, pane) { return _.bind(inst, sel, action, pane); } + // DEPRECATED METHODS + , addToggleBtn: function (sel, pane, slide) { return _.addToggle(inst, sel, pane, slide); } + , addOpenBtn: function (sel, pane, slide) { return _.addOpen(inst, sel, pane, slide); } + , addCloseBtn: function (sel, pane) { return _.addClose(inst, sel, pane); } + , addPinBtn: function (sel, pane) { return _.addPin(inst, sel, pane); } + }); + + // init state array to hold pin-buttons + for (var i=0; i<4; i++) { + var pane = $.layout.config.borderPanes[i]; + inst.state[pane].pins = []; + } + + // auto-init buttons onLoad if option is enabled + if ( inst.options.autoBindCustomButtons ) + _.init(inst); + } + +, _unload: function (inst) { + // TODO: unbind all buttons??? + } + +}; + +// add initialization method to Layout's onLoad array of functions +$.layout.onLoad.push( $.layout.buttons._load ); +//$.layout.onUnload.push( $.layout.buttons._unload ); + + + +/** + * jquery.layout.browserZoom 1.0 + * $Date: 2011-12-29 08:00:00 (Thu, 29 Dec 2011) $ + * + * Copyright (c) 2012 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @requires: UI Layout 1.3.0.rc30.1 or higher + * + * @see: http://groups.google.com/group/jquery-ui-layout + * + * TODO: Extend logic to handle other problematic zooming in browsers + * TODO: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event + */ + +// tell Layout that the plugin is available +$.layout.plugins.browserZoom = true; + +$.layout.defaults.browserZoomCheckInterval = 1000; +$.layout.optionsMap.layout.push("browserZoomCheckInterval"); + +/* + * browserZoom methods + */ +$.layout.browserZoom = { + + _init: function (inst) { + // abort if browser does not need this check + if ($.layout.browserZoom.ratio() !== false) + $.layout.browserZoom._setTimer(inst); + } + +, _setTimer: function (inst) { + // abort if layout destroyed or browser does not need this check + if (inst.destroyed) return; + var o = inst.options + , s = inst.state + // don't need check if inst has parentLayout, but check occassionally in case parent destroyed! + // MINIMUM 100ms interval, for performance + , ms = inst.hasParentLayout ? 5000 : Math.max( o.browserZoomCheckInterval, 100 ) + ; + // set the timer + setTimeout(function(){ + if (inst.destroyed || !o.resizeWithWindow) return; + var d = $.layout.browserZoom.ratio(); + if (d !== s.browserZoom) { + s.browserZoom = d; + inst.resizeAll(); + } + // set a NEW timeout + $.layout.browserZoom._setTimer(inst); + } + , ms ); + } + +, ratio: function () { + var w = window + , s = screen + , d = document + , dE = d.documentElement || d.body + , b = $.layout.browser + , v = b.version + , r, sW, cW + ; + // we can ignore all browsers that fire window.resize event onZoom + if ((b.msie && v > 8) + || !b.msie + ) return false; // don't need to track zoom + + if (s.deviceXDPI && s.systemXDPI) // syntax compiler hack + return calc(s.deviceXDPI, s.systemXDPI); + // everything below is just for future reference! + if (b.webkit && (r = d.body.getBoundingClientRect)) + return calc((r.left - r.right), d.body.offsetWidth); + if (b.webkit && (sW = w.outerWidth)) + return calc(sW, w.innerWidth); + if ((sW = s.width) && (cW = dE.clientWidth)) + return calc(sW, cW); + return false; // no match, so cannot - or don't need to - track zoom + + function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); } + } + +}; +// add initialization method to Layout's onLoad array of functions +$.layout.onReady.push( $.layout.browserZoom._init ); + + })( jQuery ); \ No newline at end of file diff --git a/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.min.js b/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.min.js index 161d53617323..3f0dfea402bb 100644 --- a/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.min.js +++ b/web/src/main/webapp/components/jquery.layout/dist/jquery.layout-latest.min.js @@ -1,142 +1,142 @@ -/* - jquery.layout 1.3.0 - Release Candidate 30.79 - $Date: 2013-01-01 08:00:00 (Tue, 1 Jan 2013) $ - $Rev: 303007 $ - - Copyright (c) 2013 Kevin Dalman (http://allpro.net) - Based on work by Fabrizio Balliano (http://www.fabrizioballiano.net) - - Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - - SEE: http://layout.jquery-dev.net/LICENSE.txt - - Changelog: http://layout.jquery-dev.net/changelog.cfm#1.3.0.rc30.79 - - Docs: http://layout.jquery-dev.net/documentation.html - Tips: http://layout.jquery-dev.net/tips.html - Help: http://groups.google.com/group/jquery-ui-layout -*/ -(function(b){var a=Math.min,d=Math.max,c=Math.floor,f=function(a){return"string"===b.type(a)},j=function(a,d){if(b.isArray(d))for(var c=0,j=d.length;c').appendTo("body"),c={width:d.css("width")-d[0].clientWidth,height:d.height()-d[0].clientHeight}; -d.remove();window.scrollbarWidth=c.width;window.scrollbarHeight=c.height;return a.match(/^(width|height)$/)?c[a]:c},showInvisibly:function(b,a){if(b&&b.length&&(a||"none"===b.css("display"))){var d=b[0].style,d={display:d.display||"",visibility:d.visibility||""};b.css({display:"block",visibility:"hidden"});return d}return{}},getElementDimensions:function(a,c){var f={css:{},inset:{}},j=f.css,h={bottom:0},k=b.layout.cssNum,p=a.offset(),O,R,D;f.offsetLeft=p.left;f.offsetTop=p.top;c||(c={});b.each(["Left", -"Right","Top","Bottom"],function(d,k){O=j["border"+k]=b.layout.borderWidth(a,k);R=j["padding"+k]=b.layout.cssNum(a,"padding"+k);D=k.toLowerCase();f.inset[D]=0<=c[D]?c[D]:R;h[D]=f.inset[D]+O});j.width=a.width();j.height=a.height();j.top=k(a,"top",!0);j.bottom=k(a,"bottom",!0);j.left=k(a,"left",!0);j.right=k(a,"right",!0);f.outerWidth=a.outerWidth();f.outerHeight=a.outerHeight();f.innerWidth=d(0,f.outerWidth-h.left-h.right);f.innerHeight=d(0,f.outerHeight-h.top-h.bottom);f.layoutWidth=a.innerWidth(); -f.layoutHeight=a.innerHeight();return f},getElementStyles:function(b,a){var d={},c=b[0].style,f=a.split(","),k=["Top","Bottom","Left","Right"],j=["Color","Style","Width"],h,p,D,x,A,r;for(x=0;xA;A++)if(p=k[A],"border"===h)for(r=0;3>r;r++)D=j[r],d[h+p+D]=c[h+p+D];else d[h+p]=c[h+p];else d[h]=c[h];return d},cssWidth:function(a,c){if(0>=c)return 0;var f=!b.layout.browser.boxModel?"border-box":b.support.boxSizing?a.css("boxSizing"): -"content-box",j=b.layout.borderWidth,h=b.layout.cssNum,k=c;"border-box"!==f&&(k-=j(a,"Left")+j(a,"Right"));"content-box"===f&&(k-=h(a,"paddingLeft")+h(a,"paddingRight"));return d(0,k)},cssHeight:function(a,c){if(0>=c)return 0;var f=!b.layout.browser.boxModel?"border-box":b.support.boxSizing?a.css("boxSizing"):"content-box",j=b.layout.borderWidth,h=b.layout.cssNum,k=c;"border-box"!==f&&(k-=j(a,"Top")+j(a,"Bottom"));"content-box"===f&&(k-=h(a,"paddingTop")+h(a,"paddingBottom"));return d(0,k)},cssNum:function(a, -d,c){a.jquery||(a=b(a));var f=b.layout.showInvisibly(a);d=b.css(a[0],d,!0);c=c&&"auto"==d?d:Math.round(parseFloat(d)||0);a.css(f);return c},borderWidth:function(a,d){a.jquery&&(a=a[0]);var c="border"+d.substr(0,1).toUpperCase()+d.substr(1);return"none"===b.css(a,c+"Style",!0)?0:Math.round(parseFloat(b.css(a,c+"Width",!0))||0)},isMouseOverElem:function(a,d){var c=b(d||this),f=c.offset(),j=f.top,f=f.left,k=f+c.outerWidth(),c=j+c.outerHeight(),h=a.pageX,p=a.pageY;return b.layout.browser.msie&&0>h&&0> -p||h>=f&&h<=k&&p>=j&&p<=c},msg:function(a,d,c,f){b.isPlainObject(a)&&window.debugData?("string"===typeof d?(f=c,c=d):"object"===typeof c&&(f=c,c=null),c=c||"log( )",f=b.extend({sort:!1,returnHTML:!1,display:!1},f),!0===d||f.display?debugData(a,c,f):window.console&&console.log(debugData(a,c,f))):d?alert(a):window.console?console.log(a):(d=b("#layoutLogger"),d.length||(d=b('
        XLayout console.log
          ').appendTo("body"), -d.css("left",b(window).width()-d.outerWidth()-5),b.ui.draggable&&d.draggable({handle:":first-child"})),d.children("ul").append('
        • '+a.replace(/\/g,">")+"
        • "))}};var h=navigator.userAgent.toLowerCase(),p=/(chrome)[ \/]([\w.]+)/.exec(h)||/(webkit)[ \/]([\w.]+)/.exec(h)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(h)||/(msie) ([\w.]+)/.exec(h)||0>h.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(h)|| -[],h=p[1]||"",p=p[2]||0,x="msie"===h;b.layout.browser={version:p,safari:"webkit"===h,webkit:"chrome"===h,msie:x,isIE6:x&&6==p,boxModel:!x||!1!==b.support.boxModel};h&&(b.layout.browser[h]=!0);x&&b(function(){b.layout.browser.boxModel=b.support.boxModel});b.layout.defaults={name:"",containerClass:"ui-layout-container",inset:null,scrollToBookmarkOnLoad:!0,resizeWithWindow:!0,resizeWithWindowDelay:200,resizeWithWindowMaxDelay:0,maskPanesEarly:!1,onresizeall_start:null,onresizeall_end:null,onload_start:null, -onload_end:null,onunload_start:null,onunload_end:null,initPanes:!0,showErrorMessages:!0,showDebugMessages:!1,zIndex:null,zIndexes:{pane_normal:0,content_mask:1,resizer_normal:2,pane_sliding:100,pane_animate:1E3,resizer_drag:1E4},errors:{pane:"pane",selector:"selector",addButtonError:"Error Adding Button\nInvalid ",containerMissing:"UI Layout Initialization Error\nThe specified layout-container does not exist.",centerPaneMissing:"UI Layout Initialization Error\nThe center-pane element does not exist.\nThe center-pane is a required element.", -noContainerHeight:"UI Layout Initialization Warning\nThe layout-container \"CONTAINER\" has no height.\nTherefore the layout is 0-height and hence 'invisible'!",callbackError:"UI Layout Callback Error\nThe EVENT callback is not a valid function."},panes:{applyDemoStyles:!1,closable:!0,resizable:!0,slidable:!0,initClosed:!1,initHidden:!1,contentSelector:".ui-layout-content",contentIgnoreSelector:".ui-layout-ignore",findNestedContent:!1,paneClass:"ui-layout-pane",resizerClass:"ui-layout-resizer",togglerClass:"ui-layout-toggler", -buttonClass:"ui-layout-button",minSize:0,maxSize:0,spacing_open:6,spacing_closed:6,togglerLength_open:50,togglerLength_closed:50,togglerAlign_open:"center",togglerAlign_closed:"center",togglerContent_open:"",togglerContent_closed:"",resizerDblClickToggle:!0,autoResize:!0,autoReopen:!0,resizerDragOpacity:1,maskContents:!1,maskObjects:!1,maskZindex:null,resizingGrid:!1,livePaneResizing:!1,liveContentResizing:!1,liveResizingTolerance:1,sliderCursor:"pointer",slideTrigger_open:"click",slideTrigger_close:"mouseleave", -slideDelay_open:300,slideDelay_close:300,hideTogglerOnSlide:!1,preventQuickSlideClose:b.layout.browser.webkit,preventPrematureSlideClose:!1,tips:{Open:"Open",Close:"Close",Resize:"Resize",Slide:"Slide Open",Pin:"Pin",Unpin:"Un-Pin",noRoomToOpen:"Not enough room to show this panel.",minSizeWarning:"Panel has reached its minimum size",maxSizeWarning:"Panel has reached its maximum size"},showOverflowOnHover:!1,enableCursorHotkey:!0,customHotkeyModifier:"SHIFT",fxName:"slide",fxSpeed:null,fxSettings:{}, -fxOpacityFix:!0,animatePaneSizing:!1,children:null,containerSelector:"",initChildren:!0,destroyChildren:!0,resizeChildren:!0,triggerEventsOnLoad:!1,triggerEventsDuringLiveResize:!0,onshow_start:null,onshow_end:null,onhide_start:null,onhide_end:null,onopen_start:null,onopen_end:null,onclose_start:null,onclose_end:null,onresize_start:null,onresize_end:null,onsizecontent_start:null,onsizecontent_end:null,onswap_start:null,onswap_end:null,ondrag_start:null,ondrag_end:null},north:{paneSelector:".ui-layout-north", -size:"auto",resizerCursor:"n-resize",customHotkey:""},south:{paneSelector:".ui-layout-south",size:"auto",resizerCursor:"s-resize",customHotkey:""},east:{paneSelector:".ui-layout-east",size:200,resizerCursor:"e-resize",customHotkey:""},west:{paneSelector:".ui-layout-west",size:200,resizerCursor:"w-resize",customHotkey:""},center:{paneSelector:".ui-layout-center",minWidth:0,minHeight:0}};b.layout.optionsMap={layout:"name instanceKey stateManagement effects inset zIndexes errors zIndex scrollToBookmarkOnLoad showErrorMessages maskPanesEarly outset resizeWithWindow resizeWithWindowDelay resizeWithWindowMaxDelay onresizeall onresizeall_start onresizeall_end onload onload_start onload_end onunload onunload_start onunload_end".split(" "), -center:"paneClass contentSelector contentIgnoreSelector findNestedContent applyDemoStyles triggerEventsOnLoad showOverflowOnHover maskContents maskObjects liveContentResizing containerSelector children initChildren resizeChildren destroyChildren onresize onresize_start onresize_end onsizecontent onsizecontent_start onsizecontent_end".split(" "),noDefault:["paneSelector","resizerCursor","customHotkey"]};b.layout.transformData=function(a,d){var c=d?{panes:{},center:{}}:{},f,j,k,h,p,x,D;if("object"!== -typeof a)return c;for(j in a){f=c;p=a[j];k=j.split("__");D=k.length-1;for(x=0;x<=D;x++)h=k[x],x===D?f[h]=b.isPlainObject(p)?b.layout.transformData(p):p:(f[h]||(f[h]={}),f=f[h])}return c};b.layout.backwardCompatibility={map:{applyDefaultStyles:"applyDemoStyles",childOptions:"children",initChildLayout:"initChildren",destroyChildLayout:"destroyChildren",resizeChildLayout:"resizeChildren",resizeNestedLayout:"resizeChildren",resizeWhileDragging:"livePaneResizing",resizeContentWhileDragging:"liveContentResizing", -triggerEventsWhileDragging:"triggerEventsDuringLiveResize",maskIframesOnResize:"maskContents",useStateCookie:"stateManagement.enabled","cookie.autoLoad":"stateManagement.autoLoad","cookie.autoSave":"stateManagement.autoSave","cookie.keys":"stateManagement.stateKeys","cookie.name":"stateManagement.cookie.name","cookie.domain":"stateManagement.cookie.domain","cookie.path":"stateManagement.cookie.path","cookie.expires":"stateManagement.cookie.expires","cookie.secure":"stateManagement.cookie.secure", -noRoomToOpenTip:"tips.noRoomToOpen",togglerTip_open:"tips.Close",togglerTip_closed:"tips.Open",resizerTip:"tips.Resize",sliderTip:"tips.Slide"},renameOptions:function(a){function d(b,c){for(var f=b.split("."),k=f.length-1,j={branch:a,key:f[k]},r=0,q;rw)return!0;var m={38:"north",40:"south",37:"west",39:"east"},a=e.shiftKey,g=e.ctrlKey,t,n,d,c;g&&(37<=w&&40>=w)&&r[m[w]].enableCursorHotkey?c=m[w]:(g||a)&&b.each(k.borderPanes,function(e, -b){t=r[b];n=t.customHotkey;d=t.customHotkeyModifier;if(a&&"SHIFT"==d||g&&"CTRL"==d||g&&a)if(n&&w===(isNaN(n)||9>=n?n.toUpperCase().charCodeAt(0):n))return c=b,!1});if(!c||!y[c]||!r[c].closable||q[c].isHidden)return!0;na(c);e.stopPropagation();return e.returnValue=!1}function x(e){if(H()){this&&this.tagName&&(e=this);var w;f(e)?w=y[e]:b(e).data("layoutRole")?w=b(e):b(e).parents().each(function(){if(b(this).data("layoutRole"))return w=b(this),!1});if(w&&w.length){var m=w.data("layoutEdge");e=q[m];e.cssSaved&& -X(m);if(e.isSliding||e.isResizing||e.isClosed)e.cssSaved=!1;else{var a={zIndex:r.zIndexes.resizer_normal+1},g={},t=w.css("overflow"),n=w.css("overflowX"),d=w.css("overflowY");"visible"!=t&&(g.overflow=t,a.overflow="visible");n&&!n.match(/(visible|auto)/)&&(g.overflowX=n,a.overflowX="visible");d&&!d.match(/(visible|auto)/)&&(g.overflowY=n,a.overflowY="visible");e.cssSaved=g;w.css(a);b.each(k.allPanes,function(e,b){b!=m&&X(b)})}}}}function X(e){if(H()){this&&this.tagName&&(e=this);var w;f(e)?w=y[e]: -b(e).data("layoutRole")?w=b(e):b(e).parents().each(function(){if(b(this).data("layoutRole"))return w=b(this),!1});if(w&&w.length){e=w.data("layoutEdge");e=q[e];var m=e.cssSaved||{};!e.isSliding&&!e.isResizing&&w.css("zIndex",r.zIndexes.pane_normal);w.css(m);e.cssSaved=!1}}}var G=b.layout.browser,k=b.layout.config,Q=b.layout.cssWidth,O=b.layout.cssHeight,R=b.layout.getElementDimensions,D=b.layout.getElementStyles,Ma=b.layout.getEventObject,A=b.layout.parsePaneName,r=b.extend(!0,{},b.layout.defaults); -r.effects=b.extend(!0,{},b.layout.effects);var q={id:"layout"+b.now(),initialized:!1,paneResizing:!1,panesSliding:{},container:{innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0,layoutWidth:0,layoutHeight:0},north:{childIdx:0},south:{childIdx:0},east:{childIdx:0},west:{childIdx:0},center:{childIdx:0}},ba={north:null,south:null,east:null,west:null,center:null},M={data:{},set:function(e,b,m){M.clear(e);M.data[e]=setTimeout(b,m)},clear:function(e){var b=M.data;b[e]&&(clearTimeout(b[e]),delete b[e])}}, -ca=function(e,w,m){var a=r;(a.showErrorMessages&&!m||m&&a.showDebugMessages)&&b.layout.msg(a.name+" / "+e,!1!==w);return!1},C=function(e,w,m){var a=w&&f(w),g=a?q[w]:q,t=a?r[w]:r,n=r.name,d=e+(e.match(/_/)?"":"_end"),c=d.match(/_end$/)?d.substr(0,d.length-4):"",l=t[d]||t[c],h="NC",k=[];!a&&"boolean"===b.type(w)&&(m=w,w="");if(l)try{f(l)&&(l.match(/,/)?(k=l.split(","),l=eval(k[0])):l=eval(l)),b.isFunction(l)&&(h=k.length?l(k[1]):a?l(w,y[w],g,t,n):l(z,g,t,n))}catch(j){ca(r.errors.callbackError.replace(/EVENT/, -b.trim((w||"")+" "+d)),!1),"string"===b.type(j)&&string.length&&ca("Exception: "+j,!1)}!m&&!1!==h&&(a?(m=y[w],t=r[w],g=q[w],m.triggerHandler("layoutpane"+d,[w,m,g,t,n]),c&&m.triggerHandler("layoutpane"+c,[w,m,g,t,n])):(u.triggerHandler("layout"+d,[z,g,t,n]),c&&u.triggerHandler("layout"+c,[z,g,t,n])));a&&"onresize_end"===e&&db(w+"",!0);return h},eb=function(e){if(!G.mozilla){var b=y[e];"IFRAME"===q[e].tagName?b.css(k.hidden).css(k.visible):b.find("IFRAME").css(k.hidden).css(k.visible)}},ya=function(e){var b= -y[e];e=k[e].dir;b={minWidth:1001-Q(b,1E3),minHeight:1001-O(b,1E3)};"horz"===e&&(b.minSize=b.minHeight);"vert"===e&&(b.minSize=b.minWidth);return b},fa=function(e,w,m){m||(m=k[e].dir);f(w)&&w.match(/%/)&&(w="100%"===w?-1:parseInt(w,10)/100);if(0===w)return 0;if(1<=w)return parseInt(w,10);var a=r,g=0;"horz"==m?g=v.innerHeight-(y.north?a.north.spacing_open:0)-(y.south?a.south.spacing_open:0):"vert"==m&&(g=v.innerWidth-(y.west?a.west.spacing_open:0)-(y.east?a.east.spacing_open:0));if(-1===w)return g; -if(0b&&(b=100);M.clear("winResize");M.set("winResize",function(){M.clear("winResize");M.clear("winResizeRepeater");var b=R(u,e.inset);(b.innerWidth!==v.innerWidth||b.innerHeight!==v.innerHeight)&&oa()},b);M.data.winResizeRepeater||lb()},lb=function(){var e= -Number(r.resizeWithWindowMaxDelay);0"),l=l.toggler=g.closable?P[a]=b("
          "):!1;!d.isVisible&&g.slidable&&j.attr("title",g.tips.Slide).css("cursor",g.sliderCursor);j.attr("id",c?c+"-resizer":"").data({parentLayout:z,layoutPane:z[a],layoutEdge:a,layoutRole:"resizer"}).css(k.resizers.cssReq).css("zIndex",r.zIndexes.resizer_normal).css(g.applyDemoStyles?k.resizers.cssDemo:{}).addClass(n+" "+n+h).hover(Oa,da).hover(fb,gb).appendTo(u); -g.resizerDblClickToggle&&j.bind("dblclick."+K,na);l&&(l.attr("id",c?c+"-toggler":"").data({parentLayout:z,layoutPane:z[a],layoutEdge:a,layoutRole:"toggler"}).css(k.togglers.cssReq).css(g.applyDemoStyles?k.togglers.cssDemo:{}).addClass(f+" "+f+h).hover(Oa,da).bind("mouseenter",fb).appendTo(j),g.togglerContent_open&&b(""+g.togglerContent_open+"").data({layoutEdge:a,layoutRole:"togglerContent"}).data("layoutRole","togglerContent").data("layoutEdge",a).addClass("content content-open").css("display", -"none").appendTo(l),g.togglerContent_closed&&b(""+g.togglerContent_closed+"").data({layoutEdge:a,layoutRole:"togglerContent"}).addClass("content content-closed").css("display","none").appendTo(l),pb(a));var g=a,B=b.layout.plugins.draggable,g=g?g.split(","):k.borderPanes;b.each(g,function(e,a){var g=r[a];if(!B||!y[a]||!g.resizable)return g.resizable=!1,!0;var m=q[a],w=r.zIndexes,d=k[a],c="horz"==d.dir?"top":"left",t=F[a],n=g.resizerClass,f=0,l,h,E=n+"-drag",j=n+"-"+a+"-drag",J=n+"-dragging", -zb=n+"-"+a+"-dragging",cb=n+"-dragging-limit",v=n+"-"+a+"-dragging-limit",x=!1;m.isClosed||t.attr("title",g.tips.Resize).css("cursor",g.resizerCursor);t.draggable({containment:u[0],axis:"horz"==d.dir?"y":"x",delay:0,distance:1,grid:g.resizingGrid,helper:"clone",opacity:g.resizerDragOpacity,addClasses:!1,zIndex:w.resizer_drag,start:function(e,w){g=r[a];m=q[a];h=g.livePaneResizing;if(!1===C("ondrag_start",a))return!1;m.isResizing=!0;q.paneResizing=a;M.clear(a+"_closeSlider");Y(a);l=m.resizerPosition; -f=w.position[c];t.addClass(E+" "+j);x=!1;b("body").disableSelection();va(a,{resizing:!0})},drag:function(e,b){x||(b.helper.addClass(J+" "+zb).css({right:"auto",bottom:"auto"}).children().css("visibility","hidden"),x=!0,m.isSliding&&y[a].css("zIndex",w.pane_sliding));var d=0;b.position[c]l.max&&(b.position[c]=l.max,d=1);d?(b.helper.addClass(cb+" "+v),window.defaultStatus=0d&&a.match(/(south|east)/)?g.tips.maxSizeWarning: -g.tips.minSizeWarning):(b.helper.removeClass(cb+" "+v),window.defaultStatus="");h&&Math.abs(b.position[c]-f)>=g.liveResizingTolerance&&(f=b.position[c],p(e,b,a))},stop:function(e,g){b("body").enableSelection();window.defaultStatus="";t.removeClass(E+" "+j);m.isResizing=!1;q.paneResizing=!1;p(e,g,a,!0)}})});var p=function(b,e,a,g){var m=e.position,w=k[a];b=r[a];e=q[a];var d;switch(a){case "north":d=m.top;break;case "west":d=m.left;break;case "south":d=v.layoutHeight-m.top-b.spacing_open;break;case "east":d= -v.layoutWidth-m.left-b.spacing_open}d-=v.inset[w.side];g?(!1!==C("ondrag_end",a)&&Ca(a,d,!1,!0),za(!0),e.isSliding&&va(a,{resizing:!0})):Math.abs(d-e.size)j.maxSize)return Va(f,!1),!c&&h.tips.noRoomToOpen&&alert(h.tips.noRoomToOpen),a();b?wa(f,!0):j.isSliding?wa(f,!1):h.slidable&&ma(f,!1); -j.noRoom=!1;ha(f);p=j.isShowing;delete j.isShowing;l=!d&&j.isClosed&&"none"!=h.fxName_open;j.isMoving=!0;j.isVisible=!0;j.isClosed=!1;p&&(j.isHidden=!1);l?(Ga(f,!0),n.show(h.fxName_open,h.fxSettings_open,h.fxSpeed_open,function(){Ga(f,!1);j.isVisible&&g();a()})):(rb(f),g(),a())}})}},Ua=function(a,d){var c=y[a],f=F[a],g=P[a],h=r[a],n=q[a],j=k[a].side,p=h.resizerClass,l=h.togglerClass,u="-"+a;f.css(j,v.inset[j]+ga(a)).removeClass(p+"-closed "+p+u+"-closed").addClass(p+"-open "+p+u+"-open");n.isSliding? -f.addClass(p+"-sliding "+p+u+"-sliding"):f.removeClass(p+"-sliding "+p+u+"-sliding");da(0,f);h.resizable&&b.layout.plugins.draggable?f.draggable("enable").css("cursor",h.resizerCursor).attr("title",h.tips.Resize):n.isSliding||f.css("cursor","default");g&&(g.removeClass(l+"-closed "+l+u+"-closed").addClass(l+"-open "+l+u+"-open").attr("title",h.tips.Close),da(0,g),g.children(".content-closed").hide(),g.children(".content-open").css("display","block"));Va(a,!n.isSliding);b.extend(n,R(c));q.initialized&& -(qa(),pa(a,!0));if(!d&&(q.initialized||h.triggerEventsOnLoad)&&c.is(":visible"))C("onopen_end",a),n.isShowing&&C("onshow_end",a),q.initialized&&C("onresize_end",a)},sb=function(a){function b(){g.isClosed?g.isMoving||ra(c,!0):wa(c,!0)}if(H()){var d=Ma(a),c=A.call(this,a),g=q[c];a=r[c].slideDelay_open;d&&d.stopImmediatePropagation();g.isClosed&&d&&"mouseenter"===d.type&&0g.maxSize?ka(a,g.maxSize,c,!0,f):g.sizec?d(0,e.attempt-(e.actual-c)):d(0,e.attempt+(c-e.actual));h.cssSize=("horz"==k[n].dir?O:Q)(y[n],h.attempt);l.css(ua,h.cssSize);h.actual="width"==ua?l.outerWidth():l.outerHeight();h.correct=c===h.actual;1===a.length&&(ca(t,!1,!0),ca(e,!1,!0));ca(h,!1,!0);if(3B.width){var h=h.minWidth-j.outerWidth,B=r.east.minSize||0,x=r.west.minSize||0,Z=q.east.size,z=q.west.size,A=Z,D=z;0B)&&(A=d(Z-B,Z-h),h-=Z-A);0x)&&(D=d(z-x,z-h),h-=z-D);if(0===h){Z&&Z!=B&&ka("east",A,!0,!0,f);z&&z!=x&&ka("west",D,!0,!0,f);ia("center", -c,f);k.css(u);return}}}else{j.isVisible&&!j.noVerticalRoom&&b.extend(j,R(k),ya(e));if(!f&&!j.noVerticalRoom&&B.height===j.outerHeight)return k.css(u),!0;l.top=B.top;l.bottom=B.bottom;j.newSize=B.height;l.height=O(k,B.height);j.maxHeight=l.height;p=0<=j.maxHeight;p||(j.noVerticalRoom=!0)}p?(!c&&q.initialized&&C("onresize_start",e),k.css(l),"center"!==e&&qa(e),j.noRoom&&(!j.isClosed&&!j.isHidden)&&ha(e),j.isVisible&&(b.extend(j,R(k)),q.initialized&&pa(e))):!j.noRoom&&j.isVisible&&ha(e);k.css(u);delete j.newSize; -delete j.newWidth;delete j.newHeight;if(!j.isVisible)return!0;"center"===e&&(j=G.isIE6||!G.boxModel,y.north&&(j||"IFRAME"==q.north.tagName)&&y.north.css("width",Q(y.north,v.innerWidth)),y.south&&(j||"IFRAME"==q.south.tagName)&&y.south.css("width",Q(y.south,v.innerWidth)));!c&&q.initialized&&C("onresize_end",e)}})},oa=function(a){A(a);if(u.is(":visible"))if(q.initialized){if(!0===a&&b.isPlainObject(r.outset)&&u.css(r.outset),b.extend(v,R(u,r.inset)),v.outerHeight){!0===a&&ob();if(!1===C("onresizeall_start"))return!1; -var d,c,f;b.each(["south","north","east","west"],function(a,b){y[b]&&(c=r[b],f=q[b],f.autoResize&&f.size!=c.size?ka(b,c.size,!0,!0,!0):(Y(b),ha(b,!1,!0,!0)))});ia("",!0,!0);qa();b.each(k.allPanes,function(a,b){(d=y[b])&&q[b].isVisible&&C("onresize_end",b)});C("onresizeall_end")}}else Aa()},db=function(a,d){var c=A.call(this,a);r[c].resizeChildren&&(d||Ba(c),c=ba[c],b.isPlainObject(c)&&b.each(c,function(a,b){b.destroyed||b.resizeAll()}))},pa=function(a,c){if(H()){var h=A.call(this,a),h=h?h.split(","): -k.allPanes;b.each(h,function(a,e){function h(a){return d(u.css.paddingBottom,parseInt(a.css("marginBottom"),10)||0)}function j(){var a=r[e].contentIgnoreSelector,a=p.nextAll().not(".ui-layout-mask").not(a||":lt(0)"),b=a.filter(":visible"),d=b.filter(":last");v={top:p[0].offsetTop,height:p.outerHeight(),numFooters:a.length,hiddenFooters:a.length-b.length,spaceBelow:0};v.spaceAbove=v.top;v.bottom=v.top+v.height;v.spaceBelow=d.length?d[0].offsetTop+d.outerHeight()-v.bottom+h(d):h(p)}var m=y[e],p=U[e], -l=r[e],u=q[e],v=u.content;if(!m||!p||!m.is(":visible"))return!0;if(!p.length&&(Sa(e,!1),!p))return;if(!1!==C("onsizecontent_start",e)){if(!u.isMoving&&!u.isResizing||l.liveContentResizing||c||void 0==v.top)j(),0A)x=A,z=0;else if(f(z))switch(z){case "top":case "left":z=0;break;case "bottom":case "right":z=A-x;break; -default:z=c((A-x)/2)}else h=parseInt(z,10),z=0<=z?h:A-x+h;if("horz"===l){var D=Q(p,x);p.css({width:D,height:O(p,B),left:z,top:0});p.children(".content").each(function(){u=b(this);u.css("marginLeft",c((D-u.outerWidth())/2))})}else{var C=O(p,x);p.css({height:C,width:Q(p,B),top:z,left:0});p.children(".content").each(function(){u=b(this);u.css("marginTop",c((C-u.outerHeight())/2))})}da(0,p)}if(!q.initialized&&(e.initHidden||g.isHidden))j.hide(),p&&p.hide()}}})},pb=function(a){if(H()){var b=A.call(this, -a);a=P[b];var d=r[b];a&&(d.closable=!0,a.bind("click."+K,function(a){a.stopPropagation();na(b)}).css("visibility","visible").css("cursor","pointer").attr("title",q[b].isClosed?d.tips.Open:d.tips.Close).show())}},Va=function(a,d){b.layout.plugins.buttons&&b.each(q[a].pins,function(c,f){b.layout.buttons.setPinState(z,b(f),a,d)})},u=b(this).eq(0);if(!u.length)return ca(r.errors.containerMissing);if(u.data("layoutContainer")&&u.data("layout"))return u.data("layout");var y={},U={},F={},P={},ea=b([]),v= -q.container,K=q.id,z={options:r,state:q,container:u,panes:y,contents:U,resizers:F,togglers:P,hide:Ta,show:Fa,toggle:na,open:ra,close:ja,slideOpen:sb,slideClose:Wa,slideToggle:function(a){a=A.call(this,a);na(a,!0)},setSizeLimits:Y,_sizePane:ka,sizePane:Ca,sizeContent:pa,swapPanes:function(a,c){function f(a){var d=y[a],c=U[a];return!d?!1:{pane:a,P:d?d[0]:!1,C:c?c[0]:!1,state:b.extend(!0,{},q[a]),options:b.extend(!0,{},r[a])}}function h(a,c){if(a){var e=a.P,f=a.C,g=a.pane,j=k[c],m=b.extend(!0,{},q[c]), -n=r[c],w={resizerCursor:n.resizerCursor};b.each(["fxName","fxSpeed","fxSettings"],function(a,b){w[b+"_open"]=n[b+"_open"];w[b+"_close"]=n[b+"_close"];w[b+"_size"]=n[b+"_size"]});y[c]=b(e).data({layoutPane:z[c],layoutEdge:c}).css(k.hidden).css(j.cssReq);U[c]=f?b(f):!1;r[c]=b.extend(!0,{},a.options,w);q[c]=b.extend(!0,{},a.state);e.className=e.className.replace(RegExp(n.paneClass+"-"+g,"g"),n.paneClass+"-"+c);Pa(c);j.dir!=k[g].dir?(e=p[c]||0,Y(c),e=d(e,q[c].minSize),Ca(c,e,!0,!0)):F[c].css(j.side,v.inset[j.side]+ -(q[c].isVisible?ga(c):0));a.state.isVisible&&!m.isVisible?Ua(c,!0):(Da(c),ma(c,!0));a=null}}if(H()){var g=A.call(this,a);q[g].edge=c;q[c].edge=g;if(!1===C("onswap_start",g)||!1===C("onswap_start",c))q[g].edge=g,q[c].edge=c;else{var j=f(g),n=f(c),p={};p[g]=j?j.state.size:0;p[c]=n?n.state.size:0;y[g]=!1;y[c]=!1;q[g]={};q[c]={};P[g]&&P[g].remove();P[c]&&P[c].remove();F[g]&&F[g].remove();F[c]&&F[c].remove();F[g]=F[c]=P[g]=P[c]=!1;h(j,c);h(n,g);j=n=p=null;y[g]&&y[g].css(k.visible);y[c]&&y[c].css(k.visible); -oa();C("onswap_end",g);C("onswap_end",c)}}},showMasks:va,hideMasks:za,initContent:Sa,addPane:ib,removePane:Ra,createChildren:Qa,refreshChildren:Ba,enableClosable:pb,disableClosable:function(a,b){if(H()){var c=A.call(this,a),d=P[c];d&&(r[c].closable=!1,q[c].isClosed&&ra(c,!1,!0),d.unbind("."+K).css("visibility",b?"hidden":"visible").css("cursor","default").attr("title",""))}},enableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].slidable=!0,q[a].isClosed&&ma(a, -!0))}},disableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&(r[a].slidable=!1,q[a].isSliding?ja(a,!1,!0):(ma(a,!1),b.css("cursor","default").attr("title",""),da(null,b[0])))}},enableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a],c=r[a];b&&b.data("draggable")&&(c.resizable=!0,b.draggable("enable"),q[a].isClosed||b.css("cursor",c.resizerCursor).attr("title",c.tips.Resize))}},disableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].resizable= -!1,b.draggable("disable").css("cursor","default").attr("title",""),da(null,b[0]))}},allowOverflow:x,resetOverflow:X,destroy:function(a,c){b(window).unbind("."+K);b(document).unbind("."+K);"object"===typeof a?A(a):c=a;u.clearQueue().removeData("layout").removeData("layoutContainer").removeClass(r.containerClass).unbind("."+K);ea.remove();b.each(k.allPanes,function(a,b){Ra(b,!1,!0,c)});u.data("layoutCSS")&&!u.data("layoutRole")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");"BODY"===v.tagName&& -(u=b("html")).data("layoutCSS")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");j(z,b.layout.onDestroy);mb();for(var d in z)d.match(/^(container|options)$/)||delete z[d];z.destroyed=!0;return z},initPanes:H,resizeAll:oa,runCallbacks:C,hasParentLayout:!1,children:ba,north:!1,south:!1,west:!1,east:!1,center:!1},Xa;var V,Ya,N,Ha,la,sa,W;h=b.layout.transformData(h,!0);h=b.layout.backwardCompatibility.renameAllOptions(h);if(!b.isEmptyObject(h.panes)){V=b.layout.optionsMap.noDefault;la=0;for(sa=V.length;la< -sa;la++)N=V[la],delete h.panes[N];V=b.layout.optionsMap.layout;la=0;for(sa=V.length;lab.inArray(N,Bb)&&0>b.inArray(N,V)&&(h.panes[N]||(h.panes[N]=b.isPlainObject(Ha)?b.extend(!0,{},Ha):Ha),delete h[N]);b.extend(!0,r,h);b.each(k.allPanes,function(a,c){k[c]=b.extend(!0,{},k.panes,k[c]);Ya=r.panes;W=r[c];if("center"===c){V=b.layout.optionsMap.center;a=0;for(sa=V.length;av.innerHeight&&ca(L.errors.noContainerHeight.replace(/CONTAINER/,v.ref)))}ta(u,"minWidth")&&u.parent().css("overflowX","auto");ta(u,"minHeight")&&u.parent().css("overflowY","auto")}catch(Db){}nb();b(window).bind("unload."+K,mb);j(z,b.layout.onLoad);Cb.initPanes&&Aa();delete tb.creatingLayout;Xa=q.initialized}return"cancel"===Xa?null:z}})(jQuery); -(function(b){b.ui||(b.ui={});b.ui.cookie={acceptsCookies:!!navigator.cookieEnabled,read:function(a){for(var d=document.cookie,d=d?d.split(";"):[],c,f=0,j=d.length;fb.inArray(T,p)||(S=h[T][I],void 0!=S&&("isClosed"==I&&h[T].isSliding&&(S=!0),(x[T]||(x[T]={}))[j[I]?j[I]:I]=S));f&&b.each(p,function(c,d){G=a.children[d];X=h.stateData[d];b.isPlainObject(G)&&!b.isEmptyObject(G)&&(k=x[d]||(x[d]={}),k.children||(k.children={}),b.each(G,function(a,c){c.state.initialized?k.children[a]=b.layout.state.readState(c): -X&&(X.children&&X.children[a])&&(k.children[a]=b.extend(!0,{},X.children[a]))}))});return x},encodeJSON:function(a){function d(a){var f=[],j=0,h,p,x,I=b.isArray(a);for(h in a)p=a[h],x=typeof p,"string"==x?p='"'+p+'"':"object"==x&&(p=d(p)),f[j++]=(!I?'"'+h+'":':"")+p;return(I?"[":"{")+f.join(",")+(I?"]":"}")}return d(a)},decodeJSON:function(a){try{return b.parseJSON?b.parseJSON(a):window.eval("("+a+")")||{}}catch(d){return{}}},_create:function(a){var d=b.layout.state,c=a.options.stateManagement;b.extend(a, -{readCookie:function(){return d.readCookie(a)},deleteCookie:function(){d.deleteCookie(a)},saveCookie:function(b,c){return d.saveCookie(a,b,c)},loadCookie:function(){return d.loadCookie(a)},loadState:function(b,c){d.loadState(a,b,c)},readState:function(b){return d.readState(a,b)},encodeJSON:d.encodeJSON,decodeJSON:d.decodeJSON});a.state.stateData={};if(c.autoLoad)if(b.isPlainObject(c.autoLoad))b.isEmptyObject(c.autoLoad)||a.loadState(c.autoLoad);else if(c.enabled)if(b.isFunction(c.autoLoad)){var f= -{};try{f=c.autoLoad(a,a.state,a.options,a.options.name||"")}catch(j){}f&&(b.isPlainObject(f)&&!b.isEmptyObject(f))&&a.loadState(f)}else a.loadCookie()},_unload:function(a){var d=a.options.stateManagement;if(d.enabled&&d.autoSave)if(b.isFunction(d.autoSave))try{d.autoSave(a,a.state,a.options,a.options.name||"")}catch(c){}else a.saveCookie()}};b.layout.onCreate.push(b.layout.state._create);b.layout.onUnload.push(b.layout.state._unload);b.layout.plugins.buttons=!0;b.layout.defaults.autoBindCustomButtons= -!1;b.layout.optionsMap.layout.push("autoBindCustomButtons");b.layout.buttons={init:function(a){var d=a.options.name||"",c;b.each("toggle open close pin toggle-slide open-slide".split(" "),function(f,j){b.each(b.layout.config.borderPanes,function(f,p){b(".ui-layout-button-"+j+"-"+p).each(function(){c=b(this).data("layoutName")||b(this).attr("layoutName");(void 0==c||c===d)&&a.bindButton(this,j,p)})})})},get:function(a,d,c,f){var j=b(d);a=a.options;var h=a.errors.addButtonError;j.length?0>b.inArray(c, -b.layout.config.borderPanes)?(b.layout.msg(h+" "+a.errors.pane+": "+c,!0),j=b("")):(d=a[c].buttonClass+"-"+f,j.addClass(d+" "+d+"-"+c).data("layoutName",a.name)):b.layout.msg(h+" "+a.errors.selector+": "+d,!0);return j},bind:function(a,d,c,f){var j=b.layout.buttons;switch(c.toLowerCase()){case "toggle":j.addToggle(a,d,f);break;case "open":j.addOpen(a,d,f);break;case "close":j.addClose(a,d,f);break;case "pin":j.addPin(a,d,f);break;case "toggle-slide":j.addToggle(a,d,f,!0);break;case "open-slide":j.addOpen(a, -d,f,!0)}return a},addToggle:function(a,d,c,f){b.layout.buttons.get(a,d,c,"toggle").click(function(b){a.toggle(c,!!f);b.stopPropagation()});return a},addOpen:function(a,d,c,f){b.layout.buttons.get(a,d,c,"open").attr("title",a.options[c].tips.Open).click(function(b){a.open(c,!!f);b.stopPropagation()});return a},addClose:function(a,d,c){b.layout.buttons.get(a,d,c,"close").attr("title",a.options[c].tips.Close).click(function(b){a.close(c);b.stopPropagation()});return a},addPin:function(a,d,c){var f=b.layout.buttons, -j=f.get(a,d,c,"pin");if(j.length){var h=a.state[c];j.click(function(d){f.setPinState(a,b(this),c,h.isSliding||h.isClosed);h.isSliding||h.isClosed?a.open(c):a.close(c);d.stopPropagation()});f.setPinState(a,j,c,!h.isClosed&&!h.isSliding);h.pins.push(d)}return a},setPinState:function(a,b,c,f){var j=b.attr("pin");if(!(j&&f===("down"==j))){a=a.options[c];var j=a.buttonClass+"-pin",h=j+"-"+c;c=j+"-up "+h+"-up";j=j+"-down "+h+"-down";b.attr("pin",f?"down":"up").attr("title",f?a.tips.Unpin:a.tips.Pin).removeClass(f? -c:j).addClass(f?j:c)}},syncPinBtns:function(a,d,c){b.each(a.state[d].pins,function(f,j){b.layout.buttons.setPinState(a,b(j),d,c)})},_load:function(a){var d=b.layout.buttons;b.extend(a,{bindButton:function(b,c,h){return d.bind(a,b,c,h)},addToggleBtn:function(b,c,h){return d.addToggle(a,b,c,h)},addOpenBtn:function(b,c,h){return d.addOpen(a,b,c,h)},addCloseBtn:function(b,c){return d.addClose(a,b,c)},addPinBtn:function(b,c){return d.addPin(a,b,c)}});for(var c=0;4>c;c++)a.state[b.layout.config.borderPanes[c]].pins= -[];a.options.autoBindCustomButtons&&d.init(a)},_unload:function(){}};b.layout.onLoad.push(b.layout.buttons._load);b.layout.plugins.browserZoom=!0;b.layout.defaults.browserZoomCheckInterval=1E3;b.layout.optionsMap.layout.push("browserZoomCheckInterval");b.layout.browserZoom={_init:function(a){!1!==b.layout.browserZoom.ratio()&&b.layout.browserZoom._setTimer(a)},_setTimer:function(a){if(!a.destroyed){var d=a.options,c=a.state,f=a.hasParentLayout?5E3:Math.max(d.browserZoomCheckInterval,100);setTimeout(function(){if(!a.destroyed&& -d.resizeWithWindow){var f=b.layout.browserZoom.ratio();f!==c.browserZoom&&(c.browserZoom=f,a.resizeAll());b.layout.browserZoom._setTimer(a)}},f)}},ratio:function(){function a(a,b){return(100*(parseInt(a,10)/parseInt(b,10))).toFixed()}var d=window,c=screen,f=document,j=f.documentElement||f.body,h=b.layout.browser,p=h.version,x,I,T;return h.msie&&8').appendTo("body"),c={width:d.css("width")-d[0].clientWidth,height:d.height()-d[0].clientHeight}; +d.remove();window.scrollbarWidth=c.width;window.scrollbarHeight=c.height;return a.match(/^(width|height)$/)?c[a]:c},showInvisibly:function(b,a){if(b&&b.length&&(a||"none"===b.css("display"))){var d=b[0].style,d={display:d.display||"",visibility:d.visibility||""};b.css({display:"block",visibility:"hidden"});return d}return{}},getElementDimensions:function(a,c){var f={css:{},inset:{}},j=f.css,h={bottom:0},k=b.layout.cssNum,p=a.offset(),O,R,D;f.offsetLeft=p.left;f.offsetTop=p.top;c||(c={});b.each(["Left", +"Right","Top","Bottom"],function(d,k){O=j["border"+k]=b.layout.borderWidth(a,k);R=j["padding"+k]=b.layout.cssNum(a,"padding"+k);D=k.toLowerCase();f.inset[D]=0<=c[D]?c[D]:R;h[D]=f.inset[D]+O});j.width=a.width();j.height=a.height();j.top=k(a,"top",!0);j.bottom=k(a,"bottom",!0);j.left=k(a,"left",!0);j.right=k(a,"right",!0);f.outerWidth=a.outerWidth();f.outerHeight=a.outerHeight();f.innerWidth=d(0,f.outerWidth-h.left-h.right);f.innerHeight=d(0,f.outerHeight-h.top-h.bottom);f.layoutWidth=a.innerWidth(); +f.layoutHeight=a.innerHeight();return f},getElementStyles:function(b,a){var d={},c=b[0].style,f=a.split(","),k=["Top","Bottom","Left","Right"],j=["Color","Style","Width"],h,p,D,x,A,r;for(x=0;xA;A++)if(p=k[A],"border"===h)for(r=0;3>r;r++)D=j[r],d[h+p+D]=c[h+p+D];else d[h+p]=c[h+p];else d[h]=c[h];return d},cssWidth:function(a,c){if(0>=c)return 0;var f=!b.layout.browser.boxModel?"border-box":b.support.boxSizing?a.css("boxSizing"): +"content-box",j=b.layout.borderWidth,h=b.layout.cssNum,k=c;"border-box"!==f&&(k-=j(a,"Left")+j(a,"Right"));"content-box"===f&&(k-=h(a,"paddingLeft")+h(a,"paddingRight"));return d(0,k)},cssHeight:function(a,c){if(0>=c)return 0;var f=!b.layout.browser.boxModel?"border-box":b.support.boxSizing?a.css("boxSizing"):"content-box",j=b.layout.borderWidth,h=b.layout.cssNum,k=c;"border-box"!==f&&(k-=j(a,"Top")+j(a,"Bottom"));"content-box"===f&&(k-=h(a,"paddingTop")+h(a,"paddingBottom"));return d(0,k)},cssNum:function(a, +d,c){a.jquery||(a=b(a));var f=b.layout.showInvisibly(a);d=b.css(a[0],d,!0);c=c&&"auto"==d?d:Math.round(parseFloat(d)||0);a.css(f);return c},borderWidth:function(a,d){a.jquery&&(a=a[0]);var c="border"+d.substr(0,1).toUpperCase()+d.substr(1);return"none"===b.css(a,c+"Style",!0)?0:Math.round(parseFloat(b.css(a,c+"Width",!0))||0)},isMouseOverElem:function(a,d){var c=b(d||this),f=c.offset(),j=f.top,f=f.left,k=f+c.outerWidth(),c=j+c.outerHeight(),h=a.pageX,p=a.pageY;return b.layout.browser.msie&&0>h&&0> +p||h>=f&&h<=k&&p>=j&&p<=c},msg:function(a,d,c,f){b.isPlainObject(a)&&window.debugData?("string"===typeof d?(f=c,c=d):"object"===typeof c&&(f=c,c=null),c=c||"log( )",f=b.extend({sort:!1,returnHTML:!1,display:!1},f),!0===d||f.display?debugData(a,c,f):window.console&&console.log(debugData(a,c,f))):d?alert(a):window.console?console.log(a):(d=b("#layoutLogger"),d.length||(d=b('
          XLayout console.log
            ').appendTo("body"), +d.css("left",b(window).width()-d.outerWidth()-5),b.ui.draggable&&d.draggable({handle:":first-child"})),d.children("ul").append('
          • '+a.replace(/\/g,">")+"
          • "))}};var h=navigator.userAgent.toLowerCase(),p=/(chrome)[ \/]([\w.]+)/.exec(h)||/(webkit)[ \/]([\w.]+)/.exec(h)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(h)||/(msie) ([\w.]+)/.exec(h)||0>h.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(h)|| +[],h=p[1]||"",p=p[2]||0,x="msie"===h;b.layout.browser={version:p,safari:"webkit"===h,webkit:"chrome"===h,msie:x,isIE6:x&&6==p,boxModel:!x||!1!==b.support.boxModel};h&&(b.layout.browser[h]=!0);x&&b(function(){b.layout.browser.boxModel=b.support.boxModel});b.layout.defaults={name:"",containerClass:"ui-layout-container",inset:null,scrollToBookmarkOnLoad:!0,resizeWithWindow:!0,resizeWithWindowDelay:200,resizeWithWindowMaxDelay:0,maskPanesEarly:!1,onresizeall_start:null,onresizeall_end:null,onload_start:null, +onload_end:null,onunload_start:null,onunload_end:null,initPanes:!0,showErrorMessages:!0,showDebugMessages:!1,zIndex:null,zIndexes:{pane_normal:0,content_mask:1,resizer_normal:2,pane_sliding:100,pane_animate:1E3,resizer_drag:1E4},errors:{pane:"pane",selector:"selector",addButtonError:"Error Adding Button\nInvalid ",containerMissing:"UI Layout Initialization Error\nThe specified layout-container does not exist.",centerPaneMissing:"UI Layout Initialization Error\nThe center-pane element does not exist.\nThe center-pane is a required element.", +noContainerHeight:"UI Layout Initialization Warning\nThe layout-container \"CONTAINER\" has no height.\nTherefore the layout is 0-height and hence 'invisible'!",callbackError:"UI Layout Callback Error\nThe EVENT callback is not a valid function."},panes:{applyDemoStyles:!1,closable:!0,resizable:!0,slidable:!0,initClosed:!1,initHidden:!1,contentSelector:".ui-layout-content",contentIgnoreSelector:".ui-layout-ignore",findNestedContent:!1,paneClass:"ui-layout-pane",resizerClass:"ui-layout-resizer",togglerClass:"ui-layout-toggler", +buttonClass:"ui-layout-button",minSize:0,maxSize:0,spacing_open:6,spacing_closed:6,togglerLength_open:50,togglerLength_closed:50,togglerAlign_open:"center",togglerAlign_closed:"center",togglerContent_open:"",togglerContent_closed:"",resizerDblClickToggle:!0,autoResize:!0,autoReopen:!0,resizerDragOpacity:1,maskContents:!1,maskObjects:!1,maskZindex:null,resizingGrid:!1,livePaneResizing:!1,liveContentResizing:!1,liveResizingTolerance:1,sliderCursor:"pointer",slideTrigger_open:"click",slideTrigger_close:"mouseleave", +slideDelay_open:300,slideDelay_close:300,hideTogglerOnSlide:!1,preventQuickSlideClose:b.layout.browser.webkit,preventPrematureSlideClose:!1,tips:{Open:"Open",Close:"Close",Resize:"Resize",Slide:"Slide Open",Pin:"Pin",Unpin:"Un-Pin",noRoomToOpen:"Not enough room to show this panel.",minSizeWarning:"Panel has reached its minimum size",maxSizeWarning:"Panel has reached its maximum size"},showOverflowOnHover:!1,enableCursorHotkey:!0,customHotkeyModifier:"SHIFT",fxName:"slide",fxSpeed:null,fxSettings:{}, +fxOpacityFix:!0,animatePaneSizing:!1,children:null,containerSelector:"",initChildren:!0,destroyChildren:!0,resizeChildren:!0,triggerEventsOnLoad:!1,triggerEventsDuringLiveResize:!0,onshow_start:null,onshow_end:null,onhide_start:null,onhide_end:null,onopen_start:null,onopen_end:null,onclose_start:null,onclose_end:null,onresize_start:null,onresize_end:null,onsizecontent_start:null,onsizecontent_end:null,onswap_start:null,onswap_end:null,ondrag_start:null,ondrag_end:null},north:{paneSelector:".ui-layout-north", +size:"auto",resizerCursor:"n-resize",customHotkey:""},south:{paneSelector:".ui-layout-south",size:"auto",resizerCursor:"s-resize",customHotkey:""},east:{paneSelector:".ui-layout-east",size:200,resizerCursor:"e-resize",customHotkey:""},west:{paneSelector:".ui-layout-west",size:200,resizerCursor:"w-resize",customHotkey:""},center:{paneSelector:".ui-layout-center",minWidth:0,minHeight:0}};b.layout.optionsMap={layout:"name instanceKey stateManagement effects inset zIndexes errors zIndex scrollToBookmarkOnLoad showErrorMessages maskPanesEarly outset resizeWithWindow resizeWithWindowDelay resizeWithWindowMaxDelay onresizeall onresizeall_start onresizeall_end onload onload_start onload_end onunload onunload_start onunload_end".split(" "), +center:"paneClass contentSelector contentIgnoreSelector findNestedContent applyDemoStyles triggerEventsOnLoad showOverflowOnHover maskContents maskObjects liveContentResizing containerSelector children initChildren resizeChildren destroyChildren onresize onresize_start onresize_end onsizecontent onsizecontent_start onsizecontent_end".split(" "),noDefault:["paneSelector","resizerCursor","customHotkey"]};b.layout.transformData=function(a,d){var c=d?{panes:{},center:{}}:{},f,j,k,h,p,x,D;if("object"!== +typeof a)return c;for(j in a){f=c;p=a[j];k=j.split("__");D=k.length-1;for(x=0;x<=D;x++)h=k[x],x===D?f[h]=b.isPlainObject(p)?b.layout.transformData(p):p:(f[h]||(f[h]={}),f=f[h])}return c};b.layout.backwardCompatibility={map:{applyDefaultStyles:"applyDemoStyles",childOptions:"children",initChildLayout:"initChildren",destroyChildLayout:"destroyChildren",resizeChildLayout:"resizeChildren",resizeNestedLayout:"resizeChildren",resizeWhileDragging:"livePaneResizing",resizeContentWhileDragging:"liveContentResizing", +triggerEventsWhileDragging:"triggerEventsDuringLiveResize",maskIframesOnResize:"maskContents",useStateCookie:"stateManagement.enabled","cookie.autoLoad":"stateManagement.autoLoad","cookie.autoSave":"stateManagement.autoSave","cookie.keys":"stateManagement.stateKeys","cookie.name":"stateManagement.cookie.name","cookie.domain":"stateManagement.cookie.domain","cookie.path":"stateManagement.cookie.path","cookie.expires":"stateManagement.cookie.expires","cookie.secure":"stateManagement.cookie.secure", +noRoomToOpenTip:"tips.noRoomToOpen",togglerTip_open:"tips.Close",togglerTip_closed:"tips.Open",resizerTip:"tips.Resize",sliderTip:"tips.Slide"},renameOptions:function(a){function d(b,c){for(var f=b.split("."),k=f.length-1,j={branch:a,key:f[k]},r=0,q;rw)return!0;var m={38:"north",40:"south",37:"west",39:"east"},a=e.shiftKey,g=e.ctrlKey,t,n,d,c;g&&(37<=w&&40>=w)&&r[m[w]].enableCursorHotkey?c=m[w]:(g||a)&&b.each(k.borderPanes,function(e, +b){t=r[b];n=t.customHotkey;d=t.customHotkeyModifier;if(a&&"SHIFT"==d||g&&"CTRL"==d||g&&a)if(n&&w===(isNaN(n)||9>=n?n.toUpperCase().charCodeAt(0):n))return c=b,!1});if(!c||!y[c]||!r[c].closable||q[c].isHidden)return!0;na(c);e.stopPropagation();return e.returnValue=!1}function x(e){if(H()){this&&this.tagName&&(e=this);var w;f(e)?w=y[e]:b(e).data("layoutRole")?w=b(e):b(e).parents().each(function(){if(b(this).data("layoutRole"))return w=b(this),!1});if(w&&w.length){var m=w.data("layoutEdge");e=q[m];e.cssSaved&& +X(m);if(e.isSliding||e.isResizing||e.isClosed)e.cssSaved=!1;else{var a={zIndex:r.zIndexes.resizer_normal+1},g={},t=w.css("overflow"),n=w.css("overflowX"),d=w.css("overflowY");"visible"!=t&&(g.overflow=t,a.overflow="visible");n&&!n.match(/(visible|auto)/)&&(g.overflowX=n,a.overflowX="visible");d&&!d.match(/(visible|auto)/)&&(g.overflowY=n,a.overflowY="visible");e.cssSaved=g;w.css(a);b.each(k.allPanes,function(e,b){b!=m&&X(b)})}}}}function X(e){if(H()){this&&this.tagName&&(e=this);var w;f(e)?w=y[e]: +b(e).data("layoutRole")?w=b(e):b(e).parents().each(function(){if(b(this).data("layoutRole"))return w=b(this),!1});if(w&&w.length){e=w.data("layoutEdge");e=q[e];var m=e.cssSaved||{};!e.isSliding&&!e.isResizing&&w.css("zIndex",r.zIndexes.pane_normal);w.css(m);e.cssSaved=!1}}}var G=b.layout.browser,k=b.layout.config,Q=b.layout.cssWidth,O=b.layout.cssHeight,R=b.layout.getElementDimensions,D=b.layout.getElementStyles,Ma=b.layout.getEventObject,A=b.layout.parsePaneName,r=b.extend(!0,{},b.layout.defaults); +r.effects=b.extend(!0,{},b.layout.effects);var q={id:"layout"+b.now(),initialized:!1,paneResizing:!1,panesSliding:{},container:{innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0,layoutWidth:0,layoutHeight:0},north:{childIdx:0},south:{childIdx:0},east:{childIdx:0},west:{childIdx:0},center:{childIdx:0}},ba={north:null,south:null,east:null,west:null,center:null},M={data:{},set:function(e,b,m){M.clear(e);M.data[e]=setTimeout(b,m)},clear:function(e){var b=M.data;b[e]&&(clearTimeout(b[e]),delete b[e])}}, +ca=function(e,w,m){var a=r;(a.showErrorMessages&&!m||m&&a.showDebugMessages)&&b.layout.msg(a.name+" / "+e,!1!==w);return!1},C=function(e,w,m){var a=w&&f(w),g=a?q[w]:q,t=a?r[w]:r,n=r.name,d=e+(e.match(/_/)?"":"_end"),c=d.match(/_end$/)?d.substr(0,d.length-4):"",l=t[d]||t[c],h="NC",k=[];!a&&"boolean"===b.type(w)&&(m=w,w="");if(l)try{f(l)&&(l.match(/,/)?(k=l.split(","),l=eval(k[0])):l=eval(l)),b.isFunction(l)&&(h=k.length?l(k[1]):a?l(w,y[w],g,t,n):l(z,g,t,n))}catch(j){ca(r.errors.callbackError.replace(/EVENT/, +b.trim((w||"")+" "+d)),!1),"string"===b.type(j)&&string.length&&ca("Exception: "+j,!1)}!m&&!1!==h&&(a?(m=y[w],t=r[w],g=q[w],m.triggerHandler("layoutpane"+d,[w,m,g,t,n]),c&&m.triggerHandler("layoutpane"+c,[w,m,g,t,n])):(u.triggerHandler("layout"+d,[z,g,t,n]),c&&u.triggerHandler("layout"+c,[z,g,t,n])));a&&"onresize_end"===e&&db(w+"",!0);return h},eb=function(e){if(!G.mozilla){var b=y[e];"IFRAME"===q[e].tagName?b.css(k.hidden).css(k.visible):b.find("IFRAME").css(k.hidden).css(k.visible)}},ya=function(e){var b= +y[e];e=k[e].dir;b={minWidth:1001-Q(b,1E3),minHeight:1001-O(b,1E3)};"horz"===e&&(b.minSize=b.minHeight);"vert"===e&&(b.minSize=b.minWidth);return b},fa=function(e,w,m){m||(m=k[e].dir);f(w)&&w.match(/%/)&&(w="100%"===w?-1:parseInt(w,10)/100);if(0===w)return 0;if(1<=w)return parseInt(w,10);var a=r,g=0;"horz"==m?g=v.innerHeight-(y.north?a.north.spacing_open:0)-(y.south?a.south.spacing_open:0):"vert"==m&&(g=v.innerWidth-(y.west?a.west.spacing_open:0)-(y.east?a.east.spacing_open:0));if(-1===w)return g; +if(0b&&(b=100);M.clear("winResize");M.set("winResize",function(){M.clear("winResize");M.clear("winResizeRepeater");var b=R(u,e.inset);(b.innerWidth!==v.innerWidth||b.innerHeight!==v.innerHeight)&&oa()},b);M.data.winResizeRepeater||lb()},lb=function(){var e= +Number(r.resizeWithWindowMaxDelay);0"),l=l.toggler=g.closable?P[a]=b("
            "):!1;!d.isVisible&&g.slidable&&j.attr("title",g.tips.Slide).css("cursor",g.sliderCursor);j.attr("id",c?c+"-resizer":"").data({parentLayout:z,layoutPane:z[a],layoutEdge:a,layoutRole:"resizer"}).css(k.resizers.cssReq).css("zIndex",r.zIndexes.resizer_normal).css(g.applyDemoStyles?k.resizers.cssDemo:{}).addClass(n+" "+n+h).hover(Oa,da).hover(fb,gb).appendTo(u); +g.resizerDblClickToggle&&j.bind("dblclick."+K,na);l&&(l.attr("id",c?c+"-toggler":"").data({parentLayout:z,layoutPane:z[a],layoutEdge:a,layoutRole:"toggler"}).css(k.togglers.cssReq).css(g.applyDemoStyles?k.togglers.cssDemo:{}).addClass(f+" "+f+h).hover(Oa,da).bind("mouseenter",fb).appendTo(j),g.togglerContent_open&&b(""+g.togglerContent_open+"").data({layoutEdge:a,layoutRole:"togglerContent"}).data("layoutRole","togglerContent").data("layoutEdge",a).addClass("content content-open").css("display", +"none").appendTo(l),g.togglerContent_closed&&b(""+g.togglerContent_closed+"").data({layoutEdge:a,layoutRole:"togglerContent"}).addClass("content content-closed").css("display","none").appendTo(l),pb(a));var g=a,B=b.layout.plugins.draggable,g=g?g.split(","):k.borderPanes;b.each(g,function(e,a){var g=r[a];if(!B||!y[a]||!g.resizable)return g.resizable=!1,!0;var m=q[a],w=r.zIndexes,d=k[a],c="horz"==d.dir?"top":"left",t=F[a],n=g.resizerClass,f=0,l,h,E=n+"-drag",j=n+"-"+a+"-drag",J=n+"-dragging", +zb=n+"-"+a+"-dragging",cb=n+"-dragging-limit",v=n+"-"+a+"-dragging-limit",x=!1;m.isClosed||t.attr("title",g.tips.Resize).css("cursor",g.resizerCursor);t.draggable({containment:u[0],axis:"horz"==d.dir?"y":"x",delay:0,distance:1,grid:g.resizingGrid,helper:"clone",opacity:g.resizerDragOpacity,addClasses:!1,zIndex:w.resizer_drag,start:function(e,w){g=r[a];m=q[a];h=g.livePaneResizing;if(!1===C("ondrag_start",a))return!1;m.isResizing=!0;q.paneResizing=a;M.clear(a+"_closeSlider");Y(a);l=m.resizerPosition; +f=w.position[c];t.addClass(E+" "+j);x=!1;b("body").disableSelection();va(a,{resizing:!0})},drag:function(e,b){x||(b.helper.addClass(J+" "+zb).css({right:"auto",bottom:"auto"}).children().css("visibility","hidden"),x=!0,m.isSliding&&y[a].css("zIndex",w.pane_sliding));var d=0;b.position[c]l.max&&(b.position[c]=l.max,d=1);d?(b.helper.addClass(cb+" "+v),window.defaultStatus=0d&&a.match(/(south|east)/)?g.tips.maxSizeWarning: +g.tips.minSizeWarning):(b.helper.removeClass(cb+" "+v),window.defaultStatus="");h&&Math.abs(b.position[c]-f)>=g.liveResizingTolerance&&(f=b.position[c],p(e,b,a))},stop:function(e,g){b("body").enableSelection();window.defaultStatus="";t.removeClass(E+" "+j);m.isResizing=!1;q.paneResizing=!1;p(e,g,a,!0)}})});var p=function(b,e,a,g){var m=e.position,w=k[a];b=r[a];e=q[a];var d;switch(a){case "north":d=m.top;break;case "west":d=m.left;break;case "south":d=v.layoutHeight-m.top-b.spacing_open;break;case "east":d= +v.layoutWidth-m.left-b.spacing_open}d-=v.inset[w.side];g?(!1!==C("ondrag_end",a)&&Ca(a,d,!1,!0),za(!0),e.isSliding&&va(a,{resizing:!0})):Math.abs(d-e.size)j.maxSize)return Va(f,!1),!c&&h.tips.noRoomToOpen&&alert(h.tips.noRoomToOpen),a();b?wa(f,!0):j.isSliding?wa(f,!1):h.slidable&&ma(f,!1); +j.noRoom=!1;ha(f);p=j.isShowing;delete j.isShowing;l=!d&&j.isClosed&&"none"!=h.fxName_open;j.isMoving=!0;j.isVisible=!0;j.isClosed=!1;p&&(j.isHidden=!1);l?(Ga(f,!0),n.show(h.fxName_open,h.fxSettings_open,h.fxSpeed_open,function(){Ga(f,!1);j.isVisible&&g();a()})):(rb(f),g(),a())}})}},Ua=function(a,d){var c=y[a],f=F[a],g=P[a],h=r[a],n=q[a],j=k[a].side,p=h.resizerClass,l=h.togglerClass,u="-"+a;f.css(j,v.inset[j]+ga(a)).removeClass(p+"-closed "+p+u+"-closed").addClass(p+"-open "+p+u+"-open");n.isSliding? +f.addClass(p+"-sliding "+p+u+"-sliding"):f.removeClass(p+"-sliding "+p+u+"-sliding");da(0,f);h.resizable&&b.layout.plugins.draggable?f.draggable("enable").css("cursor",h.resizerCursor).attr("title",h.tips.Resize):n.isSliding||f.css("cursor","default");g&&(g.removeClass(l+"-closed "+l+u+"-closed").addClass(l+"-open "+l+u+"-open").attr("title",h.tips.Close),da(0,g),g.children(".content-closed").hide(),g.children(".content-open").css("display","block"));Va(a,!n.isSliding);b.extend(n,R(c));q.initialized&& +(qa(),pa(a,!0));if(!d&&(q.initialized||h.triggerEventsOnLoad)&&c.is(":visible"))C("onopen_end",a),n.isShowing&&C("onshow_end",a),q.initialized&&C("onresize_end",a)},sb=function(a){function b(){g.isClosed?g.isMoving||ra(c,!0):wa(c,!0)}if(H()){var d=Ma(a),c=A.call(this,a),g=q[c];a=r[c].slideDelay_open;d&&d.stopImmediatePropagation();g.isClosed&&d&&"mouseenter"===d.type&&0g.maxSize?ka(a,g.maxSize,c,!0,f):g.sizec?d(0,e.attempt-(e.actual-c)):d(0,e.attempt+(c-e.actual));h.cssSize=("horz"==k[n].dir?O:Q)(y[n],h.attempt);l.css(ua,h.cssSize);h.actual="width"==ua?l.outerWidth():l.outerHeight();h.correct=c===h.actual;1===a.length&&(ca(t,!1,!0),ca(e,!1,!0));ca(h,!1,!0);if(3B.width){var h=h.minWidth-j.outerWidth,B=r.east.minSize||0,x=r.west.minSize||0,Z=q.east.size,z=q.west.size,A=Z,D=z;0B)&&(A=d(Z-B,Z-h),h-=Z-A);0x)&&(D=d(z-x,z-h),h-=z-D);if(0===h){Z&&Z!=B&&ka("east",A,!0,!0,f);z&&z!=x&&ka("west",D,!0,!0,f);ia("center", +c,f);k.css(u);return}}}else{j.isVisible&&!j.noVerticalRoom&&b.extend(j,R(k),ya(e));if(!f&&!j.noVerticalRoom&&B.height===j.outerHeight)return k.css(u),!0;l.top=B.top;l.bottom=B.bottom;j.newSize=B.height;l.height=O(k,B.height);j.maxHeight=l.height;p=0<=j.maxHeight;p||(j.noVerticalRoom=!0)}p?(!c&&q.initialized&&C("onresize_start",e),k.css(l),"center"!==e&&qa(e),j.noRoom&&(!j.isClosed&&!j.isHidden)&&ha(e),j.isVisible&&(b.extend(j,R(k)),q.initialized&&pa(e))):!j.noRoom&&j.isVisible&&ha(e);k.css(u);delete j.newSize; +delete j.newWidth;delete j.newHeight;if(!j.isVisible)return!0;"center"===e&&(j=G.isIE6||!G.boxModel,y.north&&(j||"IFRAME"==q.north.tagName)&&y.north.css("width",Q(y.north,v.innerWidth)),y.south&&(j||"IFRAME"==q.south.tagName)&&y.south.css("width",Q(y.south,v.innerWidth)));!c&&q.initialized&&C("onresize_end",e)}})},oa=function(a){A(a);if(u.is(":visible"))if(q.initialized){if(!0===a&&b.isPlainObject(r.outset)&&u.css(r.outset),b.extend(v,R(u,r.inset)),v.outerHeight){!0===a&&ob();if(!1===C("onresizeall_start"))return!1; +var d,c,f;b.each(["south","north","east","west"],function(a,b){y[b]&&(c=r[b],f=q[b],f.autoResize&&f.size!=c.size?ka(b,c.size,!0,!0,!0):(Y(b),ha(b,!1,!0,!0)))});ia("",!0,!0);qa();b.each(k.allPanes,function(a,b){(d=y[b])&&q[b].isVisible&&C("onresize_end",b)});C("onresizeall_end")}}else Aa()},db=function(a,d){var c=A.call(this,a);r[c].resizeChildren&&(d||Ba(c),c=ba[c],b.isPlainObject(c)&&b.each(c,function(a,b){b.destroyed||b.resizeAll()}))},pa=function(a,c){if(H()){var h=A.call(this,a),h=h?h.split(","): +k.allPanes;b.each(h,function(a,e){function h(a){return d(u.css.paddingBottom,parseInt(a.css("marginBottom"),10)||0)}function j(){var a=r[e].contentIgnoreSelector,a=p.nextAll().not(".ui-layout-mask").not(a||":lt(0)"),b=a.filter(":visible"),d=b.filter(":last");v={top:p[0].offsetTop,height:p.outerHeight(),numFooters:a.length,hiddenFooters:a.length-b.length,spaceBelow:0};v.spaceAbove=v.top;v.bottom=v.top+v.height;v.spaceBelow=d.length?d[0].offsetTop+d.outerHeight()-v.bottom+h(d):h(p)}var m=y[e],p=U[e], +l=r[e],u=q[e],v=u.content;if(!m||!p||!m.is(":visible"))return!0;if(!p.length&&(Sa(e,!1),!p))return;if(!1!==C("onsizecontent_start",e)){if(!u.isMoving&&!u.isResizing||l.liveContentResizing||c||void 0==v.top)j(),0A)x=A,z=0;else if(f(z))switch(z){case "top":case "left":z=0;break;case "bottom":case "right":z=A-x;break; +default:z=c((A-x)/2)}else h=parseInt(z,10),z=0<=z?h:A-x+h;if("horz"===l){var D=Q(p,x);p.css({width:D,height:O(p,B),left:z,top:0});p.children(".content").each(function(){u=b(this);u.css("marginLeft",c((D-u.outerWidth())/2))})}else{var C=O(p,x);p.css({height:C,width:Q(p,B),top:z,left:0});p.children(".content").each(function(){u=b(this);u.css("marginTop",c((C-u.outerHeight())/2))})}da(0,p)}if(!q.initialized&&(e.initHidden||g.isHidden))j.hide(),p&&p.hide()}}})},pb=function(a){if(H()){var b=A.call(this, +a);a=P[b];var d=r[b];a&&(d.closable=!0,a.bind("click."+K,function(a){a.stopPropagation();na(b)}).css("visibility","visible").css("cursor","pointer").attr("title",q[b].isClosed?d.tips.Open:d.tips.Close).show())}},Va=function(a,d){b.layout.plugins.buttons&&b.each(q[a].pins,function(c,f){b.layout.buttons.setPinState(z,b(f),a,d)})},u=b(this).eq(0);if(!u.length)return ca(r.errors.containerMissing);if(u.data("layoutContainer")&&u.data("layout"))return u.data("layout");var y={},U={},F={},P={},ea=b([]),v= +q.container,K=q.id,z={options:r,state:q,container:u,panes:y,contents:U,resizers:F,togglers:P,hide:Ta,show:Fa,toggle:na,open:ra,close:ja,slideOpen:sb,slideClose:Wa,slideToggle:function(a){a=A.call(this,a);na(a,!0)},setSizeLimits:Y,_sizePane:ka,sizePane:Ca,sizeContent:pa,swapPanes:function(a,c){function f(a){var d=y[a],c=U[a];return!d?!1:{pane:a,P:d?d[0]:!1,C:c?c[0]:!1,state:b.extend(!0,{},q[a]),options:b.extend(!0,{},r[a])}}function h(a,c){if(a){var e=a.P,f=a.C,g=a.pane,j=k[c],m=b.extend(!0,{},q[c]), +n=r[c],w={resizerCursor:n.resizerCursor};b.each(["fxName","fxSpeed","fxSettings"],function(a,b){w[b+"_open"]=n[b+"_open"];w[b+"_close"]=n[b+"_close"];w[b+"_size"]=n[b+"_size"]});y[c]=b(e).data({layoutPane:z[c],layoutEdge:c}).css(k.hidden).css(j.cssReq);U[c]=f?b(f):!1;r[c]=b.extend(!0,{},a.options,w);q[c]=b.extend(!0,{},a.state);e.className=e.className.replace(RegExp(n.paneClass+"-"+g,"g"),n.paneClass+"-"+c);Pa(c);j.dir!=k[g].dir?(e=p[c]||0,Y(c),e=d(e,q[c].minSize),Ca(c,e,!0,!0)):F[c].css(j.side,v.inset[j.side]+ +(q[c].isVisible?ga(c):0));a.state.isVisible&&!m.isVisible?Ua(c,!0):(Da(c),ma(c,!0));a=null}}if(H()){var g=A.call(this,a);q[g].edge=c;q[c].edge=g;if(!1===C("onswap_start",g)||!1===C("onswap_start",c))q[g].edge=g,q[c].edge=c;else{var j=f(g),n=f(c),p={};p[g]=j?j.state.size:0;p[c]=n?n.state.size:0;y[g]=!1;y[c]=!1;q[g]={};q[c]={};P[g]&&P[g].remove();P[c]&&P[c].remove();F[g]&&F[g].remove();F[c]&&F[c].remove();F[g]=F[c]=P[g]=P[c]=!1;h(j,c);h(n,g);j=n=p=null;y[g]&&y[g].css(k.visible);y[c]&&y[c].css(k.visible); +oa();C("onswap_end",g);C("onswap_end",c)}}},showMasks:va,hideMasks:za,initContent:Sa,addPane:ib,removePane:Ra,createChildren:Qa,refreshChildren:Ba,enableClosable:pb,disableClosable:function(a,b){if(H()){var c=A.call(this,a),d=P[c];d&&(r[c].closable=!1,q[c].isClosed&&ra(c,!1,!0),d.unbind("."+K).css("visibility",b?"hidden":"visible").css("cursor","default").attr("title",""))}},enableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].slidable=!0,q[a].isClosed&&ma(a, +!0))}},disableSlidable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&(r[a].slidable=!1,q[a].isSliding?ja(a,!1,!0):(ma(a,!1),b.css("cursor","default").attr("title",""),da(null,b[0])))}},enableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a],c=r[a];b&&b.data("draggable")&&(c.resizable=!0,b.draggable("enable"),q[a].isClosed||b.css("cursor",c.resizerCursor).attr("title",c.tips.Resize))}},disableResizable:function(a){if(H()){a=A.call(this,a);var b=F[a];b&&b.data("draggable")&&(r[a].resizable= +!1,b.draggable("disable").css("cursor","default").attr("title",""),da(null,b[0]))}},allowOverflow:x,resetOverflow:X,destroy:function(a,c){b(window).unbind("."+K);b(document).unbind("."+K);"object"===typeof a?A(a):c=a;u.clearQueue().removeData("layout").removeData("layoutContainer").removeClass(r.containerClass).unbind("."+K);ea.remove();b.each(k.allPanes,function(a,b){Ra(b,!1,!0,c)});u.data("layoutCSS")&&!u.data("layoutRole")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");"BODY"===v.tagName&& +(u=b("html")).data("layoutCSS")&&u.css(u.data("layoutCSS")).removeData("layoutCSS");j(z,b.layout.onDestroy);mb();for(var d in z)d.match(/^(container|options)$/)||delete z[d];z.destroyed=!0;return z},initPanes:H,resizeAll:oa,runCallbacks:C,hasParentLayout:!1,children:ba,north:!1,south:!1,west:!1,east:!1,center:!1},Xa;var V,Ya,N,Ha,la,sa,W;h=b.layout.transformData(h,!0);h=b.layout.backwardCompatibility.renameAllOptions(h);if(!b.isEmptyObject(h.panes)){V=b.layout.optionsMap.noDefault;la=0;for(sa=V.length;la< +sa;la++)N=V[la],delete h.panes[N];V=b.layout.optionsMap.layout;la=0;for(sa=V.length;lab.inArray(N,Bb)&&0>b.inArray(N,V)&&(h.panes[N]||(h.panes[N]=b.isPlainObject(Ha)?b.extend(!0,{},Ha):Ha),delete h[N]);b.extend(!0,r,h);b.each(k.allPanes,function(a,c){k[c]=b.extend(!0,{},k.panes,k[c]);Ya=r.panes;W=r[c];if("center"===c){V=b.layout.optionsMap.center;a=0;for(sa=V.length;av.innerHeight&&ca(L.errors.noContainerHeight.replace(/CONTAINER/,v.ref)))}ta(u,"minWidth")&&u.parent().css("overflowX","auto");ta(u,"minHeight")&&u.parent().css("overflowY","auto")}catch(Db){}nb();b(window).bind("unload."+K,mb);j(z,b.layout.onLoad);Cb.initPanes&&Aa();delete tb.creatingLayout;Xa=q.initialized}return"cancel"===Xa?null:z}})(jQuery); +(function(b){b.ui||(b.ui={});b.ui.cookie={acceptsCookies:!!navigator.cookieEnabled,read:function(a){for(var d=document.cookie,d=d?d.split(";"):[],c,f=0,j=d.length;fb.inArray(T,p)||(S=h[T][I],void 0!=S&&("isClosed"==I&&h[T].isSliding&&(S=!0),(x[T]||(x[T]={}))[j[I]?j[I]:I]=S));f&&b.each(p,function(c,d){G=a.children[d];X=h.stateData[d];b.isPlainObject(G)&&!b.isEmptyObject(G)&&(k=x[d]||(x[d]={}),k.children||(k.children={}),b.each(G,function(a,c){c.state.initialized?k.children[a]=b.layout.state.readState(c): +X&&(X.children&&X.children[a])&&(k.children[a]=b.extend(!0,{},X.children[a]))}))});return x},encodeJSON:function(a){function d(a){var f=[],j=0,h,p,x,I=b.isArray(a);for(h in a)p=a[h],x=typeof p,"string"==x?p='"'+p+'"':"object"==x&&(p=d(p)),f[j++]=(!I?'"'+h+'":':"")+p;return(I?"[":"{")+f.join(",")+(I?"]":"}")}return d(a)},decodeJSON:function(a){try{return b.parseJSON?b.parseJSON(a):window.eval("("+a+")")||{}}catch(d){return{}}},_create:function(a){var d=b.layout.state,c=a.options.stateManagement;b.extend(a, +{readCookie:function(){return d.readCookie(a)},deleteCookie:function(){d.deleteCookie(a)},saveCookie:function(b,c){return d.saveCookie(a,b,c)},loadCookie:function(){return d.loadCookie(a)},loadState:function(b,c){d.loadState(a,b,c)},readState:function(b){return d.readState(a,b)},encodeJSON:d.encodeJSON,decodeJSON:d.decodeJSON});a.state.stateData={};if(c.autoLoad)if(b.isPlainObject(c.autoLoad))b.isEmptyObject(c.autoLoad)||a.loadState(c.autoLoad);else if(c.enabled)if(b.isFunction(c.autoLoad)){var f= +{};try{f=c.autoLoad(a,a.state,a.options,a.options.name||"")}catch(j){}f&&(b.isPlainObject(f)&&!b.isEmptyObject(f))&&a.loadState(f)}else a.loadCookie()},_unload:function(a){var d=a.options.stateManagement;if(d.enabled&&d.autoSave)if(b.isFunction(d.autoSave))try{d.autoSave(a,a.state,a.options,a.options.name||"")}catch(c){}else a.saveCookie()}};b.layout.onCreate.push(b.layout.state._create);b.layout.onUnload.push(b.layout.state._unload);b.layout.plugins.buttons=!0;b.layout.defaults.autoBindCustomButtons= +!1;b.layout.optionsMap.layout.push("autoBindCustomButtons");b.layout.buttons={init:function(a){var d=a.options.name||"",c;b.each("toggle open close pin toggle-slide open-slide".split(" "),function(f,j){b.each(b.layout.config.borderPanes,function(f,p){b(".ui-layout-button-"+j+"-"+p).each(function(){c=b(this).data("layoutName")||b(this).attr("layoutName");(void 0==c||c===d)&&a.bindButton(this,j,p)})})})},get:function(a,d,c,f){var j=b(d);a=a.options;var h=a.errors.addButtonError;j.length?0>b.inArray(c, +b.layout.config.borderPanes)?(b.layout.msg(h+" "+a.errors.pane+": "+c,!0),j=b("")):(d=a[c].buttonClass+"-"+f,j.addClass(d+" "+d+"-"+c).data("layoutName",a.name)):b.layout.msg(h+" "+a.errors.selector+": "+d,!0);return j},bind:function(a,d,c,f){var j=b.layout.buttons;switch(c.toLowerCase()){case "toggle":j.addToggle(a,d,f);break;case "open":j.addOpen(a,d,f);break;case "close":j.addClose(a,d,f);break;case "pin":j.addPin(a,d,f);break;case "toggle-slide":j.addToggle(a,d,f,!0);break;case "open-slide":j.addOpen(a, +d,f,!0)}return a},addToggle:function(a,d,c,f){b.layout.buttons.get(a,d,c,"toggle").click(function(b){a.toggle(c,!!f);b.stopPropagation()});return a},addOpen:function(a,d,c,f){b.layout.buttons.get(a,d,c,"open").attr("title",a.options[c].tips.Open).click(function(b){a.open(c,!!f);b.stopPropagation()});return a},addClose:function(a,d,c){b.layout.buttons.get(a,d,c,"close").attr("title",a.options[c].tips.Close).click(function(b){a.close(c);b.stopPropagation()});return a},addPin:function(a,d,c){var f=b.layout.buttons, +j=f.get(a,d,c,"pin");if(j.length){var h=a.state[c];j.click(function(d){f.setPinState(a,b(this),c,h.isSliding||h.isClosed);h.isSliding||h.isClosed?a.open(c):a.close(c);d.stopPropagation()});f.setPinState(a,j,c,!h.isClosed&&!h.isSliding);h.pins.push(d)}return a},setPinState:function(a,b,c,f){var j=b.attr("pin");if(!(j&&f===("down"==j))){a=a.options[c];var j=a.buttonClass+"-pin",h=j+"-"+c;c=j+"-up "+h+"-up";j=j+"-down "+h+"-down";b.attr("pin",f?"down":"up").attr("title",f?a.tips.Unpin:a.tips.Pin).removeClass(f? +c:j).addClass(f?j:c)}},syncPinBtns:function(a,d,c){b.each(a.state[d].pins,function(f,j){b.layout.buttons.setPinState(a,b(j),d,c)})},_load:function(a){var d=b.layout.buttons;b.extend(a,{bindButton:function(b,c,h){return d.bind(a,b,c,h)},addToggleBtn:function(b,c,h){return d.addToggle(a,b,c,h)},addOpenBtn:function(b,c,h){return d.addOpen(a,b,c,h)},addCloseBtn:function(b,c){return d.addClose(a,b,c)},addPinBtn:function(b,c){return d.addPin(a,b,c)}});for(var c=0;4>c;c++)a.state[b.layout.config.borderPanes[c]].pins= +[];a.options.autoBindCustomButtons&&d.init(a)},_unload:function(){}};b.layout.onLoad.push(b.layout.buttons._load);b.layout.plugins.browserZoom=!0;b.layout.defaults.browserZoomCheckInterval=1E3;b.layout.optionsMap.layout.push("browserZoomCheckInterval");b.layout.browserZoom={_init:function(a){!1!==b.layout.browserZoom.ratio()&&b.layout.browserZoom._setTimer(a)},_setTimer:function(a){if(!a.destroyed){var d=a.options,c=a.state,f=a.hasParentLayout?5E3:Math.max(d.browserZoomCheckInterval,100);setTimeout(function(){if(!a.destroyed&& +d.resizeWithWindow){var f=b.layout.browserZoom.ratio();f!==c.browserZoom&&(c.browserZoom=f,a.resizeAll());b.layout.browserZoom._setTimer(a)}},f)}},ratio:function(){function a(a,b){return(100*(parseInt(a,10)/parseInt(b,10))).toFixed()}var d=window,c=screen,f=document,j=f.documentElement||f.body,h=b.layout.browser,p=h.version,x,I,T;return h.msie&&8