├── .gitignore ├── .idea └── libraries │ └── Maven__com_google_inject_extensions_guice_assistedinject_3_0.xml ├── csdn-common.ipr ├── csdn-common.iws ├── open-source.xml ├── pom-maven.xml ├── pom.xml └── src └── main └── java └── net └── csdn └── common ├── Base64.java ├── Booleans.java ├── Classes.java ├── Strings.java ├── Type.java ├── Unicode.java ├── collect ├── MapBuilder.java ├── Tuple.java └── Tuple3.java ├── collections ├── WowCollections.java ├── WowLists.java ├── WowMaps.java └── WowSerializable.java ├── enhancer └── EnhancerHelper.java ├── env └── Environment.java ├── exception ├── ArgumentErrorException.java ├── AutoGeneration.java ├── ConfigurationException.java ├── ExceptionHandler.java ├── FailedToResolveConfigException.java ├── ParseException.java ├── RecordExistedException.java ├── RecordNotFoundException.java ├── RenderFinish.java └── SettingsException.java ├── io └── Streams.java ├── jline └── ANSI.java ├── logging ├── CSLogger.java ├── CSLoggerFactory.java ├── Loggers.java ├── log4j │ ├── ConsoleAppender.java │ ├── JLinePatternLayout.java │ ├── Log4jCSLogger.java │ ├── Log4jFactory.java │ └── LogConfigurator.java └── support │ ├── AbstractCSLogger.java │ └── MessageFormat.java ├── network └── NetworkUtils.java ├── param └── ParamBinding.java ├── path ├── PathTrie.java └── Url.java ├── property └── PropertyPlaceholder.java ├── reflect ├── ReflectHelper.java └── WowMethod.java ├── scan ├── DefaultScanService.java ├── ScanModule.java ├── ScanService.java └── component │ ├── ClasspathUrlFinder.java │ ├── DirectoryIteratorFactory.java │ ├── FileIterator.java │ ├── FileProtocolIteratorFactory.java │ ├── Filter.java │ ├── InputStreamWrapper.java │ ├── IteratorFactory.java │ ├── JarIterator.java │ └── StreamIterator.java ├── settings ├── ImmutableSettings.java ├── InternalSettingsPreparer.java ├── NoClassSettingsException.java └── Settings.java ├── time └── NumberExtendedForTime.java └── unit ├── ByteSizeUnit.java ├── ByteSizeValue.java ├── SizeUnit.java ├── SizeValue.java └── TimeValue.java /.gitignore: -------------------------------------------------------------------------------- 1 | /CSDNCommon.iml 2 | .idea 3 | target/ 4 | csdn-common.iml 5 | pom.xml.releaseBackup 6 | release.properties 7 | /pom.xml.bak 8 | /csdn-common.ipr 9 | /csdn-common.iws 10 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_google_inject_extensions_guice_assistedinject_3_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /csdn-common.ipr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 11 | 12 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 45 | 46 | 48 | 49 | 56 | 57 | 73 | 74 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /open-source.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.sonatype.oss 6 | oss-parent 7 | 7 8 | 9 | net.csdn 10 | csdn-common 11 | 1.6-SNAPSHOT 12 | 13 | 14 | 15 | The Apache Software License, Version 2.0 16 | http://www.apache.org/licenses/LICENSE-2.0.txt 17 | repo 18 | 19 | 20 | 21 | 22 | 23 | allwefantasy 24 | WilliamZhu 25 | allwefantasy@gmail.com 26 | 27 | 28 | 29 | 30 | scm:git:git@github.com:allwefantasy/csdn_common.git 31 | scm:git:git@github.com:allwefantasy/csdn_common.git 32 | https://github.com/allwefantasy/csdn_common 33 | HEAD 34 | 35 | 36 | 37 | github 38 | https://github.com/allwefantasy/csdn_common/issues 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | joda-time 47 | joda-time 48 | 2.3 49 | 50 | 51 | 52 | 53 | org.yaml 54 | snakeyaml 55 | 1.9 56 | 57 | 58 | 59 | net.sf.json-lib 60 | json-lib 61 | 2.4 62 | jdk15 63 | 64 | 65 | 66 | 67 | jline 68 | jline 69 | 0.9.94 70 | 71 | 72 | 73 | javassist 74 | javassist 75 | 3.12.1.GA 76 | 77 | 78 | 79 | 80 | log4j 81 | log4j 82 | 1.2.17 83 | 84 | 85 | 86 | org.slf4j 87 | slf4j-api 88 | 1.6.1 89 | 90 | 91 | org.slf4j 92 | jcl-over-slf4j 93 | 1.6.1 94 | 95 | 96 | org.slf4j 97 | slf4j-log4j12 98 | 1.6.1 99 | 100 | 101 | 102 | com.google.guava 103 | guava 104 | 15.0 105 | 106 | 107 | 108 | 109 | com.google.inject 110 | guice 111 | 3.0 112 | 113 | 114 | 115 | com.google.inject.extensions 116 | guice-assistedinject 117 | 3.0 118 | 119 | 120 | 121 | com.google.inject.extensions 122 | guice-multibindings 123 | 3.0 124 | 125 | 126 | 127 | com.mycila.com.google.inject 128 | guice 129 | 3.0-20100927 130 | 131 | 132 | 133 | mysql 134 | mysql-connector-java 135 | 5.1.6 136 | 137 | 138 | 139 | 140 | 141 | release-sign-artifacts 142 | 143 | 144 | performRelease 145 | true 146 | 147 | 148 | 149 | 150 | 151 | org.apache.maven.plugins 152 | maven-gpg-plugin 153 | 1.1 154 | 155 | 156 | sign-artifacts 157 | verify 158 | 159 | sign 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | org.apache.maven.plugins 172 | maven-source-plugin 173 | 174 | 175 | attach-sources 176 | 177 | jar 178 | 179 | 180 | 181 | 182 | 183 | org.apache.maven.plugins 184 | maven-javadoc-plugin 185 | 186 | 187 | attach-javadocs 188 | 189 | jar 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | sonatype-nexus-snapshots 199 | Sonatype Nexus snapshot repository 200 | https://oss.sonatype.org/content/repositories/snapshots 201 | 202 | 203 | sonatype-nexus-staging 204 | Sonatype Nexus release repository 205 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /pom-maven.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.sonatype.oss 6 | oss-parent 7 | 7 8 | 9 | net.csdn 10 | csdn-common 11 | 1.5-SNAPSHOT 12 | 13 | 14 | 15 | The Apache Software License, Version 2.0 16 | http://www.apache.org/licenses/LICENSE-2.0.txt 17 | repo 18 | 19 | 20 | 21 | 22 | 23 | allwefantasy 24 | WilliamZhu 25 | allwefantasy@gmail.com 26 | 27 | 28 | 29 | 30 | scm:git:git@github.com:allwefantasy/csdn_common.git 31 | scm:git:git@github.com:allwefantasy/csdn_common.git 32 | https://github.com/allwefantasy/csdn_common 33 | HEAD 34 | 35 | 36 | 37 | github 38 | https://github.com/allwefantasy/csdn_common/issues 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | joda-time 47 | joda-time 48 | 2.3 49 | 50 | 51 | 52 | 53 | org.yaml 54 | snakeyaml 55 | 1.9 56 | 57 | 58 | 59 | net.sf.json-lib 60 | json-lib 61 | 2.4 62 | jdk15 63 | 64 | 65 | 66 | 67 | jline 68 | jline 69 | 0.9.94 70 | 71 | 72 | 73 | javassist 74 | javassist 75 | 3.12.1.GA 76 | 77 | 78 | 79 | 80 | log4j 81 | log4j 82 | 1.2.17 83 | 84 | 85 | 86 | org.slf4j 87 | slf4j-api 88 | 1.6.1 89 | 90 | 91 | org.slf4j 92 | jcl-over-slf4j 93 | 1.6.1 94 | 95 | 96 | org.slf4j 97 | slf4j-log4j12 98 | 1.6.1 99 | 100 | 101 | 102 | com.google.guava 103 | guava 104 | 15.0 105 | 106 | 107 | 108 | 109 | com.google.inject 110 | guice 111 | 3.0 112 | 113 | 114 | 115 | com.google.inject.extensions 116 | guice-assistedinject 117 | 3.0 118 | 119 | 120 | 121 | com.google.inject.extensions 122 | guice-multibindings 123 | 3.0 124 | 125 | 126 | 127 | com.mycila.com.google.inject 128 | guice 129 | 3.0-20100927 130 | 131 | 132 | 133 | mysql 134 | mysql-connector-java 135 | 5.1.6 136 | 137 | 138 | 139 | 140 | 141 | release-sign-artifacts 142 | 143 | 144 | performRelease 145 | true 146 | 147 | 148 | 149 | 150 | 151 | org.apache.maven.plugins 152 | maven-gpg-plugin 153 | 1.1 154 | 155 | 156 | sign-artifacts 157 | verify 158 | 159 | sign 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | org.apache.maven.plugins 172 | maven-source-plugin 173 | 174 | 175 | attach-sources 176 | 177 | jar 178 | 179 | 180 | 181 | 182 | 183 | org.apache.maven.plugins 184 | maven-javadoc-plugin 185 | 186 | 187 | attach-javadocs 188 | 189 | jar 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | sonatype-nexus-snapshots 199 | Sonatype Nexus snapshot repository 200 | https://oss.sonatype.org/content/repositories/snapshots 201 | 202 | 203 | sonatype-nexus-staging 204 | Sonatype Nexus release repository 205 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.csdn 5 | csdn-common 6 | 1.5-SNAPSHOT 7 | 8 | 9 | 10 | The Apache Software License, Version 2.0 11 | http://www.apache.org/licenses/LICENSE-2.0.txt 12 | repo 13 | 14 | 15 | 16 | 17 | 18 | allwefantasy 19 | WilliamZhu 20 | allwefantasy@gmail.com 21 | 22 | 23 | 24 | 25 | scm:git:git@github.com:allwefantasy/csdn_common.git 26 | scm:git:git@github.com:allwefantasy/csdn_common.git 27 | https://github.com/allwefantasy/csdn_common 28 | HEAD 29 | 30 | 31 | 32 | github 33 | https://github.com/allwefantasy/csdn_common/issues 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | joda-time 42 | joda-time 43 | 2.3 44 | 45 | 46 | 47 | 48 | org.yaml 49 | snakeyaml 50 | 1.9 51 | 52 | 53 | 54 | net.sf.json-lib 55 | json-lib 56 | 2.4 57 | jdk15 58 | 59 | 60 | 61 | 62 | jline 63 | jline 64 | 0.9.94 65 | 66 | 67 | 68 | javassist 69 | javassist 70 | 3.12.1.GA 71 | 72 | 73 | 74 | 75 | log4j 76 | log4j 77 | 1.2.17 78 | 79 | 80 | 81 | org.slf4j 82 | slf4j-api 83 | 1.6.1 84 | 85 | 86 | org.slf4j 87 | jcl-over-slf4j 88 | 1.6.1 89 | 90 | 91 | org.slf4j 92 | slf4j-log4j12 93 | 1.6.1 94 | 95 | 96 | 97 | com.google.guava 98 | guava 99 | 15.0 100 | 101 | 102 | 103 | 104 | com.google.inject 105 | guice 106 | 3.0 107 | 108 | 109 | 110 | com.google.inject.extensions 111 | guice-assistedinject 112 | 3.0 113 | 114 | 115 | 116 | com.google.inject.extensions 117 | guice-multibindings 118 | 3.0 119 | 120 | 121 | 122 | com.mycila.com.google.inject 123 | guice 124 | 3.0-20100927 125 | 126 | 127 | 128 | mysql 129 | mysql-connector-java 130 | 5.1.6 131 | 132 | 133 | 134 | 135 | release-sign-artifacts 136 | 137 | 138 | performRelease 139 | true 140 | 141 | 142 | 143 | 144 | 145 | org.apache.maven.plugins 146 | maven-gpg-plugin 147 | 1.1 148 | 149 | 150 | sign-artifacts 151 | verify 152 | 153 | sign 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | disable-java8-doclint 163 | 164 | [1.8,) 165 | 166 | 167 | -Xdoclint:none 168 | 169 | 170 | 171 | 172 | 173 | 174 | org.apache.maven.plugins 175 | maven-source-plugin 176 | 177 | 178 | attach-sources 179 | 180 | jar 181 | 182 | 183 | 184 | 185 | 186 | org.apache.maven.plugins 187 | maven-javadoc-plugin 188 | 189 | 190 | attach-javadocs 191 | 192 | jar 193 | 194 | 195 | 196 | 197 | 198 | org.apache.maven.plugins 199 | maven-compiler-plugin 200 | 2.3.2 201 | 202 | 1.6 203 | 1.6 204 | -g 205 | true 206 | UTF-8 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/Booleans.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common; 2 | 3 | 4 | public class Booleans { 5 | 6 | public static boolean parseBoolean(char[] text, int offset, int length, boolean defaultValue) { 7 | if (text == null || length == 0) { 8 | return defaultValue; 9 | } 10 | if (length == 1) { 11 | return text[offset] != '0'; 12 | } 13 | if (length == 2) { 14 | return !(text[offset] == 'n' && text[offset + 1] == 'o'); 15 | } 16 | if (length == 3) { 17 | return !(text[offset] == 'o' && text[offset + 1] == 'f' && text[offset + 2] == 'f'); 18 | } 19 | if (length == 5) { 20 | return !(text[offset] == 'f' && text[offset + 1] == 'a' && text[offset + 2] == 'l' && text[offset + 3] == 's' && text[offset + 4] == 'e'); 21 | } 22 | return true; 23 | } 24 | 25 | public static boolean parseBoolean(String value, boolean defaultValue) { 26 | if (value == null) { 27 | return defaultValue; 28 | } 29 | return !(value.equals("false") || value.equals("0") || value.equals("off") || value.equals("no")); 30 | } 31 | 32 | public static Boolean parseBoolean(String value, Boolean defaultValue) { 33 | if (value == null) { 34 | return defaultValue; 35 | } 36 | return !(value.equals("false") || value.equals("0") || value.equals("off") || value.equals("no")); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/Classes.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common; 2 | 3 | import java.lang.reflect.Modifier; 4 | 5 | /** 6 | * BlogInfo: william 7 | * Date: 11-9-1 8 | * Time: 上午11:39 9 | */ 10 | public class Classes { 11 | private static final char PACKAGE_SEPARATOR = '.'; 12 | 13 | public static ClassLoader getDefaultClassLoader() { 14 | ClassLoader cl = null; 15 | try { 16 | cl = Thread.currentThread().getContextClassLoader(); 17 | } catch (Throwable ex) { 18 | //cannot access thread context ClassLoader - falling back to system class loader 19 | } 20 | if (cl == null) { 21 | cl = Classes.class.getClassLoader(); 22 | } 23 | return cl; 24 | } 25 | 26 | public static String getPackageName(Class clazz) { 27 | String className = clazz.getName(); 28 | int lastDotIndex = className.lastIndexOf(PACKAGE_SEPARATOR); 29 | return (lastDotIndex != -1 ? className.substring(0, lastDotIndex) : ""); 30 | } 31 | 32 | public static String getPackageNameNoDomain(Class clazz) { 33 | String fullPackage = getPackageName(clazz); 34 | if (fullPackage.startsWith("org.") || fullPackage.startsWith("com.") || fullPackage.startsWith("net.")) { 35 | return fullPackage.substring(4); 36 | } 37 | return fullPackage; 38 | } 39 | 40 | public static boolean isInnerClass(Class clazz) { 41 | return !Modifier.isStatic(clazz.getModifiers()) 42 | && clazz.getEnclosingClass() != null; 43 | } 44 | 45 | public static boolean isConcrete(Class clazz) { 46 | int modifiers = clazz.getModifiers(); 47 | return !clazz.isInterface() && !Modifier.isAbstract(modifiers); 48 | } 49 | 50 | private Classes() { 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/Type.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | /** 8 | * BlogInfo: william 9 | * Date: 11-9-14 10 | * Time: 下午4:45 11 | */ 12 | public class Type { 13 | public static void field(String name, double value) { 14 | 15 | 16 | } 17 | 18 | public static void field(String name, float value) { 19 | 20 | } 21 | 22 | public static void field(String name, int value) { 23 | 24 | } 25 | 26 | public static void field(String name, long value) { 27 | 28 | } 29 | 30 | public static void field(String name, short value) { 31 | 32 | } 33 | 34 | public static void field(String name, byte value) { 35 | 36 | } 37 | 38 | public static void field(String name, boolean value) { 39 | 40 | } 41 | 42 | 43 | public static void field(String name, double[] value) { 44 | 45 | } 46 | 47 | public static void field(String name, float[] value) { 48 | 49 | } 50 | 51 | public static void field(String name, int[] value) { 52 | 53 | } 54 | 55 | public static void field(String name, byte[] value) { 56 | 57 | } 58 | 59 | 60 | public static void field(String name, long[] value) { 61 | 62 | } 63 | 64 | public static void field(String name, Date value) { 65 | 66 | } 67 | 68 | public static void field(String name, Map value) { 69 | 70 | } 71 | 72 | public static void field(String name, List value) { 73 | 74 | } 75 | 76 | public static void field(String name, Object[] value) { 77 | 78 | } 79 | 80 | public static void field(String name, Object value) { 81 | Class type = value.getClass(); 82 | if (type == String.class) { 83 | field(name, ((Float) value).floatValue()); 84 | } else if (type == Float.class) { 85 | field(name, ((Float) value).floatValue()); 86 | } else if (type == Double.class) { 87 | field(name, ((Double) value).doubleValue()); 88 | } else if (type == Integer.class) { 89 | field(name, ((Integer) value).intValue()); 90 | } else if (type == Long.class) { 91 | field(name, ((Long) value).longValue()); 92 | } else if (type == Short.class) { 93 | field(name, ((Short) value).shortValue()); 94 | } else if (type == Byte.class) { 95 | field(name, ((Byte) value).byteValue()); 96 | } else if (type == Boolean.class) { 97 | field(name, ((Boolean) value).booleanValue()); 98 | } else if (type == Date.class) { 99 | field(name, (Date) value); 100 | } else if (type == byte[].class) { 101 | field(name, (byte[]) value); 102 | } else if (value instanceof Map) { 103 | //noinspection unchecked 104 | field(name, (Map) value); 105 | } else if (value instanceof List) { 106 | field(name, (List) value); 107 | } else if (value instanceof Object[]) { 108 | field(name, (Object[]) value); 109 | } else if (value instanceof int[]) { 110 | field(name, (int[]) value); 111 | } else if (value instanceof long[]) { 112 | field(name, (long[]) value); 113 | } else if (value instanceof float[]) { 114 | field(name, (float[]) value); 115 | } else if (value instanceof double[]) { 116 | field(name, (double[]) value); 117 | } else { 118 | field(name, value.toString()); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/collect/MapBuilder.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.collect; 2 | 3 | import com.google.common.collect.ImmutableMap; 4 | import com.google.common.collect.Maps; 5 | 6 | import java.util.Map; 7 | 8 | import static com.google.common.collect.Maps.newHashMap; 9 | 10 | /** 11 | * BlogInfo: william 12 | * Date: 11-9-1 13 | * Time: 下午2:15 14 | */ 15 | public class MapBuilder { 16 | public static MapBuilder newMapBuilder() { 17 | return new MapBuilder(); 18 | } 19 | 20 | public static MapBuilder newLinkedHashMap() { 21 | return new MapBuilder(Maps.newLinkedHashMap()); 22 | } 23 | 24 | public static MapBuilder newMapBuilder(Map map) { 25 | return new MapBuilder().putAll(map); 26 | } 27 | 28 | private Map map = newHashMap(); 29 | 30 | public MapBuilder() { 31 | this.map = newHashMap(); 32 | } 33 | 34 | public MapBuilder(Map map) { 35 | this.map = map; 36 | } 37 | 38 | public MapBuilder putAll(Map map) { 39 | this.map.putAll(map); 40 | return this; 41 | } 42 | 43 | public MapBuilder put(K key, V value) { 44 | this.map.put(key, value); 45 | return this; 46 | } 47 | 48 | public MapBuilder remove(K key) { 49 | this.map.remove(key); 50 | return this; 51 | } 52 | 53 | public V get(K key) { 54 | return map.get(key); 55 | } 56 | 57 | public boolean containsKey(K key) { 58 | return map.containsKey(key); 59 | } 60 | 61 | public Map map() { 62 | return this.map; 63 | } 64 | 65 | public ImmutableMap immutableMap() { 66 | return ImmutableMap.copyOf(map); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/collect/Tuple.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.collect; 2 | 3 | /** 4 | * BlogInfo: william 5 | * Date: 11-9-2 6 | * Time: 上午10:01 7 | */ 8 | public class Tuple { 9 | 10 | public static Tuple tuple(V1 v1, V2 v2) { 11 | return new Tuple(v1, v2); 12 | } 13 | 14 | private final V1 v1; 15 | private final V2 v2; 16 | 17 | public Tuple(V1 v1, V2 v2) { 18 | this.v1 = v1; 19 | this.v2 = v2; 20 | } 21 | 22 | public V1 v1() { 23 | return v1; 24 | } 25 | 26 | public V2 v2() { 27 | return v2; 28 | } 29 | 30 | @Override 31 | public boolean equals(Object o) { 32 | if (this == o) return true; 33 | if (o == null || getClass() != o.getClass()) return false; 34 | 35 | Tuple tuple = (Tuple) o; 36 | 37 | if (v1 != null ? !v1.equals(tuple.v1) : tuple.v1 != null) return false; 38 | if (v2 != null ? !v2.equals(tuple.v2) : tuple.v2 != null) return false; 39 | 40 | return true; 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | int result = v1 != null ? v1.hashCode() : 0; 46 | result = 31 * result + (v2 != null ? v2.hashCode() : 0); 47 | return result; 48 | } 49 | 50 | //for json generation 51 | public V1 getV1() { 52 | return v1; 53 | } 54 | 55 | public V2 getV2() { 56 | return v2; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/collect/Tuple3.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.collect; 2 | 3 | /** 4 | * BlogInfo: william 5 | * Date: 11-9-2 6 | * Time: 上午10:01 7 | */ 8 | public class Tuple3 { 9 | 10 | public static Tuple3 tuple(V1 v1, V2 v2, V3 v3) { 11 | return new Tuple3(v1, v2, v3); 12 | } 13 | 14 | private final V1 v1; 15 | private final V2 v2; 16 | private final V3 v3; 17 | 18 | public Tuple3(V1 v1, V2 v2, V3 v3) { 19 | this.v1 = v1; 20 | this.v2 = v2; 21 | this.v3 = v3; 22 | } 23 | 24 | public V1 v1() { 25 | return v1; 26 | } 27 | 28 | public V2 v2() { 29 | return v2; 30 | } 31 | 32 | public V3 v3() { 33 | return v3; 34 | } 35 | 36 | @Override 37 | public boolean equals(Object o) { 38 | if (this == o) return true; 39 | if (o == null || getClass() != o.getClass()) return false; 40 | 41 | Tuple3 tuple = (Tuple3) o; 42 | 43 | if (v1 != null ? !v1.equals(tuple.v1) : tuple.v1 != null) return false; 44 | if (v2 != null ? !v2.equals(tuple.v2) : tuple.v2 != null) return false; 45 | if (v3 != null ? !v3.equals(tuple.v3) : tuple.v3 != null) return false; 46 | 47 | return true; 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | int result = v1 != null ? v1.hashCode() : 0; 53 | result = 31 * result + (v2 != null ? v2.hashCode() : 0); 54 | result = 31 * result + (v3 != null ? v3.hashCode() : 0); 55 | return result; 56 | } 57 | 58 | //for json generation 59 | public V1 getV1() { 60 | return v1; 61 | } 62 | 63 | public V2 getV2() { 64 | return v2; 65 | } 66 | 67 | public V3 getV3() { 68 | return v3; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/collections/WowLists.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.collections; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * BlogInfo: william 7 | * Date: 12-4-17 8 | * Time: 上午10:41 9 | */ 10 | public class WowLists { 11 | public static String join(List lists, String splitter) { 12 | StringBuffer sb = new StringBuffer(); 13 | int len = lists.size(); 14 | for (int i = 0; i < len; i++) { 15 | sb.append(lists.get(i)); 16 | if (i != len - 1) { 17 | sb.append(splitter); 18 | } 19 | } 20 | return sb.toString(); 21 | } 22 | 23 | public static String join(List lists) { 24 | return join(lists, ","); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/collections/WowMaps.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.collections; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * BlogInfo: william 8 | * Date: 12-4-16 9 | * Time: 下午3:11 10 | */ 11 | public class WowMaps { 12 | private Map map = new HashMap(); 13 | 14 | public static WowMaps newHashMap() { 15 | return new WowMaps(); 16 | } 17 | 18 | public WowMaps put(K k, V v) { 19 | map.put(k, v); 20 | return this; 21 | } 22 | 23 | public Map map() { 24 | return map; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/collections/WowSerializable.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.collections; 2 | 3 | import java.io.*; 4 | 5 | /** 6 | * BlogInfo: william 7 | * Date: 12-4-17 8 | * Time: 下午1:23 9 | */ 10 | public class WowSerializable { 11 | 12 | public static void saveFile(String fileName, Object content) { 13 | 14 | try { 15 | FileOutputStream fileOutputStream = new FileOutputStream(new File(fileName)); 16 | ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream); 17 | outputStream.writeObject(content); 18 | outputStream.flush(); 19 | outputStream.close(); 20 | fileOutputStream.flush(); 21 | fileOutputStream.close(); 22 | } catch (IOException e) { 23 | e.printStackTrace(); 24 | } 25 | } 26 | 27 | public static Object loadFile(String fileName) { 28 | Object obj = null; 29 | try { 30 | FileInputStream fileInputStream = new FileInputStream(new File(fileName)); 31 | ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); 32 | obj = objectInputStream.readObject(); 33 | objectInputStream.close(); 34 | fileInputStream.close(); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | return obj; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/enhancer/EnhancerHelper.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.enhancer; 2 | 3 | import javassist.CtClass; 4 | import javassist.CtField; 5 | import javassist.CtMethod; 6 | import javassist.bytecode.AnnotationsAttribute; 7 | import javassist.bytecode.AttributeInfo; 8 | import javassist.bytecode.BadBytecode; 9 | import javassist.bytecode.SignatureAttribute; 10 | import javassist.bytecode.annotation.MemberValue; 11 | 12 | import java.lang.annotation.Annotation; 13 | import java.lang.reflect.Field; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | /** 19 | * User: WilliamZhu 20 | * Date: 12-7-12 21 | * Time: 下午1:35 22 | */ 23 | public class EnhancerHelper { 24 | 25 | public static String findFieldGenericType(SignatureAttribute.ObjectType fieldSignatureType) { 26 | try { 27 | Field field = fieldSignatureType.getClass().getDeclaredField("arguments"); 28 | field.setAccessible(true); 29 | 30 | SignatureAttribute.TypeArgument[] arguments = (SignatureAttribute.TypeArgument[]) field.get(fieldSignatureType); 31 | return arguments[0].toString(); 32 | } catch (Exception e) { 33 | 34 | } 35 | return null; 36 | } 37 | 38 | public static SignatureAttribute.ObjectType getFieldSignature(CtField field) { 39 | if (field == null) 40 | throw new IllegalArgumentException("Null method/constructor"); 41 | SignatureAttribute signature = (SignatureAttribute) field.getFieldInfo2().getAttribute(SignatureAttribute.tag); 42 | if (signature == null) 43 | return null; 44 | String sig = signature.getSignature(); 45 | try { 46 | return SignatureAttribute.toFieldSignature(sig); 47 | } catch (BadBytecode e) { 48 | throw new IllegalStateException(e); 49 | } 50 | } 51 | 52 | public static void createAnnotation(CtField ctField, Class annotationType, Map members) { 53 | if (ctField.hasAnnotation(annotationType)) return; 54 | 55 | AnnotationsAttribute attr = new AnnotationsAttribute(ctField.getFieldInfo().getConstPool(), AnnotationsAttribute.visibleTag); 56 | boolean isNewAttr = true; 57 | List attributeInfos = ctField.getFieldInfo().getAttributes(); 58 | for (AttributeInfo attributeInfo : attributeInfos) { 59 | if (attributeInfo instanceof AnnotationsAttribute) { 60 | attr = (AnnotationsAttribute) attributeInfo; 61 | isNewAttr = false; 62 | } 63 | } 64 | 65 | javassist.bytecode.annotation.Annotation[] annotations = attr.getAnnotations(); 66 | javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation(annotationType.getName(), attr.getConstPool()); 67 | 68 | for (javassist.bytecode.annotation.Annotation annotation1 : annotations) { 69 | if (annotation1.getTypeName().equals(annotationType.getName())) { 70 | annotation = annotation1; 71 | break; 72 | } 73 | } 74 | 75 | for (Map.Entry member : members.entrySet()) { 76 | try { 77 | if (annotation.getMemberValue(member.getKey()) == null) { 78 | annotation.addMemberValue(member.getKey(), member.getValue()); 79 | } 80 | } catch (Exception e) { 81 | e.printStackTrace(); 82 | annotation.addMemberValue(member.getKey(), member.getValue()); 83 | } 84 | 85 | } 86 | 87 | attr.addAnnotation(annotation); 88 | if (isNewAttr) { 89 | ctField.getFieldInfo().addAttribute(attr); 90 | } 91 | 92 | } 93 | 94 | public static void createAnnotation(CtClass ctClass, Class annotationType, Map members) { 95 | 96 | 97 | if (ctClass.hasAnnotation(annotationType)) return; 98 | 99 | AnnotationsAttribute attr = new AnnotationsAttribute(ctClass.getClassFile().getConstPool(), AnnotationsAttribute.visibleTag); 100 | boolean isNewAttr = true; 101 | List attributeInfos = ctClass.getClassFile2().getAttributes(); 102 | for (AttributeInfo attributeInfo : attributeInfos) { 103 | if (attributeInfo instanceof AnnotationsAttribute) { 104 | attr = (AnnotationsAttribute) attributeInfo; 105 | isNewAttr = false; 106 | } 107 | } 108 | 109 | javassist.bytecode.annotation.Annotation[] annotations = attr.getAnnotations(); 110 | javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation(annotationType.getName(), attr.getConstPool()); 111 | 112 | for (javassist.bytecode.annotation.Annotation annotation1 : annotations) { 113 | if (annotation1.getTypeName().equals(annotationType.getName())) { 114 | annotation = annotation1; 115 | break; 116 | } 117 | } 118 | 119 | for (Map.Entry member : members.entrySet()) { 120 | try { 121 | if (annotation.getMemberValue(member.getKey()) == null) { 122 | annotation.addMemberValue(member.getKey(), member.getValue()); 123 | } 124 | } catch (Exception e) { 125 | e.printStackTrace(); 126 | annotation.addMemberValue(member.getKey(), member.getValue()); 127 | } 128 | 129 | } 130 | 131 | attr.addAnnotation(annotation); 132 | 133 | if (isNewAttr) { 134 | ctClass.getClassFile().addAttribute(attr); 135 | } 136 | 137 | } 138 | 139 | public static void createAnnotation(AnnotationsAttribute attribute, Class annotationType, Map members) { 140 | 141 | javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation(annotationType.getName(), attribute.getConstPool()); 142 | for (Map.Entry member : members.entrySet()) { 143 | annotation.addMemberValue(member.getKey(), member.getValue()); 144 | } 145 | attribute.addAnnotation(annotation); 146 | } 147 | 148 | 149 | public static boolean hasAnnotation(CtClass ctClass, String annotation) throws ClassNotFoundException { 150 | for (Object object : ctClass.getAvailableAnnotations()) { 151 | Annotation ann = (Annotation) object; 152 | if (ann.annotationType().getName().equals(annotation)) { 153 | return true; 154 | } 155 | } 156 | return false; 157 | } 158 | 159 | 160 | public static boolean hasAnnotationWithPrefix(CtClass ctClass, String annotationPrefix) throws ClassNotFoundException { 161 | for (Object object : ctClass.getAvailableAnnotations()) { 162 | Annotation ann = (Annotation) object; 163 | if (ann.annotationType().getName().startsWith(annotationPrefix)) { 164 | return true; 165 | } 166 | } 167 | return false; 168 | } 169 | 170 | 171 | public static boolean hasAnnotation(CtField ctField, String annotation) throws ClassNotFoundException { 172 | for (Object object : ctField.getAvailableAnnotations()) { 173 | Annotation ann = (Annotation) object; 174 | if (ann.annotationType().getName().equals(annotation)) { 175 | return true; 176 | } 177 | } 178 | return false; 179 | } 180 | 181 | public static boolean hasAnnotation(CtMethod ctMethod, String annotation) throws ClassNotFoundException { 182 | for (Object object : ctMethod.getAvailableAnnotations()) { 183 | Annotation ann = (Annotation) object; 184 | if (ann.annotationType().getName().equals(annotation)) { 185 | return true; 186 | } 187 | } 188 | return false; 189 | } 190 | 191 | 192 | public static AnnotationsAttribute getAnnotations(CtClass ctClass) { 193 | AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) ctClass.getClassFile().getAttribute(AnnotationsAttribute.visibleTag); 194 | if (annotationsAttribute == null) { 195 | annotationsAttribute = new AnnotationsAttribute(ctClass.getClassFile().getConstPool(), AnnotationsAttribute.visibleTag); 196 | ctClass.getClassFile().addAttribute(annotationsAttribute); 197 | } 198 | return annotationsAttribute; 199 | } 200 | 201 | public static AnnotationsAttribute getAnnotations(CtField ctField) { 202 | AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) ctField.getFieldInfo().getAttribute(AnnotationsAttribute.visibleTag); 203 | return annotationsAttribute; 204 | } 205 | 206 | 207 | public static AnnotationsAttribute getAnnotations(CtMethod ctMethod) { 208 | AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) ctMethod.getMethodInfo().getAttribute(AnnotationsAttribute.visibleTag); 209 | return annotationsAttribute; 210 | } 211 | 212 | 213 | public static void createAnnotation(AnnotationsAttribute attribute, Class annotationType) { 214 | createAnnotation(attribute, annotationType, new HashMap()); 215 | } 216 | 217 | 218 | } 219 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/env/Environment.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.env; 2 | 3 | import net.csdn.common.Classes; 4 | import net.csdn.common.exception.FailedToResolveConfigException; 5 | import net.csdn.common.io.Streams; 6 | import net.csdn.common.settings.Settings; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.io.InputStreamReader; 11 | import java.net.MalformedURLException; 12 | import java.net.URL; 13 | 14 | import static net.csdn.common.Strings.cleanPath; 15 | import static net.csdn.common.settings.ImmutableSettings.Builder.EMPTY_SETTINGS; 16 | 17 | /** 18 | * BlogInfo: william 19 | * Date: 11-9-1 20 | * Time: 下午3:51 21 | */ 22 | public class Environment { 23 | 24 | private final File homeFile; 25 | 26 | private final File workFile; 27 | 28 | private final File workWithClusterFile; 29 | 30 | private final File dataFile; 31 | 32 | private final File dataWithClusterFile; 33 | 34 | private final File configFile; 35 | 36 | private final File pluginsFile; 37 | 38 | private final File logsFile; 39 | 40 | private final File dictionariesFile; 41 | 42 | private final File gatewayFile; 43 | 44 | private final File fingerprintFile; 45 | 46 | private final File templateDirFile; 47 | 48 | 49 | public Environment() { 50 | this(EMPTY_SETTINGS); 51 | } 52 | 53 | public Environment(Settings settings) { 54 | if (settings.get("path.home") != null) { 55 | homeFile = new File(cleanPath(settings.get("path.home"))); 56 | } else { 57 | homeFile = new File(System.getProperty("user.dir")); 58 | } 59 | 60 | if (settings.get("path.conf") != null) { 61 | configFile = new File(cleanPath(settings.get("path.conf"))); 62 | } else { 63 | configFile = new File(homeFile, "config"); 64 | } 65 | 66 | if (settings.get("path.plugins") != null) { 67 | pluginsFile = new File(cleanPath(settings.get("path.plugins"))); 68 | } else { 69 | pluginsFile = new File(homeFile, "plugins"); 70 | } 71 | 72 | if (settings.get("path.work") != null) { 73 | workFile = new File(cleanPath(settings.get("path.work"))); 74 | } else { 75 | workFile = new File(homeFile, "work"); 76 | } 77 | workWithClusterFile = new File(workFile, settings.get("cluster.name", "csdnsearch")); 78 | 79 | if (settings.get("path.data") != null) { 80 | dataFile = new File(cleanPath(settings.get("path.data"))); 81 | } else { 82 | dataFile = new File(homeFile, "data"); 83 | } 84 | 85 | if (settings.get("path.template") != null) { 86 | templateDirFile = new File(cleanPath(settings.get("path.template"))); 87 | } else { 88 | templateDirFile = new File(homeFile, "template"); 89 | } 90 | 91 | dataWithClusterFile = new File(dataFile, settings.get("cluster.name", "csdnsearch")); 92 | 93 | if (settings.get("path.logs") != null) { 94 | logsFile = new File(cleanPath(settings.get("path.logs"))); 95 | } else { 96 | logsFile = new File(homeFile, "logs"); 97 | } 98 | 99 | if (settings.get("path.dictionaries") != null) { 100 | dictionariesFile = new File(cleanPath(settings.get("path.dictionaries"))); 101 | } else { 102 | dictionariesFile = new File(homeFile, "dictionaries"); 103 | } 104 | if (settings.get("path.gateway") != null) { 105 | gatewayFile = new File(cleanPath(settings.get("path.gateway"))); 106 | } else { 107 | gatewayFile = new File(homeFile, "gateway"); 108 | } 109 | if (settings.get("path.fingerprintdic") != null) { 110 | fingerprintFile = new File(cleanPath(settings.get("path.fingerprintdic"))); 111 | } else { 112 | fingerprintFile = new File(homeFile, "fingerprintdic"); 113 | } 114 | } 115 | 116 | /** 117 | * The home of the installation. 118 | */ 119 | public File homeFile() { 120 | return homeFile; 121 | } 122 | 123 | /** 124 | * The home of dictionaries 125 | */ 126 | public File dictionariesFile() { 127 | return dictionariesFile; 128 | } 129 | 130 | /** 131 | * The work location. 132 | */ 133 | public File workFile() { 134 | return workFile; 135 | } 136 | 137 | /** 138 | * The work location with the cluster name as a sub directory. 139 | */ 140 | public File workWithClusterFile() { 141 | return workWithClusterFile; 142 | } 143 | 144 | /** 145 | * The data location. 146 | */ 147 | public File dataFile() { 148 | return dataFile; 149 | } 150 | 151 | /** 152 | * The data location with the cluster name as a sub directory. 153 | */ 154 | public File dataWithClusterFile() { 155 | return dataWithClusterFile; 156 | } 157 | 158 | /** 159 | * The config location. 160 | */ 161 | public File configFile() { 162 | return configFile; 163 | } 164 | 165 | public File pluginsFile() { 166 | return pluginsFile; 167 | } 168 | 169 | public File logsFile() { 170 | return logsFile; 171 | } 172 | 173 | public File gateway() { 174 | return gatewayFile; 175 | } 176 | 177 | public File fingerprintFile() { 178 | return fingerprintFile; 179 | } 180 | 181 | public File templateDirFile() { 182 | return templateDirFile; 183 | } 184 | 185 | public String resolveConfigAndLoadToString(String path) throws FailedToResolveConfigException, IOException { 186 | return Streams.copyToString(new InputStreamReader(resolveConfig(path).openStream(), "UTF-8")); 187 | } 188 | 189 | public URL resolveConfig(String path) throws FailedToResolveConfigException { 190 | // first, try it as a path on the file system 191 | File f1 = new File(path); 192 | if (f1.exists()) { 193 | try { 194 | return f1.toURI().toURL(); 195 | } catch (MalformedURLException e) { 196 | throw new FailedToResolveConfigException("Failed to resolve path [" + f1 + "]", e); 197 | } 198 | } 199 | if (path.startsWith("/")) { 200 | path = path.substring(1); 201 | } 202 | // next, try it relative to the config location 203 | File f2 = new File(configFile, path); 204 | if (f2.exists()) { 205 | try { 206 | return f2.toURI().toURL(); 207 | } catch (MalformedURLException e) { 208 | throw new FailedToResolveConfigException("Failed to resolve path [" + f2 + "]", e); 209 | } 210 | } 211 | // try and load it from the classpath directly 212 | URL resource = Classes.getDefaultClassLoader().getResource(path); 213 | if (resource != null) { 214 | return resource; 215 | } 216 | // try and load it from the classpath with config/ prefix 217 | if (!path.startsWith("config/")) { 218 | resource = Classes.getDefaultClassLoader().getResource("config/" + path); 219 | if (resource != null) { 220 | return resource; 221 | } 222 | } 223 | throw new FailedToResolveConfigException("Failed to resolve config path [" + path + "], tried file path [" + f1 + "], path file [" + f2 + "], and classpath"); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/ArgumentErrorException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | /** 4 | * BlogInfo: WilliamZhu 5 | * Date: 12-6-6 6 | * Time: 上午11:00 7 | */ 8 | public class ArgumentErrorException extends RuntimeException { 9 | 10 | public ArgumentErrorException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/AutoGeneration.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | /** 4 | * User: WilliamZhu 5 | * Date: 12-7-28 6 | * Time: 下午9:16 7 | */ 8 | public class AutoGeneration extends RuntimeException { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/ConfigurationException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | /** 4 | * BlogInfo: WilliamZhu 5 | * Date: 12-6-13 6 | * Time: 下午7:50 7 | */ 8 | public class ConfigurationException extends RuntimeException { 9 | public ConfigurationException(String message) { 10 | super(message); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | 5 | /** 6 | * User: WilliamZhu 7 | * Date: 12-7-10 8 | * Time: 上午8:25 9 | */ 10 | public class ExceptionHandler { 11 | public static void renderHandle(Exception e) throws Exception { 12 | Exception temp = new Exception(); 13 | if (e instanceof InvocationTargetException) { 14 | temp = (InvocationTargetException) e; 15 | for (int i = 0; i < 10; i++) { 16 | InvocationTargetException wow = (InvocationTargetException) temp; 17 | if (!(wow.getTargetException() instanceof Exception)) { 18 | wow.getTargetException().printStackTrace(); 19 | throw wow; 20 | } 21 | temp = (Exception) wow.getTargetException(); 22 | if (temp instanceof RenderFinish) { 23 | return; 24 | } 25 | if (!(temp instanceof InvocationTargetException)) { 26 | break; 27 | } 28 | } 29 | } else if (e instanceof RenderFinish) { 30 | return; 31 | } else { 32 | throw e; 33 | } 34 | 35 | throw temp; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/FailedToResolveConfigException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | /** 4 | * BlogInfo: william 5 | * Date: 11-9-1 6 | * Time: 下午4:40 7 | */ 8 | public class FailedToResolveConfigException extends RuntimeException { 9 | public FailedToResolveConfigException(String msg) { 10 | super(msg); 11 | } 12 | 13 | public FailedToResolveConfigException(String msg, Throwable cause) { 14 | super(msg, cause); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/ParseException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | /** 4 | * BlogInfo: william 5 | * Date: 11-9-1 6 | * Time: 下午4:33 7 | */ 8 | public class ParseException extends RuntimeException { 9 | 10 | public ParseException(String msg) { 11 | super(msg); 12 | } 13 | 14 | public ParseException(String msg, Throwable cause) { 15 | super(msg, cause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/RecordExistedException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | 4 | public class RecordExistedException extends RuntimeException { 5 | public RecordExistedException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/RecordNotFoundException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | public class RecordNotFoundException extends RuntimeException { 4 | public RecordNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/RenderFinish.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | /** 4 | * User: WilliamZhu 5 | * Date: 12-7-9 6 | * Time: 下午9:47 7 | */ 8 | public class RenderFinish extends RuntimeException { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/exception/SettingsException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.exception; 2 | 3 | /** 4 | * BlogInfo: william 5 | * Date: 11-9-1 6 | * Time: 下午2:22 7 | */ 8 | public class SettingsException extends RuntimeException { 9 | 10 | public SettingsException(String message) { 11 | super(message); 12 | } 13 | 14 | public SettingsException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/io/Streams.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.io; 2 | 3 | import com.google.common.base.Preconditions; 4 | 5 | import java.io.*; 6 | 7 | /** 8 | * BlogInfo: william 9 | * Date: 11-9-1 10 | * Time: 下午4:07 11 | */ 12 | public abstract class Streams { 13 | 14 | public static final int BUFFER_SIZE = 1024 * 8; 15 | 16 | 17 | //--------------------------------------------------------------------- 18 | // Copy methods for java.io.File 19 | //--------------------------------------------------------------------- 20 | 21 | /** 22 | * Copy the contents of the given input File to the given output File. 23 | * 24 | * @param in the file to copy from 25 | * @param out the file to copy to 26 | * @return the number of bytes copied 27 | * @throws java.io.IOException in case of I/O errors 28 | */ 29 | public static long copy(File in, File out) throws IOException { 30 | Preconditions.checkNotNull(in, "No input File specified"); 31 | Preconditions.checkNotNull(out, "No output File specified"); 32 | return copy(new BufferedInputStream(new FileInputStream(in)), 33 | new BufferedOutputStream(new FileOutputStream(out))); 34 | } 35 | 36 | /** 37 | * Copy the contents of the given byte array to the given output File. 38 | * 39 | * @param in the byte array to copy from 40 | * @param out the file to copy to 41 | * @throws java.io.IOException in case of I/O errors 42 | */ 43 | public static void copy(byte[] in, File out) throws IOException { 44 | Preconditions.checkNotNull(in, "No input byte array specified"); 45 | Preconditions.checkNotNull(out, "No output File specified"); 46 | ByteArrayInputStream inStream = new ByteArrayInputStream(in); 47 | OutputStream outStream = new BufferedOutputStream(new FileOutputStream(out)); 48 | copy(inStream, outStream); 49 | } 50 | 51 | 52 | //--------------------------------------------------------------------- 53 | // Copy methods for java.io.InputStream / java.io.OutputStream 54 | //--------------------------------------------------------------------- 55 | 56 | 57 | public static long copy(InputStream in, OutputStream out) throws IOException { 58 | return copy(in, out, new byte[BUFFER_SIZE]); 59 | } 60 | 61 | /** 62 | * Copy the contents of the given InputStream to the given OutputStream. 63 | * Closes both streams when done. 64 | * 65 | * @param in the stream to copy from 66 | * @param out the stream to copy to 67 | * @return the number of bytes copied 68 | * @throws java.io.IOException in case of I/O errors 69 | */ 70 | public static long copy(InputStream in, OutputStream out, byte[] buffer) throws IOException { 71 | Preconditions.checkNotNull(in, "No InputStream specified"); 72 | Preconditions.checkNotNull(out, "No OutputStream specified"); 73 | try { 74 | long byteCount = 0; 75 | int bytesRead; 76 | while ((bytesRead = in.read(buffer)) != -1) { 77 | out.write(buffer, 0, bytesRead); 78 | byteCount += bytesRead; 79 | } 80 | out.flush(); 81 | return byteCount; 82 | } finally { 83 | try { 84 | in.close(); 85 | } catch (IOException ex) { 86 | // do nothing 87 | } 88 | try { 89 | out.close(); 90 | } catch (IOException ex) { 91 | // do nothing 92 | } 93 | } 94 | } 95 | 96 | public static byte[] copyToByteArray(InputStream in) throws IOException { 97 | Preconditions.checkNotNull(in, "No InputStream specified"); 98 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 99 | byte[] buffer = new byte[6 * 1024]; 100 | try { 101 | long byteCount = 0; 102 | int bytesRead; 103 | while ((bytesRead = in.read(buffer)) != -1) { 104 | out.write(buffer, 0, bytesRead); 105 | byteCount += bytesRead; 106 | } 107 | out.flush(); 108 | return out.toByteArray(); 109 | } finally { 110 | try { 111 | in.close(); 112 | } catch (IOException ex) { 113 | // do nothing 114 | } 115 | try { 116 | out.close(); 117 | } catch (IOException ex) { 118 | // do nothing 119 | } 120 | } 121 | } 122 | 123 | /** 124 | * Copy the contents of the given byte array to the given OutputStream. 125 | * Closes the stream when done. 126 | * 127 | * @param in the byte array to copy from 128 | * @param out the OutputStream to copy to 129 | * @throws java.io.IOException in case of I/O errors 130 | */ 131 | public static void copy(byte[] in, OutputStream out) throws IOException { 132 | Preconditions.checkNotNull(in, "No input byte array specified"); 133 | Preconditions.checkNotNull(out, "No OutputStream specified"); 134 | try { 135 | out.write(in); 136 | } finally { 137 | try { 138 | out.close(); 139 | } catch (IOException ex) { 140 | // do nothing 141 | } 142 | } 143 | } 144 | 145 | 146 | //--------------------------------------------------------------------- 147 | // Copy methods for java.io.Reader / java.io.Writer 148 | //--------------------------------------------------------------------- 149 | 150 | /** 151 | * Copy the contents of the given Reader to the given Writer. 152 | * Closes both when done. 153 | * 154 | * @param in the Reader to copy from 155 | * @param out the Writer to copy to 156 | * @return the number of characters copied 157 | * @throws java.io.IOException in case of I/O errors 158 | */ 159 | public static int copy(Reader in, Writer out) throws IOException { 160 | Preconditions.checkNotNull(in, "No Reader specified"); 161 | Preconditions.checkNotNull(out, "No Writer specified"); 162 | try { 163 | int byteCount = 0; 164 | char[] buffer = new char[BUFFER_SIZE]; 165 | int bytesRead; 166 | while ((bytesRead = in.read(buffer)) != -1) { 167 | out.write(buffer, 0, bytesRead); 168 | byteCount += bytesRead; 169 | } 170 | out.flush(); 171 | return byteCount; 172 | } finally { 173 | try { 174 | in.close(); 175 | } catch (IOException ex) { 176 | // do nothing 177 | } 178 | try { 179 | out.close(); 180 | } catch (IOException ex) { 181 | // do nothing 182 | } 183 | } 184 | } 185 | 186 | /** 187 | * Copy the contents of the given String to the given output Writer. 188 | * Closes the write when done. 189 | * 190 | * @param in the String to copy from 191 | * @param out the Writer to copy to 192 | * @throws java.io.IOException in case of I/O errors 193 | */ 194 | public static void copy(String in, Writer out) throws IOException { 195 | Preconditions.checkNotNull(in, "No input String specified"); 196 | Preconditions.checkNotNull(out, "No Writer specified"); 197 | try { 198 | out.write(in); 199 | } finally { 200 | try { 201 | out.close(); 202 | } catch (IOException ex) { 203 | // do nothing 204 | } 205 | } 206 | } 207 | 208 | /** 209 | * Copy the contents of the given Reader into a String. 210 | * Closes the reader when done. 211 | * 212 | * @param in the reader to copy from 213 | * @return the String that has been copied to 214 | * @throws java.io.IOException in case of I/O errors 215 | */ 216 | public static String copyToString(Reader in) throws IOException { 217 | StringWriter out = new StringWriter(); 218 | copy(in, out); 219 | return out.toString(); 220 | } 221 | 222 | public static String copyToStringFromClasspath(ClassLoader classLoader, String path) throws IOException { 223 | InputStream is = classLoader.getResourceAsStream(path); 224 | if (is == null) { 225 | throw new FileNotFoundException("Resource [" + path + "] not found in classpath with class loader [" + classLoader + "]"); 226 | } 227 | return copyToString(new InputStreamReader(is, "UTF-8")); 228 | } 229 | 230 | public static String copyToStringFromClasspath(String path) throws IOException { 231 | InputStream is = Streams.class.getResourceAsStream(path); 232 | if (is == null) { 233 | throw new FileNotFoundException("Resource [" + path + "] not found in classpath"); 234 | } 235 | return copyToString(new InputStreamReader(is)); 236 | } 237 | 238 | } 239 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/CSLogger.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging; 2 | 3 | /** 4 | * BlogInfo: william 5 | * Date: 11-9-1 6 | * Time: 下午2:38 7 | */ 8 | public interface CSLogger { 9 | String getPrefix(); 10 | 11 | String getName(); 12 | 13 | /** 14 | * Returns {@code true} if a TRACE level message is logged. 15 | */ 16 | boolean isTraceEnabled(); 17 | 18 | /** 19 | * Returns {@code true} if a DEBUG level message is logged. 20 | */ 21 | boolean isDebugEnabled(); 22 | 23 | /** 24 | * Returns {@code true} if an INFO level message is logged. 25 | */ 26 | boolean isInfoEnabled(); 27 | 28 | /** 29 | * Returns {@code true} if a WARN level message is logged. 30 | */ 31 | boolean isWarnEnabled(); 32 | 33 | /** 34 | * Returns {@code true} if an ERROR level message is logged. 35 | */ 36 | boolean isErrorEnabled(); 37 | 38 | boolean isHadooEnabled(); 39 | 40 | 41 | void hadoo(String msg, Object... params); 42 | 43 | void hadoo(String msg, Throwable cause, Object... params); 44 | 45 | /** 46 | * Logs a DEBUG level message. 47 | */ 48 | void trace(String msg, Object... params); 49 | 50 | /** 51 | * Logs a DEBUG level message. 52 | */ 53 | void trace(String msg, Throwable cause, Object... params); 54 | 55 | /** 56 | * Logs a DEBUG level message. 57 | */ 58 | void debug(String msg, Object... params); 59 | 60 | /** 61 | * Logs a DEBUG level message. 62 | */ 63 | void debug(String msg, Throwable cause, Object... params); 64 | 65 | /** 66 | * Logs an INFO level message. 67 | */ 68 | void info(String msg, Object... params); 69 | 70 | /** 71 | * Logs an INFO level message. 72 | */ 73 | void info(String msg, Throwable cause, Object... params); 74 | 75 | /** 76 | * Logs a WARN level message. 77 | */ 78 | void warn(String msg, Object... params); 79 | 80 | /** 81 | * Logs a WARN level message. 82 | */ 83 | void warn(String msg, Throwable cause, Object... params); 84 | 85 | /** 86 | * Logs an ERROR level message. 87 | */ 88 | void error(String msg, Object... params); 89 | 90 | /** 91 | * Logs an ERROR level message. 92 | */ 93 | void error(String msg, Throwable cause, Object... params); 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/CSLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging; 2 | 3 | import net.csdn.common.logging.log4j.Log4jFactory; 4 | 5 | /** 6 | * BlogInfo: william 7 | * Date: 11-9-1 8 | * Time: 下午3:43 9 | */ 10 | public abstract class CSLoggerFactory { 11 | private static volatile CSLoggerFactory defaultFactory = new Log4jFactory(); 12 | 13 | /** 14 | * Changes the default factory. 15 | */ 16 | public static void setDefaultFactory(CSLoggerFactory defaultFactory) { 17 | if (defaultFactory == null) { 18 | throw new NullPointerException("defaultFactory"); 19 | } 20 | CSLoggerFactory.defaultFactory = defaultFactory; 21 | } 22 | 23 | 24 | public static CSLogger getLogger(String prefix, String name) { 25 | return defaultFactory.newInstance(prefix == null ? null : prefix.intern(), name.intern()); 26 | } 27 | 28 | public static CSLogger getLogger(String name) { 29 | return defaultFactory.newInstance(name.intern()); 30 | } 31 | 32 | public CSLogger newInstance(String name) { 33 | return newInstance(null, name); 34 | } 35 | 36 | protected abstract CSLogger newInstance(String prefix, String name); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/Loggers.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging; 2 | 3 | import net.csdn.common.Classes; 4 | import net.csdn.common.settings.Settings; 5 | 6 | import java.net.InetAddress; 7 | import java.net.UnknownHostException; 8 | import java.util.List; 9 | 10 | import static com.google.common.collect.Lists.newArrayList; 11 | import static java.util.Arrays.asList; 12 | 13 | /** 14 | * BlogInfo: william 15 | * Date: 11-9-1 16 | * Time: 下午3:28 17 | */ 18 | public class Loggers { 19 | private final static String commonPrefix = System.getProperty("cs.logger.prefix", ""); 20 | 21 | public static final String SPACE = " "; 22 | 23 | private static boolean consoleLoggingEnabled = true; 24 | 25 | public static void disableConsoleLogging() { 26 | consoleLoggingEnabled = false; 27 | } 28 | 29 | public static void enableConsoleLogging() { 30 | consoleLoggingEnabled = true; 31 | } 32 | 33 | public static boolean consoleLoggingEnabled() { 34 | return consoleLoggingEnabled; 35 | } 36 | 37 | 38 | public static CSLogger getLogger(Class clazz, Settings settings, String... prefixes) { 39 | return getLogger(buildClassLoggerName(clazz), settings, prefixes); 40 | } 41 | 42 | public static CSLogger getLogger(String loggerName, Settings settings, String... prefixes) { 43 | List prefixesList = newArrayList(); 44 | if (settings.getAsBoolean("logger.logHostAddress", false)) { 45 | try { 46 | prefixesList.add(InetAddress.getLocalHost().getHostAddress()); 47 | } catch (UnknownHostException e) { 48 | // ignore 49 | } 50 | } 51 | if (settings.getAsBoolean("logger.logHostName", false)) { 52 | try { 53 | prefixesList.add(InetAddress.getLocalHost().getHostName()); 54 | } catch (UnknownHostException e) { 55 | // ignore 56 | } 57 | } 58 | String name = settings.get("name"); 59 | if (name != null) { 60 | prefixesList.add(name); 61 | } 62 | if (prefixes != null && prefixes.length > 0) { 63 | prefixesList.addAll(asList(prefixes)); 64 | } 65 | return getLogger(getLoggerName(loggerName), prefixesList.toArray(new String[prefixesList.size()])); 66 | } 67 | 68 | public static CSLogger getLogger(CSLogger parentLogger, String s) { 69 | return getLogger(parentLogger.getName() + s, parentLogger.getPrefix()); 70 | } 71 | 72 | public static CSLogger getLogger(String s) { 73 | return CSLoggerFactory.getLogger(s); 74 | } 75 | 76 | public static CSLogger getLogger(Class clazz) { 77 | return CSLoggerFactory.getLogger(getLoggerName(buildClassLoggerName(clazz))); 78 | } 79 | 80 | public static CSLogger getLogger(Class clazz, String... prefixes) { 81 | return getLogger(buildClassLoggerName(clazz), prefixes); 82 | } 83 | 84 | public static CSLogger getLogger(String name, String... prefixes) { 85 | String prefix = null; 86 | if (prefixes != null && prefixes.length > 0) { 87 | StringBuilder sb = new StringBuilder(); 88 | for (String prefixX : prefixes) { 89 | if (prefixX != null) { 90 | if (prefixX.equals(SPACE)) { 91 | sb.append(" "); 92 | } else { 93 | sb.append("[").append(prefixX).append("]"); 94 | } 95 | } 96 | } 97 | if (sb.length() > 0) { 98 | sb.append(" "); 99 | prefix = sb.toString(); 100 | } 101 | } 102 | return CSLoggerFactory.getLogger(prefix, getLoggerName(name)); 103 | } 104 | 105 | private static String buildClassLoggerName(Class clazz) { 106 | String name = clazz.getName(); 107 | if (name.startsWith("net.csdn.")) { 108 | name = Classes.getPackageName(clazz); 109 | } 110 | return name; 111 | } 112 | 113 | private static String getLoggerName(String name) { 114 | if (name.startsWith("net.csdn.")) { 115 | name = name.substring("net.csdn.".length()); 116 | } 117 | return commonPrefix + name; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/log4j/ConsoleAppender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elastic Search and Shay Banon under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. Elastic Search licenses this 6 | * file to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package net.csdn.common.logging.log4j; 21 | 22 | import net.csdn.common.logging.Loggers; 23 | import org.apache.log4j.Layout; 24 | import org.apache.log4j.WriterAppender; 25 | import org.apache.log4j.helpers.LogLog; 26 | 27 | import java.io.IOException; 28 | import java.io.OutputStream; 29 | 30 | /** 31 | * ConsoleAppender appends log events to System.out or 32 | * System.err using a layout specified by the user. The 33 | * default target is System.out. 34 | *

35 | *

ElasticSearch: Adapter from log4j to allow to disable console logging...

36 | * 37 | * @author Ceki Gülcü 38 | * @author Curt Arnold 39 | * @since 1.1 40 | */ 41 | public class ConsoleAppender extends WriterAppender { 42 | 43 | public static final String SYSTEM_OUT = "System.out"; 44 | public static final String SYSTEM_ERR = "System.err"; 45 | 46 | protected String target = SYSTEM_OUT; 47 | 48 | /** 49 | * Determines if the appender honors reassignments of System.out 50 | * or System.err made after configuration. 51 | */ 52 | private boolean follow = true; 53 | 54 | /** 55 | * Constructs an unconfigured appender. 56 | */ 57 | public ConsoleAppender() { 58 | } 59 | 60 | /** 61 | * Creates a configured appender. 62 | * 63 | * @param layout layout, may not be null. 64 | */ 65 | public ConsoleAppender(Layout layout) { 66 | this(layout, SYSTEM_OUT); 67 | } 68 | 69 | /** 70 | * Creates a configured appender. 71 | * 72 | * @param layout layout, may not be null. 73 | * @param target target, either "System.err" or "System.out". 74 | */ 75 | public ConsoleAppender(Layout layout, String target) { 76 | setLayout(layout); 77 | setTarget(target); 78 | activateOptions(); 79 | } 80 | 81 | /** 82 | * Sets the value of the Target option. Recognized values 83 | * are "System.out" and "System.err". Any other value will be 84 | * ignored. 85 | */ 86 | public void setTarget(String value) { 87 | String v = value.trim(); 88 | 89 | if (SYSTEM_OUT.equalsIgnoreCase(v)) { 90 | target = SYSTEM_OUT; 91 | } else if (SYSTEM_ERR.equalsIgnoreCase(v)) { 92 | target = SYSTEM_ERR; 93 | } else { 94 | targetWarn(value); 95 | } 96 | } 97 | 98 | /** 99 | * Returns the current value of the Target property. The 100 | * default value of the option is "System.out". 101 | *

102 | * See also {@link #setTarget}. 103 | */ 104 | public String getTarget() { 105 | return target; 106 | } 107 | 108 | /** 109 | * Sets whether the appender honors reassignments of System.out 110 | * or System.err made after configuration. 111 | * 112 | * @param newValue if true, appender will use value of System.out or 113 | * System.err in force at the time when logging events are appended. 114 | * @since 1.2.13 115 | */ 116 | public final void setFollow(final boolean newValue) { 117 | follow = newValue; 118 | } 119 | 120 | /** 121 | * Gets whether the appender honors reassignments of System.out 122 | * or System.err made after configuration. 123 | * 124 | * @return true if appender will use value of System.out or 125 | * System.err in force at the time when logging events are appended. 126 | * @since 1.2.13 127 | */ 128 | public final boolean getFollow() { 129 | return follow; 130 | } 131 | 132 | void targetWarn(String val) { 133 | LogLog.warn("[" + val + "] should be System.out or System.err."); 134 | LogLog.warn("Using previously set target, System.out by default."); 135 | } 136 | 137 | /** 138 | * Prepares the appender for use. 139 | */ 140 | public void activateOptions() { 141 | if (follow) { 142 | if (target.equals(SYSTEM_ERR)) { 143 | setWriter(createWriter(new SystemErrStream())); 144 | } else { 145 | setWriter(createWriter(new SystemOutStream())); 146 | } 147 | } else { 148 | if (target.equals(SYSTEM_ERR)) { 149 | setWriter(createWriter(System.err)); 150 | } else { 151 | setWriter(createWriter(System.out)); 152 | } 153 | } 154 | 155 | super.activateOptions(); 156 | } 157 | 158 | /** 159 | * {@inheritDoc} 160 | */ 161 | protected 162 | final void closeWriter() { 163 | if (follow) { 164 | super.closeWriter(); 165 | } 166 | } 167 | 168 | 169 | /** 170 | * An implementation of OutputStream that redirects to the 171 | * current System.err. 172 | */ 173 | private static class SystemErrStream extends OutputStream { 174 | public SystemErrStream() { 175 | } 176 | 177 | public void close() { 178 | } 179 | 180 | public void flush() { 181 | System.err.flush(); 182 | } 183 | 184 | public void write(final byte[] b) throws IOException { 185 | if (!Loggers.consoleLoggingEnabled()) { 186 | return; 187 | } 188 | System.err.write(b); 189 | } 190 | 191 | public void write(final byte[] b, final int off, final int len) 192 | throws IOException { 193 | if (!Loggers.consoleLoggingEnabled()) { 194 | return; 195 | } 196 | System.err.write(b, off, len); 197 | } 198 | 199 | public void write(final int b) throws IOException { 200 | if (!Loggers.consoleLoggingEnabled()) { 201 | return; 202 | } 203 | System.err.write(b); 204 | } 205 | } 206 | 207 | /** 208 | * An implementation of OutputStream that redirects to the 209 | * current System.out. 210 | */ 211 | private static class SystemOutStream extends OutputStream { 212 | public SystemOutStream() { 213 | } 214 | 215 | public void close() { 216 | } 217 | 218 | public void flush() { 219 | System.out.flush(); 220 | } 221 | 222 | public void write(final byte[] b) throws IOException { 223 | if (!Loggers.consoleLoggingEnabled()) { 224 | return; 225 | } 226 | System.out.write(b); 227 | } 228 | 229 | public void write(final byte[] b, final int off, final int len) 230 | throws IOException { 231 | if (!Loggers.consoleLoggingEnabled()) { 232 | return; 233 | } 234 | System.out.write(b, off, len); 235 | } 236 | 237 | public void write(final int b) throws IOException { 238 | if (!Loggers.consoleLoggingEnabled()) { 239 | return; 240 | } 241 | System.out.write(b); 242 | } 243 | } 244 | 245 | } 246 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/log4j/JLinePatternLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elastic Search and Shay Banon under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. Elastic Search licenses this 6 | * file to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package net.csdn.common.logging.log4j; 21 | 22 | import net.csdn.common.jline.ANSI; 23 | import org.apache.log4j.Level; 24 | import org.apache.log4j.PatternLayout; 25 | import org.apache.log4j.helpers.FormattingInfo; 26 | import org.apache.log4j.helpers.PatternConverter; 27 | import org.apache.log4j.helpers.PatternParser; 28 | import org.apache.log4j.spi.LoggingEvent; 29 | 30 | import java.lang.reflect.Field; 31 | 32 | import static jline.ANSIBuffer.ANSICodes.attrib; 33 | import static net.csdn.common.jline.ANSI.Code.*; 34 | 35 | /** 36 | * @author kimchy (Shay Banon) 37 | */ 38 | public class JLinePatternLayout extends PatternLayout { 39 | 40 | @Override 41 | protected PatternParser createPatternParser(String pattern) { 42 | try { 43 | return new JLinePatternParser(pattern); 44 | } catch (Throwable t) { 45 | return super.createPatternParser(pattern); 46 | } 47 | } 48 | 49 | private final static class JLinePatternParser extends PatternParser { 50 | 51 | private JLinePatternParser(String pattern) { 52 | super(pattern); 53 | } 54 | 55 | @Override 56 | protected void addConverter(PatternConverter pc) { 57 | try { 58 | if (ANSI.isEnabled()) { 59 | if (pc.getClass().getName().endsWith("BasicPatternConverter")) { 60 | Field typeField = pc.getClass().getDeclaredField("type"); 61 | typeField.setAccessible(true); 62 | Integer type = (Integer) typeField.get(pc); 63 | if (type == 2002) { 64 | pc = new ColoredLevelPatternConverter(formattingInfo); 65 | } 66 | } 67 | } 68 | } catch (Throwable t) { 69 | // ignore 70 | } 71 | super.addConverter(pc); 72 | } 73 | 74 | private static class ColoredLevelPatternConverter extends PatternConverter { 75 | 76 | ColoredLevelPatternConverter(FormattingInfo formattingInfo) { 77 | super(formattingInfo); 78 | } 79 | 80 | public String convert(LoggingEvent event) { 81 | if (!ANSI.isEnabled()) { 82 | return event.getLevel().toString(); 83 | } 84 | if (event.getLevel() == Level.FATAL) { 85 | return attrib(FG_RED) + event.getLevel().toString() + attrib(OFF); 86 | } else if (event.getLevel() == Level.ERROR) { 87 | return attrib(FG_RED) + event.getLevel().toString() + attrib(OFF); 88 | } else if (event.getLevel() == Level.WARN) { 89 | return attrib(FG_YELLOW) + event.getLevel().toString() + ' ' + attrib(OFF); 90 | } else if (event.getLevel() == Level.INFO) { 91 | return attrib(FG_GREEN) + event.getLevel().toString() + ' ' + attrib(OFF); 92 | } else if (event.getLevel() == Level.DEBUG) { 93 | return attrib(FG_CYAN) + event.getLevel().toString() + attrib(OFF); 94 | } else if (event.getLevel() == Level.TRACE) { 95 | return attrib(FG_BLUE) + event.getLevel().toString() + attrib(OFF); 96 | } 97 | return event.getLevel().toString(); 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/log4j/Log4jCSLogger.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging.log4j; 2 | 3 | import net.csdn.common.logging.support.AbstractCSLogger; 4 | import org.apache.log4j.Level; 5 | import org.apache.log4j.Logger; 6 | 7 | /** 8 | * BlogInfo: william 9 | * Date: 11-9-1 10 | * Time: 下午3:24 11 | */ 12 | public class Log4jCSLogger extends AbstractCSLogger { 13 | private final org.apache.log4j.Logger logger; 14 | 15 | public Log4jCSLogger(String prefix, Logger logger) { 16 | super(prefix); 17 | this.logger = logger; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return logger.getName(); 23 | } 24 | 25 | @Override 26 | public boolean isTraceEnabled() { 27 | return logger.isTraceEnabled(); 28 | } 29 | 30 | @Override 31 | public boolean isDebugEnabled() { 32 | return logger.isDebugEnabled(); 33 | } 34 | 35 | @Override 36 | public boolean isInfoEnabled() { 37 | return logger.isInfoEnabled(); 38 | } 39 | 40 | @Override 41 | public boolean isWarnEnabled() { 42 | return logger.isEnabledFor(Level.WARN); 43 | } 44 | 45 | @Override 46 | public boolean isErrorEnabled() { 47 | return logger.isEnabledFor(Level.ERROR); 48 | } 49 | 50 | @Override 51 | public boolean isHadooEnabled() { 52 | return logger.isEnabledFor(Log4jFactory.CSLogLevel.HADOO_LEVEL); 53 | } 54 | 55 | @Override 56 | protected void internalHadoo(String msg) { 57 | logger.log(Log4jFactory.CSLogLevel.HADOO_LEVEL, msg); 58 | } 59 | 60 | @Override 61 | protected void internalHadoo(String msg, Throwable cause) { 62 | logger.log(Log4jFactory.CSLogLevel.HADOO_LEVEL, msg, cause); 63 | } 64 | 65 | @Override 66 | protected void internalTrace(String msg) { 67 | logger.trace(msg); 68 | } 69 | 70 | @Override 71 | protected void internalTrace(String msg, Throwable cause) { 72 | logger.trace(msg, cause); 73 | } 74 | 75 | @Override 76 | protected void internalDebug(String msg) { 77 | logger.debug(msg); 78 | } 79 | 80 | @Override 81 | protected void internalDebug(String msg, Throwable cause) { 82 | logger.debug(msg, cause); 83 | } 84 | 85 | @Override 86 | protected void internalInfo(String msg) { 87 | logger.info(msg); 88 | } 89 | 90 | @Override 91 | protected void internalInfo(String msg, Throwable cause) { 92 | logger.info(msg, cause); 93 | } 94 | 95 | @Override 96 | protected void internalWarn(String msg) { 97 | logger.warn(msg); 98 | } 99 | 100 | @Override 101 | protected void internalWarn(String msg, Throwable cause) { 102 | logger.warn(msg, cause); 103 | } 104 | 105 | @Override 106 | protected void internalError(String msg) { 107 | logger.error(msg); 108 | } 109 | 110 | @Override 111 | protected void internalError(String msg, Throwable cause) { 112 | logger.error(msg, cause); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/log4j/Log4jFactory.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging.log4j; 2 | 3 | import net.csdn.common.logging.CSLogger; 4 | import net.csdn.common.logging.CSLoggerFactory; 5 | import org.apache.log4j.Level; 6 | import org.apache.log4j.Logger; 7 | import org.apache.log4j.Priority; 8 | import org.apache.log4j.net.SyslogAppender; 9 | 10 | /** 11 | * BlogInfo: william 12 | * Date: 11-9-1 13 | * Time: 下午3:44 14 | */ 15 | public class Log4jFactory extends CSLoggerFactory { 16 | @Override 17 | protected CSLogger newInstance(String prefix, String name) { 18 | final Logger logger = Logger.getLogger(name); 19 | return new Log4jCSLogger(prefix, logger); 20 | } 21 | 22 | private static class HADOOLevel extends Level { 23 | 24 | protected HADOOLevel(int level, String levelStr, int syslogEquivalent) { 25 | super(level, levelStr, syslogEquivalent); 26 | } 27 | } 28 | 29 | public interface CSLogLevel { 30 | public static final Level HADOO_LEVEL = new HADOOLevel(Priority.DEBUG_INT - 1, "HADOO", SyslogAppender.LOG_LOCAL0); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/log4j/LogConfigurator.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging.log4j; 2 | 3 | import com.google.common.collect.ImmutableMap; 4 | import net.csdn.common.collect.MapBuilder; 5 | import net.csdn.common.env.Environment; 6 | import net.csdn.common.settings.ImmutableSettings; 7 | import net.csdn.common.settings.Settings; 8 | import org.apache.log4j.PropertyConfigurator; 9 | 10 | import java.util.Map; 11 | import java.util.Properties; 12 | 13 | import static net.csdn.common.settings.ImmutableSettings.settingsBuilder; 14 | 15 | /** 16 | * BlogInfo: william 17 | * Date: 11-9-1 18 | * Time: 下午2:11 19 | */ 20 | public class LogConfigurator { 21 | private static boolean loaded; 22 | 23 | private static ImmutableMap replacements = new MapBuilder() 24 | .put("console", "net.csdn.common.logging.log4j.ConsoleAppender") 25 | .put("async", "org.apache.log4j.AsyncAppender") 26 | .put("dailyRollingFile", "org.apache.log4j.DailyRollingFileAppender") 27 | .put("externallyRolledFile", "org.apache.log4j.ExternallyRolledFileAppender") 28 | .put("file", "org.apache.log4j.FileAppender") 29 | .put("hadoo", "org.apache.log4j.FileAppender") 30 | .put("jdbc", "org.apache.log4j.jdbc.JDBCAppender") 31 | .put("jms", "org.apache.log4j.net.JMSAppender") 32 | .put("lf5", "org.apache.log4j.lf5.LF5Appender") 33 | .put("ntevent", "org.apache.log4j.nt.NTEventLogAppender") 34 | .put("null", "org.apache.log4j.NullAppender") 35 | .put("rollingFile", "org.apache.log4j.RollingFileAppender") 36 | .put("smtp", "org.apache.log4j.net.SMTPAppender") 37 | .put("socket", "org.apache.log4j.net.SocketAppender") 38 | .put("socketHub", "org.apache.log4j.net.SocketHubAppender") 39 | .put("syslog", "org.apache.log4j.net.SyslogAppender") 40 | .put("telnet", "org.apache.log4j.net.TelnetAppender") 41 | // layouts 42 | .put("simple", "org.apache.log4j.SimpleLayout") 43 | .put("html", "org.apache.log4j.HTMLLayout") 44 | .put("pattern", "org.apache.log4j.PatternLayout") 45 | .put("consolePattern", "net.csdn.common.logging.log4j.JLinePatternLayout") 46 | .put("ttcc", "org.apache.log4j.TTCCLayout") 47 | .put("xml", "org.apache.log4j.XMLLayout") 48 | .immutableMap(); 49 | 50 | public static void configure(Settings settings) { 51 | if (loaded) { 52 | return; 53 | } 54 | loaded = true; 55 | Environment environment = new Environment(settings); 56 | ImmutableSettings.Builder settingsBuilder = settingsBuilder().put(settings); 57 | 58 | settingsBuilder.loadFromUrl(environment.resolveConfig("logging.yml")) 59 | .replacePropertyPlaceholders(); 60 | 61 | Properties props = new Properties(); 62 | for (Map.Entry entry : settingsBuilder.build().getAsMap().entrySet()) { 63 | String key = "log4j." + entry.getKey(); 64 | String value = entry.getValue(); 65 | 66 | if (replacements.containsKey(value)) { 67 | value = replacements.get(value); 68 | } 69 | 70 | if (key.endsWith(".value")) { 71 | props.setProperty(key.substring(0, key.length() - ".value".length()), value); 72 | } else if (key.endsWith(".type")) { 73 | props.setProperty(key.substring(0, key.length() - ".type".length()), value); 74 | } else { 75 | props.setProperty(key, value); 76 | } 77 | } 78 | PropertyConfigurator.configure(props); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/support/AbstractCSLogger.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging.support; 2 | 3 | import net.csdn.common.logging.CSLogger; 4 | 5 | /** 6 | * BlogInfo: william 7 | * Date: 11-9-1 8 | * Time: 下午2:39 9 | */ 10 | public abstract class AbstractCSLogger implements CSLogger { 11 | private final String prefix; 12 | 13 | protected AbstractCSLogger(String prefix) { 14 | this.prefix = prefix; 15 | } 16 | 17 | @Override 18 | public String getPrefix() { 19 | return this.prefix; 20 | } 21 | 22 | 23 | @Override 24 | public void hadoo(String msg, Object... params) { 25 | if (isHadooEnabled()) { 26 | internalHadoo(MessageFormat.format(msg, params)); 27 | } 28 | } 29 | 30 | protected abstract void internalHadoo(String msg); 31 | 32 | @Override 33 | public void hadoo(String msg, Throwable cause, Object... params) { 34 | if (isTraceEnabled()) { 35 | internalHadoo(MessageFormat.format(msg, params), cause); 36 | } 37 | } 38 | 39 | protected abstract void internalHadoo(String msg, Throwable cause); 40 | 41 | 42 | @Override 43 | public void trace(String msg, Object... params) { 44 | if (isTraceEnabled()) { 45 | internalTrace(MessageFormat.format(msg, params)); 46 | } 47 | } 48 | 49 | protected abstract void internalTrace(String msg); 50 | 51 | @Override 52 | public void trace(String msg, Throwable cause, Object... params) { 53 | if (isTraceEnabled()) { 54 | internalTrace(MessageFormat.format(msg, params), cause); 55 | } 56 | } 57 | 58 | protected abstract void internalTrace(String msg, Throwable cause); 59 | 60 | 61 | @Override 62 | public void debug(String msg, Object... params) { 63 | if (isDebugEnabled()) { 64 | internalDebug(MessageFormat.format(msg, params)); 65 | } 66 | } 67 | 68 | protected abstract void internalDebug(String msg); 69 | 70 | @Override 71 | public void debug(String msg, Throwable cause, Object... params) { 72 | if (isDebugEnabled()) { 73 | internalDebug(MessageFormat.format(msg, params), cause); 74 | } 75 | } 76 | 77 | protected abstract void internalDebug(String msg, Throwable cause); 78 | 79 | 80 | @Override 81 | public void info(String msg, Object... params) { 82 | if (isInfoEnabled()) { 83 | internalInfo(MessageFormat.format(msg, params)); 84 | } 85 | } 86 | 87 | protected abstract void internalInfo(String msg); 88 | 89 | @Override 90 | public void info(String msg, Throwable cause, Object... params) { 91 | if (isInfoEnabled()) { 92 | internalInfo(MessageFormat.format(msg, params), cause); 93 | } 94 | } 95 | 96 | protected abstract void internalInfo(String msg, Throwable cause); 97 | 98 | 99 | @Override 100 | public void warn(String msg, Object... params) { 101 | if (isWarnEnabled()) { 102 | internalWarn(MessageFormat.format(msg, params)); 103 | } 104 | } 105 | 106 | protected abstract void internalWarn(String msg); 107 | 108 | @Override 109 | public void warn(String msg, Throwable cause, Object... params) { 110 | if (isWarnEnabled()) { 111 | internalWarn(MessageFormat.format(msg, params), cause); 112 | } 113 | } 114 | 115 | protected abstract void internalWarn(String msg, Throwable cause); 116 | 117 | 118 | @Override 119 | public void error(String msg, Object... params) { 120 | if (isErrorEnabled()) { 121 | internalError(MessageFormat.format(msg, params)); 122 | } 123 | } 124 | 125 | protected abstract void internalError(String msg); 126 | 127 | @Override 128 | public void error(String msg, Throwable cause, Object... params) { 129 | if (isErrorEnabled()) { 130 | internalError(MessageFormat.format(msg, params), cause); 131 | } 132 | } 133 | 134 | protected abstract void internalError(String msg, Throwable cause); 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/logging/support/MessageFormat.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.logging.support; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * BlogInfo: william 8 | * Date: 11-9-1 9 | * Time: 下午2:41 10 | */ 11 | public class MessageFormat { 12 | static final char DELIM_START = '{'; 13 | static final char DELIM_STOP = '}'; 14 | static final String DELIM_STR = "{}"; 15 | private static final char ESCAPE_CHAR = '\\'; 16 | 17 | public static String format(final String messagePattern, final Object... argArray) { 18 | return sFormat(null, messagePattern, argArray); 19 | } 20 | 21 | public static void main(String[] args) { 22 | System.out.println(format("http://tag.api.csdn.net/docTag/{}/insert2", "news")); 23 | } 24 | 25 | public static String copyMessagesFromException(Exception e) { 26 | //输出详细错误日志 27 | StringBuffer message = new StringBuffer(); 28 | StackTraceElement[] stackTraces = e.getStackTrace(); 29 | for (StackTraceElement stackTraceElement : stackTraces) { 30 | message.append(stackTraceElement.toString() + "\n"); 31 | } 32 | return message.toString(); 33 | } 34 | 35 | public static String sFormat(final String prefix, final String messagePattern, final Object... argArray) { 36 | if (messagePattern == null) { 37 | return null; 38 | } 39 | if (argArray == null) { 40 | if (prefix == null) { 41 | return messagePattern; 42 | } else { 43 | return prefix + messagePattern; 44 | } 45 | } 46 | int i = 0; 47 | int j; 48 | StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50); 49 | if (prefix != null) { 50 | sbuf.append(prefix); 51 | } 52 | 53 | for (int L = 0; L < argArray.length; L++) { 54 | 55 | j = messagePattern.indexOf(DELIM_STR, i); 56 | 57 | if (j == -1) { 58 | // no more variables 59 | if (i == 0) { // this is a simple string 60 | return messagePattern; 61 | } else { // add the tail string which contains no variables and return 62 | // the result. 63 | sbuf.append(messagePattern.substring(i, messagePattern.length())); 64 | return sbuf.toString(); 65 | } 66 | } else { 67 | if (isEscapedDelimeter(messagePattern, j)) { 68 | if (!isDoubleEscaped(messagePattern, j)) { 69 | L--; // DELIM_START was escaped, thus should not be incremented 70 | sbuf.append(messagePattern.substring(i, j - 1)); 71 | sbuf.append(DELIM_START); 72 | i = j + 1; 73 | } else { 74 | // The escape character preceding the delimiter start is 75 | // itself escaped: "abc x:\\{}" 76 | // we have to consume one backward slash 77 | sbuf.append(messagePattern.substring(i, j - 1)); 78 | deeplyAppendParameter(sbuf, argArray[L], new HashMap()); 79 | i = j + 2; 80 | } 81 | } else { 82 | // normal case 83 | sbuf.append(messagePattern.substring(i, j)); 84 | deeplyAppendParameter(sbuf, argArray[L], new HashMap()); 85 | i = j + 2; 86 | } 87 | } 88 | } 89 | // append the characters following the last {} pair. 90 | sbuf.append(messagePattern.substring(i, messagePattern.length())); 91 | return sbuf.toString(); 92 | } 93 | 94 | static boolean isEscapedDelimeter(String messagePattern, 95 | int delimeterStartIndex) { 96 | 97 | if (delimeterStartIndex == 0) { 98 | return false; 99 | } 100 | char potentialEscape = messagePattern.charAt(delimeterStartIndex - 1); 101 | if (potentialEscape == ESCAPE_CHAR) { 102 | return true; 103 | } else { 104 | return false; 105 | } 106 | } 107 | 108 | static boolean isDoubleEscaped(String messagePattern, int delimeterStartIndex) { 109 | if (delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR) { 110 | return true; 111 | } else { 112 | return false; 113 | } 114 | } 115 | 116 | private static void deeplyAppendParameter(StringBuffer sbuf, Object o, Map seenMap) { 117 | if (o == null) { 118 | sbuf.append("null"); 119 | return; 120 | } 121 | if (!o.getClass().isArray()) { 122 | safeObjectAppend(sbuf, o); 123 | } else { 124 | // check for primitive array types because they 125 | // unfortunately cannot be cast to Object[] 126 | if (o instanceof boolean[]) { 127 | booleanArrayAppend(sbuf, (boolean[]) o); 128 | } else if (o instanceof byte[]) { 129 | byteArrayAppend(sbuf, (byte[]) o); 130 | } else if (o instanceof char[]) { 131 | charArrayAppend(sbuf, (char[]) o); 132 | } else if (o instanceof short[]) { 133 | shortArrayAppend(sbuf, (short[]) o); 134 | } else if (o instanceof int[]) { 135 | intArrayAppend(sbuf, (int[]) o); 136 | } else if (o instanceof long[]) { 137 | longArrayAppend(sbuf, (long[]) o); 138 | } else if (o instanceof float[]) { 139 | floatArrayAppend(sbuf, (float[]) o); 140 | } else if (o instanceof double[]) { 141 | doubleArrayAppend(sbuf, (double[]) o); 142 | } else { 143 | objectArrayAppend(sbuf, (Object[]) o, seenMap); 144 | } 145 | } 146 | } 147 | 148 | private static void safeObjectAppend(StringBuffer sbuf, Object o) { 149 | try { 150 | String oAsString = o.toString(); 151 | sbuf.append(oAsString); 152 | } catch (Throwable t) { 153 | System.err.println("Logger: Failed toString() invocation on an object of type [" + o.getClass().getName() + "]"); 154 | t.printStackTrace(); 155 | sbuf.append("[FAILED toString()]"); 156 | } 157 | 158 | } 159 | 160 | private static void objectArrayAppend(StringBuffer sbuf, Object[] a, Map seenMap) { 161 | sbuf.append('['); 162 | if (!seenMap.containsKey(a)) { 163 | seenMap.put(a, null); 164 | final int len = a.length; 165 | for (int i = 0; i < len; i++) { 166 | deeplyAppendParameter(sbuf, a[i], seenMap); 167 | if (i != len - 1) 168 | sbuf.append(", "); 169 | } 170 | // allow repeats in siblings 171 | seenMap.remove(a); 172 | } else { 173 | sbuf.append("..."); 174 | } 175 | sbuf.append(']'); 176 | } 177 | 178 | private static void booleanArrayAppend(StringBuffer sbuf, boolean[] a) { 179 | sbuf.append('['); 180 | final int len = a.length; 181 | for (int i = 0; i < len; i++) { 182 | sbuf.append(a[i]); 183 | if (i != len - 1) 184 | sbuf.append(", "); 185 | } 186 | sbuf.append(']'); 187 | } 188 | 189 | private static void byteArrayAppend(StringBuffer sbuf, byte[] a) { 190 | sbuf.append('['); 191 | final int len = a.length; 192 | for (int i = 0; i < len; i++) { 193 | sbuf.append(a[i]); 194 | if (i != len - 1) 195 | sbuf.append(", "); 196 | } 197 | sbuf.append(']'); 198 | } 199 | 200 | private static void charArrayAppend(StringBuffer sbuf, char[] a) { 201 | sbuf.append('['); 202 | final int len = a.length; 203 | for (int i = 0; i < len; i++) { 204 | sbuf.append(a[i]); 205 | if (i != len - 1) 206 | sbuf.append(", "); 207 | } 208 | sbuf.append(']'); 209 | } 210 | 211 | private static void shortArrayAppend(StringBuffer sbuf, short[] a) { 212 | sbuf.append('['); 213 | final int len = a.length; 214 | for (int i = 0; i < len; i++) { 215 | sbuf.append(a[i]); 216 | if (i != len - 1) 217 | sbuf.append(", "); 218 | } 219 | sbuf.append(']'); 220 | } 221 | 222 | private static void intArrayAppend(StringBuffer sbuf, int[] a) { 223 | sbuf.append('['); 224 | final int len = a.length; 225 | for (int i = 0; i < len; i++) { 226 | sbuf.append(a[i]); 227 | if (i != len - 1) 228 | sbuf.append(", "); 229 | } 230 | sbuf.append(']'); 231 | } 232 | 233 | private static void longArrayAppend(StringBuffer sbuf, long[] a) { 234 | sbuf.append('['); 235 | final int len = a.length; 236 | for (int i = 0; i < len; i++) { 237 | sbuf.append(a[i]); 238 | if (i != len - 1) 239 | sbuf.append(", "); 240 | } 241 | sbuf.append(']'); 242 | } 243 | 244 | private static void floatArrayAppend(StringBuffer sbuf, float[] a) { 245 | sbuf.append('['); 246 | final int len = a.length; 247 | for (int i = 0; i < len; i++) { 248 | sbuf.append(a[i]); 249 | if (i != len - 1) 250 | sbuf.append(", "); 251 | } 252 | sbuf.append(']'); 253 | } 254 | 255 | private static void doubleArrayAppend(StringBuffer sbuf, double[] a) { 256 | sbuf.append('['); 257 | final int len = a.length; 258 | for (int i = 0; i < len; i++) { 259 | sbuf.append(a[i]); 260 | if (i != len - 1) 261 | sbuf.append(", "); 262 | } 263 | sbuf.append(']'); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/network/NetworkUtils.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.network; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.csdn.common.logging.CSLogger; 5 | import net.csdn.common.logging.Loggers; 6 | 7 | import java.lang.reflect.Method; 8 | import java.net.*; 9 | import java.util.*; 10 | 11 | /** 12 | * BlogInfo: william 13 | * Date: 11-12-6 14 | * Time: 上午10:29 15 | * 主要获取本机内网IP.避免需要手动在配置文件配置本机IP内网地址。 16 | */ 17 | public class NetworkUtils { 18 | private final static CSLogger logger = Loggers.getLogger(NetworkUtils.class); 19 | 20 | public static enum StackType { 21 | IPv4, IPv6, Unknown 22 | } 23 | 24 | public static void main(String[] args) { 25 | 26 | System.out.println(intranet_ip.getHostAddress()); 27 | 28 | 29 | } 30 | 31 | public static final String IPv4_SETTING = "java.net.preferIPv4Stack"; 32 | public static final String IPv6_SETTING = "java.net.preferIPv6Addresses"; 33 | 34 | public static final String NON_LOOPBACK_ADDRESS = "non_loopback_address"; 35 | 36 | 37 | private static InetAddress localAddress; 38 | private static InetAddress intranet_ip; 39 | 40 | static { 41 | InetAddress localAddressX = null; 42 | InetAddress intranet_ip_x = null; 43 | try { 44 | localAddressX = InetAddress.getLocalHost(); 45 | } catch (Exception e) { 46 | logger.warn("Failed to find local hostAndPort", e); 47 | } 48 | 49 | localAddress = localAddressX; 50 | 51 | Collection inetAddresses = getAllAvailableAddresses(); 52 | for (InetAddress ia : inetAddresses) { 53 | if (ia.getHostAddress().startsWith("192.168")) { 54 | intranet_ip = ia; 55 | break; 56 | } 57 | } 58 | if (intranet_ip == null) { 59 | try { 60 | intranet_ip = getFirstNonLoopbackAddress(StackType.IPv4); 61 | } catch (Exception e) { 62 | 63 | } 64 | } 65 | } 66 | 67 | public static InetAddress local_address() { 68 | return localAddress; 69 | } 70 | 71 | public static InetAddress intranet_ip() { 72 | return intranet_ip; 73 | } 74 | 75 | 76 | public static boolean isIPv4() { 77 | return System.getProperty("java.net.preferIPv4Stack") != null && System.getProperty("java.net.preferIPv4Stack").equals("true"); 78 | } 79 | 80 | public static InetAddress getFirstNonLoopbackAddress(StackType ip_version) { 81 | try { 82 | InetAddress address = null; 83 | 84 | Enumeration intfs = NetworkInterface.getNetworkInterfaces(); 85 | 86 | 87 | List intfsList = Lists.newArrayList(); 88 | while (intfs.hasMoreElements()) { 89 | intfsList.add((NetworkInterface) intfs.nextElement()); 90 | } 91 | 92 | // order by index, assuming first ones are more interesting 93 | try { 94 | final Method getIndexMethod = NetworkInterface.class.getDeclaredMethod("getIndex"); 95 | getIndexMethod.setAccessible(true); 96 | 97 | Collections.sort(intfsList, new Comparator() { 98 | @Override 99 | public int compare(NetworkInterface o1, NetworkInterface o2) { 100 | try { 101 | return ((Integer) getIndexMethod.invoke(o1)).intValue() - ((Integer) getIndexMethod.invoke(o2)).intValue(); 102 | } catch (Exception e) { 103 | throw new IllegalArgumentException("failed to fetch index of network interface"); 104 | } 105 | } 106 | }); 107 | } catch (Exception e) { 108 | // ignore 109 | } 110 | 111 | for (NetworkInterface intf : intfsList) { 112 | if (!intf.isUp() || intf.isLoopback()) 113 | continue; 114 | address = getFirstNonLoopbackAddress(intf, ip_version); 115 | if (address != null) { 116 | return address; 117 | } 118 | } 119 | } catch (SocketException e) { 120 | e.printStackTrace(); 121 | } 122 | 123 | return null; 124 | } 125 | 126 | public static InetAddress getFirstNonLoopbackAddress(NetworkInterface intf, StackType ipVersion) throws SocketException { 127 | if (intf == null) 128 | throw new IllegalArgumentException("Network interface pointer is null"); 129 | 130 | for (Enumeration addresses = intf.getInetAddresses(); addresses.hasMoreElements(); ) { 131 | InetAddress address = (InetAddress) addresses.nextElement(); 132 | if (!address.isLoopbackAddress()) { 133 | if ((address instanceof Inet4Address && ipVersion == StackType.IPv4) || 134 | (address instanceof Inet6Address && ipVersion == StackType.IPv6)) 135 | return address; 136 | } 137 | } 138 | return null; 139 | } 140 | 141 | public static List getAllAvailableInterfaces() throws SocketException { 142 | List allInterfaces = new ArrayList(10); 143 | NetworkInterface intf; 144 | for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { 145 | intf = (NetworkInterface) en.nextElement(); 146 | allInterfaces.add(intf); 147 | } 148 | return allInterfaces; 149 | } 150 | 151 | public static Collection getAllAvailableAddresses() { 152 | Set retval = new HashSet(); 153 | Enumeration en; 154 | 155 | try { 156 | en = NetworkInterface.getNetworkInterfaces(); 157 | if (en == null) 158 | return retval; 159 | while (en.hasMoreElements()) { 160 | NetworkInterface intf = (NetworkInterface) en.nextElement(); 161 | Enumeration addrs = intf.getInetAddresses(); 162 | while (addrs.hasMoreElements()) 163 | retval.add(addrs.nextElement()); 164 | } 165 | } catch (SocketException e) { 166 | logger.warn("Failed to derive all available interfaces", e); 167 | } 168 | 169 | return retval; 170 | } 171 | 172 | private NetworkUtils() { 173 | 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/param/ParamBinding.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.param; 2 | 3 | 4 | import net.csdn.common.exception.ArgumentErrorException; 5 | import org.apache.commons.beanutils.BeanUtils; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | import static net.csdn.common.collections.WowCollections.map; 11 | 12 | /** 13 | * User: WilliamZhu 14 | * Date: 12-7-4 15 | * Time: 下午7:40 16 | */ 17 | public class ParamBinding { 18 | 19 | /*支持如下类型的参数绑定,目前只支持两级接口。 20 | a=8 21 | b.c=12 22 | b[c]=12 23 | [] 是为了兼容rails的表单风格。 "."则是传统Java风格 24 | */ 25 | private Map> _children = new HashMap(); 26 | private Map rootValues = new HashMap(); 27 | private final static String keyPartDelimiter = "[\\.\\[\\]]+"; 28 | 29 | public void toModel(Object model) { 30 | for (Map.Entry entry : rootValues.entrySet()) { 31 | try { 32 | BeanUtils.setProperty(model, entry.getKey(), entry.getValue()); 33 | } catch (Exception e) { 34 | 35 | } 36 | } 37 | for (Map.Entry> entry : _children.entrySet()) { 38 | Object newModel; 39 | try { 40 | Object obj = BeanUtils.getProperty(model, entry.getKey()); 41 | if (obj != null) { 42 | newModel = obj; 43 | } else { 44 | Class clzz = model.getClass().getDeclaredField(entry.getKey()).getType(); 45 | newModel = clzz.newInstance(); 46 | } 47 | 48 | } catch (Exception e) { 49 | e.printStackTrace(); 50 | continue; 51 | } 52 | for (Map.Entry entry1 : entry.getValue().entrySet()) { 53 | try { 54 | BeanUtils.setProperty(newModel, entry1.getKey(), entry1.getValue()); 55 | BeanUtils.setProperty(model, entry.getKey(), newModel); 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | } 61 | } 62 | 63 | public void parse(Map params) { 64 | for (Map.Entry entry : params.entrySet()) { 65 | String[] keys = entry.getKey().split(keyPartDelimiter); 66 | if (keys.length > 2) throw new ArgumentErrorException("不支持超过三级层次的参数传递"); 67 | if (keys.length == 1) { 68 | rootValues.put(keys[0], entry.getValue()); 69 | } else { 70 | if (_children.get(keys[0]) == null) { 71 | _children.put(keys[0], map(keys[1], entry.getValue())); 72 | } else { 73 | _children.get(keys[0]).put(keys[1], entry.getValue()); 74 | _children.put(keys[0], _children.get(keys[0])); 75 | } 76 | 77 | } 78 | } 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/path/PathTrie.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.path; 2 | 3 | import com.google.common.collect.ImmutableMap; 4 | 5 | import java.util.Map; 6 | import java.util.regex.Pattern; 7 | 8 | import static net.csdn.common.collect.MapBuilder.newMapBuilder; 9 | 10 | /** 11 | * BlogInfo: william 12 | * Date: 11-9-2 13 | * Time: 下午4:39 14 | */ 15 | public class PathTrie { 16 | 17 | private final TrieNode root; 18 | private final Pattern pattern; 19 | private T rootValue; 20 | 21 | 22 | public PathTrie() { 23 | this("/", "*"); 24 | } 25 | 26 | public PathTrie(String separator, String wildcard) { 27 | pattern = Pattern.compile(separator); 28 | root = new TrieNode(separator, null, null, wildcard); 29 | } 30 | 31 | public void insert(String path, T value) { 32 | String[] strings = pattern.split(path); 33 | if (strings.length == 0) { 34 | rootValue = value; 35 | return; 36 | } 37 | int index = 0; 38 | // supports initial delimiter. 39 | if (strings.length > 0 && strings[0].isEmpty()) { 40 | index = 1; 41 | } 42 | root.insert(strings, index, value); 43 | } 44 | 45 | 46 | public class TrieNode { 47 | private transient String key; 48 | private transient T value; 49 | private boolean isWildcard; 50 | private final String wildcard; 51 | private transient String namedWildcard; 52 | 53 | private ImmutableMap> children; 54 | 55 | private final TrieNode parent; 56 | 57 | public TrieNode(String key, T value, TrieNode parent, String wildcard) { 58 | this.key = key; 59 | this.wildcard = wildcard; 60 | this.isWildcard = (key.equals(wildcard)); 61 | this.parent = parent; 62 | this.value = value; 63 | this.children = ImmutableMap.of(); 64 | if (isNamedWildcard(key)) { 65 | namedWildcard = key.substring(key.indexOf('{') + 1, key.indexOf('}')); 66 | } else { 67 | namedWildcard = null; 68 | } 69 | } 70 | 71 | 72 | public synchronized void addChild(TrieNode child) { 73 | children = newMapBuilder(children).put(child.key, child).immutableMap(); 74 | } 75 | 76 | public TrieNode getChild(String key) { 77 | return children.get(key); 78 | } 79 | 80 | public synchronized void insert(String[] path, int index, T value) { 81 | if (index >= path.length) return; 82 | 83 | String token = path[index]; 84 | String key = token; 85 | if (isNamedWildcard(token)) { 86 | key = wildcard; 87 | } 88 | TrieNode node = children.get(key); 89 | if (node == null) { 90 | if (index == (path.length - 1)) { 91 | node = new TrieNode(token, value, this, wildcard); 92 | } else { 93 | node = new TrieNode(token, null, this, wildcard); 94 | } 95 | children = newMapBuilder(children).put(key, node).immutableMap(); 96 | } else { 97 | if (isNamedWildcard(token)) { 98 | node.updateKeyWithNamedWildcard(token); 99 | } 100 | 101 | if (index == (path.length - 1)) { 102 | assert (node.value == null || node.value == value); 103 | if (node.value == null) { 104 | node.value = value; 105 | } 106 | } 107 | } 108 | node.insert(path, index + 1, value); 109 | } 110 | 111 | public T retrieve(String[] path, int index, Map params) { 112 | if (index >= path.length) 113 | return null; 114 | 115 | String token = path[index]; 116 | TrieNode node = children.get(token); 117 | boolean usedWildcard = false; 118 | if (node == null) { 119 | node = children.get(wildcard); 120 | if (node == null) { 121 | return null; 122 | } else { 123 | usedWildcard = true; 124 | if (params != null && node.isNamedWildcard()) { 125 | put(params, node.namedWildcard(), token); 126 | } 127 | } 128 | } 129 | 130 | if (index == (path.length - 1)) { 131 | return node.value; 132 | } 133 | 134 | T res = node.retrieve(path, index + 1, params); 135 | if (res == null && !usedWildcard) { 136 | node = children.get(wildcard); 137 | if (node != null) { 138 | if (params != null && node.isNamedWildcard()) { 139 | put(params, node.namedWildcard(), token); 140 | } 141 | res = node.retrieve(path, index + 1, params); 142 | } 143 | } 144 | 145 | return res; 146 | } 147 | 148 | private void put(Map params, String key, String value) { 149 | params.put(key, value); 150 | } 151 | 152 | public void updateKeyWithNamedWildcard(String key) { 153 | this.key = key; 154 | namedWildcard = key.substring(key.indexOf('{') + 1, key.indexOf('}')); 155 | } 156 | 157 | public boolean isWildcard() { 158 | return isWildcard; 159 | } 160 | 161 | private boolean isNamedWildcard(String key) { 162 | return key.indexOf('{') != -1 && key.indexOf('}') != -1; 163 | } 164 | 165 | private String namedWildcard() { 166 | return namedWildcard; 167 | } 168 | 169 | private boolean isNamedWildcard() { 170 | return namedWildcard != null; 171 | } 172 | 173 | } 174 | 175 | public T retrieve(String path) { 176 | return retrieve(path, null); 177 | } 178 | 179 | public T retrieve(String path, Map params) { 180 | if (path.length() == 0) { 181 | return rootValue; 182 | } 183 | String[] strings = pattern.split(path); 184 | if (strings.length == 0) { 185 | return rootValue; 186 | } 187 | int index = 0; 188 | // supports initial delimiter. 189 | if (strings.length > 0 && strings[0].isEmpty()) { 190 | index = 1; 191 | } 192 | return root.retrieve(strings, index, params); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/path/Url.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.path; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.csdn.common.collect.Tuple; 5 | 6 | import java.net.URI; 7 | import java.net.URISyntaxException; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * BlogInfo: william 14 | * Date: 11-9-26 15 | * Time: 上午10:31 16 | */ 17 | public class Url { 18 | private String schema = "http"; 19 | private String host; 20 | private List path = Lists.newArrayList(); 21 | private int port = 80; 22 | private List query = Lists.newArrayList(); 23 | 24 | public Url() { 25 | } 26 | 27 | public Url(URI uri) { 28 | this.schema = uri.getScheme(); 29 | host = uri.getHost(); 30 | parsePath(uri.getPath()); 31 | parseQuery(uri.getQuery()); 32 | this.port = uri.getPort() == -1 ? 80 : uri.getPort(); 33 | 34 | } 35 | 36 | 37 | public static List urls(String[] hosts, String path, String... queries) { 38 | List urls = new ArrayList(hosts.length); 39 | for (String host : hosts) { 40 | Url url = new Url(); 41 | url.hostAndPort(host); 42 | url.path(path); 43 | if (queries != null) { 44 | for (String query : queries) { 45 | url.query(query); 46 | } 47 | } 48 | urls.add(url); 49 | } 50 | return urls; 51 | } 52 | 53 | public static List urls(String[] hosts, String path, Map params, String... queries) { 54 | List urls = new ArrayList(hosts.length); 55 | for (String host : hosts) { 56 | Url url = new Url(); 57 | url.hostAndPort(host); 58 | url.path(path); 59 | if (params != null) { 60 | url.query(params); 61 | } 62 | 63 | if (queries != null) { 64 | for (String query : queries) { 65 | url.query(query); 66 | } 67 | } 68 | urls.add(url); 69 | } 70 | return urls; 71 | } 72 | 73 | private void parsePath(String _path) { 74 | if (_path == null) return; 75 | String[] paths = _path.split("/"); 76 | for (String temp : paths) { 77 | if (temp.isEmpty()) continue; 78 | path.add(temp); 79 | } 80 | } 81 | 82 | private void parseQuery(String _query) { 83 | if (_query == null) return; 84 | String[] queries = _query.split("&"); 85 | for (String temp : queries) { 86 | if (temp.isEmpty() || !temp.contains("=")) continue; 87 | String[] key_pair = temp.split("="); 88 | query.add(new Tuple(key_pair[0], key_pair[1])); 89 | } 90 | } 91 | 92 | 93 | public Url hostAndPort(String hostAndPort) { 94 | String[] hostAndPortArray = hostAndPort.split(":"); 95 | this.host = hostAndPortArray[0]; 96 | this.port = Integer.parseInt(hostAndPortArray[1]); 97 | return this; 98 | 99 | } 100 | 101 | public String hostAndPort() { 102 | return host + ":" + port; 103 | 104 | } 105 | 106 | public Url query(String query) { 107 | parseQuery(query); 108 | return this; 109 | } 110 | 111 | public Url query(Map _query) { 112 | for (Object key : _query.keySet()) { 113 | addParam(key.toString(), _query.get(key).toString()); 114 | } 115 | return this; 116 | } 117 | 118 | public Url path(String path) { 119 | parsePath(path); 120 | return this; 121 | } 122 | 123 | public Url(String url) { 124 | this(URI.create(url)); 125 | } 126 | 127 | public Url addParam(String key, String value) { 128 | query.add(new Tuple(key, value)); 129 | return this; 130 | } 131 | 132 | public String getPath() { 133 | String result = ""; 134 | for (String temp : path) { 135 | result += ("/" + temp); 136 | } 137 | return result; 138 | } 139 | 140 | public String getQuery() { 141 | String result = ""; 142 | for (Tuple temp : query) { 143 | result += ("&" + temp.v1() + "=" + temp.v2()); 144 | } 145 | if (result.isEmpty()) return result; 146 | return result.substring(1); 147 | } 148 | 149 | @Override 150 | public String toString() { 151 | String url = schema + "://" + host + ":" + port + getPath(); 152 | String query = getQuery(); 153 | if (query != null && !query.isEmpty()) { 154 | url += ("?" + query); 155 | } 156 | return url; 157 | } 158 | 159 | public URI toURI() { 160 | try { 161 | return new URI(toString()); 162 | } catch (URISyntaxException e) { 163 | e.printStackTrace(); 164 | } 165 | return null; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/property/PropertyPlaceholder.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.property; 2 | 3 | import com.google.common.base.Preconditions; 4 | import net.csdn.common.Strings; 5 | 6 | import java.util.HashSet; 7 | import java.util.Properties; 8 | import java.util.Set; 9 | 10 | /** 11 | * BlogInfo: william 12 | * Date: 11-9-2 13 | * Time: 上午11:32 14 | */ 15 | public class PropertyPlaceholder { 16 | 17 | private final String placeholderPrefix; 18 | 19 | private final String placeholderSuffix; 20 | 21 | private final boolean ignoreUnresolvablePlaceholders; 22 | 23 | /** 24 | * Creates a new PropertyPlaceholderHelper that uses the supplied prefix and suffix. Unresolvable 25 | * placeholders are ignored. 26 | * 27 | * @param placeholderPrefix the prefix that denotes the start of a placeholder. 28 | * @param placeholderSuffix the suffix that denotes the end of a placeholder. 29 | */ 30 | public PropertyPlaceholder(String placeholderPrefix, String placeholderSuffix) { 31 | this(placeholderPrefix, placeholderSuffix, true); 32 | } 33 | 34 | /** 35 | * Creates a new PropertyPlaceholderHelper that uses the supplied prefix and suffix. 36 | * 37 | * @param placeholderPrefix the prefix that denotes the start of a placeholder. 38 | * @param placeholderSuffix the suffix that denotes the end of a placeholder. 39 | * @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should be ignored 40 | * (true) or cause an exception (false). 41 | */ 42 | public PropertyPlaceholder(String placeholderPrefix, String placeholderSuffix, 43 | boolean ignoreUnresolvablePlaceholders) { 44 | Preconditions.checkNotNull(placeholderPrefix, "Argument 'placeholderPrefix' must not be null."); 45 | Preconditions.checkNotNull(placeholderSuffix, "Argument 'placeholderSuffix' must not be null."); 46 | this.placeholderPrefix = placeholderPrefix; 47 | this.placeholderSuffix = placeholderSuffix; 48 | this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; 49 | } 50 | 51 | /** 52 | * Replaces all placeholders of format ${name} with the corresponding property from the supplied {@link 53 | * java.util.Properties}. 54 | * 55 | * @param value the value containing the placeholders to be replaced. 56 | * @param properties the Properties to use for replacement. 57 | * @return the supplied value with placeholders replaced inline. 58 | */ 59 | public String replacePlaceholders(String value, final Properties properties) { 60 | Preconditions.checkNotNull(properties, "Argument 'properties' must not be null."); 61 | return replacePlaceholders(value, new PlaceholderResolver() { 62 | 63 | public String resolvePlaceholder(String placeholderName) { 64 | return properties.getProperty(placeholderName); 65 | } 66 | }); 67 | } 68 | 69 | /** 70 | * Replaces all placeholders of format ${name} with the value returned from the supplied {@link 71 | * PlaceholderResolver}. 72 | * 73 | * @param value the value containing the placeholders to be replaced. 74 | * @param placeholderResolver the PlaceholderResolver to use for replacement. 75 | * @return the supplied value with placeholders replaced inline. 76 | */ 77 | public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) { 78 | Preconditions.checkNotNull(value, "Argument 'value' must not be null."); 79 | return parseStringValue(value, placeholderResolver, new HashSet()); 80 | } 81 | 82 | protected String parseStringValue(String strVal, PlaceholderResolver placeholderResolver, 83 | Set visitedPlaceholders) { 84 | StringBuilder buf = new StringBuilder(strVal); 85 | 86 | int startIndex = strVal.indexOf(this.placeholderPrefix); 87 | while (startIndex != -1) { 88 | int endIndex = findPlaceholderEndIndex(buf, startIndex); 89 | if (endIndex != -1) { 90 | String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex); 91 | if (!visitedPlaceholders.add(placeholder)) { 92 | throw new IllegalArgumentException( 93 | "Circular placeholder reference '" + placeholder + "' in property definitions"); 94 | } 95 | // Recursive invocation, parsing placeholders contained in the placeholder key. 96 | placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); 97 | 98 | // Now obtain the value for the fully resolved key... 99 | int defaultValueIdx = placeholder.indexOf(':'); 100 | String defaultValue = null; 101 | if (defaultValueIdx != -1) { 102 | defaultValue = placeholder.substring(defaultValueIdx + 1); 103 | placeholder = placeholder.substring(0, defaultValueIdx); 104 | } 105 | String propVal = placeholderResolver.resolvePlaceholder(placeholder); 106 | if (propVal == null) { 107 | propVal = defaultValue; 108 | } 109 | if (propVal != null) { 110 | // Recursive invocation, parsing placeholders contained in the 111 | // previously resolved placeholder value. 112 | propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); 113 | buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); 114 | startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length()); 115 | } else if (this.ignoreUnresolvablePlaceholders) { 116 | // Proceed with unprocessed value. 117 | startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); 118 | } else { 119 | throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'"); 120 | } 121 | 122 | visitedPlaceholders.remove(placeholder); 123 | } else { 124 | startIndex = -1; 125 | } 126 | } 127 | 128 | return buf.toString(); 129 | } 130 | 131 | private int findPlaceholderEndIndex(CharSequence buf, int startIndex) { 132 | int index = startIndex + this.placeholderPrefix.length(); 133 | int withinNestedPlaceholder = 0; 134 | while (index < buf.length()) { 135 | if (Strings.substringMatch(buf, index, this.placeholderSuffix)) { 136 | if (withinNestedPlaceholder > 0) { 137 | withinNestedPlaceholder--; 138 | index = index + this.placeholderPrefix.length() - 1; 139 | } else { 140 | return index; 141 | } 142 | } else if (Strings.substringMatch(buf, index, this.placeholderPrefix)) { 143 | withinNestedPlaceholder++; 144 | index = index + this.placeholderPrefix.length(); 145 | } else { 146 | index++; 147 | } 148 | } 149 | return -1; 150 | } 151 | 152 | /** 153 | * Strategy interface used to resolve replacement values for placeholders contained in Strings. 154 | * 155 | * @see net.csdn.common.property.PropertyPlaceholder 156 | */ 157 | public static interface PlaceholderResolver { 158 | 159 | /** 160 | * Resolves the supplied placeholder name into the replacement value. 161 | * 162 | * @param placeholderName the name of the placeholder to resolve. 163 | * @return the replacement value or null if no replacement is to be made. 164 | */ 165 | String resolvePlaceholder(String placeholderName); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/reflect/ReflectHelper.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.reflect; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.csdn.common.exception.ExceptionHandler; 5 | import org.apache.commons.beanutils.MethodUtils; 6 | 7 | import java.lang.annotation.Annotation; 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.Method; 10 | import java.lang.reflect.Modifier; 11 | import java.util.HashSet; 12 | import java.util.List; 13 | import java.util.Set; 14 | 15 | import static net.csdn.common.collections.WowCollections.list; 16 | 17 | /** 18 | * User: WilliamZhu 19 | * Date: 12-7-12 20 | * Time: 下午4:48 21 | */ 22 | public class ReflectHelper { 23 | 24 | 25 | public static List fields(Class clzz, Class annotation) { 26 | 27 | List result = list(); 28 | Field[] fields = clzz.getDeclaredFields(); 29 | for (Field field : fields) { 30 | if (field.isAnnotationPresent(annotation)) { 31 | result.add(field); 32 | } 33 | } 34 | return result; 35 | } 36 | 37 | public static List methods(Class clzz, Class annotation) { 38 | 39 | List result = list(); 40 | Method[] methods = clzz.getDeclaredMethods(); 41 | for (Method method : methods) { 42 | if (method.isAnnotationPresent(annotation)) { 43 | result.add(method); 44 | } 45 | } 46 | return result; 47 | } 48 | 49 | public static List findFieldsByAnnotation(Class clzz, Class annotation) { 50 | 51 | return fields(clzz, annotation); 52 | } 53 | 54 | public static List findMethodsByAnnotation(Class clzz, Class annotation) { 55 | 56 | return methods(clzz, annotation); 57 | } 58 | 59 | public static Field findField(Class clzz, String fieldName) { 60 | Field field = null; 61 | try { 62 | field = clzz.getDeclaredField(fieldName); 63 | } catch (Exception e) { 64 | if (clzz.getSuperclass() != null) { 65 | field = findField(clzz.getSuperclass(), fieldName); 66 | } 67 | } 68 | return field; 69 | } 70 | 71 | public static Method findMethodByName(Class clzz, String methodName) { 72 | Method result = null; 73 | Method[] methods = clzz.getDeclaredMethods(); 74 | for (Method method : methods) { 75 | if (method.getName().equals(methodName)) { 76 | result = method; 77 | break; 78 | } 79 | } 80 | if (result == null) { 81 | if (clzz.getSuperclass() != null) { 82 | result = findMethodByName(clzz.getSuperclass(), methodName); 83 | } 84 | } 85 | return result; 86 | } 87 | 88 | public static void field(Object obj, String fieldName, Object value) throws Exception { 89 | Field field = findField(obj.getClass(), fieldName); 90 | field.setAccessible(true); 91 | field.set(obj, value); 92 | } 93 | 94 | public static Object field(Object obj, String fieldName) throws Exception { 95 | Field field = findField(obj.getClass(), fieldName); 96 | field.setAccessible(true); 97 | return field.get(obj); 98 | } 99 | 100 | public static Object staticField(Class obj, String fieldName) { 101 | Field field = findField(obj, fieldName); 102 | field.setAccessible(true); 103 | try { 104 | return field.get(null); 105 | } catch (IllegalAccessException e) { 106 | e.printStackTrace(); 107 | } 108 | return null; 109 | } 110 | 111 | public static void staticField(Class obj, String fieldName, Object value) { 112 | Field field = findField(obj, fieldName); 113 | field.setAccessible(true); 114 | try { 115 | field.set(null, value); 116 | } catch (IllegalAccessException e) { 117 | e.printStackTrace(); 118 | } 119 | } 120 | 121 | 122 | public static void field(Object obj, Class clzz, String fieldName, Object value) throws Exception { 123 | Field field = findField(clzz, fieldName); 124 | field.setAccessible(true); 125 | field.set(obj, value); 126 | } 127 | 128 | public static Object field(Object obj, Class clzz, String fieldName) throws Exception { 129 | Field field = findField(clzz, fieldName); 130 | field.setAccessible(true); 131 | return field.get(obj); 132 | } 133 | 134 | public static Method findTTMethod(Class clazz, String methodName, Class... paramTypes) { 135 | Class superclass = clazz; 136 | try { 137 | return superclass.getDeclaredMethod(methodName, paramTypes); 138 | } catch (Exception e2) { 139 | do { 140 | superclass = superclass.getSuperclass(); 141 | try { 142 | return superclass.getDeclaredMethod(methodName, paramTypes); 143 | } catch (NoSuchMethodException e) { 144 | continue; 145 | } 146 | } 147 | while (superclass != null && !Object.class.getName().equals(superclass.getName())); 148 | } 149 | 150 | return null; 151 | } 152 | 153 | public static List findTTMethods(Class clazz, String methodName) { 154 | Set methodSet = new HashSet(); 155 | Class superclass = clazz; 156 | for (Method method : clazz.getDeclaredMethods()) { 157 | if (method.getName().equals(methodName)) { 158 | methodSet.add(method); 159 | } 160 | } 161 | 162 | do { 163 | superclass = superclass.getSuperclass(); 164 | for (Method method : superclass.getDeclaredMethods()) { 165 | if (method.getName().equals(methodName)) { 166 | methodSet.add(method); 167 | } 168 | } 169 | } 170 | while (superclass != null && !Object.class.getName().equals(superclass.getName())); 171 | return Lists.newArrayList(methodSet); 172 | } 173 | 174 | public static void method2(Object obj, String methodName) { 175 | try { 176 | Method method = null; 177 | try { 178 | method = obj.getClass().getDeclaredMethod(methodName); 179 | } catch (Exception e) { 180 | method = obj.getClass().getMethod(methodName); 181 | } 182 | method.setAccessible(true); 183 | method.invoke(obj); 184 | } catch (Exception e) { 185 | try { 186 | ExceptionHandler.renderHandle(e); 187 | } catch (Exception e1) { 188 | 189 | e1.printStackTrace(); 190 | } 191 | } 192 | } 193 | 194 | public static Object method(Object obj, String methodName) { 195 | try { 196 | Method method = null; 197 | try { 198 | method = obj.getClass().getDeclaredMethod(methodName); 199 | } catch (Exception e) { 200 | method = obj.getClass().getMethod(methodName); 201 | } 202 | method.setAccessible(true); 203 | return method.invoke(obj); 204 | } catch (Exception e) { 205 | try { 206 | ExceptionHandler.renderHandle(e); 207 | } catch (Exception e1) { 208 | 209 | e1.printStackTrace(); 210 | } 211 | return null; 212 | } 213 | } 214 | 215 | public static Object staticMethod(Class obj, String methodName, Object... params) { 216 | try { 217 | 218 | Method method = null; 219 | try { 220 | method = obj.getDeclaredMethod(methodName, paramsToTypes(params)); 221 | } catch (Exception e) { 222 | try { 223 | method = obj.getMethod(methodName, paramsToTypes(params)); 224 | } catch (Exception e1) { 225 | method = MethodUtils.getMatchingAccessibleMethod(obj, methodName, paramsToTypes(params)); 226 | } 227 | } 228 | if (!Modifier.isPublic(method.getModifiers())) { 229 | method.setAccessible(true); 230 | } 231 | return method.invoke(null, params); 232 | } catch (Exception e) { 233 | try { 234 | ExceptionHandler.renderHandle(e); 235 | } catch (Exception e1) { 236 | e1.printStackTrace(); 237 | } 238 | return null; 239 | } 240 | } 241 | 242 | 243 | public static Object method(Object obj, String methodName, Object... params) { 244 | try { 245 | 246 | Method method = null; 247 | try { 248 | method = obj.getClass().getDeclaredMethod(methodName, paramsToTypes(params)); 249 | } catch (Exception e) { 250 | try { 251 | method = obj.getClass().getMethod(methodName, paramsToTypes(params)); 252 | } catch (Exception e1) { 253 | method = MethodUtils.getMatchingAccessibleMethod(obj.getClass(), methodName, paramsToTypes(params)); 254 | } 255 | } 256 | method.setAccessible(true); 257 | return method.invoke(obj, params); 258 | } catch (Exception e) { 259 | try { 260 | ExceptionHandler.renderHandle(e); 261 | } catch (Exception e1) { 262 | e1.printStackTrace(); 263 | } 264 | return null; 265 | } 266 | } 267 | 268 | 269 | public static Class[] paramsToTypes(Object... params) { 270 | Class[] clzz = new Class[params.length]; 271 | int i = 0; 272 | for (Object tt : params) { 273 | clzz[i++] = tt.getClass(); 274 | } 275 | return clzz; 276 | } 277 | 278 | public static Annotation[] annotation(Object obj, String fieldName) throws Exception { 279 | Field field = obj.getClass().getDeclaredField(fieldName); 280 | return field.getAnnotations(); 281 | } 282 | 283 | } 284 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/reflect/WowMethod.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.reflect; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * User: WilliamZhu 7 | * Date: 12-11-6 8 | * Time: 下午1:54 9 | */ 10 | public class WowMethod { 11 | private Method method; 12 | private Object target; 13 | 14 | public WowMethod(Object target, Method method) { 15 | this.method = method; 16 | this.target = target; 17 | } 18 | 19 | public Object invoke(Object... params) { 20 | try { 21 | method.setAccessible(true); 22 | return method.invoke(target, params); 23 | } catch (Exception e) { 24 | e.printStackTrace(); 25 | } 26 | return null; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/DefaultScanService.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan; 2 | 3 | import com.mysql.jdbc.StringUtils; 4 | import net.csdn.common.scan.component.ClasspathUrlFinder; 5 | import net.csdn.common.scan.component.Filter; 6 | import net.csdn.common.scan.component.IteratorFactory; 7 | import net.csdn.common.scan.component.StreamIterator; 8 | 9 | import java.io.*; 10 | import java.net.MalformedURLException; 11 | import java.net.URL; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * BlogInfo: WilliamZhu 17 | * Date: 12-6-4 18 | * Time: 下午2:04 19 | */ 20 | public class DefaultScanService implements ScanService { 21 | 22 | 23 | private Class loader = DefaultScanService.class; 24 | 25 | public Class getLoader() { 26 | return loader; 27 | } 28 | 29 | public void setLoader(Class loader) { 30 | this.loader = loader; 31 | } 32 | 33 | @Override 34 | public URL packagePath(String packageName) { 35 | URL class_file_base_url = ClasspathUrlFinder.findClassBase(loader); 36 | try { 37 | return new URL("file:" + class_file_base_url.getPath() + packageName.replaceAll("\\.", "/") + "/"); 38 | } catch (MalformedURLException e) { 39 | e.printStackTrace(); 40 | } 41 | return null; 42 | } 43 | 44 | @Override 45 | public List classNames(String packageName) { 46 | return classNames(packageName, DefaultScanService.class); 47 | } 48 | 49 | @Override 50 | public List classNames(String packageName, Class baseClass) { 51 | URL class_file_base_url = ClasspathUrlFinder.findClassBase(baseClass); 52 | String packageNameWithDot = packageName.replace(".", File.separator); 53 | File packageDir = new File(class_file_base_url.getPath() + packageNameWithDot); 54 | List classes = new ArrayList(); 55 | List files = new ArrayList(); 56 | iterateDir(packageDir, files); 57 | for (File f : files) { 58 | String path = f.getPath(); 59 | int pos = StringUtils.indexOfIgnoreCase(path, packageNameWithDot); 60 | if (pos == -1) pos = 0; 61 | path = path.substring(pos, path.length() - 6).replace(File.separator, "."); 62 | classes.add(path); 63 | } 64 | return classes; 65 | } 66 | 67 | private void iterateDir(File file, List files) { 68 | if (file.isDirectory()) { 69 | for (File f : file.listFiles()) { 70 | iterateDir(f, files); 71 | } 72 | } else { 73 | files.add(file); 74 | } 75 | 76 | } 77 | 78 | @Override 79 | public List scanArchives(String packageName) throws IOException { 80 | return scanArchives(packagePath(packageName)); 81 | } 82 | 83 | @Override 84 | public List scanArchives(String packageName, LoadClassEnhanceCallBack loadClassEnhanceCallBack) throws IOException { 85 | return scanClass(scanArchives(packagePath(packageName)), loadClassEnhanceCallBack); 86 | } 87 | 88 | @Override 89 | public List scanArchives(URL... urls) throws IOException { 90 | List streamList = new ArrayList(); 91 | for (URL url : urls) { 92 | Filter filter = new Filter() { 93 | public boolean accepts(String filename) { 94 | if (filename.endsWith(".class")) { 95 | return true; 96 | 97 | } 98 | return false; 99 | } 100 | }; 101 | 102 | try { 103 | File urlPath = new File(url.getPath()); 104 | if (!urlPath.exists() || urlPath.list().length == 0) return streamList; 105 | StreamIterator it = IteratorFactory.create(url, filter); 106 | 107 | InputStream stream; 108 | while ((stream = it.next()) != null) streamList.add(stream); 109 | } catch (IOException e) { 110 | throw e; 111 | } 112 | } 113 | return streamList; 114 | 115 | } 116 | 117 | 118 | @Override 119 | public Class scanClass(InputStream bits, LoadClassEnhanceCallBack loadClassEnhanceCallBack) throws IOException { 120 | DataInputStream dstream = new DataInputStream(new BufferedInputStream(bits)); 121 | 122 | try { 123 | try { 124 | return loadClassEnhanceCallBack.loaded(dstream); 125 | } catch (Exception e) { 126 | e.printStackTrace(); 127 | } 128 | return null; 129 | } finally { 130 | dstream.close(); 131 | bits.close(); 132 | } 133 | } 134 | 135 | @Override 136 | public List scanClass(List inputStreams, LoadClassEnhanceCallBack loadClassEnhanceCallBack) throws IOException { 137 | List classList = new ArrayList(); 138 | for (InputStream inputStream : inputStreams) { 139 | classList.add(scanClass(inputStream, loadClassEnhanceCallBack)); 140 | } 141 | return classList; 142 | 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/ScanModule.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.Singleton; 5 | 6 | /** 7 | * BlogInfo: WilliamZhu 8 | * Date: 12-6-4 9 | * Time: 下午3:12 10 | */ 11 | public class ScanModule extends AbstractModule { 12 | @Override 13 | protected void configure() { 14 | bind(ScanService.class).to(DefaultScanService.class).in(Singleton.class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/ScanService.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.net.URL; 7 | import java.util.List; 8 | 9 | /** 10 | * BlogInfo: WilliamZhu 11 | * Date: 12-6-4 12 | * Time: 下午3:11 13 | */ 14 | public interface ScanService { 15 | URL packagePath(String packageName); 16 | 17 | List scanArchives(URL... urls) throws IOException; 18 | 19 | List scanArchives(String packageName) throws IOException; 20 | 21 | Class scanClass(InputStream bits, LoadClassEnhanceCallBack loadClassEnhanceCallBack) throws IOException; 22 | 23 | List scanArchives(String packageName, LoadClassEnhanceCallBack loadClassEnhanceCallBack) throws IOException; 24 | 25 | List scanClass(List inputStreams, LoadClassEnhanceCallBack loadClassEnhanceCallBack) throws IOException; 26 | 27 | public List classNames(String packageName); 28 | 29 | public List classNames(String packageName, Class baseClass); 30 | 31 | public Class getLoader(); 32 | 33 | public void setLoader(Class loader); 34 | 35 | public interface LoadClassEnhanceCallBack { 36 | public Class loaded(DataInputStream classFile); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/ClasspathUrlFinder.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.net.MalformedURLException; 6 | import java.net.URL; 7 | import java.util.ArrayList; 8 | import java.util.Enumeration; 9 | import java.util.List; 10 | import java.util.StringTokenizer; 11 | 12 | 13 | public class ClasspathUrlFinder { 14 | 15 | 16 | /** 17 | * Find the classpath URLs for a specific classpath resource. The classpath URL is extracted 18 | * from loader.getResources() using the baseResource. 19 | * 20 | * @param baseResource 21 | * @return 22 | */ 23 | public static URL[] findResourceBases(String baseResource, ClassLoader loader) { 24 | ArrayList list = new ArrayList(); 25 | try { 26 | Enumeration urls = loader.getResources(baseResource); 27 | while (urls.hasMoreElements()) { 28 | URL url = urls.nextElement(); 29 | list.add(findResourceBase(url, baseResource)); 30 | } 31 | } catch (IOException e) { 32 | throw new RuntimeException(e); 33 | } 34 | return list.toArray(new URL[list.size()]); 35 | } 36 | 37 | /** 38 | * Find the classpath URLs for a specific classpath resource. The classpath URL is extracted 39 | * from loader.getResources() using the baseResource. 40 | * 41 | * @param baseResource 42 | * @return 43 | */ 44 | public static URL[] findResourceBases(String baseResource) { 45 | return findResourceBases(baseResource, Thread.currentThread().getContextClassLoader()); 46 | } 47 | 48 | private static URL findResourceBase(URL url, String baseResource) { 49 | String urlString = url.toString(); 50 | int idx = urlString.lastIndexOf(baseResource); 51 | urlString = urlString.substring(0, idx); 52 | URL deployUrl = null; 53 | try { 54 | deployUrl = new URL(urlString); 55 | } catch (MalformedURLException e) { 56 | throw new RuntimeException(e); 57 | } 58 | return deployUrl; 59 | } 60 | 61 | /** 62 | * Find the classpath URL for a specific classpath resource. The classpath URL is extracted 63 | * from Thread.currentThread().getContextClassLoader().getResource() using the baseResource. 64 | * 65 | * @param baseResource 66 | * @return 67 | */ 68 | public static URL findResourceBase(String baseResource) { 69 | return findResourceBase(baseResource, Thread.currentThread().getContextClassLoader()); 70 | } 71 | 72 | /** 73 | * Find the classpath URL for a specific classpath resource. The classpath URL is extracted 74 | * from loader.getResource() using the baseResource. 75 | * 76 | * @param baseResource 77 | * @param loader 78 | * @return 79 | */ 80 | public static URL findResourceBase(String baseResource, ClassLoader loader) { 81 | URL url = loader.getResource(baseResource); 82 | return findResourceBase(url, baseResource); 83 | } 84 | 85 | /** 86 | * Find the classpath for the particular class 87 | * 88 | * @param clazz 89 | * @return 90 | */ 91 | public static URL findClassBase(Class clazz) { 92 | String resource = clazz.getName().replace('.', '/') + ".class"; 93 | return findResourceBase(resource, clazz.getClassLoader()); 94 | } 95 | 96 | /** 97 | * Uses the java.class.path system property to obtain a list of URLs that represent the CLASSPATH 98 | * 99 | * @return 100 | */ 101 | public static URL[] findClassPaths() { 102 | List list = new ArrayList(); 103 | String classpath = System.getProperty("java.class.path"); 104 | StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator); 105 | 106 | while (tokenizer.hasMoreTokens()) { 107 | String path = tokenizer.nextToken(); 108 | File fp = new File(path); 109 | if (!fp.exists()) throw new RuntimeException("File in java.class.path does not exist: " + fp); 110 | try { 111 | list.add(fp.toURL()); 112 | } catch (MalformedURLException e) { 113 | throw new RuntimeException(e); 114 | } 115 | } 116 | return list.toArray(new URL[list.size()]); 117 | } 118 | 119 | /** 120 | * Uses the java.class.path system property to obtain a list of URLs that represent the CLASSPATH 121 | *

122 | * paths is used as a filter to only include paths that have the specific relative file within it 123 | * 124 | * @param paths comma list of files that should exist in a particular path 125 | * @return 126 | */ 127 | public static URL[] findClassPaths(String... paths) { 128 | ArrayList list = new ArrayList(); 129 | 130 | String classpath = System.getProperty("java.class.path"); 131 | StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator); 132 | for (int i = 0; i < paths.length; i++) { 133 | paths[i] = paths[i].trim(); 134 | } 135 | 136 | while (tokenizer.hasMoreTokens()) { 137 | String path = tokenizer.nextToken().trim(); 138 | boolean found = false; 139 | for (String wantedPath : paths) { 140 | if (path.endsWith(File.separator + wantedPath)) { 141 | found = true; 142 | break; 143 | } 144 | } 145 | if (!found) continue; 146 | File fp = new File(path); 147 | if (!fp.exists()) throw new RuntimeException("File in java.class.path does not exists: " + fp); 148 | try { 149 | list.add(fp.toURL()); 150 | } catch (MalformedURLException e) { 151 | throw new RuntimeException(e); 152 | } 153 | } 154 | return list.toArray(new URL[list.size()]); 155 | } 156 | 157 | 158 | } 159 | 160 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/DirectoryIteratorFactory.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.IOException; 4 | import java.net.URL; 5 | 6 | 7 | public interface DirectoryIteratorFactory { 8 | StreamIterator create(URL url, Filter filter) throws IOException; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/FileIterator.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.InputStream; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | 11 | public class FileIterator implements StreamIterator { 12 | private ArrayList files; 13 | private int index = 0; 14 | 15 | public FileIterator(File file, Filter filter) { 16 | files = new ArrayList(); 17 | try { 18 | create(files, file, filter); 19 | } catch (Exception e) { 20 | throw new RuntimeException(e); 21 | } 22 | } 23 | 24 | protected static void create(List list, File dir, Filter filter) throws Exception { 25 | create(list, dir, filter, dir.getCanonicalPath()); 26 | } 27 | 28 | protected static void create(List list, File dir, Filter filter, String prefix) throws Exception { 29 | File[] files = dir.listFiles(); 30 | for (int i = 0; i < files.length; i++) { 31 | if (files[i].isDirectory()) { 32 | create(list, files[i], filter, prefix); 33 | } else { 34 | String path = files[i].getCanonicalPath(); 35 | String relativePath = path.substring(prefix.length() + 1); 36 | if (File.separatorChar == '\\') 37 | relativePath = relativePath.replace('\\', '/'); 38 | if (filter == null || filter.accepts(relativePath)) { 39 | list.add(files[i]); 40 | } 41 | } 42 | } 43 | } 44 | 45 | public InputStream next() { 46 | if (index >= files.size()) return null; 47 | File fp = (File) files.get(index++); 48 | try { 49 | return new FileInputStream(fp); 50 | } catch (FileNotFoundException e) { 51 | throw new RuntimeException(e); 52 | } 53 | } 54 | 55 | public void close() { 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/FileProtocolIteratorFactory.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.net.URISyntaxException; 6 | import java.net.URL; 7 | 8 | 9 | public class FileProtocolIteratorFactory implements DirectoryIteratorFactory { 10 | 11 | public StreamIterator create(URL url, Filter filter) throws IOException { 12 | // See http://weblogs.java.net/blog/2007/04/25/how-convert-javaneturl-javaiofile 13 | File f; 14 | try { 15 | f = new File(url.toURI()); 16 | } catch (URISyntaxException e) { 17 | f = new File(url.getPath()); 18 | } 19 | 20 | if (f.isDirectory()) { 21 | return new FileIterator(f, filter); 22 | } else { 23 | return new JarIterator(url.openStream(), filter); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/Filter.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | 4 | public interface Filter { 5 | boolean accepts(String filename); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/InputStreamWrapper.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | 7 | public class InputStreamWrapper extends InputStream { 8 | private InputStream delegate; 9 | 10 | public InputStreamWrapper(InputStream delegate) { 11 | this.delegate = delegate; 12 | } 13 | 14 | public int read() 15 | throws IOException { 16 | return delegate.read(); 17 | } 18 | 19 | public int read(byte[] bytes) 20 | throws IOException { 21 | return delegate.read(bytes); 22 | } 23 | 24 | public int read(byte[] bytes, int i, int i1) 25 | throws IOException { 26 | return delegate.read(bytes, i, i1); 27 | } 28 | 29 | public long skip(long l) 30 | throws IOException { 31 | return delegate.skip(l); 32 | } 33 | 34 | public int available() 35 | throws IOException { 36 | return delegate.available(); 37 | } 38 | 39 | public void close() 40 | throws IOException { 41 | // ignored 42 | } 43 | 44 | public void mark(int i) { 45 | delegate.mark(i); 46 | } 47 | 48 | public void reset() 49 | throws IOException { 50 | delegate.reset(); 51 | } 52 | 53 | public boolean markSupported() { 54 | return delegate.markSupported(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/IteratorFactory.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.IOException; 4 | import java.net.URL; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | /** 8 | * @author Bill Burke 9 | * @version $Revision: 1 $ 10 | */ 11 | public class IteratorFactory { 12 | private static final ConcurrentHashMap registry = new ConcurrentHashMap(); 13 | 14 | static { 15 | registry.put("file", new FileProtocolIteratorFactory()); 16 | } 17 | 18 | 19 | public static StreamIterator create(URL url, Filter filter) throws IOException { 20 | String urlString = url.toString(); 21 | if (urlString.endsWith("!/")) { 22 | urlString = urlString.substring(4); 23 | urlString = urlString.substring(0, urlString.length() - 2); 24 | url = new URL(urlString); 25 | } 26 | 27 | 28 | if (!urlString.endsWith("/")) { 29 | return new JarIterator(url.openStream(), filter); 30 | } else { 31 | DirectoryIteratorFactory factory = registry.get(url.getProtocol()); 32 | if (factory == null) throw new IOException("Unable to scan directory of protocol: " + url.getProtocol()); 33 | return factory.create(url, filter); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/JarIterator.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.jar.JarEntry; 8 | import java.util.jar.JarInputStream; 9 | 10 | 11 | public class JarIterator implements StreamIterator { 12 | JarInputStream jar; 13 | JarEntry next; 14 | Filter filter; 15 | boolean initial = true; 16 | boolean closed = false; 17 | 18 | public JarIterator(File file, Filter filter) throws IOException { 19 | this(new FileInputStream(file), filter); 20 | } 21 | 22 | 23 | public JarIterator(InputStream is, Filter filter) throws IOException { 24 | this.filter = filter; 25 | jar = new JarInputStream(is); 26 | } 27 | 28 | private void setNext() { 29 | initial = true; 30 | try { 31 | if (next != null) jar.closeEntry(); 32 | next = null; 33 | do { 34 | next = jar.getNextJarEntry(); 35 | } while (next != null && (next.isDirectory() || (filter == null || !filter.accepts(next.getName())))); 36 | if (next == null) { 37 | close(); 38 | } 39 | } catch (IOException e) { 40 | throw new RuntimeException("failed to browse jar", e); 41 | } 42 | } 43 | 44 | public InputStream next() { 45 | if (closed || (next == null && !initial)) return null; 46 | setNext(); 47 | if (next == null) return null; 48 | return new InputStreamWrapper(jar); 49 | } 50 | 51 | public void close() { 52 | try { 53 | closed = true; 54 | jar.close(); 55 | } catch (IOException ignored) { 56 | 57 | } 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/scan/component/StreamIterator.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.scan.component; 2 | 3 | import java.io.InputStream; 4 | 5 | 6 | public interface StreamIterator { 7 | InputStream next(); 8 | 9 | void close(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/settings/InternalSettingsPreparer.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.settings; 2 | 3 | import net.csdn.common.collect.Tuple; 4 | import net.csdn.common.env.Environment; 5 | 6 | import java.io.InputStream; 7 | 8 | import static net.csdn.common.Strings.cleanPath; 9 | import static net.csdn.common.settings.ImmutableSettings.settingsBuilder; 10 | 11 | /** 12 | * BlogInfo: william 13 | * Date: 11-9-2 14 | * Time: 上午10:00 15 | */ 16 | public class InternalSettingsPreparer { 17 | 18 | public static Tuple prepareSettings(Settings pSettings, String applicationYmlName) { 19 | ImmutableSettings.Builder settingsBuilder = settingsBuilder().put(pSettings); 20 | 21 | if (settingsBuilder.get("cluster.name") == null) { 22 | settingsBuilder.put("cluster.name", "csdn_search"); 23 | } 24 | 25 | Environment environment = new Environment(settingsBuilder.build()); 26 | String appName = "application.yml"; 27 | if (applicationYmlName != null && !applicationYmlName.isEmpty()) { 28 | appName = applicationYmlName; 29 | } 30 | settingsBuilder.loadFromUrl(environment.resolveConfig(appName)); 31 | 32 | Settings v1 = settingsBuilder.build(); 33 | 34 | environment = new Environment(v1); 35 | 36 | // put back the env settings 37 | settingsBuilder = settingsBuilder().put(v1); 38 | settingsBuilder.put("path.home", cleanPath(environment.homeFile().getAbsolutePath())); 39 | settingsBuilder.put("path.work", cleanPath(environment.workFile().getAbsolutePath())); 40 | settingsBuilder.put("path.work_with_cluster", cleanPath(environment.workWithClusterFile().getAbsolutePath())); 41 | settingsBuilder.put("path.data", cleanPath(environment.dataFile().getAbsolutePath())); 42 | settingsBuilder.put("path.data_with_cluster", cleanPath(environment.dataWithClusterFile().getAbsolutePath())); 43 | settingsBuilder.put("path.logs", cleanPath(environment.logsFile().getAbsolutePath())); 44 | 45 | 46 | return new Tuple(settingsBuilder.build(), environment); 47 | 48 | } 49 | 50 | public static Settings simplePrepareSettings(Settings pSettings, InputStream inputStream) { 51 | ImmutableSettings.Builder settingsBuilder = settingsBuilder().put(pSettings); 52 | settingsBuilder.loadFromStream("", inputStream); 53 | return settingsBuilder.build(); 54 | 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/settings/NoClassSettingsException.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.settings; 2 | 3 | import net.csdn.common.exception.SettingsException; 4 | 5 | /** 6 | * BlogInfo: william 7 | * Date: 11-9-1 8 | * Time: 下午4:37 9 | */ 10 | public class NoClassSettingsException extends SettingsException { 11 | 12 | public NoClassSettingsException(String message) { 13 | super(message); 14 | } 15 | 16 | public NoClassSettingsException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/settings/Settings.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.settings; 2 | 3 | import com.google.common.collect.ImmutableMap; 4 | import net.csdn.common.exception.SettingsException; 5 | import net.csdn.common.unit.ByteSizeValue; 6 | import net.csdn.common.unit.SizeValue; 7 | import net.csdn.common.unit.TimeValue; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * BlogInfo: william 13 | * Date: 11-9-1 14 | * Time: 下午2:20 15 | */ 16 | public interface Settings { 17 | /** 18 | * A settings that are filtered (and key is removed) with the specified prefix. 19 | */ 20 | Settings getByPrefix(String prefix); 21 | 22 | /** 23 | * The class loader associated with this settings. 24 | */ 25 | ClassLoader getClassLoader(); 26 | 27 | /** 28 | * The settings as a {@link java.util.Map}. 29 | */ 30 | ImmutableMap getAsMap(); 31 | 32 | /** 33 | * Returns the setting value associated with the setting key. 34 | * 35 | * @param setting The setting key 36 | * @return The setting value, null if it does not exists. 37 | */ 38 | String get(String setting); 39 | 40 | /** 41 | * Returns the setting value associated with the setting key. If it does not exists, 42 | * returns the default value provided. 43 | * 44 | * @param setting The setting key 45 | * @param defaultValue The value to return if no value is associated with the setting 46 | * @return The setting value, or the default value if no value exists 47 | */ 48 | String get(String setting, String defaultValue); 49 | 50 | /** 51 | * Returns group settings for the given setting prefix. 52 | */ 53 | Map getGroups(String settingPrefix) throws SettingsException; 54 | 55 | /** 56 | * Returns the setting value (as float) associated with the setting key. If it does not exists, 57 | * returns the default value provided. 58 | * 59 | * @param setting The setting key 60 | * @param defaultValue The value to return if no value is associated with the setting 61 | * @return The (float) value, or the default value if no value exists. 62 | * @throws SettingsException Failure to parse the setting 63 | */ 64 | Float getAsFloat(String setting, Float defaultValue) throws SettingsException; 65 | 66 | /** 67 | * Returns the setting value (as double) associated with the setting key. If it does not exists, 68 | * returns the default value provided. 69 | * 70 | * @param setting The setting key 71 | * @param defaultValue The value to return if no value is associated with the setting 72 | * @return The (double) value, or the default value if no value exists. 73 | * @throws SettingsException Failure to parse the setting 74 | */ 75 | Double getAsDouble(String setting, Double defaultValue) throws SettingsException; 76 | 77 | /** 78 | * Returns the setting value (as int) associated with the setting key. If it does not exists, 79 | * returns the default value provided. 80 | * 81 | * @param setting The setting key 82 | * @param defaultValue The value to return if no value is associated with the setting 83 | * @return The (int) value, or the default value if no value exists. 84 | * @throws SettingsException Failure to parse the setting 85 | */ 86 | Integer getAsInt(String setting, Integer defaultValue) throws SettingsException; 87 | 88 | /** 89 | * Returns the setting value (as long) associated with the setting key. If it does not exists, 90 | * returns the default value provided. 91 | * 92 | * @param setting The setting key 93 | * @param defaultValue The value to return if no value is associated with the setting 94 | * @return The (long) value, or the default value if no value exists. 95 | * @throws SettingsException Failure to parse the setting 96 | */ 97 | Long getAsLong(String setting, Long defaultValue) throws SettingsException; 98 | 99 | /** 100 | * Returns the setting value (as boolean) associated with the setting key. If it does not exists, 101 | * returns the default value provided. 102 | * 103 | * @param setting The setting key 104 | * @param defaultValue The value to return if no value is associated with the setting 105 | * @return The (boolean) value, or the default value if no value exists. 106 | * @throws SettingsException Failure to parse the setting 107 | */ 108 | Boolean getAsBoolean(String setting, Boolean defaultValue) throws SettingsException; 109 | 110 | /** 111 | * Returns the setting value (as time) associated with the setting key. If it does not exists, 112 | * returns the default value provided. 113 | * 114 | * @param setting The setting key 115 | * @param defaultValue The value to return if no value is associated with the setting 116 | * @return The (time) value, or the default value if no value exists. 117 | * @throws SettingsException Failure to parse the setting 118 | */ 119 | TimeValue getAsTime(String setting, TimeValue defaultValue) throws SettingsException; 120 | 121 | /** 122 | * Returns the setting value (as size) associated with the setting key. If it does not exists, 123 | * returns the default value provided. 124 | * 125 | * @param setting The setting key 126 | * @param defaultValue The value to return if no value is associated with the setting 127 | * @return The (size) value, or the default value if no value exists. 128 | * @throws SettingsException Failure to parse the setting 129 | */ 130 | ByteSizeValue getAsBytesSize(String setting, ByteSizeValue defaultValue) throws SettingsException; 131 | 132 | /** 133 | * Returns the setting value (as size) associated with the setting key. If it does not exists, 134 | * returns the default value provided. 135 | * 136 | * @param setting The setting key 137 | * @param defaultValue The value to return if no value is associated with the setting 138 | * @return The (size) value, or the default value if no value exists. 139 | * @throws SettingsException Failure to parse the setting 140 | */ 141 | SizeValue getAsSize(String setting, SizeValue defaultValue) throws SettingsException; 142 | 143 | /** 144 | * Returns the setting value (as a class) associated with the setting key. If it does not exists, 145 | * returns the default class provided. 146 | * 147 | * @param setting The setting key 148 | * @param defaultClazz The class to return if no value is associated with the setting 149 | * @param The type of the class 150 | * @return The class setting value, or the default class provided is no value exists 151 | * @throws net.csdn.common.settings.NoClassSettingsException 152 | * Failure to load a class 153 | */ 154 | Class getAsClass(String setting, Class defaultClazz) throws NoClassSettingsException; 155 | 156 | /** 157 | * Returns the setting value (as a class) associated with the setting key. If the value itself fails to 158 | * represent a loadable class, the value will be appended to the prefixPackage and suffixed with the 159 | * suffixClassName and it will try to be loaded with it. 160 | * 161 | * @param setting The setting key 162 | * @param defaultClazz The class to return if no value is associated with the setting 163 | * @param prefixPackage The prefix package to prefix the value with if failing to load the class as is 164 | * @param suffixClassName The suffix class name to prefix the value with if failing to load the class as is 165 | * @param The type of the class 166 | * @return The class represented by the setting value, or the default class provided if no value exists 167 | * @throws net.csdn.common.settings.NoClassSettingsException 168 | * Failure to load the class 169 | */ 170 | Class getAsClass(String setting, Class defaultClazz, String prefixPackage, String suffixClassName) throws NoClassSettingsException; 171 | 172 | /** 173 | * The values associated with a setting prefix as an array. The settings array is in the format of: 174 | * settingPrefix.[index]. 175 | *

176 | *

It will also automatically load a comma separated list under the settingPrefix and merge with 177 | * the numbered format. 178 | * 179 | * @param settingPrefix The setting prefix to load the array by 180 | * @return The setting array values 181 | * @throws SettingsException 182 | */ 183 | String[] getAsArray(String settingPrefix, String[] defaultArray) throws SettingsException; 184 | 185 | /** 186 | * The values associated with a setting prefix as an array. The settings array is in the format of: 187 | * settingPrefix.[index]. 188 | *

189 | *

It will also automatically load a comma separated list under the settingPrefix and merge with 190 | * the numbered format. 191 | * 192 | * @param settingPrefix The setting prefix to load the array by 193 | * @return The setting array values 194 | * @throws SettingsException 195 | */ 196 | String[] getAsArray(String settingPrefix) throws SettingsException; 197 | 198 | /** 199 | * A settings builder interface. 200 | */ 201 | interface Builder { 202 | 203 | /** 204 | * Builds the settings. 205 | */ 206 | Settings build(); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/time/NumberExtendedForTime.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.time; 2 | 3 | import net.csdn.common.collections.WowCollections; 4 | import net.csdn.common.reflect.ReflectHelper; 5 | import org.joda.time.DateTime; 6 | 7 | import java.util.Collections; 8 | import java.util.Comparator; 9 | import java.util.List; 10 | 11 | /** 12 | * 4/14/13 WilliamZhu(allwefantasy@gmail.com) 13 | */ 14 | public class NumberExtendedForTime { 15 | DateTime time = new DateTime(); 16 | private long extened; 17 | private String type; 18 | private String operate; 19 | 20 | public NumberExtendedForTime(int int_extened) { 21 | this.extened = int_extened; 22 | } 23 | 24 | public NumberExtendedForTime(long int_extened) { 25 | this.extened = int_extened; 26 | } 27 | 28 | public NumberExtendedForTime day() { 29 | type = "Days"; 30 | return this; 31 | } 32 | 33 | public NumberExtendedForTime minute() { 34 | type = "Minutes"; 35 | return this; 36 | } 37 | 38 | public NumberExtendedForTime second() { 39 | type = "Seconds"; 40 | return this; 41 | } 42 | 43 | public NumberExtendedForTime hour() { 44 | type = "Hours"; 45 | return this; 46 | } 47 | 48 | public NumberExtendedForTime week() { 49 | type = "Weeks"; 50 | return this; 51 | } 52 | 53 | public NumberExtendedForTime month() { 54 | type = "Months"; 55 | return this; 56 | } 57 | 58 | public NumberExtendedForTime millis() { 59 | type = "Millis"; 60 | return this; 61 | } 62 | 63 | public NumberExtendedForTime year() { 64 | type = "Years"; 65 | return this; 66 | } 67 | 68 | public DateTime ago() { 69 | operate = "minus"; 70 | return (DateTime) ReflectHelper.method(time, operate + type, extened); 71 | } 72 | 73 | public DateTime fromNow() { 74 | operate = "plus"; 75 | return (DateTime) ReflectHelper.method(time, operate + type, extened); 76 | } 77 | 78 | public DateTime from_now() { 79 | return fromNow(); 80 | } 81 | 82 | public static void main(String[] args) { 83 | List jack = WowCollections.list(3, 5, 1); 84 | Collections.sort(jack, new Comparator() { 85 | @Override 86 | public int compare(Integer integer, Integer integer2) { 87 | return integer - integer2; 88 | } 89 | }); 90 | System.out.println(WowCollections.join(jack, ",")); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/unit/ByteSizeUnit.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.unit; 2 | 3 | /** 4 | * BlogInfo: william 5 | * Date: 11-9-1 6 | * Time: 下午4:16 7 | */ 8 | public enum ByteSizeUnit { 9 | BYTES { 10 | @Override 11 | public long toBytes(long size) { 12 | return size; 13 | } 14 | 15 | @Override 16 | public long toKB(long size) { 17 | return size / (C1 / C0); 18 | } 19 | 20 | @Override 21 | public long toMB(long size) { 22 | return size / (C2 / C0); 23 | } 24 | 25 | @Override 26 | public long toGB(long size) { 27 | return size / (C3 / C0); 28 | } 29 | }, 30 | KB { 31 | @Override 32 | public long toBytes(long size) { 33 | return x(size, C1 / C0, MAX / (C1 / C0)); 34 | } 35 | 36 | @Override 37 | public long toKB(long size) { 38 | return size; 39 | } 40 | 41 | @Override 42 | public long toMB(long size) { 43 | return size / (C2 / C1); 44 | } 45 | 46 | @Override 47 | public long toGB(long size) { 48 | return size / (C3 / C1); 49 | } 50 | }, 51 | MB { 52 | @Override 53 | public long toBytes(long size) { 54 | return x(size, C2 / C0, MAX / (C2 / C0)); 55 | } 56 | 57 | @Override 58 | public long toKB(long size) { 59 | return x(size, C2 / C1, MAX / (C2 / C1)); 60 | } 61 | 62 | @Override 63 | public long toMB(long size) { 64 | return size; 65 | } 66 | 67 | @Override 68 | public long toGB(long size) { 69 | return size / (C3 / C2); 70 | } 71 | }, 72 | GB { 73 | @Override 74 | public long toBytes(long size) { 75 | return x(size, C3 / C0, MAX / (C3 / C0)); 76 | } 77 | 78 | @Override 79 | public long toKB(long size) { 80 | return x(size, C3 / C1, MAX / (C3 / C1)); 81 | } 82 | 83 | @Override 84 | public long toMB(long size) { 85 | return x(size, C3 / C2, MAX / (C3 / C2)); 86 | } 87 | 88 | @Override 89 | public long toGB(long size) { 90 | return size; 91 | } 92 | }; 93 | 94 | static final long C0 = 1L; 95 | static final long C1 = C0 * 1024L; 96 | static final long C2 = C1 * 1024L; 97 | static final long C3 = C2 * 1024L; 98 | 99 | static final long MAX = Long.MAX_VALUE; 100 | 101 | /** 102 | * Scale d by m, checking for overflow. 103 | * This has a short name to make above code more readable. 104 | */ 105 | static long x(long d, long m, long over) { 106 | if (d > over) return Long.MAX_VALUE; 107 | if (d < -over) return Long.MIN_VALUE; 108 | return d * m; 109 | } 110 | 111 | 112 | public long toBytes(long size) { 113 | throw new AbstractMethodError(); 114 | } 115 | 116 | public long toKB(long size) { 117 | throw new AbstractMethodError(); 118 | } 119 | 120 | public long toMB(long size) { 121 | throw new AbstractMethodError(); 122 | } 123 | 124 | public long toGB(long size) { 125 | throw new AbstractMethodError(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/unit/ByteSizeValue.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.unit; 2 | 3 | import net.csdn.common.Strings; 4 | import net.csdn.common.exception.ParseException; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * BlogInfo: william 10 | * Date: 11-9-1 11 | * Time: 下午4:12 12 | */ 13 | public class ByteSizeValue implements Serializable { 14 | private long size; 15 | 16 | private ByteSizeUnit sizeUnit; 17 | 18 | private ByteSizeValue() { 19 | 20 | } 21 | 22 | public ByteSizeValue(long bytes) { 23 | this(bytes, ByteSizeUnit.BYTES); 24 | } 25 | 26 | public ByteSizeValue(long size, ByteSizeUnit sizeUnit) { 27 | this.size = size; 28 | this.sizeUnit = sizeUnit; 29 | } 30 | 31 | public long bytes() { 32 | return sizeUnit.toBytes(size); 33 | } 34 | 35 | public long getBytes() { 36 | return bytes(); 37 | } 38 | 39 | public long kb() { 40 | return sizeUnit.toKB(size); 41 | } 42 | 43 | public long getKb() { 44 | return kb(); 45 | } 46 | 47 | public long mb() { 48 | return sizeUnit.toMB(size); 49 | } 50 | 51 | public long getMb() { 52 | return mb(); 53 | } 54 | 55 | public long gb() { 56 | return sizeUnit.toGB(size); 57 | } 58 | 59 | public long getGb() { 60 | return gb(); 61 | } 62 | 63 | public double kbFrac() { 64 | return ((double) bytes()) / ByteSizeUnit.C1; 65 | } 66 | 67 | public double getKbFrac() { 68 | return kbFrac(); 69 | } 70 | 71 | public double mbFrac() { 72 | return ((double) bytes()) / ByteSizeUnit.C2; 73 | } 74 | 75 | public double getMbFrac() { 76 | return mbFrac(); 77 | } 78 | 79 | public double gbFrac() { 80 | return ((double) bytes()) / ByteSizeUnit.C3; 81 | } 82 | 83 | public double getGbFrac() { 84 | return gbFrac(); 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | long bytes = bytes(); 90 | double value = bytes; 91 | String suffix = "b"; 92 | if (bytes >= ByteSizeUnit.C3) { 93 | value = gbFrac(); 94 | suffix = "gb"; 95 | } else if (bytes >= ByteSizeUnit.C2) { 96 | value = mbFrac(); 97 | suffix = "mb"; 98 | } else if (bytes >= ByteSizeUnit.C1) { 99 | value = kbFrac(); 100 | suffix = "kb"; 101 | } 102 | return Strings.format1Decimals(value, suffix); 103 | } 104 | 105 | public static ByteSizeValue parseBytesSizeValue(String sValue) throws ParseException { 106 | return parseBytesSizeValue(sValue, null); 107 | } 108 | 109 | public static ByteSizeValue parseBytesSizeValue(String sValue, ByteSizeValue defaultValue) throws ParseException { 110 | if (sValue == null) { 111 | return defaultValue; 112 | } 113 | long bytes; 114 | try { 115 | if (sValue.endsWith("k") || sValue.endsWith("K")) { 116 | bytes = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * ByteSizeUnit.C1); 117 | } else if (sValue.endsWith("kb")) { 118 | bytes = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 2)) * ByteSizeUnit.C1); 119 | } else if (sValue.endsWith("m") || sValue.endsWith("M")) { 120 | bytes = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * ByteSizeUnit.C2); 121 | } else if (sValue.endsWith("mb")) { 122 | bytes = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 2)) * ByteSizeUnit.C2); 123 | } else if (sValue.endsWith("g") || sValue.endsWith("G")) { 124 | bytes = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * ByteSizeUnit.C3); 125 | } else if (sValue.endsWith("gb")) { 126 | bytes = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 2)) * ByteSizeUnit.C3); 127 | } else if (sValue.endsWith("b")) { 128 | bytes = Long.parseLong(sValue.substring(0, sValue.length() - 1)); 129 | } else { 130 | bytes = Long.parseLong(sValue); 131 | } 132 | } catch (NumberFormatException e) { 133 | throw new ParseException("Failed to parse [" + sValue + "]", e); 134 | } 135 | return new ByteSizeValue(bytes, ByteSizeUnit.BYTES); 136 | } 137 | 138 | 139 | @Override 140 | public boolean equals(Object o) { 141 | if (this == o) return true; 142 | if (o == null || getClass() != o.getClass()) return false; 143 | 144 | ByteSizeValue sizeValue = (ByteSizeValue) o; 145 | 146 | if (size != sizeValue.size) return false; 147 | if (sizeUnit != sizeValue.sizeUnit) return false; 148 | 149 | return true; 150 | } 151 | 152 | @Override 153 | public int hashCode() { 154 | int result = (int) (size ^ (size >>> 32)); 155 | result = 31 * result + (sizeUnit != null ? sizeUnit.hashCode() : 0); 156 | return result; 157 | } 158 | 159 | 160 | } 161 | -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/unit/SizeUnit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elastic Search and Shay Banon under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. Elastic Search licenses this 6 | * file to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package net.csdn.common.unit; 21 | 22 | /** 23 | * @author kimchy (shay.banon) 24 | */ 25 | public enum SizeUnit { 26 | SINGLE { 27 | @Override 28 | public long toSingles(long size) { 29 | return size; 30 | } 31 | 32 | @Override 33 | public long toKilo(long size) { 34 | return size / (C1 / C0); 35 | } 36 | 37 | @Override 38 | public long toMega(long size) { 39 | return size / (C2 / C0); 40 | } 41 | 42 | @Override 43 | public long toGiga(long size) { 44 | return size / (C3 / C0); 45 | } 46 | }, 47 | KILO { 48 | @Override 49 | public long toSingles(long size) { 50 | return x(size, C1 / C0, MAX / (C1 / C0)); 51 | } 52 | 53 | @Override 54 | public long toKilo(long size) { 55 | return size; 56 | } 57 | 58 | @Override 59 | public long toMega(long size) { 60 | return size / (C2 / C1); 61 | } 62 | 63 | @Override 64 | public long toGiga(long size) { 65 | return size / (C3 / C1); 66 | } 67 | }, 68 | MEGA { 69 | @Override 70 | public long toSingles(long size) { 71 | return x(size, C2 / C0, MAX / (C2 / C0)); 72 | } 73 | 74 | @Override 75 | public long toKilo(long size) { 76 | return x(size, C2 / C1, MAX / (C2 / C1)); 77 | } 78 | 79 | @Override 80 | public long toMega(long size) { 81 | return size; 82 | } 83 | 84 | @Override 85 | public long toGiga(long size) { 86 | return size / (C3 / C2); 87 | } 88 | }, 89 | GIGA { 90 | @Override 91 | public long toSingles(long size) { 92 | return x(size, C3 / C0, MAX / (C3 / C0)); 93 | } 94 | 95 | @Override 96 | public long toKilo(long size) { 97 | return x(size, C3 / C1, MAX / (C3 / C1)); 98 | } 99 | 100 | @Override 101 | public long toMega(long size) { 102 | return x(size, C3 / C2, MAX / (C3 / C2)); 103 | } 104 | 105 | @Override 106 | public long toGiga(long size) { 107 | return size; 108 | } 109 | }; 110 | 111 | static final long C0 = 1L; 112 | static final long C1 = C0 * 1000L; 113 | static final long C2 = C1 * 1000L; 114 | static final long C3 = C2 * 1000L; 115 | 116 | static final long MAX = Long.MAX_VALUE; 117 | 118 | /** 119 | * Scale d by m, checking for overflow. 120 | * This has a short name to make above code more readable. 121 | */ 122 | static long x(long d, long m, long over) { 123 | if (d > over) return Long.MAX_VALUE; 124 | if (d < -over) return Long.MIN_VALUE; 125 | return d * m; 126 | } 127 | 128 | 129 | public long toSingles(long size) { 130 | throw new AbstractMethodError(); 131 | } 132 | 133 | public long toKilo(long size) { 134 | throw new AbstractMethodError(); 135 | } 136 | 137 | public long toMega(long size) { 138 | throw new AbstractMethodError(); 139 | } 140 | 141 | public long toGiga(long size) { 142 | throw new AbstractMethodError(); 143 | } 144 | } -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/unit/SizeValue.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.unit; 2 | 3 | 4 | import net.csdn.common.Strings; 5 | import net.csdn.common.exception.ParseException; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | */ 11 | public class SizeValue implements Serializable { 12 | 13 | private long size; 14 | 15 | private SizeUnit sizeUnit; 16 | 17 | private SizeValue() { 18 | 19 | } 20 | 21 | public SizeValue(long singles) { 22 | this(singles, SizeUnit.SINGLE); 23 | } 24 | 25 | public SizeValue(long size, SizeUnit sizeUnit) { 26 | this.size = size; 27 | this.sizeUnit = sizeUnit; 28 | } 29 | 30 | public long singles() { 31 | return sizeUnit.toSingles(size); 32 | } 33 | 34 | public long getSingles() { 35 | return singles(); 36 | } 37 | 38 | public long kilo() { 39 | return sizeUnit.toKilo(size); 40 | } 41 | 42 | public long getKilo() { 43 | return kilo(); 44 | } 45 | 46 | public long mega() { 47 | return sizeUnit.toMega(size); 48 | } 49 | 50 | public long getMega() { 51 | return mega(); 52 | } 53 | 54 | public long giga() { 55 | return sizeUnit.toGiga(size); 56 | } 57 | 58 | public long getGiga() { 59 | return giga(); 60 | } 61 | 62 | public double kiloFrac() { 63 | return ((double) singles()) / SizeUnit.C1; 64 | } 65 | 66 | public double getKiloFrac() { 67 | return kiloFrac(); 68 | } 69 | 70 | public double megaFrac() { 71 | return ((double) singles()) / SizeUnit.C2; 72 | } 73 | 74 | public double getMegaFrac() { 75 | return megaFrac(); 76 | } 77 | 78 | public double gigaFrac() { 79 | return ((double) singles()) / SizeUnit.C3; 80 | } 81 | 82 | public double getGigaFrac() { 83 | return gigaFrac(); 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | long singles = singles(); 89 | double value = singles; 90 | String suffix = ""; 91 | if (singles >= SizeUnit.C3) { 92 | value = gigaFrac(); 93 | suffix = "g"; 94 | } else if (singles >= SizeUnit.C2) { 95 | value = megaFrac(); 96 | suffix = "m"; 97 | } else if (singles >= SizeUnit.C1) { 98 | value = kiloFrac(); 99 | suffix = "k"; 100 | } 101 | return Strings.format1Decimals(value, suffix); 102 | } 103 | 104 | public static SizeValue parseSizeValue(String sValue) throws ParseException { 105 | return parseSizeValue(sValue, null); 106 | } 107 | 108 | public static SizeValue parseSizeValue(String sValue, SizeValue defaultValue) throws ParseException { 109 | if (sValue == null) { 110 | return defaultValue; 111 | } 112 | long singles; 113 | try { 114 | if (sValue.endsWith("b")) { 115 | singles = Long.parseLong(sValue.substring(0, sValue.length() - 1)); 116 | } else if (sValue.endsWith("k") || sValue.endsWith("K")) { 117 | singles = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * SizeUnit.C1); 118 | } else if (sValue.endsWith("m") || sValue.endsWith("M")) { 119 | singles = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * SizeUnit.C2); 120 | } else if (sValue.endsWith("g") || sValue.endsWith("G")) { 121 | singles = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * SizeUnit.C3); 122 | } else { 123 | singles = Long.parseLong(sValue); 124 | } 125 | } catch (NumberFormatException e) { 126 | throw new ParseException("Failed to parse [" + sValue + "]", e); 127 | } 128 | return new SizeValue(singles, SizeUnit.SINGLE); 129 | } 130 | 131 | 132 | @Override 133 | public boolean equals(Object o) { 134 | if (this == o) return true; 135 | if (o == null || getClass() != o.getClass()) return false; 136 | 137 | SizeValue sizeValue = (SizeValue) o; 138 | 139 | if (size != sizeValue.size) return false; 140 | if (sizeUnit != sizeValue.sizeUnit) return false; 141 | 142 | return true; 143 | } 144 | 145 | @Override 146 | public int hashCode() { 147 | int result = (int) (size ^ (size >>> 32)); 148 | result = 31 * result + (sizeUnit != null ? sizeUnit.hashCode() : 0); 149 | return result; 150 | } 151 | } -------------------------------------------------------------------------------- /src/main/java/net/csdn/common/unit/TimeValue.java: -------------------------------------------------------------------------------- 1 | package net.csdn.common.unit; 2 | 3 | import net.csdn.common.Strings; 4 | import net.csdn.common.exception.ParseException; 5 | import org.joda.time.Period; 6 | import org.joda.time.PeriodType; 7 | import org.joda.time.format.PeriodFormat; 8 | import org.joda.time.format.PeriodFormatter; 9 | 10 | import java.io.Serializable; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | /** 14 | * BlogInfo: william 15 | * Date: 11-9-1 16 | * Time: 下午4:18 17 | */ 18 | public class TimeValue implements Serializable { 19 | 20 | public static TimeValue timeValueMillis(long millis) { 21 | return new TimeValue(millis, TimeUnit.MILLISECONDS); 22 | } 23 | 24 | public static TimeValue timeValueSeconds(long seconds) { 25 | return new TimeValue(seconds, TimeUnit.SECONDS); 26 | } 27 | 28 | public static TimeValue timeValueMinutes(long minutes) { 29 | return new TimeValue(minutes, TimeUnit.MINUTES); 30 | } 31 | 32 | public static TimeValue timeValueHours(long hours) { 33 | return new TimeValue(hours, TimeUnit.HOURS); 34 | } 35 | 36 | private long duration; 37 | 38 | private TimeUnit timeUnit; 39 | 40 | private TimeValue() { 41 | 42 | } 43 | 44 | public TimeValue(long millis) { 45 | this(millis, TimeUnit.MILLISECONDS); 46 | } 47 | 48 | public TimeValue(long duration, TimeUnit timeUnit) { 49 | this.duration = duration; 50 | this.timeUnit = timeUnit; 51 | } 52 | 53 | public long nanos() { 54 | return timeUnit.toNanos(duration); 55 | } 56 | 57 | public long getNanos() { 58 | return nanos(); 59 | } 60 | 61 | public long micros() { 62 | return timeUnit.toMicros(duration); 63 | } 64 | 65 | public long getMicros() { 66 | return micros(); 67 | } 68 | 69 | public long millis() { 70 | return timeUnit.toMillis(duration); 71 | } 72 | 73 | public long getMillis() { 74 | return millis(); 75 | } 76 | 77 | public long seconds() { 78 | return timeUnit.toSeconds(duration); 79 | } 80 | 81 | public long getSeconds() { 82 | return seconds(); 83 | } 84 | 85 | public long minutes() { 86 | return timeUnit.toMinutes(duration); 87 | } 88 | 89 | public long getMinutes() { 90 | return minutes(); 91 | } 92 | 93 | public long hours() { 94 | return timeUnit.toHours(duration); 95 | } 96 | 97 | public long getHours() { 98 | return hours(); 99 | } 100 | 101 | public long days() { 102 | return timeUnit.toDays(duration); 103 | } 104 | 105 | public long getDays() { 106 | return days(); 107 | } 108 | 109 | public double microsFrac() { 110 | return ((double) nanos()) / C1; 111 | } 112 | 113 | public double getMicrosFrac() { 114 | return microsFrac(); 115 | } 116 | 117 | public double millisFrac() { 118 | return ((double) nanos()) / C2; 119 | } 120 | 121 | public double getMillisFrac() { 122 | return millisFrac(); 123 | } 124 | 125 | public double secondsFrac() { 126 | return ((double) nanos()) / C3; 127 | } 128 | 129 | public double getSecondsFrac() { 130 | return secondsFrac(); 131 | } 132 | 133 | public double minutesFrac() { 134 | return ((double) nanos()) / C4; 135 | } 136 | 137 | public double getMinutesFrac() { 138 | return minutesFrac(); 139 | } 140 | 141 | public double hoursFrac() { 142 | return ((double) nanos()) / C5; 143 | } 144 | 145 | public double getHoursFrac() { 146 | return hoursFrac(); 147 | } 148 | 149 | public double daysFrac() { 150 | return ((double) nanos()) / C6; 151 | } 152 | 153 | public double getDaysFrac() { 154 | return daysFrac(); 155 | } 156 | 157 | private final PeriodFormatter defaultFormatter = PeriodFormat.getDefault() 158 | .withParseType(PeriodType.standard()); 159 | 160 | public String format() { 161 | Period period = new Period(millis()); 162 | return defaultFormatter.print(period); 163 | } 164 | 165 | public String format(PeriodType type) { 166 | Period period = new Period(millis()); 167 | return PeriodFormat.getDefault().withParseType(type).print(period); 168 | } 169 | 170 | @Override 171 | public String toString() { 172 | if (duration < 0 && timeUnit == TimeUnit.MILLISECONDS) { 173 | return Long.toString(duration); 174 | } 175 | long nanos = nanos(); 176 | if (nanos == 0) { 177 | return "0s"; 178 | } 179 | double value = nanos; 180 | String suffix = "nanos"; 181 | if (nanos >= C6) { 182 | value = daysFrac(); 183 | suffix = "d"; 184 | } else if (nanos >= C5) { 185 | value = hoursFrac(); 186 | suffix = "h"; 187 | } else if (nanos >= C4) { 188 | value = minutesFrac(); 189 | suffix = "m"; 190 | } else if (nanos >= C3) { 191 | value = secondsFrac(); 192 | suffix = "s"; 193 | } else if (nanos >= C2) { 194 | value = millisFrac(); 195 | suffix = "ms"; 196 | } else if (nanos >= C1) { 197 | value = microsFrac(); 198 | suffix = "micros"; 199 | } 200 | return Strings.format1Decimals(value, suffix); 201 | } 202 | 203 | public static TimeValue parseTimeValue(String sValue) { 204 | return parseTimeValue(sValue, null); 205 | } 206 | 207 | public static TimeValue parseTimeValue(String sValue, TimeValue defaultValue) { 208 | if (sValue == null) { 209 | return defaultValue; 210 | } 211 | try { 212 | long millis; 213 | if (sValue.endsWith("S")) { 214 | millis = Long.parseLong(sValue.substring(0, sValue.length() - 1)); 215 | } else if (sValue.endsWith("ms")) { 216 | millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - "ms".length()))); 217 | } else if (sValue.endsWith("s")) { 218 | millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 1000); 219 | } else if (sValue.endsWith("m")) { 220 | millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 1000); 221 | } else if (sValue.endsWith("H") || sValue.endsWith("h")) { 222 | millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 60 * 1000); 223 | } else if (sValue.endsWith("d")) { 224 | millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 24 * 60 * 60 * 1000); 225 | } else if (sValue.endsWith("w")) { 226 | millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 7 * 24 * 60 * 60 * 1000); 227 | } else { 228 | millis = Long.parseLong(sValue); 229 | } 230 | return new TimeValue(millis, TimeUnit.MILLISECONDS); 231 | } catch (NumberFormatException e) { 232 | throw new ParseException("Failed to parse [" + sValue + "]", e); 233 | } 234 | } 235 | 236 | static final long C0 = 1L; 237 | static final long C1 = C0 * 1000L; 238 | static final long C2 = C1 * 1000L; 239 | static final long C3 = C2 * 1000L; 240 | static final long C4 = C3 * 60L; 241 | static final long C5 = C4 * 60L; 242 | static final long C6 = C5 * 24L; 243 | 244 | 245 | @Override 246 | public boolean equals(Object o) { 247 | if (this == o) return true; 248 | if (o == null || getClass() != o.getClass()) return false; 249 | 250 | TimeValue timeValue = (TimeValue) o; 251 | 252 | if (duration != timeValue.duration) return false; 253 | if (timeUnit != timeValue.timeUnit) return false; 254 | 255 | return true; 256 | } 257 | 258 | @Override 259 | public int hashCode() { 260 | int result = (int) (duration ^ (duration >>> 32)); 261 | result = 31 * result + (timeUnit != null ? timeUnit.hashCode() : 0); 262 | return result; 263 | } 264 | } 265 | --------------------------------------------------------------------------------